from __future__ import annotations
from typing import Optional, TYPE_CHECKING, cast
import abc
import enum
import logging
import os
import pathlib

from ezdxf import options
from .font_face import FontFace
from .font_manager import (
    FontManager,
    SUPPORTED_TTF_TYPES,
    FontNotFoundError,
    UnsupportedFont,
)
from .font_measurements import FontMeasurements
from .glyphs import GlyphPath, Glyphs

if TYPE_CHECKING:
    from ezdxf.document import Drawing
    from ezdxf.entities import DXFEntity, Textstyle

logger = logging.getLogger("ezdxf")
FONT_MANAGER_CACHE_FILE = "font_manager_cache.json"
# SUT = System Under Test, see build_sut_font_manager_cache() function
SUT_FONT_MANAGER_CACHE = False
CACHE_DIRECTORY = ".cache"
font_manager = FontManager()

SHX_FONTS = {
    # See examples in: CADKitSamples/Shapefont.dxf
    # Shape file structure is not documented, therefore, replace these fonts by
    # true type fonts.
    # `None` is for: use the default font.
    #
    # All these replacement TTF fonts have a copyright remark:
    # "(c) Copyright 1996 by Autodesk Inc., All rights reserved"
    # and therefore can not be included in ezdxf or the associated repository!
    # You got them if you install any Autodesk product, like the free available
    # DWG/DXF viewer "TrueView" : https://www.autodesk.com/viewers
    "AMGDT": "amgdt___.ttf",  # Tolerance symbols
    "AMGDT.SHX": "amgdt___.ttf",
    "COMPLEX": "complex_.ttf",
    "COMPLEX.SHX": "complex_.ttf",
    "ISOCP": "isocp.ttf",
    "ISOCP.SHX": "isocp.ttf",
    "ITALIC": "italicc_.ttf",
    "ITALIC.SHX": "italicc_.ttf",
    "GOTHICG": "gothicg_.ttf",
    "GOTHICG.SHX": "gothicg_.ttf",
    "GREEKC": "greekc.ttf",
    "GREEKC.SHX": "greekc.ttf",
    "ROMANS": "romans__.ttf",
    "ROMANS.SHX": "romans__.ttf",
    "SCRIPTS": "scripts_.ttf",
    "SCRIPTS.SHX": "scripts_.ttf",
    "SCRIPTC": "scriptc_.ttf",
    "SCRIPTC.SHX": "scriptc_.ttf",
    "SIMPLEX": "simplex_.ttf",
    "SIMPLEX.SHX": "simplex_.ttf",
    "SYMATH": "symath__.ttf",
    "SYMATH.SHX": "symath__.ttf",
    "SYMAP": "symap___.ttf",
    "SYMAP.SHX": "symap___.ttf",
    "SYMETEO": "symeteo_.ttf",
    "SYMETEO.SHX": "symeteo_.ttf",
    "TXT": "txt_____.ttf",  # Default AutoCAD font
    "TXT.SHX": "txt_____.ttf",
}
LFF_FONTS = {
    "TXT": "standard.lff",
    "TXT.SHX": "standard.lff",
}
TTF_TO_SHX = {v: k for k, v in SHX_FONTS.items() if k.endswith("SHX")}
DESCENDER_FACTOR = 0.333  # from TXT SHX font - just guessing
X_HEIGHT_FACTOR = 0.666  # from TXT SHX font - just guessing
MONOSPACE = "*monospace"  # last resort fallback font only for measurement

def map_shx_to_ttf(font_name: str) -> str:
    """Map .shx font names to .ttf file names. e.g. "TXT" -> "txt_____.ttf" """
    # Map SHX fonts to True Type Fonts:
    font_upper = font_name.upper()
    if font_upper in SHX_FONTS:
        font_name = SHX_FONTS[font_upper]
    return font_name

def map_shx_to_lff(font_name: str) -> str:
    """Map .shx font names to .lff file names. e.g. "TXT" -> "standard.lff" """
    font_upper = font_name.upper()
    name = LFF_FONTS.get(font_upper, "")
    if font_manager.has_font(name):
        return name
    if not font_upper.endswith(".SHX"):
        lff_name = font_name + ".lff"
    else:
        lff_name = font_name[:-4] + ".lff"
    if font_manager.has_font(lff_name):
        return lff_name
    return font_name

def is_shx_font_name(font_name: str) -> bool:
    name = font_name.lower()
    if name.endswith(".shx"):
        return True
    if "." not in name:
        return True
    return False

def map_ttf_to_shx(ttf: str) -> Optional[str]:
    """Maps .ttf filenames to .shx font names. e.g. "txt_____.ttf" -> "TXT" """
    return TTF_TO_SHX.get(ttf.lower())

def build_system_font_cache() -> None:
    """Builds or rebuilds the font manager cache. The font manager cache has a fixed
    location in the cache directory of the users home directory "~/.cache/ezdxf" or the
    directory specified by the environment variable "XDG_CACHE_HOME".
    """
    build_font_manager_cache(_get_font_manager_path())

def find_font_face(font_name: str) -> FontFace:
    """Returns the :class:`FontFace` definition for the given font filename
    e.g. "LiberationSans-Regular.ttf".

    """
    return font_manager.get_font_face(font_name)

def get_font_face(font_name: str, map_shx=True) -> FontFace:
    """Returns  the :class:`FontFace` definition for the given font filename
    e.g. "LiberationSans-Regular.ttf".

    This function translates a DXF font definition by the TTF font file name into a
    :class:`FontFace` object. Returns the :class:`FontFace` of the default font when a
    font is not available on the current system.

    Args:
        font_name: raw font file name as stored in the
            :class:`~ezdxf.entities.Textstyle` entity
        map_shx: maps SHX font names to TTF replacement fonts,
            e.g. "TXT" -> "txt_____.ttf"

    """
    if not isinstance(font_name, str):
        raise TypeError("font_name has invalid type")
    if map_shx:
        font_name = map_shx_to_ttf(font_name)
    return find_font_face(font_name)

def resolve_shx_font_name(font_name: str, order: str) -> str:
    """Resolves a .shx font name, the argument `order` defines the resolve order:

    - "t" = map .shx fonts to TrueType fonts (.ttf, .ttc, .otf)
    - "s" = use shapefile fonts (.shx, .shp)
    - "l" = map .shx fonts to LibreCAD fonts (.lff)

    """
    if len(order) == 0:
        return font_name
    order = order.lower()
    for type_str in order:
        if type_str == "t":
            name = map_shx_to_ttf(font_name)
            if font_manager.has_font(name):
                return name
        elif type_str == "s":
            if not font_name.lower().endswith(".shx"):
                font_name += ".shx"
            if font_manager.has_font(font_name):
                return font_name
        elif type_str == "l":
            name = map_shx_to_lff(font_name)
            if font_manager.has_font(name):
                return name
    return font_name

def resolve_font_face(font_name: str, order="tsl") -> FontFace:
    """Returns the :class:`FontFace` definition for the given font filename
    e.g. "LiberationSans-Regular.ttf".

    This function translates a DXF font definition by the TTF font file name into a
    :class:`FontFace` object. Returns the :class:`FontFace` of the default font when a
    font is not available on the current system.

    The order argument defines the resolve order for .shx fonts:

    - "t" = map .shx fonts to TrueType fonts (.ttf, .ttc, .otf)
    - "s" = use shapefile fonts (.shx, .shp)
    - "l" = map .shx fonts to LibreCAD fonts (.lff)

    Args:
        font_name: raw font file name as stored in the
            :class:`~ezdxf.entities.Textstyle` entity
        order: resolving order

    """
    if not isinstance(font_name, str):
        raise TypeError("font_name has invalid type")
    if is_shx_font_name(font_name):
        font_name = resolve_shx_font_name(font_name, order)
    return find_font_face(font_name)

def get_font_measurements(font_name: str, map_shx=True) -> FontMeasurements:
    """Get :class:`FontMeasurements` for the given font filename
    e.g. "LiberationSans-Regular.ttf".

    Args:
        font_name: raw font file name as stored in the
            :class:`~ezdxf.entities.Textstyle` entity
        map_shx: maps SHX font names to TTF replacement fonts,
            e.g. "TXT" -> "txt_____.ttf"

    """
    if map_shx:
        font_name = map_shx_to_ttf(font_name)
    elif is_shx_font_name(font_name):
        return FontMeasurements(
            baseline=0,
            cap_height=1,
            x_height=X_HEIGHT_FACTOR,
            descender_height=DESCENDER_FACTOR,
        )
    font = TrueTypeFont(font_name, cap_height=1)
    return font.measurements

def find_best_match(
    *,
    family: str = "sans-serif",
    style: str = "Regular",
    weight: int = 400,
    width: int = 5,
    italic: Optional[bool] = False,
) -> Optional[FontFace]:
    """Returns a :class:`FontFace` that matches the given properties best. The search
    is based the descriptive properties and not on comparing glyph shapes. Returns
    ``None`` if no font was found.

    Args:
        family: font family name e.g. "sans-serif", "Liberation Sans"
        style: font style e.g. "Regular", "Italic", "Bold"
        weight: weight in the range from 1-1000 (usWeightClass)
        width: width in the range from 1-9 (usWidthClass)
        italic: ``True``, ``False`` or ``None`` to ignore this flag

    """
    return font_manager.find_best_match(family, style, weight, width, italic)

def find_font_file_name(font_face: FontFace) -> str:
    """Returns the true type font file name without parent directories e.g. "Arial.ttf"."""
    return font_manager.find_font_name(font_face)

def load():
    """Reload all cache files. The cache files are loaded automatically at the import
    of `ezdxf`.
    """
    _load_font_manager()

def _get_font_manager_path():
    cache_path = options.xdg_path("XDG_CACHE_HOME", CACHE_DIRECTORY)
    return cache_path / FONT_MANAGER_CACHE_FILE

def _load_font_manager() -> None:
    fm_path = _get_font_manager_path()
    if fm_path.exists():
        try:
            font_manager.loads(fm_path.read_text())
            return
        except IOError as e:
            logger.info(f"Error loading cache file: {str(e)}")
    build_font_manager_cache(fm_path)

def build_sut_font_manager_cache(repo_font_path: pathlib.Path) -> None:
    """Load font manger cache for system under test (sut).

    Load the fonts included in the repository folder "./fonts" to guarantee the tests
    have the same fonts available on all systems.

    This function should be called from "conftest.py".

    """
    global SUT_FONT_MANAGER_CACHE
    SUT_FONT_MANAGER_CACHE = True
    font_manager.clear()
    cache_file = repo_font_path / "font_manager_cache.json"
    if cache_file.exists():
        try:
            font_manager.loads(cache_file.read_text())
            return
        except IOError as e:
            print(f"Error loading cache file: {str(e)}")
    font_manager.build([str(repo_font_path)], support_dirs=False)
    s = font_manager.dumps()
    try:
        cache_file.write_text(s)
    except IOError as e:
        print(f"Error writing cache file: {str(e)}")

def make_cache_directory(path: pathlib.Path) -> None:
    if not path.exists():
        try:
            path.mkdir(parents=True)
        except IOError:
            pass

