import functools

from scipy.special import gamma
from scipy.stats import binned_statistic, iqr
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import iqr
import torch
from scipy.optimize import minimize

from ..utils.initialize import isophotes
from ..utils.parametric_profiles import (
    sersic_torch,
    sersic_np,
    gaussian_torch,
    gaussian_np,
    exponential_torch,
    exponential_np,
    spline_torch,
    moffat_torch,
    moffat_np,
    nuker_torch,
    nuker_np,
)
from ..utils.decorators import ignore_numpy_warnings, default_internal
from ..utils.conversions.coordinates import Rotate_Cartesian
from ..utils.conversions.functions import sersic_I0_to_flux_np, sersic_flux_to_I0_torch
from ..image import (
    Image_List,
    Target_Image,
    Model_Image_List,
    Target_Image_List,
    Window_List,
)
from ..param import Param_Unlock, Param_SoftLimits
from .. import AP_config

# Target Selector Decorator
######################################################################
def select_target(func):
    @functools.wraps(func)
    def targeted(self, target=None, **kwargs):
        if target is None:
            send_target = self.target
        elif isinstance(target, Target_Image_List) and not isinstance(
            self.target, Image_List
        ):
            for sub_target in target:
                if sub_target.identity == self.target.identity:
                    send_target = sub_target
                    break
            else:
                raise RuntimeError(
                    "{self.name} could not find matching target to initialize with"
                )
        else:
            send_target = target
        return func(self, target=send_target, **kwargs)

    return targeted

def select_sample(func):
    @functools.wraps(func)
    def targeted(self, image=None, **kwargs):
        if isinstance(image, Model_Image_List) and not isinstance(
            self.target, Image_List
        ):
            for i, sub_image in enumerate(image):
                if sub_image.target_identity == self.target.identity:
                    send_image = sub_image
                    if "window" in kwargs and isinstance(kwargs["window"], Window_List):
                        kwargs["window"] = kwargs["window"].window_list[i]
                    break
            else:
                raise RuntimeError(
                    "{self.name} could not find matching image to sample with"
                )
        else:
            send_image = image
        return func(self, image=send_image, **kwargs)

    return targeted

# General parametric
######################################################################
@torch.no_grad()
@ignore_numpy_warnings
def parametric_initialize(
    model, parameters, target, prof_func, params, x0_func, force_uncertainty=None
):
    if all(list(parameters[param].value is not None for param in params)):
        return
    # Get the sub-image area corresponding to the model image
    target_area = target[model.window]
    target_dat = target_area.data.detach().cpu().numpy()
    if target_area.has_mask:
        mask = target_area.mask.detach().cpu().numpy()
        target_dat[mask] = np.median(target_dat[np.logical_not(mask)])
    edge = np.concatenate(
        (
            target_dat[:, 0],
            target_dat[:, -1],
            target_dat[0, :],
            target_dat[-1, :],
        )
    )
    edge_average = np.median(edge)
    edge_scatter = iqr(edge, rng=(16, 84)) / 2
    # Convert center coordinates to target area array indices
    icenter = target_area.plane_to_pixel(parameters["center"].value)

    # Collect isophotes for 1D fit
    iso_info = isophotes(
        target_dat - edge_average,
        (icenter[1].item(), icenter[0].item()),
        threshold=3 * edge_scatter,
        pa=(parameters["PA"].value - target.north).detach().cpu().item()
        if "PA" in parameters
        else 0.0,
        q=parameters["q"].value.detach().cpu().item() if "q" in parameters else 1.0,
        n_isophotes=15,
    )
    R = np.array(list(iso["R"] for iso in iso_info)) * target.pixel_length.item()
    flux = np.array(list(iso["flux"] for iso in iso_info)) / target.pixel_area.item()
    # Correct the flux if values are negative, so fit can be done in log space
    if np.sum(flux < 0) > 0:
        AP_config.ap_logger.debug("fixing flux")
        flux -= np.min(flux) - np.abs(np.min(flux) * 0.1)
    flux = np.log10(flux)

    x0 = list(x0_func(model, R, flux))
    for i, param in enumerate(params):
        x0[i] = (
            x0[i] if parameters[param].value is None else parameters[param].value.item()
        )

    def optim(x, r, f):
        residual = (f - np.log10(prof_func(r, *x))) ** 2
        N = np.argsort(residual)
        return np.mean(residual[:-3])

    res = minimize(optim, x0=x0, args=(R, flux), method="Nelder-Mead")
    if not res.success and AP_config.ap_verbose >= 2:
        AP_config.ap_logger.warn(
            f"initialization fit not successful for {model.name}, falling back to defaults"
        )

    if force_uncertainty is None:
        reses = []
        for i in range(10):
            N = np.random.randint(0, len(R), len(R))
            reses.append(
                minimize(optim, x0=x0, args=(R[N], flux[N]), method="Nelder-Mead")
            )
    for param, resx, x0x in zip(params, res.x, x0):
        with Param_Unlock(parameters[param]), Param_SoftLimits(parameters[param]):
            if parameters[param].value is None:
                parameters[param].value = resx if res.success else x0x
            if force_uncertainty is None and parameters[param].uncertainty is None:
                parameters[param].uncertainty = np.std(list(subres.x[params.index(param)] for subres in reses))
            elif force_uncertainty is not None:
                parameters[param].uncertainty = force_uncertainty[params.index(param)]

@torch.no_grad()
@ignore_numpy_warnings
def parametric_segment_initialize(
    model=None,
    parameters=None,
    target=None,
    prof_func=None,
    params=None,
    x0_func=None,
    segments=None,
    force_uncertainty=None,
):
    if all(list(model[param].value is not None for param in params)):
        return
    # Get the sub-image area corresponding to the model image
    target_area = target[model.window]
    target_dat = target_area.data.detach().cpu().numpy()
    if target_area.has_mask:
        mask = target_area.mask.detach().cpu().numpy()
        target_dat[mask] = np.median(target_dat[np.logical_not(mask)])
    edge = np.concatenate(
        (
            target_dat[:, 0],
            target_dat[:, -1],
            target_dat[0, :],
            target_dat[-1, :],
        )
    )
    edge_average = np.median(edge)
    edge_scatter = iqr(edge, rng=(16, 84)) / 2
    # Convert center coordinates to target area array indices
    icenter = target_area.plane_to_pixel(model["center"].value)

    iso_info = isophotes(
        target_dat - edge_average,
        (icenter[1].item(), icenter[0].item()),
        threshold=3 * edge_scatter,
        pa=(model["PA"].value - target.north).item() if "PA" in model else 0.0,
        q=model["q"].value.item() if "q" in model else 1.0,
        n_isophotes=15,
        more=True,
    )
    R = np.array(list(iso["R"] for iso in iso_info)) * target.pixel_length.item()
    was_none = list(False for i in range(len(params)))
    val = {}
    unc = {}
    for i, p in enumerate(params):
        if model[p].value is None:
            was_none[i] = True
            val[p] = np.zeros(segments)
            unc[p] = np.zeros(segments)
    for r in range(segments):
        flux = []
        for iso in iso_info:
            modangles = (
                iso["angles"]
                - (
                    (model["PA"].value - target.north).detach().cpu().item()
                    + r * np.pi / segments
                )
            ) % np.pi
            flux.append(
                np.median(
                    iso["isovals"][
                        np.logical_or(
                            modangles < (0.5 * np.pi / segments),
                            modangles >= (np.pi * (1 - 0.5 / segments)),
                        )
                    ]
                )
            )
        flux = np.array(flux) / target.pixel_area.item()
        if np.sum(flux < 0) >= 1:
            flux -= np.min(flux) - np.abs(np.min(flux) * 0.1)
        flux = np.log10(flux)

        x0 = list(x0_func(model, R, flux))
        for i, param in enumerate(params):
            x0[i] = (
                x0[i] if was_none[i] else model[param].value.detach().cpu().numpy()[r]
            )
        res = minimize(
            lambda x: np.mean((flux - np.log10(prof_func(R, *x))) ** 2),
            x0=x0,
            method="Nelder-Mead",
        )
        if force_uncertainty is None:
            reses = []
            for i in range(10):
                N = np.random.randint(0, len(R), len(R))
                reses.append(
                    minimize(
                        lambda x: np.mean((flux - np.log10(prof_func(R, *x))) ** 2),
                        x0=x0,
                        method="Nelder-Mead",
                    )
                )
        for i, param in enumerate(params):
            if was_none[i]:
                val[param][r] = res.x[i] if res.success else x0[i]
                if force_uncertainty is None and model[param].uncertainty is None:
                    unc[r] = np.std(list(subres.x[params.index(param)] for subres in reses))
                elif force_uncertainty is not None:
                    unc[r] = force_uncertainty[params.index(param)][r]

            with Param_Unlock(model[param]), Param_SoftLimits(model[param]):
                model[param].value = val[param]
                model[param].uncertainty = unc[param]

# Exponential
######################################################################
@default_internal
def exponential_radial_model(self, R, image=None, parameters=None):
    return exponential_torch(
        R,
        parameters["Re"].value,
        image.pixel_area * 10 ** parameters["Ie"].value,
    )

@default_internal
def exponential_iradial_model(self, i, R, image=None, parameters=None):
    return exponential_torch(
        R,
        parameters["Re"].value[i],
        image.pixel_area * 10 ** parameters["Ie"].value[i],
    )

# Sersic
######################################################################
@default_internal
def sersic_radial_model(self, R, image=None, parameters=None):
    return sersic_torch(
        R,
        parameters["n"].value,
        parameters["Re"].value,
        image.pixel_area * 10 ** parameters["Ie"].value,
    )

@default_internal
def sersic_iradial_model(self, i, R, image=None, parameters=None):
    return sersic_torch(
        R,
        parameters["n"].value[i],
        parameters["Re"].value[i],
        image.pixel_area * 10 ** parameters["Ie"].value[i],
    )

# Moffat
######################################################################
@default_internal
def moffat_radial_model(self, R, image=None, parameters=None):
    return moffat_torch(
        R,
        parameters["n"].value,
        parameters["Rd"].value,
        image.pixel_area * 10 ** parameters["I0"].value,
    )

@default_internal
def moffat_iradial_model(self, i, R, image=None, parameters=None):
    return moffat_torch(
        R,
        parameters["n"].value[i],
        parameters["Rd"].value[i],
        image.pixel_area * 10 ** parameters["I0"].value[i],
    )

# Nuker Profile
######################################################################
@default_internal
def nuker_radial_model(self, R, image=None, parameters=None):
    return nuker_torch(
        R,
        parameters["Rb"].value,
        image.pixel_area * 10 ** parameters["Ib"].value,
        parameters["alpha"].value,
        parameters["beta"].value,
        parameters["gamma"].value,
    )