def build_font_manager_cache(path: pathlib.Path) -> None:
    font_manager.clear()
    font_manager.build()
    s = font_manager.dumps()
    cache_dir = path.parent
    make_cache_directory(cache_dir)
    if not cache_dir.exists():
        logger.warning(
            f"Cannot create cache home directory: '{str(cache_dir)}', cache files will "
            f"not be saved.\nSee also issue https://github.com/mozman/ezdxf/issues/923."
        )
        return
    try:
        path.write_text(s)
    except IOError as e:
        logger.warning(f"Error writing cache file: '{str(e)}'")

class FontRenderType(enum.Enum):
    # render glyphs as filled paths: TTF, OTF
    OUTLINE = enum.auto()

    # render glyphs as line strokes: SHX, SHP
    STROKE = enum.auto

class AbstractFont:
    """The `ezdxf` font abstraction for text measurement and text path rendering."""

    font_render_type = FontRenderType.STROKE
    name: str = "undefined"

    def __init__(self, measurements: FontMeasurements):
        self.measurements = measurements

    @abc.abstractmethod
    def text_width(self, text: str) -> float:
        """Returns the text width in drawing units for the given `text` string."""
        pass

    @abc.abstractmethod
    def text_width_ex(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> float:
        """Returns the text width in drawing units, bypasses the stored `cap_height` and
        `width_factor`.
        """
        pass

    @abc.abstractmethod
    def space_width(self) -> float:
        """Returns the width of a "space" character a.k.a. word spacing."""
        pass

    @abc.abstractmethod
    def text_path(self, text: str) -> GlyphPath:
        """Returns the 2D text path for the given text."""
        ...

    @abc.abstractmethod
    def text_path_ex(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> GlyphPath:
        """Returns the 2D text path for the given text, bypasses the stored `cap_height`
        and `width_factor`."""
        ...

    @abc.abstractmethod
    def text_glyph_paths(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> list[GlyphPath]:
        """Returns a list of 2D glyph paths for the given text, bypasses the stored
        `cap_height` and `width_factor`."""
        ...

class MonospaceFont(AbstractFont):
    """Represents a monospaced font where each letter has the same cap- and descender
    height and the same width. The given cap height and width factor are the default
    values for measurements and rendering. The extended methods can override these
    default values.

    This font exists only for generic text measurement in tests and does not render any
    glyphs!

    """

    font_render_type = FontRenderType.STROKE
    name = MONOSPACE

    def __init__(
        self,
        cap_height: float,
        width_factor: float = 1.0,
        baseline: float = 0,
        descender_factor: float = DESCENDER_FACTOR,
        x_height_factor: float = X_HEIGHT_FACTOR,
    ):
        super().__init__(
            FontMeasurements(
                baseline=baseline,
                cap_height=cap_height,
                x_height=cap_height * x_height_factor,
                descender_height=cap_height * descender_factor,
            )
        )
        self._width_factor: float = abs(width_factor)
        self._space_width = self.measurements.cap_height * self._width_factor

    def text_width(self, text: str) -> float:
        """Returns the text width in drawing units for the given `text`."""
        return self.text_width_ex(
            text, self.measurements.cap_height, self._width_factor
        )

    def text_width_ex(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> float:
        """Returns the text width in drawing units, bypasses the stored `cap_height` and
        `width_factor`.
        """
        return len(text) * cap_height * width_factor

    def text_path(self, text: str) -> GlyphPath:
        """Returns the rectangle text width x cap height as :class:`NumpyPath2d` instance."""
        return self.text_path_ex(text, self.measurements.cap_height, self._width_factor)

    def text_path_ex(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> GlyphPath:
        """Returns the rectangle text width x cap height as  :class:`NumpyPath2d`
        instance, bypasses the stored `cap_height` and `width_factor`.
        """
        from ezdxf.path import Path

        text_width = self.text_width_ex(text, cap_height, width_factor)
        p = Path((0, 0))
        p.line_to((text_width, 0))
        p.line_to((text_width, cap_height))
        p.line_to((0, cap_height))
        p.close()
        return GlyphPath(p)

    def text_glyph_paths(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> list[GlyphPath]:
        """Returns the same rectangle as the method :meth:`text_path_ex` in a list."""
        return [self.text_path_ex(text, cap_height, width_factor)]

    def space_width(self) -> float:
        """Returns the width of a "space" char."""
        return self._space_width

class _CachedFont(AbstractFont, abc.ABC):
    """Abstract font with caching support."""

    _glyph_caches: dict[str, Glyphs] = dict()

    def __init__(self, font_name: str, cap_height: float, width_factor: float = 1.0):
        self.name = font_name
        cache = self.create_cache(font_name)
        self.glyph_cache = cache
        self.cap_height = float(cap_height)
        self.width_factor = float(width_factor)
        scale_factor: float = cache.get_scaling_factor(self.cap_height)
        super().__init__(cache.font_measurements.scale(scale_factor))
        self._space_width: float = (
            self.glyph_cache.space_width * scale_factor * width_factor
        )

    @abc.abstractmethod
    def create_cache(self, font_name: str) -> Glyphs:
        ...

    def text_width(self, text: str) -> float:
        """Returns the text width in drawing units for the given `text` string."""
        return self.text_width_ex(text, self.cap_height, self.width_factor)

    def text_width_ex(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> float:
        """Returns the text width in drawing units, bypasses the stored `cap_height` and
        `width_factor`.
        """
        if not text.strip():
            return 0
        return self.glyph_cache.get_text_length(text, cap_height, width_factor)

    def text_path(self, text: str) -> GlyphPath:
        """Returns the 2D text path for the given text."""

        return self.text_path_ex(text, self.cap_height, self.width_factor)

    def text_path_ex(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> GlyphPath:
        """Returns the 2D text path for the given text, bypasses the stored `cap_height`
        and `width_factor`."""
        return self.glyph_cache.get_text_path(text, cap_height, width_factor)

    def text_glyph_paths(
        self, text: str, cap_height: float, width_factor: float = 1.0
    ) -> list[GlyphPath]:
        """Returns a list of 2D glyph paths for the given text, bypasses the stored
        `cap_height` and `width_factor`."""
        return self.glyph_cache.get_text_glyph_paths(text, cap_height, width_factor)

    def space_width(self) -> float:
        """Returns the width of a "space" char."""
        return self._space_width

class TrueTypeFont(_CachedFont):
    """Represents a TrueType font. Font measurement and glyph rendering is done by the
    `fontTools` package. The given cap height and width factor are the default values
    for measurements and glyph rendering. The extended methods can override these
    default values.
    """

    font_render_type = FontRenderType.OUTLINE

    def create_cache(self, ttf: str) -> Glyphs:
        from .ttfonts import TTFontRenderer

        key = pathlib.Path(ttf).name.lower()
        try:
            return self._glyph_caches[key]
        except KeyError:
            pass
        try:
            cache = TTFontRenderer(font_manager.get_ttf_font(ttf))
        except UnsupportedFont:
            fallback_font_name = font_manager.fallback_font_name()
            logger.info(f"replacing unsupported font '{ttf}' by '{fallback_font_name}'")
            cache = TTFontRenderer(font_manager.get_ttf_font(fallback_font_name))
        self._glyph_caches[key] = cache
        return cache

class _UnmanagedTrueTypeFont(_CachedFont):
    font_render_type = FontRenderType.OUTLINE

    def create_cache(self, ttf: str) -> Glyphs:
        from .ttfonts import TTFontRenderer
        from fontTools.ttLib import TTFont

        key = ttf.lower()
        try:
            return self._glyph_caches[key]
        except KeyError:
            pass
        cache = TTFontRenderer(TTFont(ttf, fontNumber=0))
        self._glyph_caches[key] = cache
        return cache

def sideload_ttf(font_path: str | os.PathLike, cap_height) -> AbstractFont:
    """This function bypasses the FontManager and loads the TrueType font straight from
    the file system, requires the absolute font file path e.g. "C:/Windows/Fonts/Arial.ttf".

    .. warning::

        Expert feature, use with care: no fallback font and no error handling.

    """

    return _UnmanagedTrueTypeFont(str(font_path), cap_height)

class ShapeFileFont(_CachedFont):
    """Represents a shapefile font (.shx, .shp). Font measurement and glyph rendering is
    done by the ezdxf.fonts.shapefile module. The given cap height and width factor are
    the default values for measurements and glyph rendering. The extended methods can
    override these default values.

    """

    font_render_type = FontRenderType.STROKE

    def create_cache(self, font_name: str) -> Glyphs:
        key = font_name.lower()
        try:
            return self._glyph_caches[key]
        except KeyError:
            pass
        glyph_cache = font_manager.get_shapefile_glyph_cache(font_name)
        self._glyph_caches[key] = glyph_cache
        return glyph_cache

class LibreCadFont(_CachedFont):
    """Represents a LibreCAD font (.shx, .shp). Font measurement and glyph rendering is
    done by the ezdxf.fonts.lff module. The given cap height and width factor are the
    default values for measurements and glyph rendering. The extended methods can
    override these default values.

    """

    font_render_type = FontRenderType.STROKE

    def create_cache(self, font_name: str) -> Glyphs:
        key = font_name.lower()
        try:
            return self._glyph_caches[key]
        except KeyError:
            pass
        glyph_cache = font_manager.get_lff_glyph_cache(font_name)
        self._glyph_caches[key] = glyph_cache
        return glyph_cache

def make_font(
    font_name: str, cap_height: float, width_factor: float = 1.0
) -> AbstractFont:
    r"""Returns a font abstraction based on class :class:`AbstractFont`.

    Supported font types:

    - .ttf, .ttc and .otf - TrueType fonts
    - .shx, .shp - Autodesk® shapefile fonts
    - .lff - LibreCAD font format

    The special name "\*monospace" returns the fallback font :class:`MonospaceFont` for
    testing and basic measurements.

    .. note:: The font definition files are not included in `ezdxf`.

    Args:
        font_name: font file name as stored in the :class:`~ezdxf.entities.Textstyle`
            entity e.g. "OpenSans-Regular.ttf"
        cap_height: desired cap height in drawing units.
        width_factor: horizontal text stretch factor

    """
    if font_name == MONOSPACE:
        return MonospaceFont(cap_height, width_factor)
    ext = pathlib.Path(font_name).suffix.lower()
    last_resort = MonospaceFont(cap_height, width_factor)
    if ext in SUPPORTED_TTF_TYPES:
        try:
            return TrueTypeFont(font_name, cap_height, width_factor)
        except FontNotFoundError as e:
            logger.warning(f"no default font found: {str(e)}")
            return last_resort
    elif ext == ".shx" or ext == ".shp":
        try:
            return ShapeFileFont(font_name, cap_height, width_factor)
        except FontNotFoundError:
            pass
        except UnsupportedFont:
            # change name - the font exists but is not supported
            font_name = font_manager.fallback_font_name()
    elif ext == ".lff":
        try:
            return LibreCadFont(font_name, cap_height, width_factor)
        except FontNotFoundError:
            pass
    elif ext == "":  # e.g. "TXT"
        font_face = font_manager.find_best_match(
            family=font_name, style=".shx", italic=None
        )
        if font_face is not None:
            return make_font(font_face.filename, cap_height, width_factor)
    else:
        logger.warning(f"unsupported font-name suffix: {font_name}")
        font_name = font_manager.fallback_font_name()

    # return default TrueType font
    try:
        return TrueTypeFont(font_name, cap_height, width_factor)
    except FontNotFoundError as e:
        logger.warning(f"no default font found: {str(e)}")
        return last_resort

def get_entity_font_face(entity: DXFEntity, doc: Optional[Drawing] = None) -> FontFace:
    """Returns the :class:`FontFace` defined by the associated text style.
    Returns the default font face if the `entity` does not have or support
    the DXF attribute "style". Supports the extended font information stored in
    :class:`~ezdxf.entities.Textstyle` table entries.

    Pass a DXF document as argument `doc` to resolve text styles for virtual
    entities which are not assigned to a DXF document. The argument `doc`
    always overrides the DXF document to which the `entity` is assigned to.

    """
    if entity.doc and doc is None:
        doc = entity.doc
    if doc is None:
        return FontFace()

    style_name = ""
    # This works also for entities which do not support "style",
    # where style_name = entity.dxf.get("style") would fail.
    if entity.dxf.is_supported("style"):
        style_name = entity.dxf.style

    font_face = FontFace()
    if style_name:
        style = cast("Textstyle", doc.styles.get(style_name))
        family, italic, bold = style.get_extended_font_data()
        if family:
            text_style = "Italic" if italic else "Regular"
            text_weight = 700 if bold else 400
            font_face = FontFace(family=family, style=text_style, weight=text_weight)
        else:
            ttf = style.dxf.font
            if ttf:
                font_face = get_font_face(ttf)
    return font_face

_load_font_manager()

{'TTFontRenderer': 'ttfonts.TTFontRenderer', 'TTFont': 'fontTools.ttLib.TTFont'}


# -*- coding: utf-8 -*-
# author: itimor

from django import forms
from blog.models import Article, BlogTypes
from mdeditor.fields import MDTextFormField
from taggit.forms import TagField

class ArticleAddForm(forms.Form):
    name = forms.CharField(label=u'文章标题', max_length=50)
    cover = forms.ImageField(label=u'封面', )
    content = MDTextFormField(label=u'内容', min_length=50)
    type = forms.ChoiceField(label=u'分类', choices=BlogTypes)
    tags = TagField(label=u'标签', max_length=50)

    def save(self):
        cd = self.cleaned_data
        name = cd['name']
        cover = cd['cover']
        type = cd['type']
        content = cd['content']
        tags = cd['tags']
        article = Article(
            name=name,
            cover=cover,
            content=content,
            type=type,
            tags=tags)
        article.save()


import os
import time
import sys
import shutil
import argparse

# for production stuff, consider the custom container images mentioned in buildNetworkWithAzure.py
#os.system('rm -rd keras-audio')
#os.system('rm -rd model')
os.system('apt update && apt-get install -y python python-dev python-pip build-essential swig git libpulse-dev libasound2-dev portaudio19-dev')
#os.system('git clone https://github.com/chen0040/keras-audio.git')
#os.system('cp -r keras-audio/keras_audio .')
#os.system('mkdir model')

sys.path.append('.')
from azure.storage.blob import BlockBlobService
from keras_audio.library.cifar10 import Cifar10AudioClassifier

azureStorgeAccountName = 'kevinsayazstorage'
azureStorageKeyName = '8H5YxVREMOVEDoHvaXvHgxiA=='
azureStorageContainer = 'completedmodel2'
labels = [100,90,80,70,60,50,40,30,20,10]
parser = argparse.ArgumentParser()
parser.add_argument("--data_dir")
args = parser.parse_args()

def load_path_labels(sourcePath):
    # here we are expecting file in the format XXXXXXX-N.wav, where N is the label
    pairs = []
    for f in os.listdir(sourcePath):
        try:
            if str(f.split('.')[1]).lower() == 'wav':          # only process wav files
                label = int(f.split('.')[0].split('-')[1])
                path = sourcePath + '/' + f
                pairs.append((path, labels.index(label)))
        except:
            print('error with: ' + str(f))
    return pairs

def main():
    block_blob_service = BlockBlobService(account_name=azureStorgeAccountName, account_key=azureStorageKeyName)
    if (block_blob_service.exists(container_name=azureStorageContainer) == False):
        block_blob_service.create_container(container_name=azureStorageContainer)

    audio_path_label_pairs = load_path_labels(str(args.data_dir))
    print('loaded: ' + str(len(audio_path_label_pairs)) + ' files')

    classifier = Cifar10AudioClassifier()
    batch_size = 8
    epochs = 50
    classifier.fit(audio_path_label_pairs=audio_path_label_pairs, model_dir_path='model', batch_size=batch_size, epochs=epochs)

    #zipping and uploading the compiled model to blob storage
    shutil.make_archive(base_name='model', format='zip', base_dir='model')
    block_blob_service.create_blob_from_path(azureStorageContainer, str(int(time.time() * 1000)) + 'model.zip', 'model.zip')

    # copying the model contents to the output directory
    os.system('cp -r ./model outputs')

if __name__ == '__main__':
    main()


import time

import cv2
import numpy as np

# img = cv2.imread('images/stih.jpg')
video=cv2.VideoCapture('videos/i_am_ya_2023-04-14-11-03-46_1681452226541.mp4')
k=0
while cv2.waitKey(1) & 0xFF !=ord('q'):
    # img_shape = cv2.resize(img, (img.shape[1] // 2, img.shape[0] // 2))
    succ,img=video.read()
    img = cv2.GaussianBlur(img, (9, 9), 0)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    img = cv2.Canny(img,55,55)

    kernel = np.ones((3,3),np.uint8)
    img = cv2.dilate(img, kernel,iterations=1)
    cv2.putText(img,f'{k}', (0,0),cv2.FONT_HERSHEY_TRIPLEX,50,(0,0,255),thickness=0)
    img=cv2.erode(img,kernel,iterations=1)
    # img_shape[400:800,400:800]
    # cv2.putText(img, f'{k}', (0, 0), cv2.FONT_HERSHEY_TRIPLEX, 50, (0, 0, 255), thickness=0)
    cv2.imshow('Result', img)
    k+=1
    print(img.shape)

# print(img_shape.shape)
#
    cv2.waitKey(0)


import os
import pwd
import grp
import time
import errno
from stat import *

from Mailman import mm_cfg
from Mailman import Utils
from Mailman import LockFile
from Mailman.i18n import C_
from Mailman.MailList import MailList
from Mailman.MTA.Utils import makealiases
from Mailman.Logging.Syslog import syslog

LOCKFILE = os.path.join(mm_cfg.LOCK_DIR, 'creator')
ALIASFILE = os.path.join(mm_cfg.DATA_DIR, 'aliases')
VIRTFILE = os.path.join(mm_cfg.DATA_DIR, 'virtual-mailman')
# Desired mode for aliases(.db) and virtual-mailman(.db) for both creation
# and check_perms.
targetmode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH

def _update_maps():
    # Helper function to fix owner and mode.
    def fixom(file):
        # It's not necessary for the non-db file to be S_IROTH, but for
        # simplicity and compatibility with check_perms, we set it.
        stat = os.stat(file)
        if (stat[ST_MODE] & targetmode) != targetmode:
            os.chmod(file, stat[ST_MODE] | targetmode)
        dbfile = file + '.db'
        try:
            stat = os.stat(dbfile)
        except OSError as e:
            if e.errno != errno.ENOENT:
                raise
            return
        if (stat[ST_MODE] & targetmode) != targetmode:
            os.chmod(dbfile, stat[ST_MODE] | targetmode)
        user = mm_cfg.MAILMAN_USER
        if stat[ST_UID] != pwd.getpwnam(user)[2]:
            uid = pwd.getpwnam(user)[2]
            gid = grp.getgrnam(mm_cfg.MAILMAN_GROUP)[2]
            os.chown(dbfile, uid, gid)
    msg = 'command failed: %s (status: %s, %s)'
    acmd = mm_cfg.POSTFIX_ALIAS_CMD + ' ' + ALIASFILE
    status = (os.system(acmd) >> 8) & 0xff
    if status:
        errstr = os.strerror(status)
        syslog('error', msg, acmd, status, errstr)
        raise RuntimeError(msg % (acmd, status, errstr))
    # Fix owner and mode of .db if needed.
    fixom(ALIASFILE)
    if os.path.exists(VIRTFILE):
        vcmd = mm_cfg.POSTFIX_MAP_CMD + ' ' + VIRTFILE
        status = (os.system(vcmd) >> 8) & 0xff
        if status:
            errstr = os.strerror(status)
            syslog('error', msg, vcmd, status, errstr)
            raise RuntimeError(msg % (vcmd, status, errstr))
        # Fix owner and mode of .db if needed.
        fixom(VIRTFILE)

def makelock():
    return LockFile.LockFile(LOCKFILE)

def _zapfile(filename):
    # Truncate the file w/o messing with the file permissions, but only if it
    # already exists.
    if os.path.exists(filename):
        fp = open(filename, 'w')
        fp.close()

def clear():
    _zapfile(ALIASFILE)
    _zapfile(VIRTFILE)

def _addlist(mlist, fp):
    # Set up the mailman-loop address
    loopaddr = Utils.ParseEmail(Utils.get_site_email(extra='loop'))[0]
    loopmbox = os.path.join(mm_cfg.DATA_DIR, 'owner-bounces.mbox')
    # Seek to the end of the text file, but if it's empty write the standard
    # disclaimer, and the loop catch address.
    fp.seek(0, 2)
    if not fp.tell():
        print("""\
# This file is generated by Mailman, and is kept in sync with the
# binary hash file aliases.db.  YOU SHOULD NOT MANUALLY EDIT THIS FILE
# unless you know what you're doing, and can keep the two files properly
# in sync.  If you screw it up, you're on your own.
""", file=fp)
        print('# The ultimate loop stopper address', file=fp)
        print('%s: %s' % (loopaddr, loopmbox), file=fp)
        print(file=fp)
    # Bootstrapping.  bin/genaliases must be run before any lists are created,
    # but if no lists exist yet then mlist is None.  The whole point of the
    # exercise is to get the minimal aliases.db file into existance.
    if mlist is None:
        return
    listname = mlist.internal_name()
    fieldsz = len(listname) + len('-unsubscribe')
    # The text file entries get a little extra info
    print('# STANZA START:', listname, file=fp)
    print('# CREATED:', time.ctime(time.time()), file=fp)
    # Now add all the standard alias entries
    for k, v in makealiases(listname):
        # Format the text file nicely
        print(k + ':', ((fieldsz - len(k)) * ' ') + v, file=fp)
    # Finish the text file stanza
    print('# STANZA END:', listname, file=fp)
    print(file=fp)

def _isvirtual(mlist):
    return (mlist and mlist.host_name.lower() in
            [d.lower() for d in mm_cfg.POSTFIX_STYLE_VIRTUAL_DOMAINS])

def _addvirtual(mlist, fp):
    listname = mlist.internal_name()
    fieldsz = len(listname) + len('-unsubscribe')
    hostname = mlist.host_name
    # Set up the mailman-loop address
    loopaddr = Utils.get_site_email(mlist.host_name, extra='loop')
    loopdest = Utils.ParseEmail(loopaddr)[0]
    # And the site list posting address.
    siteaddr = Utils.get_site_email(mlist.host_name)
    sitedest = Utils.ParseEmail(siteaddr)[0]
    # And the site list -owner, -bounces and -request addresses.
    siteowneraddr = Utils.get_site_email(mlist.host_name, extra='owner')
    siteownerdest = Utils.ParseEmail(siteowneraddr)[0]
    sitebouncesaddr = Utils.get_site_email(mlist.host_name, extra='bounces')
    sitebouncesdest = Utils.ParseEmail(sitebouncesaddr)[0]
    siterequestaddr = Utils.get_site_email(mlist.host_name, extra='request')
    siterequestdest = Utils.ParseEmail(siterequestaddr)[0]
    if mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN:
        loopdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        sitedest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        siteownerdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        sitebouncesdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        siterequestdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
    # If the site list's host_name is a virtual domain, adding the list and
    # owner addresses to the SITE ADDRESSES will duplicate the entries in the
    # stanza for the list.  Postfix doesn't like dups so we try to comment them
    # here, but only for the actual site list domain.
    if (MailList(mm_cfg.MAILMAN_SITE_LIST, lock=False).host_name.lower() ==
            hostname.lower()):
        siteaddr = '#' + siteaddr
        siteowneraddr = '#' + siteowneraddr
        sitebouncesaddr = '#' + sitebouncesaddr
        siterequestaddr = '#' + siterequestaddr
    # Seek to the end of the text file, but if it's empty write the standard
    # disclaimer, and the loop catch address and site address.
    fp.seek(0, 2)
    if not fp.tell():
        print("""\
# This file is generated by Mailman, and is kept in sync with the binary hash
# file virtual-mailman.db.  YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you
# know what you're doing, and can keep the two files properly in sync.  If you
# screw it up, you're on your own.
#
# Note that you should already have this virtual domain set up properly in
# your Postfix installation.  See README.POSTFIX for details.

# LOOP ADDRESSES START
%s\t%s
# LOOP ADDRESSES END

# We also add the site list address in each virtual domain as that address
# is exposed on admin and listinfo overviews, and we add the site list-owner,
# -bounces and -request addresses as they are exposed in the list created
# and/or password reminder email notices.

# SITE ADDRESSES START
%s\t%s
%s\t%s
%s\t%s
%s\t%s
# SITE ADDRESSES END
""" % (loopaddr, loopdest, siteaddr, sitedest, siteowneraddr, siteownerdest,
       sitebouncesaddr, sitebouncesdest, siterequestaddr, siterequestdest), file=fp)
    # The text file entries get a little extra info
    print('# STANZA START:', listname, file=fp)
    print('# CREATED:', time.ctime(time.time()), file=fp)
    # Now add all the standard alias entries
    for k, v in makealiases(listname):
        fqdnaddr = '%s@%s' % (k, hostname)
        if mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN:
            localaddr = '%s@%s' % (k, mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN)
        else:
            localaddr = k
        # Format the text file nicely
        print(fqdnaddr, ((fieldsz - len(k)) * ' '), localaddr, file=fp)
    # Finish the text file stanza
    print('# STANZA END:', listname, file=fp)
    print(file=fp)

# Blech.
def _check_for_virtual_loopaddr(mlist, filename):
    loopaddr = Utils.get_site_email(mlist.host_name, extra='loop')
    loopdest = Utils.ParseEmail(loopaddr)[0]
    siteaddr = Utils.get_site_email(mlist.host_name)
    sitedest = Utils.ParseEmail(siteaddr)[0]
    siteowneraddr = Utils.get_site_email(mlist.host_name, extra='owner')
    siteownerdest = Utils.ParseEmail(siteowneraddr)[0]
    sitebouncesaddr = Utils.get_site_email(mlist.host_name, extra='bounces')
    sitebouncesdest = Utils.ParseEmail(sitebouncesaddr)[0]
    siterequestaddr = Utils.get_site_email(mlist.host_name, extra='request')
    siterequestdest = Utils.ParseEmail(siterequestaddr)[0]
    if mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN:
        loopdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        sitedest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        siteownerdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        sitebouncesdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
        siterequestdest += '@' + mm_cfg.VIRTUAL_MAILMAN_LOCAL_DOMAIN
    # If the site list's host_name is a virtual domain, adding the list and
    # owner addresses to the SITE ADDRESSES will duplicate the entries in the
    # stanza for the list.  Postfix doesn't like dups so we try to comment them
    # here, but only for the actual site list domain.
    if (MailList(mm_cfg.MAILMAN_SITE_LIST, lock=False).host_name.lower() ==
            mlist.host_name.lower()):
        siteaddr = '#' + siteaddr
        siteowneraddr = '#' + siteowneraddr
        sitebouncesaddr = '#' + sitebouncesaddr
        siterequestaddr = '#' + siterequestaddr
    infp = open(filename)
    omask = os.umask(0o007)
    try:
        outfp = open(filename + '.tmp', 'w')
    finally:
        os.umask(omask)
    try:
        # Find the start of the loop address block
        while True:
            line = infp.readline()
            if not line:
                break
            outfp.write(line)
            if line.startswith('# LOOP ADDRESSES START'):
                break
        # Now see if our domain has already been written
        while True:
            line = infp.readline()
            if not line:
                break
            if line.startswith('# LOOP ADDRESSES END'):
                # It hasn't
                print >> outfp, '%s\t%s' % (loopaddr, loopdest)
                outfp.write(line)
                break
            elif line.startswith(loopaddr):
                # We just found it
                outfp.write(line)
                break
            else:
                # This isn't our loop address, so spit it out and continue
                outfp.write(line)
        # Now do it all again for the site list address. It must follow the
        # loop addresses.
        while True:
            line = infp.readline()
            if not line:
                break
            outfp.write(line)
            if line.startswith('# SITE ADDRESSES START'):
                break
        # Now see if our domain has already been written
        while True:
            line = infp.readline()
            if not line:
                break
            if line.startswith('# SITE ADDRESSES END'):
                # It hasn't
                print >> outfp, '%s\t%s' % (siteaddr, sitedest)
                print >> outfp, '%s\t%s' % (siteowneraddr, siteownerdest)
                print >> outfp, '%s\t%s' % (sitebouncesaddr, sitebouncesdest)
                print >> outfp, '%s\t%s' % (siterequestaddr, siterequestdest)
                outfp.write(line)
                break
            elif line.startswith(siteaddr) or line.startswith('#' + siteaddr):
                # We just found it
                outfp.write(line)
                break
            else:
                # This isn't our loop address, so spit it out and continue
                outfp.write(line)
        outfp.writelines(infp.readlines())
    finally:
        infp.close()
        outfp.close()
    os.rename(filename + '.tmp', filename)

def _do_create(mlist, textfile, func):
    # Crack open the plain text file
    try:
        fp = open(textfile, 'r+')
    except IOError as e:
        if e.errno != errno.ENOENT: raise
        omask = os.umask(0o007)
        try:
            fp = open(textfile, 'w+')
        finally:
            os.umask(omask)
    try:
        func(mlist, fp)
    finally:
        fp.close()
    # Now double check the virtual plain text file
    if func is _addvirtual:
        _check_for_virtual_loopaddr(mlist, textfile)

def create(mlist, cgi=False, nolock=False, quiet=False):
    # Acquire the global list database lock.  quiet flag is ignored.
    lock = None
    if not nolock:
        lock = makelock()
        lock.lock()
    # Do the aliases file, which need to be done in any case
    try:
        _do_create(mlist, ALIASFILE, _addlist)
        if _isvirtual(mlist):
            _do_create(mlist, VIRTFILE, _addvirtual)
        # bin/genaliases is the only one that calls create with nolock = True.
        # Use that to only update the maps at the end of genaliases.
        if not nolock:
            _update_maps()
    finally:
        if lock:
            lock.unlock(unconditionally=True)

def _do_remove(mlist, textfile, virtualp):
    listname = mlist.internal_name()
    # Now do our best to filter out the proper stanza from the text file.
    # The text file better exist!
    outfp = None
    try:
        infp = open(textfile)
    except IOError as e:
        if e.errno != errno.ENOENT: raise
        # Otherwise, there's no text file to filter so we're done.
        return
    try:
        omask = os.umask(0o007)
        try:
            outfp = open(textfile + '.tmp', 'w')
        finally:
            os.umask(omask)
        filteroutp = False
        start = '# STANZA START: ' + listname
        end = '# STANZA END: ' + listname
        oops = '# STANZA START: '
        while 1:
            line = infp.readline()
            if not line:
                break
            # If we're filtering out a stanza, just look for the end marker and
            # filter out everything in between.  If we're not in the middle of
            # filtering out a stanza, we're just looking for the proper begin
            # marker.
            if filteroutp:
                if line.strip() == end:
                    filteroutp = False
                    # Discard the trailing blank line, but don't worry if
                    # we're at the end of the file.
                    infp.readline()
                elif line.startswith(oops):
                    # Stanza end must be missing - start writing from here.
                    filteroutp = False
                    outfp.write(line)
                # Otherwise, ignore the line
            else:
                if line.strip() == start:
                    # Filter out this stanza
                    filteroutp = True
                else:
                    outfp.write(line)
    # Close up shop, and rotate the files
    finally:
        infp.close()
        outfp.close()
    os.rename(textfile+'.tmp', textfile)

def remove(mlist, cgi=False):
    # Acquire the global list database lock
    lock = makelock()
    lock.lock()
    try:
        _do_remove(mlist, ALIASFILE, False)
        if _isvirtual(mlist):
            _do_remove(mlist, VIRTFILE, True)
        # Regenerate the alias and map files
        _update_maps()
    finally:
        lock.unlock(unconditionally=True)

def checkperms(state):
    for file in ALIASFILE, VIRTFILE:
        if state.VERBOSE:
            print(C_('checking permissions on %(file)s'))
        stat = None
        try:
            stat = os.stat(file)
        except OSError as e:
            if e.errno != errno.ENOENT:
                raise
        if stat and (stat[ST_MODE] & targetmode) != targetmode:
            state.ERRORS += 1
            octmode = oct(stat[ST_MODE])
            print(C_('%(file)s permissions must be 0664 (got %(octmode)s)'),)
            if state.FIX:
                print(C_('(fixing)'))
                os.chmod(file, stat[ST_MODE] | targetmode)
            else:
                print
        # Make sure the corresponding .db files are owned by the Mailman user.
        # We don't need to check the group ownership of the file, since
        # check_perms checks this itself.
        dbfile = file + '.db'
        stat = None
        try:
            stat = os.stat(dbfile)
        except OSError as e:
            if e.errno != errno.ENOENT:
                raise
            continue
        if state.VERBOSE:
            print(C_('checking ownership of %(dbfile)s'))
        user = mm_cfg.MAILMAN_USER
        ownerok = stat[ST_UID] == pwd.getpwnam(user)[2]
        if not ownerok:
            try:
                owner = pwd.getpwuid(stat[ST_UID])[0]
            except KeyError:
                owner = 'uid %d' % stat[ST_UID]
            print(C_(
                '%(dbfile)s owned by %(owner)s (must be owned by %(user)s'),)
            state.ERRORS += 1
            if state.FIX:
                print(C_('(fixing)'))
                uid = pwd.getpwnam(user)[2]
                gid = grp.getgrnam(mm_cfg.MAILMAN_GROUP)[2]
                os.chown(dbfile, uid, gid)
            else:
                print
        if stat and (stat[ST_MODE] & targetmode) != targetmode:
            state.ERRORS += 1
            octmode = oct(stat[ST_MODE])
            print(C_('%(dbfile)s permissions must be 0664 (got %(octmode)s)'),)
            if state.FIX:
                print(C_('(fixing)'))
                os.chmod(dbfile, stat[ST_MODE] | targetmode)
            else:
                print()


import os
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal
from scipy import optimize
from scipy.linalg import svd
import argparse

# using the argparse module to make use of command line options
parser = argparse.ArgumentParser(description="Evaluation script for MoSES measurements")

# add commandline options
parser.add_argument("--filename_ions",
                    "-f_ions",
                    help="Specify a filename (ions) to be evaluated. Defaults to ions.txt",
                    default='data/ions.txt')
parser.add_argument("--filename_electrons",
                    "-f_electrons",
                    help="Specify a filename (electrons) to be evaluated. Defaults to electrons.txt",
                    default='data/electrons.txt')
parser.add_argument("--fit_plot",
                    "-fp",
                    help="Specify which fit to plot. Defaults to 22",
					type=int,
                    default=22)

# parse it
args = parser.parse_args()

fn_electrons = args.filename_electrons
fn_ions = args.filename_ions

# number of measurement cycles
m_cycles = 26
cycle_time = 300
cycle_offset = 276
extrema_search_range = 15
# this determines, whether minima are used instead of maxima
minima_used = False

# cutoffs
co_start = 250
co_end = 7850

# minimum optimality for fit. if larger than that, a "molecule-potential" (negative amplitude) is tried
min_optimality_req = 1e-6

# maximum time constant to be accepted for fit.
max_time_constant = 2000

# time to not use for fitting before and after a peak
peak_dist_before = 5
peak_dist_after = 2

# which measurement section to plot
fittoplot = args.fit_plot

# lambda to remove nA unit from reading files
remove_nA = lambda s: float(s.decode("utf-8").replace(' nA', ''))

# import electrons
# check whether the file exists. if not, try to use it as a relative path.
if not os.path.exists(fn_electrons):
    fn_electrons = os.path.normcase(os.path.join(os.path.dirname(__file__), fn_electrons))

electrons = np.loadtxt(fn_electrons, skiprows=0, usecols=1, delimiter=',', converters={1: remove_nA},
                       dtype=np.float64)

# import ions
# check whether the file exists. if not, try to use it as a relative path.
if not os.path.exists(fn_ions):
    fn_ions = os.path.normcase(os.path.join(os.path.dirname(__file__), fn_ions))

# export path for the fit results
export_file_results = fn_ions.split('_ions.')[0] + '_results.txt'
export_file_gamma = fn_ions.split('_ions.')[0] + '_gamma.txt'

ions = np.loadtxt(fn_ions, skiprows=0, delimiter=',', converters={1: remove_nA}, dtype=np.float64)

# combine everything into one array: 0 = time, 1 = ions, 2 = electrons, 3 = gamma
data = np.zeros((ions.shape[0], 4), dtype=np.float64)
data[:, 0] = ions[:, 0]
data[:, 1] = ions[:, 1]
try:
    data[:, 2] = electrons[0:ions.shape[0]]
except ValueError:
    # not enough electron measurement points -> let's do it the other way around
    # combine everything into one array: 0 = time, 1 = ions, 2 = electrons, 3 = gamma
    data = np.zeros((electrons.shape[0], 4), dtype=np.float64)
    data[:, 0] = ions[0:electrons.shape[0], 0]
    data[:, 1] = ions[0:electrons.shape[0], 1]
    data[:, 2] = electrons[:]

data[:, 3] = np.abs(data[:, 2]) / (np.abs(data[:, 1]) - np.abs(data[:, 2]))

# cutoff data in the beginning and end
data = data[np.where((data[:, 0] >= co_start) & (data[:, 0] <= co_end)), :][0]

# find extrema
extrema = np.zeros((m_cycles, 2), np.float64)

for i in range(0, m_cycles):
    # restrict to search range
    range_end = i * cycle_time + cycle_offset + extrema_search_range
    range_start = i * cycle_time + cycle_offset - extrema_search_range
    if range_end < co_start:
        print('Skipping first peak - please re-check your cutoff an search range settings!')
        continue
    search_range = data[np.where((data[:, 0] >= range_start) & (data[:, 0] <= range_end)), :][0]

    # search for maximum / minimum
    if not minima_used:
        extrema[i, 1] = max(search_range[:, 3])
    else:
        extrema[i, 1] = min(search_range[:, 3])

    try:
        extrema[i, 0] = search_range[np.where(search_range[:, 3] == extrema[i, 1]), 0][0]
    except ValueError:
        # apparently there where two equally extreme extrema - let's just take the first one
        extrema[i, 0] = search_range[np.where(search_range[:, 3] == extrema[i, 1]), 0][0][0]

# resort by time
extrema = extrema[np.argsort(extrema[:, 0])]

# define error function for fit
exp_decay_2 = lambda p, x: p[0] + p[2]*np.exp(-(x-p[1])/p[3]) + p[4]*np.exp(-(x-p[1])/p[5])
errfunc = lambda p, x, y: exp_decay_2(p, x) - y

# prepare empty fit parameter list
p = [None] * 6
# prepare figure for plotting
fig1 = plt.figure()
ax0 = fig1.add_subplot(2, 2, 1)
ax1 = fig1.add_subplot(2, 2, 2)
ax2 = fig1.add_subplot(2, 2, 3)
ax3 = fig1.add_subplot(2, 2, 4)

# prepare list of results
fit_results = np.zeros((m_cycles, 6), dtype=np.float64)
boundary_met = [None]*m_cycles # to note, whether a boundary was met by a fit parameter

# boundaries for fits
bounds_lower = [0.0, min(data[:, 0]), -1e6, 0, -1e6, 0]
bounds_upper = [0.3, max(data[:, 0]), 1e6, 900, 1e6, 900]

bounds_range = np.array(bounds_upper) - np.array(bounds_lower)

def calc_std_deviation(res):
    """
    Calculate the standard deviation from the Jacobian returned by the fit result.
    From scipy: https://github.com/scipy/scipy/blob/11509c4a98edded6c59423ac44ca1b7f28fba1fd/scipy/optimize/minpack.py#L762
    """

    # Code from scipy
    _, s, VT = svd(res.jac, full_matrices=False)
    threshold = np.finfo(float).eps * max(res.jac.shape) * s[0]
    s = s[s > threshold]
    VT = VT[:s.size]
    pcov = np.dot(VT.T / s**2, VT)

    # Std-dev is sqrt of diagonal of covariance matrix
    return np.sqrt(np.diag(pcov))

# loop through all between-extrema-intervals
for i in range(0, m_cycles):
    # select proper data interval
    try:
        fitdata = data[np.where((data[:, 0] >= extrema[i, 0] + peak_dist_after) & (data[:, 0] <= extrema[i + 1, 0] - peak_dist_before)), :][0]
    except IndexError:
        # last one
        fitdata = data[np.where(data[:, 0] >= extrema[i, 0] + peak_dist_after), :][0]

    # starting values for fit
    p[0] = 0.08 # gamma
    p[1] = extrema[i, 0]# time offset
    p[2] = 0.05
    p[3] = 8
    p[4] = 0.01
    p[5] = 100

    # fit the data
    try:
        res = optimize.least_squares(errfunc, np.asarray(p, dtype=np.float64), args=(fitdata[:, 0], fitdata[:, 3]), bounds=(bounds_lower, bounds_upper))
        p1 = res.x
        perr = calc_std_deviation(res)

        if res.optimality > min_optimality_req:
            print('Optimality larger than {} for cycle {}. Retrying with new parameters.'.format(min_optimality_req, i+1))
            # fit did not converge well. could be a molecule-potential-like case. try new starting parameters
            p[0] = fit_results[i-1, 0]  # gamma
            p[1] = extrema[i, 0]  # time offset
            p[2] = 0.05
            p[3] = 8
            p[4] = -0.01
            p[5] = 100

            res = optimize.least_squares(errfunc, np.asarray(p, dtype=np.float64), args=(fitdata[:, 0], fitdata[:, 3]), bounds=(bounds_lower, bounds_upper))
            p1 = res.x
            perr = calc_std_deviation(res)
            print('New optimality: {}'.format(res.optimality))

    except TypeError:
        print('Could not fit section {}.'.format(i+1))
        p1 = [None] * 6

    fit_results[i, :] = p1

    # try to detect, whether one of the parameters came close to a boundary.
    # bounds_range_percentage is 0 for value at bounds_lower, 1 for value at bounds_upper
    bounds_range_percentage=  np.divide(np.abs(bounds_lower + p1), bounds_range)
    # note if any of the values is close (1e-4) to a boundary
    boundary_met[i] = np.any(np.piecewise(bounds_range_percentage, [1 - bounds_range_percentage < 1e-4, bounds_range_percentage < 1e-4], [1, 1]))

    if i == fittoplot - 1:
        fitplot, = ax0.plot(fitdata[:, 0], exp_decay_2(p1, fitdata[:, 0]), 'r-')
        print('Fit results for {}'.format(fittoplot))
        print(fit_results[i, :])
    else:
        ax0.plot(fitdata[:, 0], exp_decay_2(p1, fitdata[:, 0]), 'g-')

gammaplot, = ax0.plot(data[:, 0], data[:, 3])
maximaplot, = ax0.plot(extrema[:, 0], extrema[:, 1], 'x')
ax0.set_title('$\gamma$ from raw data')
ax0.set_xlabel('time (s)')
ax0.set_ylabel('$\gamma$ (-)')
ax0.legend([gammaplot, maximaplot, fitplot], ['$\gamma$', 'peak extrema', 'fit to section {}'.format(fittoplot)])

electronplot, = ax1.plot(data[:, 0], data[:, 2])
ax1.set_title('electron current')
ax1.set_xlabel('time (s)')
ax1.set_ylabel('current (nA)')

ionplot, = ax2.plot(data[:, 0], data[:, 1])
ionelectronplot, = ax2.plot(data[:, 0], data[:, 1] + data[:, 2])
ax2.set_xlabel('time (s)')
ax2.set_ylabel('current (nA)')
ax2.legend([ionplot, ionelectronplot], ['ion current', 'sum of ion and electron current'])

for i in range(0, m_cycles):
    if boundary_met[i]:
        ax3.plot(i+1, fit_results[i, 0], 'r+')
    else:
        ax3.plot(i + 1, fit_results[i, 0], 'b+')

ax3.set_title('$\gamma$ evaluated')
ax3.set_ylabel('$\gamma$ (-)')
ax3.set_xlabel('measurement position')

fig1.tight_layout()
fig1.suptitle('data from: {}'.format(fn_electrons))

# export fit shit to a file
export_values = np.concatenate(
    (np.arange(1, m_cycles + 1).reshape((m_cycles, 1)), fit_results[:, [0, 3, 5]]), axis=1)
np.savetxt(export_file_results,
           export_values,
           fmt=('%d', '%10.4f', '%10.4f', '%10.4f'),
           delimiter='\t',
header='Measurement\tGamma\tTime constant 1\tTime constant 2')

#export gamma to a new file
np.savetxt(export_file_gamma,
           data[:, [0, 3]],
           fmt=('%10.1f', '%10.4f'),
           delimiter='\t',
header='Time (s)\tGamma')

plt.show()


from django.contrib import admin
from .models import Women, Category

@admin.register(Women)
class WomenAdmin(admin.ModelAdmin):
    list_display = ("pk", "title", "content")
    search_fields = ("title", "text",)
    list_filter = ("time_create", "time_update")

admin.site.register(Category)


from .views import (
                    RegisterAPIView,
                    ProfileDetailApiView,
                    LoginView,
                    RefreshTokenView,
                    LogoutView)
from django.urls import path, include

app_name = "accounts"

urlpatterns = [
    path('register', RegisterAPIView.as_view(), name='register'),
    path('profile/<int:pk>', ProfileDetailApiView.as_view(), name='profile'),
    path('login', LoginView.as_view(), name='login'),
    path('refresh', RefreshTokenView.as_view(), name='refresh'),
    path('logout', LogoutView.as_view(), name='logout'),
]


from django.contrib import admin
from django import forms

from ncfmusic.apps.content.models import *

class ListenAdmin(admin.ModelAdmin):
    list_display = ('title', 'album_title', 'songwriter', 'church', 'record_date', )
    list_filter = ('church', 'record_date' )
    search_fields = ('title', 'album_title', )
    prepopulated_fields = {'slug': ('title',)}

admin.site.register(Listen, ListenAdmin)

class WatchAdminForm(forms.ModelForm):
    class Meta:
        model = Watch

    def clean_vimeo_url(self):
        return self.cleaned_data['vimeo_url'] or None

    def clean_youtube_url(self):
        return self.cleaned_data['youtube_url'] or None

class WatchAdmin(admin.ModelAdmin):
    form = WatchAdminForm
    list_display = ('title', 'church', 'date', )
    list_filter = ('church', 'date', )
    search_fields = ('title', )
    prepopulated_fields = {'slug': ('title',)}
    readonly_fields = ('insert_date',)

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Watch, WatchAdmin)

class TutorialAdmin(admin.ModelAdmin):
    list_display = ('title', 'date', 'author', 'church', )
    list_filter = ('date', 'author', 'church', )
    search_fields = ('title', )
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Tutorial, TutorialAdmin)

class TalkAdmin(admin.ModelAdmin):
    list_display = ('title', 'date', 'author', 'church', )
    list_filter = ('date', 'author', 'church', )
    search_fields = ('title', )
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Talk, TalkAdmin)

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'date', 'author', 'church', )
    list_filter = ('date', 'author', 'church', )
    search_fields = ('title', )
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Article, ArticleAdmin)

class TagAdmin(admin.ModelAdmin):
    list_display = ('name', 'slug', )
    list_filter = ('name', 'slug', )
    search_fields = ('name', )
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Tag, TagAdmin)

class SongAdmin(admin.ModelAdmin):
    list_display = ('title', 'album_title', 'songwriter', 'church', 'release_date', )
    list_filter = ('songwriter', 'church', 'release_date', )
    search_fields = ('title', )
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Song, SongAdmin)

class EventAdmin(admin.ModelAdmin):
    list_display = ('title', 'start_date', 'end_date', 'church', )
    list_filter = ('start_date', 'church', )
    search_fields = ('title', )
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Event, EventAdmin)