@default_internal
def nuker_iradial_model(self, i, R, image=None, parameters=None):
    return nuker_torch(
        R,
        parameters["Rb"].value[i],
        image.pixel_area * 10 ** parameters["Ib"].value[i],
        parameters["alpha"].value[i],
        parameters["beta"].value[i],
        parameters["gamma"].value[i],
    )

# Gaussian
######################################################################
@default_internal
def gaussian_radial_model(self, R, image=None, parameters=None):
    return gaussian_torch(
        R,
        parameters["sigma"].value,
        image.pixel_area * 10 ** parameters["flux"].value,
    )

@default_internal
def gaussian_iradial_model(self, i, R, image=None, parameters=None):
    return gaussian_torch(
        R,
        parameters["sigma"].value[i],
        image.pixel_area * 10 ** parameters["flux"].value[i],
    )

# Spline
######################################################################
@torch.no_grad()
@ignore_numpy_warnings
@select_target
@default_internal
def spline_initialize(self, target=None, parameters=None, **kwargs):
    super(self.__class__, self).initialize(target=target, parameters=parameters)

    if parameters["I(R)"].value is not None and parameters["I(R)"].prof is not None:
        return

    # Create the I(R) profile radii if needed
    if parameters["I(R)"].prof is None:
        new_prof = [0, 2 * target.pixel_length]
        while new_prof[-1] < torch.max(self.window.shape / 2):
            new_prof.append(
                new_prof[-1] + torch.max(2 * target.pixel_length, new_prof[-1] * 0.2)
            )
        new_prof.pop()
        new_prof.pop()
        new_prof.append(torch.sqrt(torch.sum((self.window.shape / 2) ** 2)))
        parameters["I(R)"].prof = new_prof

    profR = parameters["I(R)"].prof.detach().cpu().numpy()
    target_area = target[self.window]
    target_dat = target_area.data.detach().cpu().numpy()
    if target_area.has_mask:
        mask = target_area.mask.detach().cpu().numpy()
        target_dat[mask] = np.median(target_dat[np.logical_not(mask)])
    Coords = target_area.get_coordinate_meshgrid()
    X, Y = Coords - parameters["center"].value[..., None, None]
    X, Y = self.transform_coordinates(X, Y, target, parameters)
    R = self.radius_metric(X, Y, target, parameters).detach().cpu().numpy()
    rad_bins = [profR[0]] + list((profR[:-1] + profR[1:]) / 2) + [profR[-1] * 100]
    raveldat = target_dat.ravel()

    I = (
        binned_statistic(R.ravel(), raveldat, statistic="median", bins=rad_bins)[0]
    ) / target.pixel_area.item()
    N = np.isfinite(I)
    if not np.all(N):
        I[np.logical_not(N)] = np.interp(profR[np.logical_not(N)], profR[N], I[N])
    I = np.abs(I)
    if I[-1] >= I[-2]:
        I[-1] = I[-2] / 2
    S = binned_statistic(
        R.ravel(), raveldat, statistic=lambda d: iqr(d, rng=[16, 84]) / 2, bins=rad_bins
    )[0]
    N = np.isfinite(S)
    if not np.all(N):
        S[np.logical_not(N)] = np.interp(profR[np.logical_not(N)], profR[N], S[N])
    with Param_Unlock(parameters["I(R)"]), Param_SoftLimits(parameters["I(R)"]):
        parameters["I(R)"].value = np.log10(I)
        parameters["I(R)"].uncertainty = S / (I * np.log(10))

@torch.no_grad()
@ignore_numpy_warnings
@select_target
@default_internal
def spline_segment_initialize(
    self, target=None, parameters=None, segments=1, symmetric=True, **kwargs
):
    super(self.__class__, self).initialize(target=target, parameters=parameters)

    if parameters["I(R)"].value is not None and parameters["I(R)"].prof is not None:
        return

    # Create the I(R) profile radii if needed
    if parameters["I(R)"].prof is None:
        new_prof = [0, 2 * target.pixel_length]
        while new_prof[-1] < torch.max(self.window.shape / 2):
            new_prof.append(
                new_prof[-1] + torch.max(2 * target.pixel_length, new_prof[-1] * 0.2)
            )
        new_prof.pop()
        new_prof.pop()
        new_prof.append(torch.sqrt(torch.sum((self.window.shape / 2) ** 2)))
        parameters["I(R)"].prof = new_prof

    profR = parameters["I(R)"].prof.detach().cpu().numpy()
    target_area = target[self.window]
    target_dat = target_area.data.detach().cpu().numpy()
    if target_area.has_mask:
        mask = target_area.mask.detach().cpu().numpy()
        target_dat[mask] = np.median(target_dat[np.logical_not(mask)])
    Coords = target_area.get_coordinate_meshgrid()
    X, Y = Coords - parameters["center"].value[..., None, None]
    X, Y = self.transform_coordinates(X, Y, target, parameters)
    R = self.radius_metric(X, Y, target, parameters).detach().cpu().numpy()
    T = self.angular_metric(X, Y, target, parameters).detach().cpu().numpy()
    rad_bins = [profR[0]] + list((profR[:-1] + profR[1:]) / 2) + [profR[-1] * 100]
    raveldat = target_dat.ravel()
    val = np.zeros((segments, len(parameters["I(R)"].prof)))
    unc = np.zeros((segments, len(parameters["I(R)"].prof)))
    for s in range(segments):
        if segments % 2 == 0 and symmetric:
            angles = (T - (s * np.pi / segments)) % np.pi
            TCHOOSE = np.logical_or(
                angles < (np.pi / segments), angles >= (np.pi * (1 - 1 / segments))
            )
        elif segments % 2 == 1 and symmetric:
            angles = (T - (s * np.pi / segments)) % (2 * np.pi)
            TCHOOSE = np.logical_or(
                angles < (np.pi / segments), angles >= (np.pi * (2 - 1 / segments))
            )
            angles = (T - (np.pi + r * np.pi / segments)) % (2 * np.pi)
            TCHOOSE = np.logical_or(
                TCHOOSE,
                np.logical_or(
                    angles < (np.pi / segments), angles >= (np.pi * (2 - 1 / segments))
                ),
            )
        elif segments % 2 == 0 and not symmetric:
            angles = (T - (s * 2 * np.pi / segments)) % (2 * np.pi)
            TCHOOSE = torch.logical_or(
                angles < (2 * np.pi / segments),
                angles >= (2 * np.pi * (1 - 1 / segments)),
            )
        else:
            angles = (T - (s * 2 * np.pi / segments)) % (2 * np.pi)
            TCHOOSE = torch.logical_or(
                angles < (2 * np.pi / segments), angles >= (np.pi * (2 - 1 / segments))
            )
        TCHOOSE = TCHOOSE.ravel()
        I = (
            binned_statistic(
                R.ravel()[TCHOOSE], raveldat[TCHOOSE], statistic="median", bins=rad_bins
            )[0]
        ) / target.pixel_area.item()
        N = np.isfinite(I)
        if not np.all(N):
            I[np.logical_not(N)] = np.interp(profR[np.logical_not(N)], profR[N], I[N])
        S = binned_statistic(
            R.ravel(),
            raveldat,
            statistic=lambda d: iqr(d, rng=[16, 84]) / 2,
            bins=rad_bins,
        )[0]
        N = np.isfinite(S)
        if not np.all(N):
            S[np.logical_not(N)] = np.interp(profR[np.logical_not(N)], profR[N], S[N])
        val[s] = np.log10(np.abs(I))
        unc[s] = S / (np.abs(I) * np.log(10))
    with Param_Unlock(parameters["I(R)"]), Param_SoftLimits(parameters["I(R)"]):
        parameters["I(R)"].value = val
        parameters["I(R)"].uncertainty = unc

@default_internal
def spline_radial_model(self, R, image=None, parameters=None):
    return (
        spline_torch(
            R,
            parameters["I(R)"].prof,
            parameters["I(R)"].value,
            extend=self.extend_profile,
        )
        * image.pixel_area
    )

@default_internal
def spline_iradial_model(self, i, R, image=None, parameters=None):
    return (
        spline_torch(
            R,
            parameters["I(R)"].prof,
            parameters["I(R)"].value[i],
            extend=self.extend_profile,
        )
        * image.pixel_area
    )

# RelSpline
######################################################################
@torch.no_grad()
@ignore_numpy_warnings
@select_target
@default_internal
def relspline_initialize(self, target=None, parameters=None, **kwargs):
    super(self.__class__, self).initialize(target=target, parameters=parameters)

    target_area = target[self.window]
    target_dat = target_area.data.detach().cpu().numpy()
    if target_area.has_mask:
        mask = target_area.mask.detach().cpu().numpy()
        target_dat[mask] = np.median(target_dat[np.logical_not(mask)])
    if parameters["I0"].value is None:
        center = target_area.plane_to_pixel(parameters["center"].value)
        flux = target_dat[center[1].int().item(), center[0].int().item()]
        with Param_Unlock(parameters["I0"]), Param_SoftLimits(parameters["I0"]):
            parameters["I0"].value = np.log10(np.abs(flux) / target_area.pixel_area.item())
            parameters["I0"].uncertainty = 0.01

    if parameters["dI(R)"].value is not None and parameters["dI(R)"].prof is not None:
        return

    # Create the I(R) profile radii if needed
    if parameters["dI(R)"].prof is None:
        new_prof = [2 * target.pixel_length]
        while new_prof[-1] < torch.max(self.window.shape / 2):
            new_prof.append(
                new_prof[-1] + torch.max(2 * target.pixel_length, new_prof[-1] * 0.2)
            )
        new_prof.pop()
        new_prof.pop()
        new_prof.append(torch.sqrt(torch.sum((self.window.shape / 2) ** 2)))
        parameters["dI(R)"].prof = new_prof

    profR = parameters["dI(R)"].prof.detach().cpu().numpy()

    Coords = target_area.get_coordinate_meshgrid()
    X, Y = Coords - parameters["center"].value[..., None, None]
    X, Y = self.transform_coordinates(X, Y, target, parameters)
    R = self.radius_metric(X, Y, target, parameters).detach().cpu().numpy()
    rad_bins = [profR[0]] + list((profR[:-1] + profR[1:]) / 2) + [profR[-1] * 100]
    raveldat = target_dat.ravel()

    I = (
        binned_statistic(R.ravel(), raveldat, statistic="median", bins=rad_bins)[0]
    ) / target.pixel_area.item()
    N = np.isfinite(I)
    if not np.all(N):
        I[np.logical_not(N)] = np.interp(profR[np.logical_not(N)], profR[N], I[N])
    if I[-1] >= I[-2]:
        I[-1] = I[-2] / 2
    S = binned_statistic(
        R.ravel(), raveldat, statistic=lambda d: iqr(d, rng=[16, 84]) / 2, bins=rad_bins
    )[0]
    N = np.isfinite(S)
    if not np.all(N):
        S[np.logical_not(N)] = np.interp(profR[np.logical_not(N)], profR[N], S[N])
    with Param_Unlock(parameters["dI(R)"]), Param_SoftLimits(parameters["dI(R)"]):
        parameters["dI(R)"].value = np.log10(np.abs(I)) - parameters["I0"].value.item()
        parameters["dI(R)"].uncertainty = S / (np.abs(I) * np.log(10))

@default_internal
def relspline_radial_model(self, R, image=None, parameters=None):
    return (
        spline_torch(
            R,
            torch.cat((torch.zeros_like(parameters["I0"].value).unsqueeze(-1),parameters["dI(R)"].prof)),
            torch.cat((parameters["I0"].value.unsqueeze(-1), parameters["I0"].value + parameters["dI(R)"].value)),
            extend=self.extend_profile,
        )
        * image.pixel_area
    )


import os
import cv2

path = "/home/bo/桌面/LSVT/train_origin/train_full_images_0/"
datanames = os.listdir(path)
list = []
for i in datanames:
    list.append(i)
# print(list)

i=0
scale = 2.4
for img_name in list:
    img = cv2.imread(path+img_name)
    h,w,c = img.shape

    if h/w>1.2 or w/h>1.2 or h/512>scale or 512/h>scale or w/512>scale or 512/w>scale or min(h,w)/512<1:
        continue
    img_test = cv2.resize(img, (512, 512))

    cv2.imwrite('/home/bo/桌面/LSVT/train_32/'+img_name, img_test)

    print(str(i)+'/'+str(len(list))+': '+img_name)
    i+=1


import os
import asyncio
import logging
import logging.config
import argparse
import sentry_sdk
from random import randint
from sentry_sdk.integrations.logging import LoggingIntegration

MAX_DELAY_SECONDS = 5
parent_logger = logging.getLogger('parent')
children_logger = logging.getLogger('parent.children')
logging.config.fileConfig('logging.ini')

async def sleep():
    await asyncio.sleep(randint(1, MAX_DELAY_SECONDS))

async def debug(event: 'asyncio.Event'):
    while not event.set():
        parent_logger.debug('Debug message')
        children_logger.debug('Debug message')
        await sleep()

async def info(event: 'asyncio.Event'):
    while not event.set():
        parent_logger.info('Info message')
        children_logger.info('Info message')
        await sleep()

async def warning(event: 'asyncio.Event'):
    while not event.set():
        parent_logger.warning('Warning message')
        children_logger.warning('Warning message')
        await sleep()

async def error(event: 'asyncio.Event'):
    while not event.set():
        parent_logger.error('Error message')
        children_logger.warning('Error message')
        await sleep()

async def exception(event: 'asyncio.Event'):
    while not event.set():
        try:
            _ = {}['key']
        except KeyError:
            parent_logger.exception('Exception message')

        try:
            _ = {}['key']
        except KeyError:
            children_logger.exception('Exception message')
        await sleep()

def create_tasks(loop, event, exception_enable):
    sentry_dsn = os.environ.get('SENTRY_DSN', None)
    if sentry_dsn:
        sentry_logging = LoggingIntegration(
            level=logging.INFO,
            event_level=logging.ERROR
        )
        sentry_sdk.init(sentry_dsn, traces_sample_rate=1.0, integrations=[sentry_logging])
    functions = [debug, info, warning, error]
    if exception_enable:
        functions.append(exception)
    [loop.create_task(func(event)) for func in functions]

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--ex_enable', action='store_true', required=False)
    logging.info('Start application')
    current_loop = asyncio.get_event_loop()
    signal_event = asyncio.Event()
    args = parser.parse_args()
    create_tasks(current_loop, signal_event, args.ex_enable)
    try:
        current_loop.run_forever()
    except KeyboardInterrupt:
        logging.info('Wait stop application')
        signal_event.set()
        current_loop.stop()
        logging.info('Application success stop')


from datetime import datetime, timedelta, date, time
from django.core.paginator import Paginator
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from .models import Expense, Category, Limit
from .forms import ExpenseForm, CategoryForm

@login_required(login_url='login-user')
def home(request):
    _MONTHNAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    today = datetime.combine(date.today(), time(0, 0, 0))
    today_end = datetime.combine(date.today(), time(23, 59, 59))
    week = timedelta(minutes=60*24*7)
    expenses = Expense.objects.filter(user=request.user)[0:5]
    categories = Category.objects.filter(user=request.user)
    total_year = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__year=today.year))
    total_month = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__year=today.year, created__month=today.month))
    total_week = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__gte=today - week, created__lte=today_end))
    total_day = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__year=today.year, created__month=today.month, created__day=today.day))
    last_year = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__year=today.year - 1))
    last_month = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__year=today.year, created__month=today.month - 1))
    last_week = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__gte=today - week - week, created__lte=today - week))
    last_day = sum(i.price for i in Expense.objects.filter(
        user=request.user, created__year=today.year, created__month=today.month, created__day=today.day - 1))
    percent_last_year = _get_percent_last(now=total_year, last=last_year)
    percent_last_month = _get_percent_last(now=total_month, last=last_month)
    percent_last_week = _get_percent_last(now=total_week, last=last_week)
    percent_last_day = _get_percent_last(now=total_day, last=last_day)
    categories_percent = _get_categories_percent(
        expenses=Expense.objects.filter(user=request.user), categories=categories)
    expenses_data = []
    for m in range(1, 13):
        expenses_data.append(float(sum(e.price for e in Expense.objects.filter(
            user=request.user, created__year=today.year, created__month=m))))

    try:
        limit = Limit.objects.get(user=request.user)
        limit_percent = (total_month * 100) / limit.number
        limit_progress = limit.number - total_month
        if limit_progress >= 0:
            before_limit = True
        else:
            limit_progress = limit_progress * -1
            before_limit = False

    except:
        limit = False
        limit_percent = False
        limit_progress = False
        before_limit = False

    context = {
        'form': ExpenseForm(),
        'expenses': expenses,
        'categories': categories,
        'categories_percent': categories_percent,
        'total_year': total_year,
        'total_month': total_month,
        'total_week': total_week,
        'total_day': total_day,
        'percent_last_year': percent_last_year,
        'percent_last_month': percent_last_month,
        'percent_last_week': percent_last_week,
        'percent_last_day': percent_last_day,
        'expenses_data': expenses_data,
        'months': _MONTHNAMES,
        'chart_year': today.year,
        'limit': limit,
        'limit_percent': limit_percent,
        'limit_progress': limit_progress,
        'before_limit': before_limit,
    }
    return render(request, 'expenses/home.html', context)

@login_required(login_url='login-user')
def chart_year_change(request, action):
    _MONTHNAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    chart_year = int(request.GET.get('chart_year'))
    if action == 'previous':
        chart_year -= 1
    elif action == 'next':
        chart_year += 1

    e = []
    for m in range(1, 13):
        e.append(float(sum(e.price for e in Expense.objects.filter(
            user=request.user, created__year=chart_year, created__month=m))))

    if e != [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]:
        expenses_data = e
    else:
        chart_year = request.GET.get('chart_year')

    print(expenses_data)
    context = {
        'expenses_data': expenses_data,
        'months': _MONTHNAMES,
        'chart_year': chart_year,
    }
    return render(request, 'expenses/expense-chart.html', context)

@login_required(login_url='login-user')
def expenses_date_filter(request, period, action):
    year, month, day, week_start, week_end = '', '', '', '', ''

    _YEARS = [2020, 2021, 2022]
    _MONTHNAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    today = datetime.combine(date.today(), time(0, 0, 0))
    week = timedelta(minutes=60*24*7)
    categories = Category.objects.filter(user=request.user)

    q = request.GET.get('q') if request.GET.get('q') is not None else ''

    if period == 'year':
        year = today.year
        expenses = Expense.objects.filter(
            user=request.user, created__year=year)
    elif period == 'month':
        month = today.month
        year = today.year
        expenses = Expense.objects.filter(
            user=request.user, created__month=month, created__year=year)
        month = _MONTHNAMES[month - 1]
    elif period == 'week':
        week_start = today - week
        week_end = today
        expenses = Expense.objects.filter(
            user=request.user, created__gte=week_start)
    elif period == 'day':
        day = today.day
        month = today.month
        year = today.year
        expenses = Expense.objects.filter(
            user=request.user, created__day=day, created__month=month, created__year=year)
        day = f'0{day}' if len(str(day)) == 1 else day
        month = _MONTHNAMES[month - 1]

    if action != 'show':
        htmx = True
        if period == 'year':
            year = int(request.GET.get('year'))
            if action == 'previous':
                if year > _YEARS[0]:
                    year -= 1
            elif action == 'next':
                if year < _YEARS[-1]:
                    year += 1

            expenses = Expense.objects.filter(
                user=request.user, created__year=year, name__iregex=q)
            year = year
        elif period == 'month':
            month = int(_MONTHNAMES.index(request.GET.get('month'))) + 1
            year = int(request.GET.get('year'))
            if action == 'previous':
                if year == _YEARS[0] and month == 1:
                    pass
                else:
                    month -= 1
                    if month == 0:
                        year -= 1
            elif action == 'next':
                if year == _YEARS[-1] and month == 12:
                    pass
                else:
                    if month == 12:
                        month = 1
                        year += 1
                    else:
                        month += 1

            expenses = Expense.objects.filter(
                user=request.user, created__month=month, created__year=year, name__iregex=q)
            month = _MONTHNAMES[month - 1]
            year = year
        elif period == 'week':
            week_start = request.GET.get('week_start')
            week_end = request.GET.get('week_end')

            week_start_year = int(week_start.rstrip(', midnight')[-4:])
            week_start_month = int(_MONTHNAMES.index(week_start[:3])) + 1
            week_start_day = int(week_start.split()[1].rstrip(','))
            week_start = datetime(
                week_start_year, week_start_month, week_start_day)

            week_end_year = int(week_end.rstrip(', midnight')[-4:])
            week_end_month = int(_MONTHNAMES.index(week_end[:3])) + 1
            week_end_day = int(week_end.split()[1].rstrip(','))
            week_end = datetime(week_end_year, week_end_month, week_end_day)

            if action == 'previous':
                week_start = week_start - week
                week_end = week_end - week
                if week_start.year < _YEARS[0]:
                    week_start = week_start + week
                    week_end = week_end + week
            elif action == 'next':
                if week_end < today:
                    week_start = week_start + week
                    week_end = week_end + week

            expenses = Expense.objects.filter(
                user=request.user, created__gte=week_start, created__lte=week_end, name__iregex=q)
        elif period == 'day':
            day = int(request.GET.get('day'))
            month = int(_MONTHNAMES.index(request.GET.get('month'))) + 1
            year = int(request.GET.get('year'))
            if action == 'previous':
                if day > 1:
                    day -= 1
            elif action == 'next':
                try:
                    datetime(year, month, day + 1)
                    day += 1
                except:
                    day = day

            expenses = Expense.objects.filter(
                user=request.user, created__day=day, created__month=month, created__year=year, name__iregex=q)
            day = f'0{day}' if len(str(day)) == 1 else day
            month = _MONTHNAMES[month - 1]
    else:
        htmx = False

    paginator = Paginator(expenses, 10)
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)

    context = {
        'expenses': page_obj,
        'categories': categories,
        'expenses_length': len(expenses),
        'period': period,
        'year': year,
        'month': month,
        'day': day,
        'week_start': week_start,
        'week_end': week_end,
        'years': _YEARS,
        'months': _MONTHNAMES,
    }

    if request.GET.get('load-more') == 'True' or action == 'search':
        return render(request, 'expenses/expenses-card-rows.html', context)

    if htmx == True:
        return render(request, 'expenses/expenses-card.html', context)
    else:
        return render(request, 'expenses/total-period.html', context)