class ChurchAdmin(admin.ModelAdmin):
    list_display = ('name', 'city', 'state', )
    list_filter = ('state', )
    search_fields = ('name', 'city', 'state', )
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Church, ChurchAdmin)

class ContributorAdmin(admin.ModelAdmin):
    list_display = ('name', 'title', 'church', )
    list_filter = ('church', )
    search_fields = ('name', 'title', )
    prepopulated_fields = {'slug': ('name',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Contributor, ContributorAdmin)

class ContactAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email_address', )
    search_fields = ('first_name', 'last_name', 'email_address', )

admin.site.register(Contact, ContactAdmin)

class PageAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

admin.site.register(Page, PageAdmin)

class GenreAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(Genre, GenreAdmin)

class BlogCategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}

admin.site.register(BlogCategory, BlogCategoryAdmin)

class BlogEntryAdmin(admin.ModelAdmin):
    list_display = ('title', 'date')
    prepopulated_fields = {'slug': ('title',)}

    class Media:
        js = [
            '/media/admin/tinymce/jscripts/tiny_mce/tiny_mce.js',
            '/media/admin/tinymce_setup/tinymce_setup.js',
        ]

    def save_model(self, request, obj, form, change):
        try:
            author = obj.author
        except User.DoesNotExist:
            obj.author = request.user

        obj.save()