@login_required(login_url='login-user')
def add_expense(request):
    today = datetime.combine(date.today(), time(0, 0, 0))
    form = ExpenseForm()
    categories = Category.objects.filter(user=request.user)
    expenses = Expense.objects.filter(
        Q(user=request.user),
        Q(created__year=today.year, created__month=today.month, created__day=today.day - 1) |
        Q(created__year=today.year, created__month=today.month, created__day=today.day))
    if request.method == 'POST':
        form = ExpenseForm(request.POST)
        if form.is_valid():
            expense = form.save()
            expense.user = request.user
            for pk in request.POST.getlist('category'):
                expense.category.add(Category.objects.get(pk=pk))
            expense.save()
            messages.add_message(request, messages.SUCCESS, 'Expense added!')
            return redirect('add-expense')

    context = {
        'recently_add': True,
        'form': form,
        'expenses': expenses,
        'categories': categories,
    }
    return render(request, 'expenses/add-expense.html', context)

@login_required(login_url='login-user')
def add_category(request):
    today = datetime.combine(date.today(), time(0, 0, 0))
    form = CategoryForm()
    categories = Category.objects.filter(user=request.user)
    recently_categories = Category.objects.filter(
        Q(user=request.user),
        Q(created__year=today.year, created__month=today.month, created__day=today.day - 1) |
        Q(created__year=today.year, created__month=today.month, created__day=today.day))
    if request.method == 'POST':
        form = CategoryForm(request.POST)
        if form.is_valid():
            category = form.save()
            category.user = request.user
            category.save()
            messages.add_message(request, messages.SUCCESS, 'Category added!')
            return redirect('add-category')
        else:
            print('ERROR')

    context = {
        'form': form,
        'categories': categories,
        'recently_categories': recently_categories,
    }
    return render(request, 'expenses/add-category.html', context)

@login_required(login_url='login-user')
def update_expense(request, pk):
    expense = get_object_or_404(Expense, pk=pk, user=request.user)
    name = request.POST.get('name')
    price = request.POST.get('price')

    if _expense_validator(request, name=name, price=price):
        expense.name = name
        expense.price = price
        expense.category.clear()
        for pk in request.POST.getlist('category'):
            expense.category.add(Category.objects.get(pk=pk))

        expense.save()
        messages.add_message(request, messages.SUCCESS, 'Expense updated!')

    return redirect(request.META.get('HTTP_REFERER'))

@login_required(login_url='login-user')
def update_category(request, pk):
    category = get_object_or_404(Category, pk=pk, user=request.user)
    name = request.POST.get('name')
    color = request.POST.get('color')
    if _category_validator(request, name=name):
        category.name = name
        category.color = color
        category.save()
        messages.add_message(request, messages.SUCCESS, 'Category updated!')

    return redirect(request.META.get('HTTP_REFERER'))

@login_required(login_url='login-user')
def delete_expense(request, pk):
    expense = get_object_or_404(Expense, pk=pk, user=request.user)
    expense.delete()
    messages.add_message(request, messages.SUCCESS, 'Expense deleted!')
    return redirect(request.META.get('HTTP_REFERER'))

@login_required(login_url='login-user')
def delete_category(request, pk):
    category = get_object_or_404(Category, pk=pk, user=request.user)
    category.delete()
    messages.add_message(request, messages.SUCCESS, 'Category deleted!')
    return redirect(request.META.get('HTTP_REFERER'))

@login_required(login_url='login-user')
def set_limit(request):
    number = request.POST.get('number')
    try:
        limit = Limit.objects.get(user=request.user)
        limit.number = number
        limit.save()
    except:
        Limit.objects.create(user=request.user, number=number)

    return redirect('home')

def _get_percent_last(now, last):
    percent_status = []
    if now == 0 and last == 0:
        percent_status.append(0)
        percent_status.append('Null')
        return percent_status

    if last == 0:
        percent_status.append(0)
        percent_status.append('Up')
        return percent_status
    else:
        if now >= last:
            percent_status.append((now - last) / last * 100)
            percent_status.append('Up')
            return percent_status
        else:
            percent_status.append((last - now) / last * 100)
            percent_status.append('Down')
            return percent_status

def _get_categories_percent(expenses, categories):
    categories_percent = dict()
    all_sum = 0
    for e in expenses:
        all_sum += e.price

    for category in categories:
        sum = 0
        for i in category.category.all():
            print(i)
            sum += i.price
        if sum > 0:
            categories_percent[category.name] = sum / all_sum * 100
        else:
            categories_percent[category.name] = 0

    return categories_percent

def _expense_validator(request, name, price):
    valid = False
    if len(name) == 0:
        messages.add_message(request, messages.ERROR,
                             'The name must contain at least 1 character!')
    elif len(name) > 100:
        messages.add_message(request, messages.ERROR,
                             'The name must be less than 100 characters!')
    elif float(price) < 0.01:
        messages.add_message(request, messages.ERROR,
                             'The price should be more than $0.01!')
    elif float(price) > 9999999999.99:
        messages.add_message(request, messages.ERROR,
                             'The price should be less than $9999999999.99!')
    else:
        valid = True

    return valid

def _category_validator(request, name):
    valid = False
    if len(name) == 0:
        messages.add_message(request, messages.ERROR,
                             'The name must contain at least 1 character!')
    elif len(name) > 100:
        messages.add_message(request, messages.ERROR,
                             'The name must be less than 100 characters!')
    else:
        valid = True

    return valid


import json
import urllib.parse
import boto3

print('Loading function')

def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Extracting relevant information from the S3 event trigger
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    object_key = event['Records'][0]['s3']['object']['key']

    print(f"File '{object_key}' was uploaded to bucket '{bucket_name}'")

    # Send a notification via SNS

    try:
        sns = boto3.client('sns')
        topic_arn = 'arn:aws:sns:ap-south-1:<AWS account-id>:s3-lambda-sns'
        sns.publish(
            TopicArn=topic_arn,
            Subject='S3 Object Created',
            Message='File ' +  object_key + ' was uploaded to bucket ' + bucket_name
            )

    except Exception as e:

        print(e)
        print('Error getting object_key{} from bucket_name{}. Make sure they exist and your bucket is in the same region as this function.'.format(object_key, bucket_name))
        raise e

    return {
        'statusCode': 200,
            'body': json.dumps('Lambda function executed successfully')
	    }


import cv2
import numpy as np

img=cv2.imread('mermer.jpg')

img=cv2.resize(img,(800,800))

hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# kırmızı renk için HSV değerleri
low_red=np.array([170, 50, 70])
high_red=np.array([180, 255, 255])

mask = cv2.inRange(hsv_img, low_red, high_red)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
mask = cv2.GaussianBlur(mask, (3, 3), 0)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                        cv2.CHAIN_APPROX_SIMPLE)[-2]

for cnt in cnts:
    (x, y, w, h) = cv2.boundingRect(cnt)

    if w > 50: # Resimdeki küçük yerleri tespit etmesin diye. Bu değer resimden resime değişir
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 4)

cv2.imshow("Resim", img)
cv2.waitKey(0)
cv2.destroyAllWindows()


import requests

from elasticsearch import Elasticsearch

SETTINGS = {
    'analysis': {
        'analyzer': {
            # for the vector scoring plug-in configuration
            'payload_analyzer': {
                'type': 'custom',
                'tokenizer': 'whitespace',
                'filter': 'delimited_payload_filter'
            }
        }
    }
}

BING_MAPPINGS = {
    "bing": {
        "properties": {
            "summary": {"type": "text"},
            "url": {"type": "text"},
            "article_name": {"type": "text"},
            "news_source_name": {"type": "text"},
            "date_published": {"type": "date"},
            "all_text": {"type": "text"},
        }
    }
}

DENSITY_MAPPINGS = {
    "arson_density": {
        "properties": {
            "state": {"type": "text"},
            "count": {"type": "integer"},
            "population": {"type": "integer"},
            "year": {"type": "text"},
            "pop_density": {"type": "float"}
            }
        }
}

MAPPINGS = {
    "motives": {
        "properties": {
            "state": {"type": "text"},
            "motive": {"type": "text"},
            "year": {"type": "text"}
        }
    },
    "method": {
        "properties": {
            "state": {"type": "text"},
            "method": {"type": "text"},
            "year": {"type": "text"}
        }
    },
    "ownership": {
        "properties": {
            "state": {"type": "text"},
            "ownership": {"type": "text"},
            "year": {"type": "text"}
        }
    },
    "monthly_counts": {
        "properties": {
            "state": {"type": "text"},
            "month": {"type": "text"},
            "count": {"type": "integer"},
            "year": {"type": "text"}
        }

    },
    "arson_density": {
        "properties": {
            "state": {"type": "text"},
            "count": {"type": "integer"},
            "population": {"type": "integer"},
            "year": {"type": "text"},
            "pop_density": {"type": "float"}
        }
    }
}

class ElasticSearch(object):

    def __init__(self):
        self.host = "localhost"
        self.port = 9200
        self.es = Elasticsearch([{'host': self.host, 'port': self.port}])

    def delete_index(self, index):
        if self.es.indices.exists(index):
            print("Index '{}' exists. Deleting it now...".format(index))
            es_object.indices.delete(index=index)
            print("Deleted index...")

    def create_indices(self, settings=SETTINGS, mappings=MAPPINGS):
        for key, value in mappings.items():
            if not self.es.indices.exists(key):
                self.es.indices.create(
                    index=key,
                    body={"settings": settings, "mappings": {key: value}}
                )
                print("Index '{}' created.".format(key))
            else:
                print("Index '{}' already exists. Cannot create it.".format(key))

    def add_to_index(self, index, doc_type, body):
        self.es.index(index=index, doc_type=doc_type, body=body)

    def add_to_elastic(self, aggs, key, year, fields):
        if key == "monthly_counts":
            for row in aggs:
                self.es.index(
                    index=key,
                    doc_type=key,
                    body=dict(zip(fields[key], [row["state"], row["inc_date"], row["count"], year]))
                )

        elif key == "arson_density":
            for row in aggs:
                self.es.index(
                    index=key,
                    doc_type=key,
                    body=dict(zip(fields[key], [row[field] for field in fields[key]]))
                )

        else:
            for state, value in aggs.items():
                self.es.index(
                    index=key,
                    doc_type=key,
                    body=dict(zip(fields[key], [state, value, year]))
                )

    def query_index(self, index_name, query, field="", max_size=51):
        if len(field) > 0:
            query = field + ":" + query
        res = self.es.search(index=index_name, q=query, size=max_size)
        return res["hits"]["hits"]


# Task:
# - Processed the data: On a particular date, If 70% number of confirmed case is zero, then Delete the column. i.e. whole February will be deleted and few more.
# - Plot the graph
#     - Country Wise
#     - Date Wise
#     - Continent Wise

import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('../Datasets/time_series_2019-ncov-Confirmed.csv')
# print(data.head())
# print(data.describe())
calcuation = (len(data)*70)/100
totalZeroCasesInCol = (data == 0).sum()
dropCol = [k for k,v in totalZeroCasesInCol.iteritems() if v > calcuation]
data.drop(dropCol, axis=1, inplace=True)
# print(data.info)

# Country wise ploting.
curData = data.groupby(data['Country/Region']).sum()
curData.drop(['Lat', 'Long'],axis=1, inplace=True)
# print(curData)

xCountry = curData.index[5:20]
yCountry = curData.iloc[5:20,-1]

plt.title('Country wise ploting',fontsize=16, fontweight='bold')
plt.xlabel('Countries')
plt.xticks(rotation=90)
plt.ylabel('NO. of confirmed cases')
plt.bar(xCountry, yCountry, color='red')
plt.show()
# Date Wise Ploting.

curData.loc['total'] = curData.sum(axis=0)
print(curData)

xDate = curData.columns
yDate = curData.loc['total']

plt.title('Date wise ploting')
plt.xlabel('Date',fontsize=16)
plt.xticks(rotation=90)
plt.ylabel('NO. of confirmed cases')

plt.plot(xDate,yDate, '-or')
plt.show()


import logging

from homeassistant.components.sensor import SensorEntity, SensorDeviceClass
from homeassistant.const import UnitOfTemperature
from homeassistant.core import HomeAssistant

from .WebBoilerGenericSensor import WebBoilerGenericSensor

_LOGGER = logging.getLogger(__name__)

class WebBoilerHeatingCircuitSensor:
    """Representation of a Centrometal Boiler Sensor."""

    @staticmethod
    def create_heating_circuits_entities(
        hass: HomeAssistant, device
    ) -> list[SensorEntity]:
        """Creates heating circuits entities."""
        entities = []
        for i in range(1, 5):
            prefix = f"C{i}B"
            name = f"Circuit {i}"
            if WebBoilerHeatingCircuitSensor.device_has_prefix(device, prefix):
                entities.extend(
                    WebBoilerHeatingCircuitSensor.create_heating_circuit_entities(
                        hass, device, prefix, name
                    )
                )
        for i in range(1, 5):
            prefix = f"K{i}B"
            name = f"Circuit {i}K"
            if WebBoilerHeatingCircuitSensor.device_has_prefix(device, prefix):
                entities.extend(
                    WebBoilerHeatingCircuitSensor.create_heating_circuit_entities(
                        hass, device, prefix, name
                    )
                )
        return entities

    @staticmethod
    def device_has_prefix(device, prefix):
        """Returns if device has prefix."""
        for param in device["parameters"].keys():
            if param.startswith(prefix):
                return True
        return False

    @staticmethod
    def create_heating_circuit_entities(
        hass: HomeAssistant, device, prefix, name
    ) -> list[SensorEntity]:
        """Creates entities for heating circuit."""
        entities = []
        items = {}
        items[prefix + "_CircType"] = [
            None,
            "mdi:view-list",
            None,
            name + " Heating Type",
        ]
        items[prefix + "_dayNight"] = [
            None,
            "mdi:view-list",
            None,
            name + " Day Night Mode",
        ]
        items[prefix + "_kor"] = [
            UnitOfTemperature.CELSIUS,
            "mdi:thermometer",
            SensorDeviceClass.TEMPERATURE,
            name + " Room Target Correction",
        ]
        items[prefix + "_korType"] = [
            None,
            "mdi:view-list",
            None,
            name + " Correction Type",
        ]
        items[prefix + "_onOff"] = [None, "mdi:pump", None, name + " Pump Demand"]
        items[prefix + "_P"] = [None, "mdi:pump", None, name + " Pump"]
        items[prefix + "_Tpol"] = [
            UnitOfTemperature.CELSIUS,
            "mdi:thermometer",
            SensorDeviceClass.TEMPERATURE,
            name + " Flow Target Temperature",
        ]
        items[prefix + "_Tpol1"] = [
            UnitOfTemperature.CELSIUS,
            "mdi:thermometer",
            SensorDeviceClass.TEMPERATURE,
            name + " Flow Measured Temperature",
        ]
        items[prefix + "_Tsob"] = [
            UnitOfTemperature.CELSIUS,
            "mdi:thermometer",
            SensorDeviceClass.TEMPERATURE,
            name + " Room Target Temperature",
        ]
        items[prefix + "_Tsob1"] = [
            UnitOfTemperature.CELSIUS,
            "mdi:thermometer",
            SensorDeviceClass.TEMPERATURE,
            name + " Room Measured Temperature",
        ]
        items[prefix + "_misC"] = [
            None,
            "mdi:pipe-valve",
            None,
            name + " Valve Closing",
        ]
        items[prefix + "_misO"] = [
            None,
            "mdi:pipe-valve",
            None,
            name + " Valve Opening",
        ]
        for param_id, sensor_data in items.items():
            parameter = device.get_parameter(param_id)
            entities.append(
                WebBoilerGenericSensor(hass, device, sensor_data, parameter)
            )
        return entities


from __future__ import absolute_import

from ansible.modules.source_control.gitlab_project import GitLabProject

from .gitlab import (GitlabModuleTestCase,
                     python_version_match_requirement,
                     resp_get_group, resp_get_project_by_name, resp_create_project,
                     resp_get_project, resp_delete_project, resp_get_user)

# Gitlab module requirements
if python_version_match_requirement():
    from gitlab.v4.objects import Project

# Unit tests requirements
from httmock import with_httmock  # noqa

class TestGitlabProject(GitlabModuleTestCase):
    @with_httmock(resp_get_user)
    def setUp(self):
        super(TestGitlabProject, self).setUp()

        self.gitlab_instance.user = self.gitlab_instance.users.get(1)
        self.moduleUtil = GitLabProject(module=self.mock_module, gitlab_instance=self.gitlab_instance)

    @with_httmock(resp_get_group)
    @with_httmock(resp_get_project_by_name)
    def test_project_exist(self):
        group = self.gitlab_instance.groups.get(1)

        rvalue = self.moduleUtil.existsProject(group, "diaspora-client")

        self.assertEqual(rvalue, True)

        rvalue = self.moduleUtil.existsProject(group, "missing-project")

        self.assertEqual(rvalue, False)

    @with_httmock(resp_get_group)
    @with_httmock(resp_create_project)
    def test_create_project(self):
        group = self.gitlab_instance.groups.get(1)
        project = self.moduleUtil.createProject(group, {"name": "Diaspora Client", "path": "diaspora-client", "namespace_id": group.id})

        self.assertEqual(type(project), Project)
        self.assertEqual(project.name, "Diaspora Client")

    @with_httmock(resp_get_project)
    def test_update_project(self):
        project = self.gitlab_instance.projects.get(1)

        changed, newProject = self.moduleUtil.updateProject(project, {"name": "New Name"})

        self.assertEqual(changed, True)
        self.assertEqual(type(newProject), Project)
        self.assertEqual(newProject.name, "New Name")

        changed, newProject = self.moduleUtil.updateProject(project, {"name": "New Name"})

        self.assertEqual(changed, False)
        self.assertEqual(newProject.name, "New Name")

    @with_httmock(resp_get_group)
    @with_httmock(resp_get_project_by_name)
    @with_httmock(resp_delete_project)
    def test_delete_project(self):
        group = self.gitlab_instance.groups.get(1)

        self.moduleUtil.existsProject(group, "diaspora-client")

        rvalue = self.moduleUtil.deleteProject()

        self.assertEqual(rvalue, None)


from multiprocessing import cpu_count, Process
from abc import ABCMeta, abstractmethod
from functools import reduce
import pickle
import types
import time
import os

def run(infile, mapper, reducer, max_cores=None):
    master = Master(infile, mapper, reducer, max_cores)
    return master.run()

class Mapper(metaclass=ABCMeta):
    """
        mapper
    """
    def create(self, x):
        """ will be used once when func combine() exists """
        return x
    @abstractmethod
    def map(self):
        pass
    def destory(self):
        pass

class Reducer(metaclass=ABCMeta):
    """
        reducer
    """
    def create(self, x):
        """ will be used once when getting the first map result """
        return x
    @abstractmethod
    def reduce(self):
        pass
    def destory(self):
        pass

class SimpleFileReducer(Reducer):
    """
        a reducer outputs result to a file directly and return None
    """
    def __init__(self, outfile):
        self.writer = open(outfile, 'w', encoding='utf-8')
        assert self.writer != None
    def create(self, a):
        self.writer.write(a)
    def reduce(self, a, b):
        self.writer.write(b)
    def destory(self):
        self.writer.close()

class SimpleMapper(Mapper):
    """
        simple mapper
    """
    def map(self):
        pass

class SimpleReducer(Reducer):
    """
        simple reducer
    """
    def reduce(self):
        pass

class ShuffleIO(object):
    """
        data io, local file
    """
    @staticmethod
    def write_to_file(data_fp, index_fp, x):
        """
            write x to file with pickle format
        """
        data = pickle.dumps(x)
        size = len(data)
        data_fp.write(data)
        index_fp.write("%d\n" % size)

    @staticmethod
    def read_from_file(data_fp, index_fp):
        """
            iterator, read data from file with pickle format
        """
        for line in index_fp:
            size = int(line.strip())
            data = pickle.loads(data_fp.read(size))
            yield data