admin.site.register(BlogEntry, BlogEntryAdmin)

class ConferenceRegistrantInline(admin.StackedInline):
    model = ConferenceRegistrant

class ConferenceRegistrationAdmin(admin.ModelAdmin):
    list_display = ('last_name', 'first_name', 'insert_date', 'has_paid',)

    inlines = [ConferenceRegistrantInline]

admin.site.register(ConferenceRegistration, ConferenceRegistrationAdmin)


import cv2 as cv
import paho.mqtt.client as mqtt

# mqtt parameters
local_mqtt_host = 'broker'
mqtt_port = 1883
mqtt_topic = 'faces'

# global variable indicating disconnect status
dc_flag = False

# create callback functions
def on_connect_local(local_client, userdata, flags, rc):
    """
    This function handles the callback from the broker when it sends acknowledgement of connection status.
    """

    if rc == 0:
        local_client.connected_flag = True
        print("Connected OK returned code = ", rc)
    else:
        print("Bad connection Returned code = ", rc)

def on_disconnect_local(local_client, userdata, rc):
    #global dc_flag
    print("Disconnected due to ", rc)
    #dc_flag = True

# initiate local client instance
local_client = mqtt.Client("detector")

# connection flag indicating connection status
local_client.connected_flag = False

# bind call back functions
local_client.on_connect = on_connect_local
local_client.on_disconnect = on_disconnect_local