class Worker(object):
    """
        worker, using 1 core
    """
    def __init__(self, infile, task_name, proc_num, start, length, mapper):
        self.infile = infile
        self.task_name = task_name
        self.proc_num = proc_num
        self.start = start
        self.length = length
        self.mapper = mapper
        self.data_file_name = self.filename("data")
        self.index_file_name = self.filename("index")

    def filename(self, target):
        """
            return the filename corresponding to target
        """
        if target == "data":
            return "%s_%d.data" % (self.task_name, self.proc_num)
        elif target == "index":
            return "%s_%d.index" % (self.task_name, self.proc_num)

    def run_with_combine(self, fp, data_fp, index_fp):
        result = None
        isCreated = False
        for _ in range(self.length):
            data = self.mapper.map(fp.readline())
            if data is None: continue

            if isCreated:
                result = self.mapper.combine(result, data)
            else:
                result = self.mapper.create(data)
                isCreated = True

        ShuffleIO.write_to_file(data_fp, index_fp, result)

    def run_without_combine(self, fp, data_fp, index_fp):
        for _ in range(self.length):
            data = self.mapper.map(fp.readline())
            if data is None: continue
            ShuffleIO.write_to_file(data_fp, index_fp, data)

    def run(self):
        """
            worker runs mapper function in a working loop
        """

        with open(self.infile, encoding='utf-8') as fp, \
            open(self.data_file_name, 'wb') as data_fp, \
            open(self.index_file_name, 'w') as index_fp:

            # jump to start pos
            fp.seek(self.start)

            if hasattr(self.mapper, 'combine'):
                self.run_with_combine(fp, data_fp, index_fp)
            else:
                self.run_without_combine(fp, data_fp, index_fp)

            self.mapper.destory()

class Master(object):
    """
        master of the parallel computing framework, create it at first
    """
    def __init__(self, infile=None, mapper=None, reducer=None, max_cores=None):
        assert mapper!=None and (type(mapper) is types.FunctionType or issubclass(type(mapper), Mapper))
        assert reducer!=None and (type(reducer) is types.FunctionType or issubclass(type(reducer), Reducer))
        assert os.path.isfile(infile)

        self.infile = infile
        self.task_name = "parallel_%d" % int(time.time())
        self.cores = cpu_count()

        if max_cores != None:
            assert type(max_cores) == type(1)
            assert 0 < max_cores <= cpu_count()
            self.cores = max_cores

        if type(mapper) is types.FunctionType:
            self.mapper = SimpleMapper()
            self.mapper.map = mapper
        else:
            self.mapper = mapper

        if type(reducer) is types.FunctionType:
            self.reducer = SimpleReducer()
            self.reducer.reduce = reducer
        else:
            self.reducer = reducer

    def run(self):
        """
            running task by mapper & reducer, using all cpu cores
        """

        starts_lengths = self.get_workload_for_workers()

        workers = []
        for i, start_len in enumerate(starts_lengths):
            proc_num = i+1
            start = start_len[0]
            length = start_len[1]

            worker = Worker(self.infile, self.task_name, proc_num, start, length, self.mapper)
            worker.proc = Process(target=lambda x:x.run(), args=(worker,))
            workers.append(worker)

        # start workers
        for worker in workers: worker.proc.start()

        # block
        self.block_until_workers_done(workers)

        # reducing
        result = self.reducing(workers)

        # join
        for worker in workers: worker.proc.join()

        return result

    def get_workload_for_workers(self):
        """
            get start pos & number of lines need to be mapped, for every worker
        """
        pos = 0
        total_line = 0
        line_pos = []

        # get total line and pos of every line
        with open(self.infile, encoding='utf-8') as fp:
            for line in fp:
                line_pos.append(pos)
                total_line += 1
                pos += len(line.encode('utf-8'))

        assert total_line > 0, "total number of lines must be more than 0"

        # workload(the number of lines) of every worker
        if total_line <= self.cores:
            lengths = [1 for _ in range(total_line)]
        else:
            lengths = [int(total_line/self.cores) for _ in range(self.cores)]
            for i in range(total_line%self.cores):
                lengths[i] += 1

        # start pos of infile for every worker
        cur_line = 0
        starts = []
        for length in lengths:
            starts.append(line_pos[cur_line])
            cur_line += length

        return list(zip(starts, lengths))

    def block_until_workers_done(self, workers):
        """
            blocking
        """
        states = [False for _ in range(len(workers))]
        while not reduce(lambda a,b: a and b, states):
            need_sleep = True

            for i, worker in enumerate(workers):
                if states[i]:
                    continue
                if not worker.proc.is_alive():
                    states[i] = True
                    need_sleep = False

            if need_sleep: time.sleep(0.2)

    def reducing(self, workers):
        """
            master process running reducer function
        """
        result = None
        isCreated = False

        # read intermediate results from files written by workers, and reduce them
        for worker in workers:
            data_file = worker.data_file_name
            index_file = worker.index_file_name

            if os.path.isfile(data_file) and os.path.isfile(index_file):

                # reducer
                for data in ShuffleIO.read_from_file(open(data_file, 'rb'), open(index_file, 'r')):
                    if isCreated:
                        result = self.reducer.reduce(result, data)
                    else:
                        result = self.reducer.create(data)
                        isCreated = True

                # delete files
                os.remove(data_file)
                os.remove(index_file)

        self.reducer.destory()
        return result


import tkinter as tk
import threading
from PIL import ImageTk, Image
from socket import *

class AXEPapichAXE:
    def __init__(self):
        self.win = tk.Tk()
        self.win.title('AXEpapichAXE')
        self.win.geometry("256x256+150+80")
        self.win.config(bg='#800000')
        self.win.minsize(512, 294)

        self.images = [ImageTk.PhotoImage(Image.open(f"images/axe{i}.jpg")) for i in range(1, 35)]
        self.image_index = 0

        self.frame = None
        self.lab = None

        self.setup_ui()
        self.start_server()

    def setup_ui(self):
        self.frame = tk.Frame(self.win, bg='#800000')
        self.frame.pack(fill=tk.BOTH, expand=True)

        self.lab = tk.Label(self.frame, image=self.images[0])
        self.lab.pack(pady=20)

        self.win.protocol("WM_DELETE_WINDOW", self.finish)

    def change_image(self):
        self.image_index = (self.image_index + 1) % len(self.images)
        self.lab.configure(image=self.images[self.image_index])

    def start_server(self):
        new_thread = threading.Thread(target=self._server_thread)
        new_thread.start()

    def _server_thread(self):
        server = socket(AF_INET, SOCK_STREAM)
        server.bind(("192.168.26.73", 6842))
        server.listen()

        user, addr = server.accept()

        while True:
            data = user.recv(1)
            if not data:
                break
            self.change_image()

    def finish(self):
        self.win.destroy()

    def run(self):
        self.win.mainloop()

if __name__ == "__main__":
    app = AXEPapichAXE()
    app.run()


import bpy
from bpy import*
from bpy.props import*

def get_AllObjectsInSelection():
    return bpy.context.selected_objects

def get_hideSelectObjects(object_list):
    for i in object_list:
        i.hide_select = True
    bpy.ops.object.select_all(action='DESELECT')
    return True

class RTS_OT_RePattern_Freeze(bpy.types.Operator):
    # base function from vismaya
    bl_idname = "rts_ot.freeze_selected"
    bl_label = "Freeze Selection"
    bl_description = "Disables Selection"

    def execute(self, context):
        selection = get_AllObjectsInSelection()
        n = len(selection)
        if n > 0:
            get_hideSelectObjects(selection)
            self.report({'INFO'}, "%d Object%s frozen." % (n, "s"[n==1:]))
        else:
            self.report({'INFO'}, 'Nothing selected.')
        return{'FINISHED'}

def get_AllObjectsInScene():
    return bpy.data.objects

def get_dehideSelectObjects(object_list):
    hidedObjs = []
    for i in object_list:
        if i.hide_select == True:
            i.hide_select = False
            hidedObjs.append(i)
    return hidedObjs

def get_highlightObjects(selection_list):
   for i in selection_list:
        bpy.data.objects[i.name].select_set(True)

class RTS_OT_RePattern_Unfreeze(bpy.types.Operator):
    # base function from vismaya
    bl_idname = "rts_ot.unfreeze_selected"
    bl_label = "Unfreeze All"
    bl_description = "Enables Selection"

    def execute(self, context):
        bpy.ops.object.select_all(action='DESELECT')
        selection = get_AllObjectsInScene()
        n = len(selection)

        if n > 0:
            freezed_array = get_dehideSelectObjects(selection)
            get_highlightObjects(freezed_array)
            self.report({'INFO'}, "%d Object%s released." % (n, "s"[n==1:]))
        else:
            self.report({'INFO'}, 'Nothing selected.')

        return{'FINISHED'}


from django.db import models
from django.db.models import signals
from django.contrib.contenttypes.models import ContentType

from savoy.core.geo.models import *
from savoy.core.geo.utils.misc import *

class GeolocatedItemManager(models.Manager):
    def remove_orphans(self, instance, **kwargs):
      """
      When an item is deleted, first delete any GeolocatedItem object that has been created
      on its behalf.
      """
      from savoy.core.geo.models import GeolocatedItem
      try:
        instance_content_type = ContentType.objects.get_for_model(instance)
        geolocated_item = GeolocatedItem.objects.get(content_type=instance_content_type, object_id=instance.id)
        geolocated_item.delete()
      except GeolocatedItem.DoesNotExist:
        return

    def create_or_update(self, instance, location=None, address=None, city=None, neighborhood=None, **kwargs):
      """
      Create or update a GeolocatedItem from some instance. Instance must provide
      either (latitude,longitude) or an address for geocoding.
      """
      from savoy.core.geo.models import GeolocatedItem
      # If the instance hasn't already been saved, save it first.
      if instance._get_pk_val() is None:
        try:
          signals.post_save.disconnect(self.create_or_update, sender=type(instance))
        except:
          reconnect = False
        else:
          reconnect = True
        instance.save()
        if reconnect:
          signals.post_save.connect(self.create_or_update, sender=type(instance))

      # Find this object's content type and model class.
      instance_content_type = ContentType.objects.get_for_model(instance)
      instance_model        = instance_content_type.model_class()

      # If we got an address, we need to geocode it.
      if address:
        location = get_location_from_address(address)

      # We should now have a location tuple (either passed in or geolocated
      # from the passed in address). Unpack it.
      if location:
        latitude, longitude = location

        # Determine the city and neighborhood for this geolocated item.
        if not city:
          city = get_city_from_flickr(latitude, longitude)
        if not neighborhood:
          try:
            neighborhood = get_neighborhood_from_urban_mapping(latitude, longitude, city)
          except:
            neighborhood = None

        # Get or create the GeolocatedItem object.
        geolocated_item, created = self.get_or_create(
          content_type = instance_content_type,
          object_id = instance._get_pk_val(),
          defaults = dict(
            city = city,
            neighborhood = neighborhood,
            latitude = str(latitude),
            longitude = str(longitude),
          )
        )

        # If this is not a new GeolocatedItem object, update it with current data.
        if not created:
          geolocated_item.latitude = str(latitude)
          geolocated_item.longitude = str(longitude)
          geolocated_item.city = city
          geolocated_item.neighborhood = neighborhood

        # Save and return the item.
        geolocated_item.save()
        return geolocated_item
      else:
        return

    def get_for_model(self, model):
      """
      Return a QuerySet of only items of a certain type.
      """
      return self.filter(content_type=ContentType.objects.get_for_model(model))


# HTTP server
from aiohttp import web
import ssl

# Discord
import discord

# Our stuff
import asyncio
import re
import datetime
import sqlite3
import logging
from os import path
from configparser import ConfigParser

LOG_FORMAT = '%(asctime)s | %(message)s'

DB_NAME = 'zmrdiscordnotify.db'

# Intents
# We need members so we can add roles.
INTENTS = discord.Intents.default()
INTENTS.members = True

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

def escape_everything(data):
    return discord.utils.escape_markdown(discord.utils.escape_mentions(data))

def get_valid_tokens():
    tokens = []
    with open(path.join(path.dirname(__file__), '.tokens.txt')) as fp:
        lines = fp.read().splitlines()
        for line in lines:
            if len(line) == 0:
                continue
            # Check for comments
            try:
                comment_index = line.index(';')
                if comment_index == 0:
                    continue
                line = line[:comment_index]
            except ValueError:
                pass
            tokens.append(line.strip())

    return tokens

class Event:
    def __init__(self, id, name, time, description='', warned=False):
        self.id = id
        self.name = name
        self.time = time
        self.description = description
        self.warned = warned

    @staticmethod
    def dateformat():
        return '%Y-%m-%d %H:%M'

    # HACK: We need timezone aware datetime object.
    @staticmethod
    def timezone_aware_time(time):
        delta = datetime.datetime.now() - datetime.datetime.utcnow()
        return time.replace(tzinfo=datetime.timezone(delta))

    @staticmethod
    def create_event(msg_content):
        data = re.findall('"(.+?)"', msg_content)

        if len(data) < 2:
            return None

        cur_time = datetime.datetime.utcnow()
        target_time = datetime.datetime.strptime(data[1], Event.dateformat())

        # We can't make an event in the past!
        if target_time < cur_time:
            return None

        delta = target_time - cur_time

        time = datetime.datetime.now() + delta
        time = Event.timezone_aware_time(time)

        logger.info('Creating event %s...' % data[0])

        return Event(0, data[0], time, '' if len(data) <= 2 else data[2])

    @staticmethod
    def create_event_sql(row):
        # id, name, description, time, warned
        # print(row)

        time = datetime.datetime.strptime(row[3], Event.dateformat())
        time = Event.timezone_aware_time(time)

        return Event(row[0], row[1], time, row[2], row[4])

    def time_to_str(self):
        return self.time.strftime(Event.dateformat())

    def time_to_str_full(self):
        return self.time.strftime(Event.dateformat() + ' (%z)')

    def get_delta_to_now(self):
        return self.time.replace(tzinfo=None) - datetime.datetime.now()

    def should_warn(self):
        if self.warned:
            return False

        timedelta = self.get_delta_to_now()
        # If the days are negative, that means it's in the past.
        # And all logic goes out the window.
        if timedelta.days < 0:
            return False
        minutes = timedelta.days * 1440 + timedelta.seconds / 60
        return minutes < 30 and minutes > 2

    def should_ping(self):
        timedelta = self.get_delta_to_now()
        # If the days are negative, that means it's in the past.
        # And all logic goes out the window.
        if timedelta.days < 0:
            return True
        minutes = timedelta.days * 1440 + timedelta.seconds / 60
        return minutes < 1

    def format_time_todelta(self):
        timedelta = self.get_delta_to_now()
        days = timedelta.days
        hours = timedelta.seconds // 3600
        minutes = timedelta.seconds // 60

        s = ''
        if days > 0:
            s = '%i days ' % days
        if hours > 0:
            s += '%i hours' % hours
        elif minutes > 0:
            s += '%i minutes' % minutes
        else:
            s += '%i seconds' % timedelta.seconds

        return s

    def db_insert(self, conn):
        c = conn.cursor()
        c.execute(
            '''INSERT INTO ntf_events (name,description,time) VALUES
            (?,?,?)''',
            (self.name, self.description, self.time_to_str())
        )
        c.execute('''SELECT LAST_INSERT_ROWID()''')
        self.id = c.fetchone()[0]
        conn.commit()

    def db_markdone(self, conn):
        c = conn.cursor()
        c.execute(
            '''UPDATE ntf_events SET done=1 WHERE id=%i''' % self.id
        )
        conn.commit()

    def db_markwarned(self, conn):
        c = conn.cursor()
        c.execute(
            '''UPDATE ntf_events SET warned=1 WHERE id=%i''' % self.id
        )
        conn.commit()

class RequestData:
    def __init__(self, data, valid_tokens):
        if 'token' not in data:
            raise Exception('No token in JSON object!')

        if not data['token'] in valid_tokens:
            raise Exception('Invalid token.')

        self.hostname = escape_everything(data['hostname'])
        self.link = 'steam://connect/' + escape_everything(data['join_ip'])
        self.num_players = int(data['num_players'])
        self.max_players = int(data['max_players'])
        self.player_name = escape_everything(data['player_name'])