# loop start
local_client.loop_start()

# make connection
local_client.connect(local_mqtt_host, mqtt_port, 60)

while not local_client.connected_flag:
    print("Waiting in loop")
    time.sleep(1)

# 1 should correspond to /dev/video1 , your USB camera.
# The 0 is reserved for the NX onboard camera or webcam on laptop
cap = cv.VideoCapture(0)
#cap.set(3, 640)
#cap.set(4, 480)

# alternative approach using background substractor
backSub = cv.createBackgroundSubtractorMOG2()

while True:

    # read frame by frame
    ret, frame = cap.read()

    ## convert frame to gray scale and implement Gaussian blur to remove unnecessary noise
    gray_frame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    gray_frame = cv.GaussianBlur(gray_frame, (55, 55), 0)

    # generate foreground mask
    fgmask = backSub.apply(gray_frame)
    fgmask = cv.dilate(fgmask, None, iterations=2)

    # identify contours for moving obejct (foreground mask)
    contours, _ = cv.findContours(fgmask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

    rectangles = []
    for c in contours:
        try:
            area = cv.contourArea(c)
            rectangles.append((area, cv.boundingRect(c)))
        except:
            pass

        for area, rect in sorted(rectangles, reverse=True):
            if area > 300:
                x, y, w, h = rect
                txt = 'Motion detected'
                txt_2 = 'Sending images to the cloud...'
                cv.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
                cv.putText(frame, txt, (100, 400), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, cv.LINE_AA)
                cv.putText(frame, txt_2, (100, 430), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1, cv.LINE_AA)

                # Extract object
                obj_extract = frame[y:y + h, x:x + w]

                # Encode extract to png
                rc, png = cv.imencode('.png', obj_extract)

                # convert png extract to bytes (for messaging)
                msg = png.tobytes()

                #if dc_flag:
                #local_client.connect(local_mqtt_host, mqtt_port, 60)
                local_client.publish(mqtt_topic, msg, qos=1, retain=False)

    cv.imshow('img', frame)
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

# loop end
local_client.disconnect()

cap.release()
cv.destroyAllWindows()


# python plot.py
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-5, 5, 100)  # xの範囲を設定
y1 = x**2 - 1
y2 = -x**2 + 1

plt.plot(x, y1, label='Quadratic Curve 1')
plt.plot(x, y2, label='Quadratic Curve 2')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Quadratic Curve')
plt.legend()
plt.grid(True)
plt.show()


# coding=utf-8
from django import template
from django.utils.log import getLogger
from django.conf import settings

import time
import qrcode
import StringIO
import bleach

ALLOWED_NOTE_TAGS = []

register = template.Library()
log = getLogger('django')
image_host = getattr(settings, 'IMAGE_HOST', None)

def enumerate_list(value):
    return enumerate(value)

register.filter(enumerate_list)

def smart_scheme(value, is_secure=False):
    if is_secure and 'guoku.com' in value:
        value = value.replace('http://', 'https://')
    return value

register.filter(smart_scheme)

def safe_note(value):
    return bleach.clean(value, tags=ALLOWED_NOTE_TAGS)

register.filter(safe_note)

def https_image_cdn(value):
    http_host = settings.IMAGE_HOST
    https_host = http_host.replace('http://', 'https://')
    value = value.replace(http_host, https_host)
    return value.replace(http_host, https_host)

register.filter(https_image_cdn)

def oss_resize(url, size=None):
    if all([url, size]):
        if 'taobaocdn.com' in url or 'alicdn.com' in url:
            # 淘宝地址，修改到淘宝规则的地址
            url = '{url}_{size}x{size}.jpg'.format(url=url, size=size)

        elif image_host in url:
            # CDN地址，修改到阿里云规则的地址
            url = '{value}/{size}'.format(value=url, size=size)

    url = url.replace('//images', '/images') if url else url
    return url

register.filter(oss_resize)

def resize(value, size=None):
    host = image_host
    if value is None:
        return value

    if 'taobaocdn.com' in value or 'alicdn.com' in value:
        value = value + '_' + size + 'x' + size + '.jpg'
        return value

    if 'guoku.com/static' in value:
        return value

    if host not in value:
        return value

    if size:
        if host in value:
            uri = value.replace(host, '')
            params = uri.split('/')
            params.insert(1, str(size))
            uri_string = '/'.join(params)
            return host + uri_string

    value = value.replace('//images', '/images')
    return value

register.filter(resize)

def show_category(value):
    title = value.split('-')
    return title[0]

register.filter(show_category)

def timestamp(value):
    return time.mktime(value.timetuple())

register.filter('timestamp', timestamp)

def filter_builder(filter_name, filter_value):
    return '%s=%s' % (filter_name, filter_value)

register.filter('filter_builder', filter_builder)

def entity_qr(value):
    url = "%s%s" % ('http://www.guoku.com', value)
    qr = qrcode.QRCode(
        version=2,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=2,
        border=1,
    )
    qr.add_data(url)
    img = qr.make_image()
    output = StringIO.StringIO()
    img.save(output)
    content = output.getvalue()
    output.close()
    return content.encode('base64').replace("\n", "")