class MyDiscordClient(discord.Client):
    def __init__(self, config):
        super().__init__(intents=INTENTS)

        self.my_channel = None
        self.my_guild = None
        self.my_ping_role = None

        self.events = []

        self.token = config.get('discord', 'token')

        self.ping_role = int(config.get('discord', 'ping_role'))
        self.channel_id = int(config.get('discord', 'channel'))

        self.port = int(config.get('server', 'port'))

        self.cert_path = config.get('server', 'cert')
        self.key_path = config.get('server', 'key')

        self.test_post = False
        if config.get('server', 'test_post'):
            self.test_post = True
            logger.info(
                'Testing POST requests. Notifications are not sent to Discord!'
            )

        self.valid_tokens = get_valid_tokens()

        logger.debug('Valid tokens:')
        for token in self.valid_tokens:
            logger.debug('"' + token + '"')

        self.webapp = web.Application()
        self.webapp.router.add_post('/', self.handle_webrequest)
        if config.get('server', 'test_get'):
            self.webapp.router.add_get('/', self.handle_webrequest_test_get)
            logger.info('Added test GET handler.')

        self.loop.run_until_complete(self.init_webapp())
        self.event_task = self.loop.create_task(self.check_events())

        self.init_sqlite()

    """Init SQL connection, create tables and get events"""
    def init_sqlite(self):
        self.sqlite_connection = sqlite3.connect(
            path.join(path.dirname(__file__), DB_NAME))

        c = self.sqlite_connection.cursor()

        #
        # Init tables
        #
        c.execute(
            '''CREATE TABLE IF NOT EXISTS ntf_events (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name VARCHAR(128) NOT NULL,
            description VARCHAR(256),
            time DATETIME NOT NULL,
            done INTEGET NOT NULL DEFAULT 0,
            warned INTEGER NOT NULL DEFAULT 0)''')

        # Get events
        c.execute(
            '''SELECT id,name,description,time,warned
            FROM ntf_events WHERE done=0''')

        for row in c.fetchall():
            self.events.append(Event.create_event_sql(row))

        self.sqlite_connection.commit()

    """Init web app"""
    async def init_webapp(self):
        try:
            logger.info('Initializing HTTP server...')

            sslcontext = None
            if self.cert_path or self.key_path:
                sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
                sslcontext.load_cert_chain(self.cert_path, self.key_path)
            else:
                logger.info('NOT USING SSL')

            runner = web.AppRunner(self.webapp)
            await runner.setup()
            site = web.TCPSite(runner, port=self.port, ssl_context=sslcontext)
            await site.start()
        except Exception as e:
            logger.error('Error initializing web server: ' + str(e))
        else:
            logger.info('Started HTTP server on port %i.' % self.port)

    """Handles the POST request from game servers."""
    async def handle_webrequest(self, request):
        if not self.is_ready():
            logger.error(
                'Received a POST request while Discord bot is not ready!')
            return

        data = None
        try:
            d = await request.json()
            data = RequestData(d, self.valid_tokens)
        except Exception as e:
            logger.error(
                'Error occurred when parsing json from request: ' + str(e))
            try:
                body = await request.text()
                logger.error('Body: ' + str(body))
            except Exception:
                pass

        if data is None:
            return web.Response(text='Failed!')

        logger.debug('Received valid JSON:')
        logger.debug(str(data))

        if self.test_post:
            logger.info('Testing POST. Not sending a mention.')
            return web.Response(text='Success!')

        try:
            logger.info('Sending mention.')

            embed = discord.Embed(
                title=data.hostname,
                description=data.link,
                color=0x13e82e)
            content = ('%s **%s** wants you to join! (*%i*/*%i*)' %
                       (self.my_ping_role.mention,
                        data.player_name,
                        data.num_players,
                        data.max_players))
            await self.my_channel.send(content=content, embed=embed)
        except Exception as e:
            logger.error('Error sending a mention: ' + str(e))

        return web.Response(text='Success!')

    async def handle_webrequest_test_get(self, request):
        logger.info('Received test GET request!')
        return web.Response(text='Hello!')

    """Task that checks for any events about to happen"""
    async def check_events(self):
        # Wait until we're ready.
        while not self.is_ready():
            await asyncio.sleep(1)

        while not self.is_closed():
            if len(self.events) > 0:
                logger.debug('Checking %i events' % len(self.events))

            for event in self.events:
                if not event.warned and event.should_warn():
                    await self.warn_event(event)
                elif event.should_ping():
                    await self.start_event(event)
                    # We will be removed from the list, so we have to break.
                    break
            await asyncio.sleep(10)

    #
    # Discord.py
    #
    async def on_ready(self):
        print('Logged on as', self.user)

        self.my_channel = self.get_channel(self.channel_id)
        if self.my_channel is None:
            raise Exception('Channel with id %i does not exist!' %
                            self.channel_id)

        self.my_guild = self.my_channel.guild
        if self.my_guild is None:
            raise Exception('Could not find guild for channel!')

        self.my_ping_role = self.my_channel.guild.get_role(self.ping_role)
        if self.my_ping_role is None:
            raise Exception('Role with id %i does not exist!' % self.ping_role)

    async def on_message(self, message):
        if not self.is_ready():
            return
        # Not command?
        if not message.content or message.content[0] != '!':
            return
        # Don't respond to ourselves
        if message.author == self.user:
            return
        # Only either in my channel or DM
        if (message.channel != self.my_channel and
                not isinstance(message.channel, discord.DMChannel)):
            return
        # Not a member of my server
        member = self.my_guild.get_member(message.author.id)
        if member is None:
            return
        #
        # Actual actions.
        #
        if message.content[1:] == 'add':
            await self.add_ping_role(member, message.channel)

        if message.content[1:] == 'remove':
            await self.remove_ping_role(member, message.channel)

        if message.content[1:] == 'events':
            await self.list_events(message.channel)

        if message.content.startswith('addevent', 1):
            await self.add_event(member, message)

        if message.content.startswith('removeevent', 1):
            await self.remove_event(member, message)

        if message.content.startswith('forceevent', 1):
            await self.force_event(member, message)

    #
    # Event stuff
    #
    async def start_event(self, event):
        logger.info('Starting event #%i (%s)' % (event.id, event.name))

        desc = ('%s **%s** is starting!' %
                (self.my_ping_role.mention, event.name))
        embed = discord.Embed(
            title=event.name,
            description=event.description,
            color=0x13e82e
        )
        try:
            await self.my_channel.send(content=desc, embed=embed)
            event.db_markdone(self.sqlite_connection)
            self.events.remove(event)
        except Exception as e:
            logger.error('Error starting an event: ' + str(e))

    async def warn_event(self, event):
        logger.info('Warning event #%i (%s)' % (event.id, event.name))

        desc = ('%s will start in %s!' %
                (event.name, event.format_time_todelta()))

        try:
            await self.my_channel.send(desc)
            event.warned = True
            event.db_markwarned()
        except Exception as e:
            logger.error('Error doing an event warning: ' + str(e))

    def init_event(self, event):
        logger.info('Adding event %s' % event.name)

        event.db_insert(self.sqlite_connection)
        self.events.append(event)

    async def quick_channel_msg(self, msg, channel=None):
        if channel is None:
            channel = self.my_channel
        try:
            await channel.send(msg)
        except Exception as e:
            logger.error('Error sending a channel message: ' + str(e))

    #
    # Command actions
    #
    #
    # Add ping role
    #
    async def add_ping_role(self, member, from_channel):
        if self.my_ping_role in member.roles:
            await self.quick_channel_msg(
                "%s You already have role %s!" %
                (member.mention,
                    self.my_ping_role.name),
                from_channel)
            return
        try:
            logger.info('Adding ping role to user %s!' % member.display_name)

            await member.add_roles(self.my_ping_role, reason='User requested.')
            await from_channel.send('%s Added role %s.' %
                                    (member.mention, self.my_ping_role.name))
        except Exception as e:
            logger.error('Error adding a ping role: ' % str(e))

    #
    # Remove ping role
    #
    async def remove_ping_role(self, member, from_channel):
        if self.my_ping_role not in member.roles:
            await self.quick_channel_msg(
                "%s You don't have role %s!" %
                (member.mention,
                    self.my_ping_role.name),
                from_channel)
            return
        try:
            logger.info('Removing role from user %s!' % member.display_name)

            await member.remove_roles(
                self.my_ping_role,
                reason='User requested.')
            await from_channel.send('%s Removed role %s.' %
                                    (member.mention,
                                        self.my_ping_role.name))
        except Exception as e:
            logger.error('Error removing a ping role: ' + str(e))

    #
    # List events
    #
    async def list_events(self, from_channel):
        if len(self.events) <= 0:
            await self.quick_channel_msg(
                "No events found! :(",
                from_channel)
            return

        embed = discord.Embed(
            title='Events',
            description='',
            color=0x13e82e)

        for event in self.events:
            embed.add_field(
                name='%s | %s' % (event.name, event.time_to_str_full()),
                value=event.format_time_todelta(),
                inline=False)

        try:
            await from_channel.send(
                content='%i event(s)' % len(self.events),
                embed=embed)
        except Exception as e:
            logger.error('Error listing events: ' + str(e))

    #
    # Add event
    #
    async def add_event(self, member, message):
        # Check if they can
        if not member.permissions_in(message.channel).manage_channels:
            return

        # Create the event
        event = Event.create_event(message.content)
        if not event:
            await self.quick_channel_msg(
                '%s Invalid syntax!' % member.mention,
                message.channel)
            return

        try:
            self.init_event(event)
            await message.channel.send(
                '%s Added event **%s** (#%i)\n%s\n**Event happens in %s**.' %
                (member.mention,
                    event.name,
                    event.id,
                    event.time_to_str_full(),
                    event.format_time_todelta())
            )
        except Exception as e:
            logger.error('Error adding an event: ' + str(e))

    #
    # Remove event
    #
    async def remove_event(self, member, message):
        # Check if they can
        if not member.permissions_in(message.channel).manage_channels:
            return

        # Find the event they want removed.
        event = None
        id = -1
        try:
            id = int(message.content.split()[1])
        except Exception as e:
            pass
        else:
            for e in self.events:
                if e.id == id:
                    event = e
                    break

        if not event:
            await self.quick_channel_msg(
                '%s Could not find event #%i!' %
                (member.mention, id),
                message.channel)
            return

        try:
            logger.info('Removing event %s!' % event.name)

            event.db_markdone(self.sqlite_connection)
            self.events.remove(event)

            await message.channel.send(
                '%s Removed event **%s** (%s).' %
                (member.mention,
                    event.name,
                    event.time_to_str_full()))
        except Exception as e:
            logger.error('Error removing an event: ' + str(e))

    #
    # Force event to start
    #
    async def force_event(self, member, message):
        # Check if they can
        if not member.permissions_in(message.channel).manage_channels:
            return

        # Find the event they want.
        event = None
        id = -1
        try:
            id = int(message.content.split()[1])
        except Exception as e:
            pass
        else:
            for e in self.events:
                if e.id == id:
                    event = e
                    break

        if not event:
            await self.quick_channel_msg(
                '%s Could not find event #%i!' %
                (member.mention, id),
                message.channel)
            return

        await self.start_event(event)

if __name__ == '__main__':
    # Read our config
    config = ConfigParser()
    with open(path.join(path.dirname(__file__), '.config.ini')) as fp:
        config.read_file(fp)

    # Init logger
    log_level_str = config.get(
        'server', 'logging', fallback='').upper()
    log_level = getattr(logging, log_level_str, logging.WARNING)
    ch = logging.StreamHandler()
    ch.setLevel(log_level)
    formatter = logging.Formatter(LOG_FORMAT)
    ch.setFormatter(formatter)
    logger.addHandler(ch)

    client = MyDiscordClient(config)

    try:
        client.run(config.get('discord', 'token'))
    except discord.LoginFailure:
        logger.error('Failed to log in! Make sure your token is correct!')
    except Exception as e:
        logger.error('Discord bot ended unexpectedly: ' + str(e))


import cv2
import numpy as np
import sys

base_path1 = 'InputContentImages/'
image_sel = sys.argv[1]

A = cv2.imread(base_path1 + image_sel + '.jpg')
G = A.copy()

# Create the pyramids
gauss_A = [G]
lap_A = []

levels = 4

for i in xrange(levels-1):
    G = cv2.pyrDown(G)
    gauss_A.append(G)

lap_A.append(gauss_A[len(gauss_A)-1])

for i in xrange(levels-1,0,-1):
    gauss_upscl = cv2.pyrUp(gauss_A[i])
    gauss_upscl = cv2.resize(gauss_upscl, (gauss_A[i-1].shape[1], gauss_A[i-1].shape[0]))
    lap = cv2.subtract(gauss_A[i-1], gauss_upscl)
    lap = lap * 2
    lap = cv2.dilate(lap, np.ones((3,3), np.uint8))
    lap_A.append(lap)

base_path2 = 'InputContentImagePyramids/'

for i in xrange(levels):
    cv2.imwrite(base_path2 + image_sel + 'g' + str(i) + '.jpg', cv2.resize(gauss_A[i], (A.shape[1], A.shape[0])))
    cv2.imshow('Levels Gauss' + str(i), cv2.resize(gauss_A[i], (A.shape[1], A.shape[0])))
    cv2.waitKey(0)

for i in xrange(levels):
    cv2.imwrite(base_path2 + image_sel + 'l' + str(i) + '.jpg', cv2.resize(lap_A[i], (A.shape[1], A.shape[0])))
    cv2.imshow('Levels Lap' + str(i), cv2.resize(lap_A[i], (A.shape[1], A.shape[0])))
    cv2.waitKey(0)

cv2.destroyAllWindows()


"""
Circuit: Schematic Creation and Analysis
----------------------------------------
This example shows how you can use PyAEDT to add a subcircuit to a Circuit design.
 Push down into the child subcircuit and pop up to the parent design.
"""

import os

##########################################################
# Set Non Graphical Mode.
# Default is False

non_graphical = os.getenv("PYAEDT_NON_GRAPHICAL", "False").lower() in ("true", "1", "t")

###############################################################################
# Launch AEDT and Circuit
# ~~~~~~~~~~~~~~~~~~~~~~~
# This examples launches AEDT 2022R1 in graphical mode.

from pyaedt import Circuit
circuit = Circuit(specified_version="2022.1", non_graphical=non_graphical)

###############################################################################
# Add new subcircuit
# ~~~~~~~~~~~~~~~~~~
# This example adds a new subcircuit to the previously created Circuit design
# becoming the child circuit.
# Then it pushes down into the child subcircuit.

subcircuit = circuit.modeler.schematic.create_subcircuit([0.0, 0.0])
subcircuit_name = subcircuit.composed_name
circuit.push_down(subcircuit)

###############################################################################
# Subcircuit parameterization
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
# This method parameterizes the subcircuit and adds a resistor, inductor,
# and a capacitor with the value given by the parameters.
# They are then connected in series.
# The ``pop_up`` method provides for getting back to the parent design.

circuit.variable_manager.set_variable("R_val", "35ohm", circuit_parameter=True)
circuit.variable_manager.set_variable("L_val", "1e-7H", circuit_parameter=True)
circuit.variable_manager.set_variable("C_val", "5e-10F", circuit_parameter=True)
p1 = circuit.modeler.schematic.create_interface_port("In")
r1 = circuit.modeler.schematic.create_resistor(value="R_val")
l1 = circuit.modeler.schematic.create_inductor(value="L_val")
c1 = circuit.modeler.schematic.create_capacitor(value="C_val")
p2 = circuit.modeler.schematic.create_interface_port("Out")
circuit.modeler.schematic.connect_components_in_series([p1, r1, l1, c1, p2])
circuit.pop_up()

###############################################################################
# Subcircuit duplication
# ~~~~~~~~~~~~~~~~~~~~~~
# The formerly created subcircuit is duplicated, and a new parameter value is set.
# It works only in graphical mode.

if not non_graphical:
    new_comp = circuit.modeler.schematic.duplicate(subcircuit_name, [0.0512, 0])
    new_comp.parameters["R_val"] = "75ohm"

circuit.release_desktop(True, True)