register.filter(entity_qr)

def tbsearch_url(word):
    return 'https://s.taobao.com/search?q=%s' % word

register.filter(tbsearch_url)


#!/usr/bin/python
# -*- coding: latin-1 -*-
from random import random

from numba import jit, vectorize
import zlib, numpy
from functools import reduce
import os

os.environ[
    "NUMBAPRO_NVVM"
] = r"D:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.1\nvvm\bin\nvvm64_32_0.dll"
os.environ[
    "NUMBAPRO_LIBDEVICE"
] = r"D:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.1\nvvm\libdevice"

@jit(nogil=True)
def xor_numpy(p1, p2):
    if (isinstance(p2, numpy.ndarray) and isinstance(p1, numpy.ndarray)) and (
        (p1.dtype == numpy.uint8 and p2.dtype == numpy.uint8)
        or (p1.dtype == numpy.bool and p2.dtype == numpy.bool)
    ):
        n_p1 = p1
        n_p2 = p2
    else:
        n_p1 = numpy.fromstring(p1, dtype="uint8")
        n_p2 = numpy.fromstring(p2, dtype="uint8")
    return xor_intern(n_p1, n_p2)

@vectorize(["uint8(uint8,uint8)", "boolean(boolean,boolean)"], target="cuda")
def xor_intern(n_p1, n_p2):
    return n_p1 ^ n_p2

@jit(cache=True)
def listXOR(plist):
    return reduce(xor_numpy, plist)

@jit(cache=True)
def logical_xor(plist):
    return reduce(numpy.logical_xor, plist)

@jit(cache=True)
def xor_pakets(packet1, packet2):
    assert len(packet1) == len(packet2)
    a = [a ^ b for (a, b) in zip(bytes(packet1, "utf-8"), bytes(packet2, "utf-8"))]
    return a

@jit(cache=True)
def should_drop_packet(rules, packet):
    rand = random()  # create number from [0,1)
    drop_chance = rules.apply_all_rules(packet)
    packet.set_error_prob(drop_chance)
    # drop packet if rand bigger than the drop_chance for this Packet.
    return drop_chance > rand

@jit(cache=True)
def calc_crc(data):
    return zlib.crc32(data) & 0xFFFFFFFF

@jit(cache=True)
def xor_mask(data, mask=0b11110000101011000011101001101010, enabled=True):
    if not enabled:
        return data
    return numpy.bitwise_xor(data, mask)

# bitSet returns true if x has the b'th bit set
@vectorize(["boolean(uint32, uint32)", "boolean(uint64, uint64)"], target="cuda")
def bitSet(x, b):
    return ((x >> b) & 1) == 1

# bitsSet returns how many bits in x are set.
# This algorithm basically uses shifts and ANDs to sum up the bits in
# a tree fashion.
@vectorize(["int64(uint64)", "int64(uint32)"], target="cuda")
def bitsSet(x):  # x is of type uint64 !
    x -= (x >> numpy.uint64(1)) & numpy.uint64(0x5555555555555555)
    x = (x & numpy.uint64(0x3333333333333333)) + (
        (x >> numpy.uint64(2)) & numpy.uint64(0x3333333333333333)
    )
    x = (x + (x >> numpy.uint64(4))) & numpy.uint64(0x0F0F0F0F0F0F0F0F)
    res = numpy.int64((x * numpy.uint64(0x0101010101010101)) >> numpy.uint64(56))
    return res

# grayCode calculates the gray code representation of the input argument
# The Gray code is a binary representation in which successive values differ
# by exactly one bit. See http://en.wikipedia.org/wiki/Gray_code
@vectorize(["uint64(uint64)", "uint64(uint32)", "uint64(float64)"], target="cuda")
def grayCode(x):
    return (numpy.uint64(x) >> numpy.uint64(1)) ^ numpy.uint64(x)

# buildGraySequence returns a sequence (in ascending order) of "length" Gray numbers,
# all of which have exactly "b" bits set.
@jit("int32(int32,int32)")
def buildGraySequence(length, b):
    s = numpy.empty(length, dtype=int)
    i = 0
    x = numpy.uint64(0)
    while True:
        g = grayCode(x)
        if bitsSet(g) == b:
            s[i] = int(g)
            i += 1
            if i >= length:
                break
        x += 1
    return s


# %%
import requests
import json
import os

from functools import lru_cache

# API constants, you shouldn't have to change these.
# API_KEY = os.environ["RAKUTEN_API_KEY"]
API_KEY = os.environ['RAKUTEN_API_KEY']
API_HOST = "https://us-restaurant-menus.p.rapidapi.com"
SEARCH_PATH = "/restaurants/search/geo"
DEFAULT_LOCATION = [38.898689814814816, -77.03749537037038]

def request(host, path, api_key, url_params=None):
    """Given your API_KEY, send a GET request to the API.

    Args:
        host (str): The domain host of the API.
        path (str): The path of the API after the domain.
        API_KEY (str): Your API Key.
        url_params (dict): An optional set of query parameters in the request.

    Returns:
        dict: The JSON response from the request.

    Raises:
        HTTPError: An error occurs from the HTTP request.
    """
    url_params = url_params or {}
    url = '{0}{1}'.format(host, path)
    headers = {
        'x-rapidapi-host': "us-restaurant-menus.p.rapidapi.com",
        'x-rapidapi-key': api_key,
    }

    print(u'Querying {0} ...'.format(url))

    response = requests.request('GET', url, headers=headers, params=url_params)

    data = json.loads(response.text)
    if 'error' in data:
        raise Exception(str(data))
    return data

def search(location=DEFAULT_LOCATION, api_key=API_KEY):
    """Given location, get all nearby (whitin 5 mile) restaurants

    Args:
        location (list): geological location of user in the form of [lat, lon].

    Returns:
        dict: JSON response containing information of nearby resturants.
    """
    latitude, longtitude = location[0], location[1]
    url_params = {"page": "1", "lon": longtitude, "lat": latitude, "distance": "5"}

    return request(API_HOST, SEARCH_PATH, api_key, url_params=url_params)['result']['data']

@lru_cache()
def get_menus(id, api_key=API_KEY):
    """Given restaurants id, get menu items of the resturant.

    Args:
        id (int): id of the resturant.

    Returns:
        dict: JSON response containing menu infos of the restaurant.
    """
    path = "/restaurant/" + str(id) + "/menuitems"

    return request(API_HOST, path, api_key, url_params=None)['result']['data']

# def get_ids_from_resonse(response_info_json):
#     # get 25 resturant ids from above response
#     if 'result' in response_info_json:
#         restaurants_data_list = response_info_json['result']['data']
#         ids = map(lambda x: x['restaurant_id'], restaurants_data_list)
#         return list(ids)
#     else:
#         return []

# def get_restaurant_menu_items_from_ids(ids):
#     # for each id get its menu items string
#     menu_items = []
#     for id in ids:
#         response_menu_json = get_menus(id)

#         # bonding all menu_item_name to form a description of the restaurant
#         menu_item_string = ""
#         if 'result' in response_menu_json:
#             for menu_item in response_menu_json['result']['data']:
#                 menu_item_name = menu_item['menu_item_name']
#                 menu_item_string += " " + menu_item_name

#         menu_items.append(menu_items_string)

#     return menu_items

def main():
    data = search()
    print(sorted([restaurant['restaurant_name'] for restaurant in data]))

if __name__ == '__main__':
    main()


from celery import shared_task
import time
from django.core.mail import send_mail
from .models import Post

@shared_task
def hello():
    time.sleep(10)
    print("Hello, world!")

@shared_task()
def printer(N):
    for i in range(N):
        time.sleep(1)
        print(i+1)

@shared_task()
def send_my_mail():
    send_mail(subject="Новые статьи)",
              message=f"Еженедельная рассылка\n актуальные новости: {Post.heading}",
              from_email='****',
              recipient_list=['']
              )

#celery -A NewsPortal worker -l INFO -- запуск Celery через консоль


import os
import sys
import re
from lxml import etree
import HyperParams as hp
from data_utils import *

def get_mov_wav_Filelist(DirPath=r'C:\Users\yaoguangming\Desktop\data', databaseNum=4):
    if DirPath is None:
        print('No path !!!')
        return None

    WavList = [DirPath + '/%03d' % (s) + '_小蜜蜂.wav' for s in range(databaseNum)]
    MovList = [DirPath + '/%03d' % (s) + '_mf.mov' for s in range(databaseNum)]

    return WavList, MovList

def getDirList(BaseDir=None, DirNum=18):
    if DirNum is None or BaseDir is None:
        print('Incorret input')
        return None

    DirList = [BaseDir + '/%03d' % (s) for s in range(DirNum)]
    return DirList

def Parsing_xml(XmlPath=None):
    """
    解析xml/eaf 文件，获取时间戳和字
    :param XmlPath:
    :return:
    """

    Timeslots = {}
    Words = {}

    tree = etree.parse(XmlPath)
    root = tree.getroot()

    mov_time_origin, wav_time_origin = 0, 0

    if 'TIME_ORIGIN' in root[0][0].attrib.keys():
        mov_time_origin = int(root[0][0].attrib['TIME_ORIGIN'])

    if 'TIME_ORIGIN' in root[0][1].attrib.keys():
        wav_time_origin = int(root[0][1].attrib['TIME_ORIGIN'])

    timeOrder = root[1]
    tier = root[2]

    for t in timeOrder:
        Timeslots[t.values()[0]] = t.values()[1]

    for t in tier:
        Words[t[0][0].text] = t[0].values()[1:]

    return Timeslots, Words, mov_time_origin, wav_time_origin

def splitHandle(input, start, end, TIME_ORIGIN=0, output=None, isMov=False):
    start_h, start_m, start_s = formateMM(start + TIME_ORIGIN)
    end_h, end_m, end_s = formateMM(end + TIME_ORIGIN)

    formated_start = '%02d:%02d:%02f' % (start_h, start_m, start_s)
    formated_end = '%02d:%02d:%02f' % (end_h, end_m, end_s)

    if isMov:
        os.system('ffmpeg -i %s -an -ss %s -to %s %s' % (input, formated_start, formated_end, output))
    else:
        os.system('ffmpeg -i %s -ss %s -to %s %s' % (input, formated_start, formated_end, output))

def formateMM(mm):
    """
    format mm ---> HH:MM:SS
    :param mm:
    :return:
    """
    h, m, s = 0, 0, 0
    s = mm / 1000
    if s >= 60:
        m = int(s / 60)
        s %= 60
    if m >= 60:
        h = int(m / 60)
        m = int(m % 60)

    return h, m, s

def split_wav_mov(BaseDir=r'C:\Users\yaoguangming\Desktop\data', outputPath=r'C:\Users\yaoguangming\Desktop\data\dict'):
    """
    切分数据
    :param BaseDir: 放置数据集的父目录
    :param outputPath: 输出切分数据的目录
    """
    DirList = getDirList(BaseDir=BaseDir, DirNum=18)
    for dir in DirList:
        wav = dir + '/' + dir[-3:] + '_小蜜蜂.wav'
        mov = dir + '/' + dir[-3:] + '.mov'

        Timeslots, Words, mov_time_origin, wav_time_origin = Parsing_xml(dir + '/' + dir[-3:] + '.eaf')

        cnt = 0
        pre_word = None

        for word in Words:

            if pre_word == None or pre_word != word:
                pre_word = word
                cnt = 1
            else:
                cnt += 1

            start = Words[word][0]
            end = Words[word][1]

            start = int(Timeslots[start])
            end = int(Timeslots[end])

            wav_path = outputPath + '/' + word + '.wav'
            mov_path = outputPath + '/' + word + '.mov'
            mix_path = outputPath + '/' + word + '_mix.mov'

            # split wav
            splitHandle(wav, start, end, TIME_ORIGIN=wav_time_origin, output=wav_path, isMov=False)
            # split mov
            splitHandle(mov, start, end, TIME_ORIGIN=mov_time_origin, output=mov_path, isMov=True)
            # mix
            os.system('ffmpeg -i %s -i %s %s' % (mov_path, wav_path, mix_path))

def split_sigle_dir(dir, outputPath):
    if os.path.exists(outputPath) is False:
        os.mkdir(outputPath)

    wav = dir + '/' + dir[-3:] + '_小蜜蜂.wav'
    mov = dir + '/' + dir[-3:] + '.mov'

    Timeslots, Words, mov_time_origin, wav_time_origin = Parsing_xml(dir + '/' + dir[-3:] + '-origin.eaf')

    cnt = 0
    pre_word = None

    for word in Words:

        if pre_word == None or pre_word != word:
            pre_word = word
            cnt = 1
        else:
            cnt += 1

        start = Words[word][0]
        end = Words[word][1]

        start = int(Timeslots[start])
        end = int(Timeslots[end])

        wav_path = outputPath + '/' + word + '.wav'
        mov_path = outputPath + '/' + word + '.mov'
        mix_path = outputPath + '/' + word + '_mix.mov'

        # split wav
        splitHandle(wav, start, end, TIME_ORIGIN=wav_time_origin, output=wav_path, isMov=False)
        # split mov
        splitHandle(mov, start, end, TIME_ORIGIN=mov_time_origin, output=mov_path, isMov=True)
        # mix
        os.system('ffmpeg -i %s -i %s %s' % (mov_path, wav_path, mix_path))

def split_by_dir(BaseDir, BaseOutput):
    if not os.path.exists(BaseDir): os.mkdir(BaseDir)

    pass
    DirList = getDirList(BaseDir=BaseDir, DirNum=19)
    print(DirList)
    from concurrent.futures import ThreadPoolExecutor
    p = ThreadPoolExecutor(20)

    for dir in DirList:
        # split_sigle_dir(dir, BaseOutput + dir[-4:])
        p.submit(split_sigle_dir, dir, BaseOutput + dir[-4:])

def split_all_sentence_dir(basedir=hp.datadir):
    from concurrent.futures import ThreadPoolExecutor
    p = ThreadPoolExecutor(10)
    dirlist = get_dir_path(basedir)
    for dir in dirlist:
        p.submit(split_single_sentence_dir, dir)

def split_single_sentence_dir(dir):
    outputdir = dir + '/split'
    # print(outputdir)
    if os.path.exists(outputdir) is False:
        os.mkdir(outputdir)
    else:
        # already split files
        return

    # split file
    files = os.listdir(dir)
    # print(files)
    movfiles = filter(lambda x: str(x).endswith('.mov'), files)
    for i in movfiles:
        # print(i[:-4])
        index = i[:-4]

        mov = os.path.join(dir, index + '.mov')
        wav = os.path.join(dir, index + '.wav')
        eaf = os.path.join(dir, index + '.eaf')

        Words, mov_time_origin, wav_time_origin = parse_EAF(eaf)

        for word in Words:
            start = Words[word][0]
            end = Words[word][1]

            wav_path = outputdir + '/' + word + '.wav'
            mov_path = outputdir + '/' + word + '.mov'
            mix_path = outputdir + '/' + word + '_mix.mov'

            # split wav
            splitHandle(wav, start, end, TIME_ORIGIN=wav_time_origin, output=wav_path, isMov=False)
            # split mov
            splitHandle(mov, start, end, TIME_ORIGIN=mov_time_origin, output=mov_path, isMov=True)
            # mix
            os.system('ffmpeg -i %s -i %s %s' % (mov_path, wav_path, mix_path))

if __name__ == '__main__':
    pass
    # mfccs, frames = load_from_npz(hp.sentence_npz_path)
    # print(mfccs.shape)
    # print(frames.shape)
    # save_to_npz(mfccs, frames, hp.sentence_npz_path)
    # split_sentence()
    # split_single_sentence_dir('./data/士兵突击')
    split_all_sentence_dir()


from django.urls import path

from . import views

app_name = "clients"

urlpatterns = [
    path("", views.view_clients, name="view_clients"),
    path("fetch", views.fetch_clients, name="fetch_clients"),
    path("export", views.export_users_csv, name="export_users_csv"),
]


import os
import yaml
import json
import socket
import secrets
import platform
import requests

from core.settings import ALIAS_CONFIGS
from core.settings import IS_DEVELOPMENT
from core.settings import IS_TRAVIS
from core.settings import SSH_CONFIGS

from core.data import conf
from core.data import paths
from core.data import remote_repository
from core.type import get_attr_value
from utils.process import git_remote_path
from utils.process import has_git_changes
from utils.process import output
from utils.validator import validate

def _check_user_privileges():
    validate(
        error="This program needs to be not execute as root.",
        target="user privileges",
        valid=(os.getuid() != 0)
    )

def _check_git_branch():
    branch = output("git rev-parse --abbrev-ref HEAD")

    validate(
        error="This program needs to be on master branch before to build.",
        target="git repository",
        valid=(branch == "master")
    )

def _check_is_docker_image():
    validate(
        error="This program needs to be executed in a docker image.",
        target="docker",
        valid=(os.environ.get("IS_DOCKER", False))
    )

def _check_internet_up():
    try:
        socket.create_connection(("www.github.com", 80))
        connected = True
    except OSError:
        connected = False

    validate(
        error="This program needs to be connected to internet.",
        target="internet",
        valid=connected
    )

def _check_deploy_key():
    valid = True
    target = "deploy_key"

    if IS_TRAVIS and os.path.isfile(os.path.join(paths.base, "deploy_key.enc")) is False:
        valid = False
        target = "deploy_key.enc"

    elif os.path.isfile(os.path.join(paths.base, "deploy_key")) is False:
        valid = False

    validate(
        error="%s could not been found." % target,
        target=target,
        valid=valid
    )

def _check_repository():
    valid = True
    target = "repository.yml"

    if IS_TRAVIS and os.path.isfile(os.path.join(paths.base, "repository.yml.enc")) is False:
        valid = False
        target = "repository.yml.enc"

    elif os.path.isfile(os.path.join(paths.base, "repository.yml")) is False:
        valid = False

    validate(
        error="%s could not been found." % target,
        target=target,
        valid=valid
    )

def _check_content():
    valid = True
    content = ALIAS_CONFIGS

    if not remote_repository():
        content = set(content) - set(SSH_CONFIGS)

    for name in content:
        if not get_attr_value(conf, name):
            valid = False
            break

    validate(
        error="%s must be defined in repository.yml" % name,
        target="content",
        valid=valid
    )

def _check_database():
    valid = True
    error_msg = ""

    if conf.db in ("core", "extra", "community"):
        valid = False
        error_msg = "Database must be different than core, community and extra."

    elif conf.db.isalnum() is False:
        valid = False
        error_msg = "Database must be an alphanumeric string."

    validate(
        error=error_msg,
        target="database",
        valid=valid
    )

def _check_port():
    validate(
        error="port must be an interger in repository.yml",
        target="port",
        valid=(type(conf.ssh_port) == int)
    )

def _check_travis_lint(content):
    error_msg = "An error occured while trying to parse your travis file.\nPlease make sure that the file is valid YAML.",

    validate(
        error=error_msg,
        target="lint",
        valid=(type(content) is dict)
    )

def _check_travis_openssl(content):
    valid = False
    error_msg = "No openssl statement could be found in your travis file.\nPlease make sure to execute: travis encrypt-file ./deploy_key --add"

    if "before_install" in content:
        for statement in content["before_install"]:
            if statement.startswith("openssl"):
                valid = True

    validate(
        error=error_msg,
        target="openssl",
        valid=valid
    )

def _check_pkg_directory():
    validate(
        error="No package was found in pkg directory.",
        target="directory",
        valid=(len(conf.packages) > 0)
    )

def _check_pkg_content():
    folders = [f.name for f in os.scandir(paths.pkg) if f.is_dir()]
    diff = set(folders) - set(conf.packages)

    validate(
        error="No package.py was found in pkg subdirectories: %s" % (", ".join(diff)),
        target="content",
        valid=(len(diff) == 0)
    )

def _check_ssh_connection():
    script = "ssh -i ./deploy_key -p %i -q %s@%s [[ -d %s ]] && echo 1 || echo 0" % (
        conf.ssh_port,
        conf.ssh_user,
        conf.ssh_host,
        conf.ssh_path
    )

    validate(
        error="ssh connection could not be established.",
        target="ssh address",
        valid=(output(script) == "1")
    )

def _check_mirror_connection():
    token = secrets.token_hex(15)
    source = os.path.join(paths.mirror, "validation_token")

    with open(source, "w") as f:
        f.write(token)
        f.close()

    os.system("rsync -aqv -e 'ssh -i ./deploy_key -p %i' %s %s@%s:%s" % (
        conf.ssh_port, source, conf.ssh_user, conf.ssh_host, conf.ssh_path)
    )

    try:
        response = requests.get(conf.url + "/validation_token")
        valid = True if response.status_code == 200 else False
    except requests.RequestException:
        valid = False

    validate(
        error="This program can't connect to %s." % conf.url,
        target="mirror host",
        valid=valid
    )

def _check_github_token():
    valid = False
    user = git_remote_path().split("/")[1]
    response = output("curl -su %s:%s https://api.github.com/user" % (user, conf.github_token))
    content = json.loads(response)

    if "login" in content:
        valid = True

    validate(
        error="An error occured while trying to connect to your github repository with your encrypted token.\nPlease make sure that your token is working.",
        target="github token api",
        valid=valid
    )

class Validator():
    def requirements(self):
        print("Validating requirements:")

        _check_user_privileges()
        _check_is_docker_image()
        _check_internet_up()

    def files(self):
        print("Validating files:")

        _check_repository()

        if remote_repository():
            _check_deploy_key()

    def configs(self):
        print("Validating repository:")

        _check_content()
        _check_database()

        if remote_repository():
            _check_port()

    def connection(self):
        print("Validating connection:")

        if remote_repository():
            _check_ssh_connection()
            _check_mirror_connection()

        _check_github_token()

    def content(self):
        print("Validating packages:")

        _check_pkg_directory()
        _check_pkg_content()

    def travis(self):
        if IS_TRAVIS is False:
            return

        print("Validating travis:")

        with open(".travis.yml", "r") as stream:
            try:
                content = yaml.safe_load(stream)
            except yaml.YAMLError as error:
                content = error

        _check_travis_lint(content)
        _check_travis_openssl(content)

validator = Validator()