# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function

import os
import sys

from six.moves import xrange

from collections import Mapping

import tensorflow as tf

from polyaxon.datasets.converters.base import BaseConverter

class ImageReader(object):
    """Base ImageReader class that provides an operation to read/encode/decode an image."""
    def __init__(self, channels=3):
        self._placeholder = tf.placeholder(dtype=tf.string)
        self._image = self.decoder(channels)

    def decoder(self, channels):
        raise NotImplementedError

    def read(self, session, image_data, processing_fn=None):
        _image = self._image
        if processing_fn:
            _image = processing_fn(session, _image)
        return image_data, session.run(_image, feed_dict={self._placeholder: image_data})

class PNGImageReader(ImageReader):
    """A png image class reader"""
    def decoder(self, channels):
        return tf.image.decode_png(self._placeholder, channels=channels)

class PNGNumpyImageReader(ImageReader):
    """A numpy png image class reader"""

    def __init__(self, shape=None):
        self._placeholder = tf.placeholder(dtype=tf.uint8, shape=shape)
        self._image = tf.image.encode_png(self._placeholder)

    def decoder(self, channels):
        pass

    def read(self, session, image_data, processing_fn=None):
        _, image = super(PNGNumpyImageReader, self).read(session, image_data, processing_fn)
        return image, image

class JPGNumpyImageReader(ImageReader):
    """A jpeg numpy image class reader"""
    def __init__(self, shape=None):
        self._placeholder = tf.placeholder(dtype=tf.uint8, shape=shape)
        self._image = tf.image.encode_jpeg(self._placeholder)

    def decoder(self, channels):
        pass

    def read(self, session, image_data, processing_fn=None):
        _, image = super(JPGNumpyImageReader, self).read(session, image_data, processing_fn)
        return image, image

class JPEGImageReader(ImageReader):
    """A jpeg image class reader"""
    def decoder(self, channels):
        return tf.image.decode_jpeg(self._placeholder, channels=channels)

class ImagesToTFExampleConverter(BaseConverter):
    """Converts images to a TFRecords of TF-Example protos.

    Each record is TF-Example protocol buffer which contain a single image and label.

    Args:
        classes: `dict` or `list`. The data classes.
            e.g. ['zero', 'one', 'two', ...] or {0: 'cats', 1: 'dogs'}
        colorspace: `str`. The color space of the images, 'rgb', 'grayscale' ...
        image_format: `str`. The format of the images, 'png', 'jpeg'.
        channels: `int`. The number of channels of the images, e.g. 1, 3.
        image_reader: `ImageReader` instance. If `None` an image reader is created automatically
            based on the `image_format`.
        height: `int`. If provided the the height per image will not be stored in the TFRecord,
            only in the meta_data file.
        width: `int`. If provided the the width per image will not be stored in the TFRecord,
            only in the meta_data file.
        store_filenames: `bool`. If `True` the filename of the image will be stored as a feature.
    """
    def __init__(self, classes, colorspace, image_format, channels, image_reader=None,
                 height=None, width=None, store_filenames=False):
        if image_reader:
            self.image_reader = image_reader
        else:
            if image_format == 'png':
                self.image_reader = PNGImageReader(channels=channels)
            elif image_format == 'jpeg':
                self.image_reader = JPEGImageReader(channels=channels)

        if isinstance(classes, Mapping):
            self.classes = list(classes.values())
            self.labels_to_classes = classes
        elif isinstance(classes, list):
            assert len(set(classes)) == len(classes), '`classes` must contain unique values.'
            self.classes = classes
            self.labels_to_classes = dict(zip(range(len(classes)), classes))
        else:
            raise TypeError('`classes` type is unsupported, received `{}`'.format(type(classes)))

        self.classes_to_labels = {v: k for k, v in self.labels_to_classes.items()}
        self.colorspace = colorspace
        self.image_format = image_format
        self.channels = channels
        self.store_filenames = store_filenames
        self.height = height
        self.width = width

    def get_meta_data(self):
        return {
            'classes': self.classes,
            'num_classes': len(self.classes),
            'labels_to_classes': self.labels_to_classes,
            'colorspace': self.colorspace,
            'image_format': self.image_format,
            'channels': self.channels,
            'height': self.height,
            'width': self.width
        }

    def get_image_features(self, image):
        height = image.shape[0]
        width = image.shape[1]
        assert image.shape[2] == self.channels
        if self.height:
            assert height == self.height
        if self.width:
            assert height == self.width
        return height, width

    def create_example(self, image_data, encoded_image, label, filename=None):
        if hasattr(encoded_image, 'shape'):
            height, width = self.get_image_features(image=encoded_image)
        else:
            # the image could a bytes string
            height, width = self.height, self.width

        if height is None:
            raise ValueError('No `height` will be stored for the images. '
                             'If all images have the `height`, please provide '
                             'the `height`  at instantiation.')

        if width is None:
            raise ValueError('No `width` will be stored for the images. '
                             'If all images have the `width`, please provide '
                             'the `width`  at instantiation.')

        features = {
            'image/class/label': self.to_int64_feature(label),
            'image/encoded': self.to_bytes_feature(tf.compat.as_bytes(image_data)),
            'image/width': self.to_int64_feature(width),
            'image/height': self.to_int64_feature(height),
            'image/format': self.to_bytes_feature(self.image_format.encode()),
            'image/colorspace': self.to_bytes_feature(tf.compat.as_bytes(self.colorspace)),
            'image/channels': self.to_int64_feature(self.channels),
        }
        if self.store_filenames:
            filename_feature = self.to_bytes_feature(tf.compat.as_bytes(os.path.basename(filename)))
            features['image/filename'] = filename_feature

        return tf.train.Example(features=tf.train.Features(feature=features))

    def convert(self, session, writer, images, labels, total_num_items, start_index=0,
                filenames=None, processing_fn=None, post_processing_fn=None):

        if self.store_filenames and not filenames:
            raise ValueError('`filenames` is required to store the filename in TF-Example.'
                             'Either provide a list of `filenames` or '
                             'set `store_filenames` to `False`')

        for i in xrange(start_index, len(images)):
            sys.stdout.write('\r>> Converting image %d/%d' % (i + 1, total_num_items))
            sys.stdout.flush()

            image_data, encoded_image = self.image_reader.read(
                session=session, image_data=images[i], processing_fn=processing_fn)
            if post_processing_fn:
                _, image_data = post_processing_fn(session, encoded_image)
            example = self.create_example(image_data, encoded_image, labels[i],
                                          filenames[i] if self.store_filenames else None)
            writer.write(example.SerializeToString())


from typing import List, Generator, Any

from nltk.tokenize.toktok import ToktokTokenizer
# from nltk.corpus import stopwords
# STOPWORDS = stopwords.words('russian')
import pymorphy2

from deeppavlov.core.models.component import Component
from deeppavlov.core.common.registry import register
from deeppavlov.models.tokenizers.utils import detokenize, ngramize
from deeppavlov.core.common.log import get_logger

logger = get_logger(__name__)

@register('ru_tokenizer')
class RussianTokenizer(Component):
    """
    Tokenize or lemmatize a list of documents.
    Return list of tokens or lemmas, without sentencizing.
    Works only for Russian language.
    """

    def __init__(self, stopwords: list = None, ngram_range: List[int] = None, lemmas=False,
                 lowercase: bool = None, alphas_only: bool = None, **kwargs):
        """
        :param stopwords: a set of words to skip
        :param ngram_range: range for producing ngrams, ex. for unigrams + bigrams should be set to
        [1, 2], for bigrams only should be set to [2, 2]
        :param lemmas: weather to perform lemmatizing or not while tokenizing, currently works only
        for the English language
        :param lowercase: perform lowercasing or not
        :param alphas_only: should filter numeric and alpha-numeric types or not
        """
        if ngram_range is None:
            ngram_range = [1, 1]
        self.stopwords = stopwords or []
        self.tokenizer = ToktokTokenizer()
        self.lemmatizer = pymorphy2.MorphAnalyzer()
        self.ngram_range = tuple(ngram_range)  # cast JSON array to tuple
        self.lemmas = lemmas
        self.lowercase = lowercase
        self.alphas_only = alphas_only
        self.tok2morph = {}

    def __call__(self, batch):
        if isinstance(batch[0], str):
            if self.lemmas:
                return list(self._lemmatize(batch))
            else:
                return list(self._tokenize(batch))
        if isinstance(batch[0], list):
            return [detokenize(doc) for doc in batch]
        raise TypeError(
            "StreamSpacyTokenizer.__call__() is not implemented for `{}`".format(type(batch[0])))

    def _tokenize(self, data: List[str], ngram_range=(1, 1), lowercase=True)\
            -> Generator[List[str], Any, None]:
        """
        Tokenize a list of documents.
        :param data: a list of documents to process
        :param ngram_range: range for producing ngrams, ex. for unigrams + bigrams should be set to
        (1, 2), for bigrams only should be set to (2, 2)
        :param batch_size: the number of documents to process at once
        :param lowercase: whether to perform lowercasing or not
        :return: a single processed doc generator
        """
        # DEBUG
        # size = len(data)
        _ngram_range = self.ngram_range or ngram_range

        if self.lowercase is None:
            _lowercase = lowercase
        else:
            _lowercase = self.lowercase

        for i, doc in enumerate(data):
            # DEBUG
            # logger.info("Tokenize doc {} from {}".format(i, size))
            tokens = self.tokenizer.tokenize(doc)
            if _lowercase:
                tokens = [t.lower() for t in tokens]
            filtered = self._filter(tokens)
            processed_doc = ngramize(filtered, ngram_range=_ngram_range)
            yield from processed_doc

    def _lemmatize(self, data: List[str], ngram_range=(1, 1)) -> \
            Generator[List[str], Any, None]:
        """
        Lemmatize a list of documents.
        :param data: a list of documents to process
        :param ngram_range: range for producing ngrams, ex. for unigrams + bigrams should be set to
        (1, 2), for bigrams only should be set to (2, 2)
        :return: a single processed doc generator
        """
        # DEBUG
        # size = len(data)
        _ngram_range = self.ngram_range or ngram_range

        tokenized_data = list(self._tokenize(data))

        for i, doc in enumerate(tokenized_data):
            # DEBUG
            # logger.info("Lemmatize doc {} from {}".format(i, size))
            lemmas = []
            for token in doc:
                try:
                    lemma = self.tok2morph[token]
                except KeyError:
                    lemma = self.lemmatizer.parse(token)[0].normal_form
                    self.tok2morph[token] = lemma
                lemmas.append(lemma)
            filtered = self._filter(lemmas)
            processed_doc = ngramize(filtered, ngram_range=_ngram_range)
            yield from processed_doc

    def _filter(self, items, alphas_only=True):
        """
        Make ngrams from a list of tokens/lemmas
        :param items: list of tokens, lemmas or other strings to form ngrams
        :param alphas_only: should filter numeric and alpha-numeric types or not
        :return: filtered list of tokens/lemmas
        """
        if self.alphas_only is None:
            _alphas_only = alphas_only
        else:
            _alphas_only = self.alphas_only

        if _alphas_only:
            filter_fn = lambda x: x.isalpha() and not x.isspace() and x not in self.stopwords
        else:
            filter_fn = lambda x: not x.isspace() and x not in self.stopwords

        return list(filter(filter_fn, items))

    def set_stopwords(self, stopwords):
        self.stopwords = stopwords


from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^orders/settlement/$', views.OrderSettlementView.as_view()),  # 去结算

    url(r'^orders/commit/$', views.OrderCommitView.as_view()),  # 提交订单

    url(r'^orders/success/$', views.OrderSuccessView.as_view()),  # 提交订单成功

    url(r'^orders/comment/$', views.GoodsComment.as_view()),  # 商品评价

    url(r'^comments/(?P<sku_id>\d+)/$', views.CommentView.as_view()),  # 商品评论展示

]


import numpy as np
import matplotlib.pyplot as plt
from waterfilling import divide_spectrum, power_allocation, sort_steps, rearrange_powers
from modulators.piM_DPSK import PiMDPSK
from ber_controller import create_modulators, get_curves, ber_controller
from bandpass import temporal_bandpass_filter

# Old implementation

def encode_data(modulators, data, return_psd=True):
    signals = []
    for modulator in modulators:
        signals.append(modulator.modulate(data))
    signal = np.zeros(len(signals[0]))

    for s in signals:
        signal += s
    psds = []
    if return_psd:
        for s in signals:
            psd = np.abs(np.fft.fft(s))[:int(len(s)/2)]
            psd /= np.max(psd)
            psds.append(psd)
        return signal, psds
    else:
        return signal

def decode_signal(modulators, carrier_frequencies, signal):
    data = []
    for mod in modulators:
        data.append(mod.demodulate(signal))
    return data

def ber(data_in, data_out):
    bers = []
    for data in data_out:
        num_errors = np.sum(np.abs(np.subtract(np.array(data_in), np.array(data))))
        bers.append(num_errors / len(data))  # bit error rate
    return bers

class Multicarrier:
    """Implements multi-carrier modulation by combining the single-carrier
       modulator classes"""
    def __init__(self, bandwidth, num_carriers, symbol_rate, fs, power_budget, frequency_axis, noise_spectrum, transfer_function):
        self.bandwidth = bandwidth
        self.num_carriers = num_carriers
        self.symbol_rate = symbol_rate
        self.fs = fs
        self.mod = []

        self.power_budget = power_budget
        self.f = frequency_axis
        self.n = noise_spectrum
        self.h = transfer_function
        self.subcarrier_powers()
        self.subcarrier_modulators()
        self.subcarrier_bandwidth = bandwidth/num_carriers

        self.modulators = []
        self.rates = []
        filenames = ['plotters/data/pi4dpsk_j5.csv', 'plotters/data/pi4dpsk.csv',
                     'plotters/data/pi8dpsk_j5.csv', 'plotters/data/pi8dpsk.csv',
                     'plotters/data/pi16dpsk_j5.csv', 'plotters/data/pi16dpsk.csv',
                     'plotters/data/pi32dpsk_j5.csv', 'plotters/data/pi32dpsk.csv']
        self.curves = get_curves(filenames)

    def subcarrier_powers(self):
        self.channel_noise_ratio = self.h/self.n
        inverse_cnr = 1/self.channel_noise_ratio
        self.f_steps, self.inverse_cnr_steps = divide_spectrum(self.f, inverse_cnr, self.num_carriers)
        sorted_step_depths, indices = sort_steps(self.inverse_cnr_steps)
        self.power_levels = power_allocation(self.power_budget, sorted_step_depths)
        self.power_levels = rearrange_powers(self.power_levels, indices)
        #self.power_levels = self.power_budget/self.num_carriers*np.ones(self.num_carriers)

    def subcarrier_modulators(self):
        for k, fr in enumerate(self.f_steps):
            carrier_amplitude = np.sqrt(2 * self.power_levels[k])
            self.mod.append(create_modulators(self.symbol_rate, fr, carrier_amplitude, self.fs))

    def modulate_packet(self, data, eb_n0_per_band, packet_duration):
        mods = []
        data_per_carrier = []
        s = []
        for j, eb_n0 in enumerate(eb_n0_per_band):
            mod_idx = ber_controller(eb_n0, 10**(-6), self.curves)  # select modulation level
            mods.append(self.mod[j][mod_idx])
        for j, mod in enumerate(mods):
            effective_rate = mod.data_rate
            if mod.coding:
                effective_rate *= (26/31)
            data_size = int(effective_rate*packet_duration)//1560 * 1560
            if len(data) >= data_size:
                subcarrier_data = data[:data_size]
                data_per_carrier.append(subcarrier_data)
                s.append(mod.modulate(subcarrier_data))
                data = data[data_size:]
        signal = np.zeros(np.max([len(s_i) for s_i in s]))
        for j, s_i in enumerate(s):
            signal[:len(s_i)] += s_i
            signal_power = mods[j].carrier_amplitude**2/2
            bit_energy = signal_power/mods[j].data_rate
            n0 = bit_energy/eb_n0_per_band[j]
            noise = np.sqrt(n0 * mods[j].fs / 2) * np.random.standard_normal(len(s_i))
            carrier_spacing = self.bandwidth/self.num_carriers
            in_band_noise = temporal_bandpass_filter(noise, mods[j].fs, mods[j].carrier_frequency-carrier_spacing/2, mods[j].carrier_frequency+carrier_spacing/2)
            plt.plot(np.fft.fft(in_band_noise))
            signal[:len(s_i)] += in_band_noise
        plt.title('noise')
        plt.show()

        return signal, data, data_per_carrier, mods

    def demodulate_packet(self, signal, mods):
        data_per_carrier = []
        for mod in mods:
            detected_data = mod.demodulate(signal)
            data_per_carrier.append(detected_data)
        return data_per_carrier

if __name__ == '__main__':
    datarate = 50000                # data rate [bits/s]
    fs = 1000000                    # ADC/DAC sampling frequency [Hz]
    mod_index = 1                   # modulation index
    m = 32
    P = 50
    number_of_bits = 20000

    total_bandwidth = 200000
    num_carriers = 20

    f = np.linspace(0, total_bandwidth, 2*total_bandwidth+1)
    h = np.abs(1/(1 + 1j*(f**2)/20000/10**6))
    spec = 1.5+0.05*np.random.randn(len(f)) + 10000/(f+2000) + f**2/10**6

    bits = np.random.randint(2, size=number_of_bits)  # array of data bits to be sent

    bandwidth_per_carrier = total_bandwidth/num_carriers
    carrier_frequencies = np.linspace(bandwidth_per_carrier/2, total_bandwidth-bandwidth_per_carrier/2, num_carriers)
    f_bands, noise_bands = divide_spectrum(f, spec, num_carriers)
    f_bands, h_bands = divide_spectrum(f, h, num_carriers)
    inverse_cnr = 1 / h_bands
    power_levels = power_allocation(P, inverse_cnr)

    modulators = []
    for i, f in enumerate(carrier_frequencies):
        carrier_amplitude = np.sqrt(2*power_levels[i])
        modulators.append(PiMDPSK(datarate, f, carrier_amplitude, fs, mod_index, m))

    signal, psds = encode_data(modulators, bits)
    signal = np.clip(signal, -20, 20)
    signal_psd = np.abs(np.fft.fft(signal))
    signal_psd /= np.max(signal_psd)
    f_axis = np.linspace(0, modulators[0].fs/2, int(len(signal)/2))
    plt.figure(figsize=(6, 3))
    for psd in psds:
        plt.plot(f_axis/1000, 10*np.log10(psd), alpha=0.5)
    plt.xlim([0, 200])
    plt.title("PSD of OFDM-carriers")
    plt.xlabel("Frequency [kHz]")
    plt.ylabel("Signal energy [dB]")
    plt.ylim([-20, 5])
    plt.tight_layout()
    plt.savefig("plotters/plots/multicarrier.pdf", bbox_inches='tight', dpi=600)
    plt.show()
    data_decoded = decode_signal(modulators, carrier_frequencies, signal)

    bit_errors = ber(bits, data_decoded)
    print(bit_errors)


import re
import logging
from ..index_tests import key_fields
from faker import Faker
from copy import deepcopy

LOGGER = logging.getLogger("pytest-splunk-addon")
host_ipv4, dvc_ipv4 = 51, 0
src_ipv4, dest_ipv4 = 0, 0
host_ipv6, dvc_ipv6 = 0, 0
src_ipv6, dest_ipv6 = 0, 0
host_count, fqdn_count = 0, 0
url_ip_count = 0
host_ipv4_octet_count, dvc_ipv4_octet_count = -1, 0

ip_rules = {
    "src": {
        "ipv4": "10.1.",
        "ipv6": "fdee:1fe4:2b8c:3261",
    },
    "dest": {
        "ipv4": "10.100.",
        "ipv6": "fdee:1fe4:2b8c:3262",
    },
    "dvc": {
        "ipv4": "172.16.",
        "ipv6": "fdee:1fe4:2b8c:3263",
    },
    "host": {
        "ipv4": "172.16.",
        "ipv6": "fdee:1fe4:2b8c:3264",
    },
    "url": {
        "ip_host": "192.168.",
    },
}

class SampleEvent(object):
    """
    This class represents an event which will be ingested in Splunk.

    Args:
        event_string (str): Event content
        metadata (dict): Contains metadata for the event
        sample_name (str): Name of the file containing this event
    """

    def __init__(self, event_string, metadata, sample_name, requirement_test_data=None):
        self.event = event_string
        self.key_fields = dict()
        self.time_values = list()
        self.metadata = metadata
        self.sample_name = sample_name
        self.host_count = 0
        self.requirement_test_data = requirement_test_data

    def update(self, new_event):
        """
        This method updates the event content

        Args:
            new_event (str): Event content
        """
        LOGGER.debug("Updated the event {} with {}".format(self.event, new_event))
        self.event = new_event

    def get_host(self):
        """
        Returns a unique host value
        """
        global host_count
        host_count += 1
        LOGGER.debug(
            "Creating host value: {}-{}-{}".format(
                "host", self.sample_name, str(host_count)
            )
        )
        return "{}-{}-{}".format("host", self.sample_name, str(host_count))

    def get_field_host(self, rule):
        """
        Returns unique host value for the key fields src, dest, host, dvc

        Args:
            rule (str): Type of rule either src, host, dest, dvc
        """
        global host_count
        host_count += 1
        LOGGER.debug(
            "Creating field with value: {}-{}{}".format(rule, "sample_host", host_count)
        )
        return "{}-{}{}".format(rule, "sample_host", host_count)

    def get_field_fqdn(self, rule):
        """
        Returns unique fqdn value for the key fields src, dest, host, dvc

        Args:
            rule (str): Type of rule either src, host, dest, dvc
        """
        global fqdn_count
        fqdn_count += 1
        LOGGER.debug(
            "Creating fgdn field with value: {}_{}.{}{}.com".format(
                rule, "sample_host", "sample_domain", fqdn_count
            )
        )
        return "{}_{}.{}{}.com".format(rule, "sample_host", "sample_domain", fqdn_count)

    def get_ipv4(self, rule):
        """
        Returns Ipv4 Address as per the rule.

        Args:
            rule (str): Type of rule either src, host, dest, dvc.
            If the value is not one of the key field it will return a randomly generated Ipv4 address.
        """
        if rule == "src":
            global src_ipv4
            src_ipv4 += 1
            addr = [int(src_ipv4 / 256) % 256, src_ipv4 % 256]
            LOGGER.debug(
                "Creating ipv4 field with value: {}".format(
                    "".join(
                        [ip_rules.get(rule)["ipv4"], str(addr[0]), ".", str(addr[1])]
                    )
                )
            )
            return "".join(
                [ip_rules.get(rule)["ipv4"], str(addr[0]), ".", str(addr[1])]
            )
        elif rule == "host":
            global host_ipv4, host_ipv4_octet_count
            host_ipv4_octet_count += 1
            if host_ipv4_octet_count > 255:
                host_ipv4 += 1
                host_ipv4_octet_count = host_ipv4_octet_count % 256
            if host_ipv4 == 101:
                host_ipv4 = 51
            LOGGER.debug(
                "Creating ipv4 field with value: {}".format(
                    "".join(
                        [
                            ip_rules.get(rule)["ipv4"],
                            str(host_ipv4 % 101),
                            ".",
                            str(host_ipv4_octet_count % 256),
                        ]
                    )
                )
            )
            return "".join(
                [
                    ip_rules.get(rule)["ipv4"],
                    str(host_ipv4 % 101),
                    ".",
                    str(host_ipv4_octet_count % 256),
                ]
            )
        elif rule == "dvc":
            global dvc_ipv4, dvc_ipv4_octet_count
            dvc_ipv4 += 1
            dvc_ipv4_octet_count += 1
            LOGGER.debug(
                "Creating ipv4 field with value: {}".format(
                    "".join(
                        [
                            ip_rules.get(rule)["ipv4"],
                            str(dvc_ipv4 % 51),
                            ".",
                            str(dvc_ipv4_octet_count % 256),
                        ]
                    )
                )
            )
            return "".join(
                [
                    ip_rules.get(rule)["ipv4"],
                    str(dvc_ipv4 % 51),
                    ".",
                    str(dvc_ipv4_octet_count % 256),
                ]
            )
        elif rule == "dest":
            global dest_ipv4
            dest_ipv4 += 1
            addr = [int(dest_ipv4 / 256) % 256, dest_ipv4 % 256]
            LOGGER.debug(
                "Creating ipv4 field with value: {}".format(
                    "".join(
                        [ip_rules.get(rule)["ipv4"], str(addr[0]), ".", str(addr[1])]
                    )
                )
            )
            return "".join(
                [ip_rules.get(rule)["ipv4"], str(addr[0]), ".", str(addr[1])]
            )
        elif rule == "url":
            global url_ip_count
            url_ip_count += 1
            addr = [int(url_ip_count / 256) % 256, url_ip_count % 256]
            LOGGER.debug(
                "Creating ipv4 field with value: {}".format(
                    "".join(
                        [ip_rules.get(rule)["ip_host"], str(addr[0]), ".", str(addr[1])]
                    )
                )
            )
            return "".join(
                [ip_rules.get(rule)["ip_host"], str(addr[0]), ".", str(addr[1])]
            )
        else:
            temp_ipv4 = Faker().ipv4()
            LOGGER.debug("Creating ipv4 field with value: {}".format(temp_ipv4))
            return temp_ipv4

    def get_ipv6(self, rule):
        """
        Returns Ipv6 Address as per the rule.

        Args:
            rule (str): Type of rule either src, host, dest, dvc.
            If the value is not one of the key field it will return a randomly generated Ipv6 address.
        """
        if rule == "src":
            global src_ipv6
            ipv6 = src_ipv6 % (int("ffffffffffffffff", 16))
            src_ipv6 += 1
        elif rule == "host":
            global host_ipv6
            ipv6 = host_ipv6 % (int("ffffffffffffffff", 16))
            host_ipv6 += 1
        elif rule == "dvc":
            global dvc_ipv6
            ipv6 = dvc_ipv6 % (int("ffffffffffffffff", 16))
            dvc_ipv6 += 1
        elif rule == "dest":
            global dest_ipv6
            ipv6 = dest_ipv6 % (int("ffffffffffffffff", 16))
            dest_ipv6 += 1
        else:
            temp_ipv4 = Faker().ipv6()
            LOGGER.debug("Creating ipv6 field with value: {}".format(temp_ipv4))
            return temp_ipv4

        hex_count = hex(ipv6)
        non_zero_cnt = len(hex_count[2:])
        addr = "{}{}".format("0" * (16 - non_zero_cnt), hex_count[2:])
        LOGGER.debug(
            "Creating ipv6 field with value: {}:{}".format(
                ip_rules.get(rule)["ipv6"],
                ":".join(addr[i : i + 4] for i in range(0, len(addr), 4)),
            )
        )
        return "{}:{}".format(
            ip_rules.get(rule)["ipv6"],
            ":".join(addr[i : i + 4] for i in range(0, len(addr), 4)),
        )

    def get_token_count(self, token):
        """
        Returns the token count in event

        Args:
            token (str): Token name
        """
        return len(re.findall(token, self.event, flags=re.MULTILINE))

    def get_token_extractions_count(self, token):
        """
        Returns minimum number of occurrence count if token not found in event but is in extracted fields

        Args:
            token (str): Token name
        """
        tokens_in_extractions = 0
        if (
            self.requirement_test_data is not None
            and "cim_fields" in self.requirement_test_data.keys()
        ):
            for extracted_field in self.requirement_test_data["cim_fields"].values():
                if isinstance(extracted_field, str):
                    tokens_in_extractions += len(re.findall(token, extracted_field))
                elif isinstance(extracted_field, list):
                    for each_filed in extracted_field:
                        tokens_in_extractions += len(re.findall(token, each_filed))
        return 1 if tokens_in_extractions > 0 else 0

    def replace_token(self, token, token_values):
        """
        Replaces the token value in event

        Args:
            token (str): Token name
            token_values (list/str): Value(s) to be replaced in the token
        """
        # TODO: How to handle dependent Values with list of token_values
        if isinstance(token_values, list):
            sample_tokens = re.finditer(token, self.event, flags=re.MULTILINE)

            for _, token_value in enumerate(token_values):
                token_value = token_value.value
                match_object = next(sample_tokens)
                match_str = (
                    match_object.group(0)
                    if len(match_object.groups()) == 0
                    else match_object.group(1)
                )
                match_str = re.escape(match_str)
                self.event = re.sub(
                    match_str,
                    lambda x: str(token_value),
                    self.event,
                    1,
                    flags=re.MULTILINE,
                )
        else:
            self.event = re.sub(
                token, lambda x: str(token_values), self.event, flags=re.MULTILINE
            )

    def register_field_value(self, field, token_values):
        """
        Registers the value for the key fields in its SampleEvent object

        Args:
            field (str): Token field name
            token_values (list/str): Token value(s) which are replaced in the key fields
        """
        if field == "_time":
            time_list = (
                token_values if isinstance(token_values, list) else [token_values]
            )
            self.time_values.extend([i.key for i in time_list])
        elif field in key_fields.KEY_FIELDS:
            if isinstance(token_values, list):
                for token_value in token_values:
                    self.key_fields.setdefault(field, []).append(str(token_value.key))
            else:
                self.key_fields.setdefault(field, []).append(str(token_values.key))

    def update_requirement_test_field(self, field, token, token_values):
        if field != "_time":
            if (
                self.requirement_test_data is not None
                and "cim_fields" in self.requirement_test_data.keys()
            ):
                for cim_field, value in self.requirement_test_data[
                    "cim_fields"
                ].items():
                    if token in value:
                        if isinstance(token_values, list):
                            if len(token_values) == 1:
                                self.requirement_test_data["cim_fields"][
                                    cim_field
                                ] = value.replace(token, str(token_values[0].key))
                            else:
                                self.requirement_test_data["cim_fields"][cim_field] = [
                                    value.replace(token, str(token_value.key))
                                    for token_value in token_values
                                ]
                        else:
                            self.requirement_test_data["cim_fields"][
                                cim_field
                            ] = value.replace(token, str(token_values.key))

    def get_key_fields(self):
        """
        Returns the key field value from event
        """
        return self.key_fields

    @classmethod
    def copy(cls, event):
        """
        Copies the SampleEvent object into a new one.
        Args:
            event (SampleEvent): Event object which has to be copied

        Returns:
            Copy of the SampleEvent object
        """
        new_event = cls("", {}, "")
        new_event.__dict__ = event.__dict__.copy()
        new_event.key_fields = event.key_fields.copy()
        new_event.time_values = event.time_values[:]
        new_event.metadata = deepcopy(event.metadata)
        new_event.requirement_test_data = deepcopy(event.requirement_test_data)
        return new_event

    def update_metadata(self, event, metadata, key_fields):
        """
        Processes the syslog formated samples
        Format::

            '***SPLUNK*** source=<source> sourcetype=<sourcetype> \
            field_1       field2        field3 \
            ##value1##    ##value2##   ##value3##'

        Args:
            event (str): event string containing raw syslog data
            metadata (dict): Contains metadata for the event

        Returns:
            Syslog event and the updated metadata
        """
        try:
            if isinstance(event, str) and event.startswith("***SPLUNK***"):
                header, event = event.split("\n", 1)

                for meta_field in re.findall(r"[\w]+=[^\s]+", header):
                    field, value = meta_field.split("=")
                    if field == "host":
                        metadata[field] = f"host_{metadata[field]}"
                        key_fields["host"] = list([metadata["host"]])
                    else:
                        metadata[field] = value

            return event, metadata, key_fields

        except KeyError as error:
            LOGGER.error(f"Unexpected data found. Error: {error}")
            raise error


# Desired IVs
V6 = [31,31,31,31,31,31]
S0 = [31,31,31,31,31,00]
A0 = [31,00,31,31,31,31]

useFilters = True
MaxResults = 1000
doResearch = True

# Go to root of PyNXBot
import signal
import sys
import json
sys.path.append('../')

from lookups import Util
from nxbot import RaidBot
from rng import XOROSHIRO,Raid
from structure import Den

def signal_handler(signal, frame): #CTRL+C handler
    print("Stop request")
    b.close()

config = json.load(open("../config.json"))
b = RaidBot(config["IP"])

signal.signal(signal.SIGINT, signal_handler)

seed = None

for ii in range(RaidBot.DENCOUNT):
    if ii > 189:
        den = Den(b.readDen(ii + 32))
    elif ii > 99:
        den = Den(b.readDen(ii + 11))
    else:
        den = Den(b.readDen(ii))
    if den.isActive():
        spawn = den.getSpawn(denID = ii, isSword = b.isPlayingSword)
        currShinyLock = 0
        if ii > 189:
            info = f"[CT] denID: {ii-189}"
        elif ii > 99:
            info = f"[IoA] denID: {ii-99}"
        else:
            info = f"denID: {ii+1}"
        info += f"    {den.stars()}★    Species: {Util.STRINGS.species[spawn.Species()]}"
        if spawn.IsGigantamax():
            info += " G-Max"
        if den.isEvent():
            info += "    Event"
            currShinyLock = spawn.ShinyFlag()
        if den.isWishingPiece():
            if currShinyLock != 2:
                info += f"    Next Shiny Frame: {Raid.getNextShinyFrame(den.seed())}"
            else:
                info += f"    Next Shiny Frame: 0"
            seed = den.seed()
            info = "!!! " + info
            piecedSpawn = spawn
            piecedShinyLock = currShinyLock
        print(info)
        r = Raid(seed = den.seed(), TID = b.TID, SID = b.SID, flawlessiv = spawn.FlawlessIVs(), shinyLock = currShinyLock, ability = spawn.Ability(), gender = spawn.Gender(), species = spawn.Species(), altform = spawn.AltForm())
        r.print()
        print()

# Choose RNGable den to calculate frames
if seed is not None and doResearch:
    print('\nWishing Piece Den Prediction:\n')
    i = 0
    while i < MaxResults:
        r = Raid(seed, TID = b.TID, SID = b.SID, flawlessiv = piecedSpawn.FlawlessIVs(), shinyLock = piecedShinyLock, ability = piecedSpawn.Ability(), gender = piecedSpawn.Gender(), species = piecedSpawn.Species(), altform = piecedSpawn.AltForm())
        seed = XOROSHIRO(seed).next()
        if useFilters:
            if (r.ShinyType != 'None' or r.IVs == V6 or r.IVs == S0 or r.IVs == A0) and Util.STRINGS.natures[r.Nature] == 'Careful':
                print(f"Frame:{i}")
                r.print()
                print()
        else:
            print(f"Frame:{i}")
            r.print()
            print()
        i += 1

b.close()


import datetime
from cmath import log
from typing import Any, Dict, List

import boto3
import pytz
from botocore.exceptions import ClientError
from odd_collector_sdk.domain.adapter import AbstractAdapter
from odd_models.models import DataEntity, DataEntityList, DataEntityType

from odd_collector_aws.domain.plugin import SQSPlugin

from .sqs_generator import SqsGenerator

SCHEMA_FILE_URL = (
    "https://raw.githubusercontent.com/opendatadiscovery/opendatadiscovery-specification/"
    "main/specification/extensions/sqs.json"
)

class Adapter(AbstractAdapter):
    def __init__(self, config: SQSPlugin) -> None:
        self._account_id = boto3.client(
            "sts",
            aws_access_key_id=config.aws_access_key_id,
            aws_secret_access_key=config.aws_secret_access_key,
            region_name=config.aws_region,
        ).get_caller_identity()["Account"]
        self._sqs_client = boto3.client(
            "sqs",
            aws_access_key_id=config.aws_access_key_id,
            aws_secret_access_key=config.aws_secret_access_key,
            region_name=config.aws_region,
        )

        self.__oddrn_generator = SqsGenerator(
            cloud_settings={"region": config.aws_region, "account": self._account_id}
        )

    def get_data_entity_list(self) -> DataEntityList:
        return DataEntityList(
            data_source_oddrn=self.get_data_source_oddrn(),
            items=self.get_data_entities(),
        )

    def get_data_entities(self) -> List[DataEntity]:
        try:
            sqs_queues = []
            for queue in self._sqs_client.list_queues()["QueueUrls"]:
                queue_name = queue.split("/")[-1]
                queue_attributes = self._sqs_client.get_queue_attributes(
                    QueueUrl=queue, AttributeNames=["All"]
                )["Attributes"]
                created_at = datetime.datetime.fromtimestamp(
                    int(queue_attributes["CreatedTimestamp"]), tz=pytz.utc
                )
                updated_at = datetime.datetime.fromtimestamp(
                    int(queue_attributes["LastModifiedTimestamp"]), tz=pytz.utc
                )
                del queue_attributes["CreatedTimestamp"]
                del queue_attributes["LastModifiedTimestamp"]
                del queue_attributes["Policy"]
                queue_attributes["AccountID"] = self._account_id
                metadata = [
                    {
                        "schema_url": (
                            f"{SCHEMA_FILE_URL}#/definitions/SQSDataSetExtension"
                        ),
                        "metadata": queue_attributes,
                    }
                ]
                sqs_queues.append(
                    DataEntity(
                        name=queue_name,
                        oddrn=self.__oddrn_generator.get_oddrn_by_path(
                            "queue", queue_name
                        ),
                        type=DataEntityType.KAFKA_TOPIC,
                        created_at=created_at,
                        updated_at=updated_at,
                        metadata=metadata,
                        dataset={"field_list": []},
                    )
                )
        except ClientError:
            raise
        else:
            return sqs_queues

    def get_data_source_oddrn(self) -> str:
        return self.__oddrn_generator.get_data_source_oddrn()


from . import sky_blueprint, weather
from app import Session
from flask import jsonify, request
from app.models.models import User, City, Satellites, Stars, StarsFluxV, StarsParallax
from app.models.schemas import SatellitesSchema, StarsSchema
from flask_jwt_extended import jwt_required, get_jwt_identity
from app.api.planet import Planet as PlanetClass
from datetime import datetime
from app.models.models import Planet, PlanetCoordinates
from app.models.schemas import PlanetSchema, PlanetCoordinatesSchema
from app.api.planet import load_planet_coordinates
from app.api.key import api_key_require
from app.api.satellite import Satellite

@sky_blueprint.route('/stars', methods=['GET'])
def get_stars_filter_by_limit():
    """
    optional parameters:
    limit=Value: int, Default=100
    sort=Value: str, Default=stars, Possible: flux_v, parallax, stars
    key=Value: str, Default=None, Keys are registered in database table key

    Returns list of stars limited by the given integer
    and sorted by chosen parameter

    Notice: if limit is greater than actual number of stars it will return all of them
    """

    session = Session()

    # checking api key
    key = api_key_require(request, session)
    if key:
        return key

    try:
        limit = request.args.get('limit', 100)
        mode = request.args.get('sort', 'stars')
        limit = int(limit)
    except ValueError:
        return {'message': 'Wrong input data provided'}, 400
    except Exception:
        return {'message': 'internal server error'}, 500

    if limit < 0:
        return {'message': 'Wrong input data provided'}, 400

    if mode == 'flux_v':
        model = StarsFluxV
    elif mode == 'parallax':
        model = StarsParallax
    elif mode != 'stars':
        return {'message': 'Wrong sort type provided'}, 400
    else:
        model = Stars

    result = []
    stars = session.query(model).limit(limit)

    for star in stars:
        result.append(StarsSchema().dump(star))

    session.close()
    return jsonify(result)

@sky_blueprint.route('/satellites', methods=['GET'])
def get_satellites_filter_by_limit():
    """
    limit=Value: int, Default=100
    key=Value: str, Default=None, Keys are registered in database table key

    Returns list of satellites limited by the given integer

    Notice: if limit is greater than actual number of satellite it will return all of them
    """

    session = Session()

    # checking api key
    key = api_key_require(request, session)
    if key:
        return key

    try:
        limit = request.args.get('limit', 100)
        limit = int(limit)
    except ValueError:
        return {'message': 'Wrong input data provided'}, 400
    except Exception:
        return {'message': 'internal server error'}, 500

    if limit < 0:
        return {'message': 'Wrong input data provided'}, 400

    result = []
    satellites = session.query(Satellites).limit(limit)

    for satellite in satellites:
        result.append(SatellitesSchema().dump(satellite))

    session.close()
    return jsonify(result)

@sky_blueprint.route('/weather', methods=['GET'])
@jwt_required()
def get_weather_for_user():
    """
    Before using this method make sure the api key in
    config.py is provided

    ?city=Value: str, Default=user`s location

    Returns current weather for the city.
    In case there is a trouble with city you will get 401

    Notice: all the api errors including api key errors return the same
    message and code as the city error
    """

    session = Session()
    current_identity_username = get_jwt_identity()

    user = session.query(User).filter_by(username=current_identity_username).first()
    if not user:
        return {'message': 'User not found'}, 404

    city_object = session.query(City).filter_by(id=user.city_id).first()
    if not city_object:
        return {'message': 'City not found in database'}, 404

    try:
        city = request.args.get('city', city_object.name)
    except Exception:
        return {'message': 'internal server error'}, 500

    data = weather.in_the_city(city)
    if 'cod' not in data:
        return jsonify(data), 200
    elif data['message'] == 'city not found':
        return {'message': 'Wrong city provided'}, 401
    else:
        return {'message': 'internal server error'}, 500

@sky_blueprint.route('/load_coordinates/<start_time>/<stop_time>', methods=['POST'])
@jwt_required()
def load_coordinates(start_time, stop_time):
    """
    start_time: YYYY-MM-DD
    stop_time: YYYY-MM-DD

    Loads coordinates for all the planet table objects in
    time interval into table planet_coordinates
    Returns success message

    Notice: works only for admin (with admin JWT token)
    """

    session = Session()
    current_identity_username = get_jwt_identity()

    if current_identity_username != 'admin':
        return {'message': 'Access is denied'}, 403

    planets = session.query(Planet).all()
    if not planets:
        return {'message': 'The planet table is empty'}, 200

    for planet in planets:
        try:
            coordinates = PlanetClass.get_dec_and_ra_in_time_interval(planet.name, start_time, stop_time)
        except ValueError:
            return {'message': 'Wrong input data provided'}, 400
        except Exception:
            return {'message': 'internal server error'}, 500

        loading_result = load_planet_coordinates(planet, coordinates, session)
        if loading_result:
            return {'message': 'internal server error'}, 500

    session.commit()
    session.close()
    return {'message': 'success'}

@sky_blueprint.route('/planets', methods=['GET'])
def get_planets():
    """
    ?key=Value: str, Default=None, Keys are registered in database table key

    Returns list of dicts
    {'name': planet_name, 'information': planet_dict, 'coordinates': coordinates_dict}
    where coordinates_dict is an planet_coordinates table object dict which for today`s date
    and planet_dict is planet table object dict for current planet.

    !!! In case there are no date for today in the date base the coordinates_dict will be empty.
    """

    session = Session()
    date = datetime.today().strftime('%Y-%m-%d')

    # checking api key
    key = api_key_require(request, session)
    if key:
        return key

    try:
        planets = session.query(Planet).all()
        result = []
        for planet in planets:
            if planet.name in ('Sun', 'Moon'):
                continue
            information = PlanetSchema().dump(planet)
            db_coordinates = session.query(PlanetCoordinates).filter_by(planet_id=planet.id, date=date).first()
            coordinates = PlanetCoordinatesSchema().dump(db_coordinates)
            result.append({'name': planet.name, 'information': information, 'coordinates': coordinates})
    except Exception:
        return {'message': 'internal server error'}, 500

    session.close()
    return jsonify(result)

@sky_blueprint.route('/Sun', methods=['GET'])
def get_sun():
    """
    ?key=Value: str, Default=None, Keys are registered in database table key

    Returns dict
    {'name': 'Sun', 'information': planet_dict, 'coordinates': coordinates_dict}
    where coordinates_dict is an planet_coordinates table object dict which for today`s date
    and planet_dict is planet table object dict for Sun.

    !!! In case there are no date for today in the date base the coordinates_dict will be empty.
    """

    session = Session()
    date = datetime.today().strftime('%Y-%m-%d')

    # checking api key
    key = api_key_require(request, session)
    if key:
        return key

    try:
        planet = session.query(Planet).filter_by(name='Sun').first()
        information = PlanetSchema().dump(planet)
        db_coordinates = session.query(PlanetCoordinates).filter_by(planet_id=planet.id, date=date).first()
        coordinates = PlanetCoordinatesSchema().dump(db_coordinates)
        result = {'name': planet.name, 'information': information, 'coordinates': coordinates}
    except Exception:
        return {'message': 'internal server error'}, 500

    session.close()
    return jsonify(result)

@sky_blueprint.route('/Moon', methods=['GET'])
def get_moon():
    """
    ?key=Value: str, Default=None, Keys are registered in database table key

    Returns dict
    {'name': 'Moon', 'information': planet_dict, 'coordinates': coordinates_dict}
    where coordinates_dict is an planet_coordinates table object dict which for today`s date
    and planet_dict is planet table object dict for Moon.

    !!! In case there are no date for today in the date base the coordinates_dict will be empty.
    """

    session = Session()
    date = datetime.today().strftime('%Y-%m-%d')

    # checking api key
    key = api_key_require(request, session)
    if key:
        return key

    try:
        planet = session.query(Planet).filter_by(name='Moon').first()
        information = PlanetSchema().dump(planet)
        db_coordinates = session.query(PlanetCoordinates).filter_by(planet_id=planet.id, date=date).first()
        coordinates = PlanetCoordinatesSchema().dump(db_coordinates)
        result = {'name': planet.name, 'information': information, 'coordinates': coordinates}
    except Exception:
        return {'message': 'internal server error'}, 500

    session.close()
    return jsonify(result)

@sky_blueprint.route('/satellite/<int:id>', methods=['GET'])
def get_current_satellite_coord(id):
    """
    Calculate satellite's position at current time

    Returns dict
    {'norad_id': satellite's norad, 'latitude': satellite's latitude, 'longitude': satellite's longitude,
    'elevation': satellite's elevation}
    """

    session = Session()

    try:
        satellite = session.query(Satellites).filter_by(norad_id=id).first()
        if not satellite:
            return {'message': 'Satellite not found in database'}, 404

        sat = Satellite(id)

        dateTimeObj = datetime.now()
        timestampStr = dateTimeObj.strftime("%d/%m/%y %H:%M:%S")

        tle = "2 "
        tle += str(id) + " "
        tle += satellite['inclination'] + " "
        tle += satellite['ascending_node_longitude'] + " "
        tle += satellite['eccentricity'] + " "
        tle += satellite['pericenter_argument'] + " "
        tle += satellite['average_anomaly'] + " "
        tle += satellite['call_frequency']

        lat, lon, elev = sat.get_satellite_lon_lat(tle, timestampStr)
        result = {'norad_id': id, 'latitude': lat, 'longitude': lon, 'elevation': elev}
    except Exception:
        return {'message': 'internal server error'}, 500

    session.close()
    return jsonify(result)

@sky_blueprint.route('/satellite/<int:id>/<string:date>/<string:time>', methods=['GET'])
def get_future_satellite_coord(id, date, time):
    """
    Get satellite's future position

    future date: DD-MM-YY
    future time: HH:MM:SS
    EXAMPLE: 21-01-22
             11:39:19

    Returns dict
    {'norad_id': satellite's norad, 'latitude': satellite's latitude, 'longitude': satellite's longitude,
    'elevation': satellite's elevation}
    """

    session = Session()

    try:
        satellite = session.query(Satellites).filter_by(norad_id=id).first()
        if not satellite:
            return {'message': 'Satellite not found in database'}, 404

        sat = Satellite(id)

        tle = "2 "
        tle += str(id) + " "
        tle += satellite['inclination'] + " "
        tle += satellite['ascending_node_longitude'] + " "
        tle += satellite['eccentricity'] + " "
        tle += satellite['pericenter_argument'] + " "
        tle += satellite['average_anomaly'] + " "
        tle += satellite['call_frequency']

        date = date.replace("-", "/")
        date_time = date + " " + time

        lat, lon, elev = sat.get_satellite_lon_lat(tle, date_time)
        result = {'norad_id': id, 'latitude': lat, 'longitude': lon, 'elevation': elev}
    except Exception:
        return {'message': 'internal server error'}, 500

    session.close()
    return jsonify(result)

@sky_blueprint.route('/satellite/passes/<int:id>/<string:city>', methods=['GET'])
def get_satellite_passes(id, city):
    """
    Get satellite passes through 2 days relative to an observer.
    """

    session = Session()

    try:
        satellite = session.query(Satellites).filter_by(norad_id=id).first()
        if not satellite:
            return {'message': 'Satellite not found in database'}, 404

        sat = Satellite(id)

        tle = "2 "
        tle += str(id) + " "
        tle += satellite['inclination'] + " "
        tle += satellite['ascending_node_longitude'] + " "
        tle += satellite['eccentricity'] + " "
        tle += satellite['pericenter_argument'] + " "
        tle += satellite['average_anomaly'] + " "
        tle += satellite['call_frequency']

        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        # IT IS NOT FINISHED
        # WAITING FOR ADDING CITY COORDINATES TO DATABASE CITY TABLE
        # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        # city = session.query(City).filter_by(name=city).first()
        # if not city:
        #             return {'message': 'City not found in database'}, 404
        # observer_lat = city['latitude']
        # observer_long = city['longitude']
        # result = sat.get_satellite_observation(tle, observer_lat, observer_long)
        result = []
    except Exception:
        return {'message': 'internal server error'}, 500

    session.close()
    return jsonify(result)


import collections

class TreeNode:

    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Sol:

    def helper(self,node, lst):

        if len(lst)==0:
            return None

        n=len(lst)-1
        m = n//2

        left_child_idx = (m-1)//2
        right_child_idx = m+(n-m-1)//2

        node.left = TreeNode(lst[left_child_idx])
        node.right = TreeNode(lst[right_child_idx])

        self.helper(node.left, lst[0:m-1])
        self.helper(node.right, lst[m+1:])

    def main(self, lst):

        n = len(lst)
        m = (n-1)//2
        root = TreeNode(lst[m])
        node = root
        self.helper(node, lst)
        return root

    def bfs(self,root):

        q = collections.deque([root])
        res=[]
        while(q):
            l = len(q)
            lst=[]
            for _ in range(l):
                ele = q.popleft()
                if ele:
                    lst.append(ele.val)
                    if ele.left:
                        q.append(ele.left)
                    if ele.right:
                        q.append(ele.right)

            res.append(lst)
        return res

obj = Sol()
lst = [1,2,3,4,5,6,7,8,9]
root = obj.main(lst)
print("--")
print(root.val)
print(root.left.val)
print(root.right.val)
print("--")

"""
[1,2,3,4,5,6,7,8,9]

                           5
                 2                   7
            1        3            6      8
                        4                   9

"""

res = obj.bfs(root)

print("res: {}".format(res))

"""
        1
    2       3
4       5  6  7
"""
node1 = TreeNode(1)
node2 = TreeNode(2)
node3 = TreeNode(3)
node4 = TreeNode(4)
node5 = TreeNode(5)
node6 = TreeNode(6)
node7 = TreeNode(7)

node1.left = node2
node1.right = node3

node2.left = node4
node2.right = node5

node3.left = node6
node3.right = node7

print("----")
print("----")

res = obj.bfs(node1)

print("res: {}".format(res))

"""

          5
    3            7
1       3      7   9

"""


import pymongo
from uncomtrade import comtrade_api
from uncomtrade.notification import notify
import time
import logging

logging.basicConfig(filename='com_trade.log', level=logging.DEBUG)

INTERVAL_BETWEEN_REQUESTS = 2
MINUTE = 60
MINUTES_BETWEEN_409_REQUESTS = 3

COMMODITY = "TOTAL"

client = pymongo.MongoClient()
COLLECTION = client.comtrade.total

country_dict = list(client.comtrade.country_codes.find({}, {"id": 1, "_id": 0}))
country_codes = [code["id"] for code in country_dict if "all" not in code["id"]]

VPN_STATUS = "on"  # !!!!! TURN THE FREAKING VPN OFF !!!!!!

LOGO = r"""
 #     # #     #     #####
 #     # ##    #    #     #  ####  #    # ##### #####    ##   #####  ######
 #     # # #   #    #       #    # ##  ##   #   #    #  #  #  #    # #
 #     # #  #  #    #       #    # # ## #   #   #    # #    # #    # #####
 #     # #   # #    #       #    # #    #   #   #####  ###### #    # #
 #     # #    ##    #     # #    # #    #   #   #   #  #    # #    # #
  #####  #     #     #####   ####  #    #   #   #    # #    # #####  ######

                                            (c) Luca Verginer
"""

print(LOGO)

def is_in_db(country_cd, com_code, year_check):
    return True if COLLECTION.find_one({"rtCode": int(country_cd), "cmdCode": com_code, "yr": year_check}) else False

for year in range(1975, 2015):
    logging.info("-*"*10)
    logging.info(msg="Starting Year: {year}".format(year=year))
    logging.info("-*"*10)
    i = len(country_codes)-1

    # i = START_POSITION
    while i >= 0:
        country = country_codes[i]
        if is_in_db(country, COMMODITY, year):
            logging.debug("already in DB, country: {country}, year: {year} at position, {pos}".format(
                country=country,
                year=year,
                pos=i)
            )
            i -= 1
            continue

        time.sleep(INTERVAL_BETWEEN_REQUESTS)

        json_data = comtrade_api.get_commodity_data(country, COMMODITY, year)

        if type(json_data) is list and json_data:
            try:
                COLLECTION.insert_many(json_data)
                logging.info(msg="inserted country: {country} at position {position} using insert_many".format(
                    country=country,
                    position=i)
                )
                i -= 1
            except pymongo.errors.BulkWriteError:
                for element in json_data:
                    COLLECTION.insert_one(element)
                logging.debug(msg="inserted country: {country} at position {position} using insert_one".format(
                    country=country,
                    position=i)
                )
                i -= 1
                continue
        elif type(json_data) is list and not json_data:
            res = COLLECTION.insert_one({"rtCode": int(country), "cmdCode": COMMODITY, "yr": year, "pfCode": "S1"})
            logging.debug("inserted empty entry in MongoDB at (Object_ID) {id} at position {pos}".format(id=str(res.inserted_id), pos=i))
            i -= 1
        elif json_data == 409:

            message = "409 code received at: {country} at position {position},sleeping for {sleep}".format(
                country=country,
                sleep=MINUTES_BETWEEN_409_REQUESTS,
                position=i)
            logging.warning(msg=message)

            notify(title="UN Comtrade Quota Limit reached",
                   subtitle="Please change proxy",
                   message=message,
                   sound='bell')

            if VPN_STATUS is "on":
                VPN_STATUS = comtrade_api.swithch_vpn("off")
            else:
                VPN_STATUS = comtrade_api.swithch_vpn("on")

            for minute in range(MINUTES_BETWEEN_409_REQUESTS):
                logging.debug("{minute} minute(s) of {max_min} passed.".format(
                    minute=minute,
                    max_min=MINUTES_BETWEEN_409_REQUESTS))
                time.sleep(MINUTE)

            logging.warning(msg="resuming requests")
            continue

        elif json_data == 500:
            logging.warning(msg="500 code received at: {country} at position {position}".format(
                country=country,
                position=i
            ))
            continue

        else:
            logging.debug(msg="skipped for reason: {reason}".format(reason=json_data))
            i -= 1
            continue


from datetime import date
maiores = 0
menores = 0
ano = date.today().year

for c in range(1, 8):
    nascimento = int(input('Digite o ano de nascimento da {}ª pessoa: '.format(c)))
    if ano - nascimento < 18:
        menores += 1
    else:
        maiores += 1
print('Total de maiores de idade: {}'.format(maiores))
print('Total de menores de idade: {}'.format(menores))


from plone.server import utils
from plone.server.testing import FakeRequest
from plone.server.transactions import get_current_request

import gc
import resource

def test_module_resolve_path():
    assert utils.resolve_module_path('plone.server') == 'plone.server'
    assert utils.resolve_module_path('plone.server.tests') == 'plone.server.tests'
    assert utils.resolve_module_path('..test_queue') == 'plone.server.tests.test_queue'
    assert utils.resolve_module_path('....api') == 'plone.server.api'

class TestGetCurrentRequest:
    def test_gcr_memory(self):
        self.request = FakeRequest()

        count = 0
        current = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024.0 / 1024.0
        while True:
            count += 1
            get_current_request()

            if count % 1000000 == 0:
                break

            if count % 100000 == 0:
                gc.collect()
                new = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1024.0 / 1024.0
                if new - current > 10:  # memory leak, this shouldn't happen
                    assert new == current


import pandas as pd
import argparse
from processor.Analyzer import Analyzer
from processor.Reader import Reader
from processor.Cleaner import Cleaner
from processor.ColumnRemover import ColumnRemover
from processor.Writer import Writer
import logging

logging.basicConfig(
    level=logging.DEBUG, format="'%(asctime)s - %(levelname)s - %(message)s"
)

class Main:
    """
    Handles coordinating and running the application.
    It receives command line arguments and
        1. Reads in source data, transforming it into a dataframe
        2. Removes excess columns
        3. Cleans the dataframe
        4. Runs the analysis (queries)
        5. Writes the query results to the output directory
    """

    def __init__(
        self, data_loc, remove_useless_cols, fill_strategy, output_dir, output_fmt
    ):
        self.data_loc = data_loc
        self.remove_useless_cols = remove_useless_cols
        self.fill_strategy = fill_strategy
        self.output_dir = output_dir
        self.output_fmt = output_fmt
        self.writer = Writer(self.output_dir)
        self.groups = ["payment_type", "year", "month"]

    def do_read(self):
        r = Reader(self.data_loc)
        df = r.reader()
        return df

    def do_column_removal(self, df):
        cr = ColumnRemover(df, self.remove_useless_cols)
        df = cr.df
        return df

    def do_clean(self, df):
        c = Cleaner(df, self.fill_strategy)
        c.handle_null_rows()
        df = c.df
        return df

    def initial_processing(self):
        df = self.do_read()
        df = self.do_column_removal(df)
        df = self.do_clean(df)
        return df

    def analyze(self, analyzer, group):
        df = analyzer.group_by(group)
        return df

    def main(self):
        df = self.initial_processing()
        a = Analyzer(df)
        for group in self.groups:
            output_df = self.analyze(a, group)
            self.writer.write(output_df, group, self.output_fmt)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Presents summary statistics")
    parser.add_argument("-data_source", help="path to source data", required=True)
    parser.add_argument("-data_dest", help="path to output data dir", required=True)
    parser.add_argument(
        "-output_format",
        help="Format of output dataframes (csv, parquet)",
        choices=["csv", "parquet"],
        required=True,
    )
    parser.add_argument(
        "-remove_useless_cols",
        help="Remove cost-related columns that have no values",
        action="store_true",
    )
    parser.add_argument(
        "-fill_strategy",
        help="How to handle null values in cost-related columns (remove, mean)",
        choices=["remove", "mean"],
        required=True,
    )

    args = parser.parse_args()
    data_source = args.data_source
    data_dest = args.data_dest
    output_format = args.output_format
    remove_useless_cols = args.remove_useless_cols
    fill_strategy = args.fill_strategy
    logging.info(
        f"Running with -data_source {data_source} -data_dest {data_dest} -output_format {output_format} -remove_useless_cols {remove_useless_cols} -fill_strategy {fill_strategy}"
    )

    m = Main(data_source, remove_useless_cols, fill_strategy, data_dest, output_format)
    m.main()


# import required modules
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from youtube_transcript_api import YouTubeTranscriptApi

import os
import pickle
import pandas as pd
import sys

SCOPES = ["https://www.googleapis.com/auth/youtube.force-ssl"]

# Function to authorize API access using OAuth2
def youtube_authenticate():
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
    api_service_name = "youtube"
    api_version = "v3"
    client_secrets_file = "credentials.json" #change with credentials.json
    creds = None
    # the file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first time
    if os.path.exists("token.pickle"):
        with open("token.pickle", "rb") as token:
            creds = pickle.load(token)
    # if there are no (valid) credentials availablle, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(client_secrets_file, SCOPES)
            creds = flow.run_local_server(port=0)
        # save the credentials for the next run
        with open("token.pickle", "wb") as token:
            pickle.dump(creds, token)

    return build(api_service_name, api_version, credentials=creds)

# Function to search for videos based on a keyword
def search_videos(service, threshold_api_units, **kwargs):
    all_results = []
    next_page_token = ''

    total_api_units_used = 0
    print("Total units used: %d" % total_api_units_used)

    while total_api_units_used < threshold_api_units and next_page_token is not None:
        # Calculate the number of API units needed for the upcoming request (e.g., 100 units for search)
        api_units_needed = 100

        # Check if making the next request would exceed the threshold
        if total_api_units_used + api_units_needed <= threshold_api_units:

            search_results = service.search().list(**kwargs).execute()
            all_results.extend(search_results.get('items', []))

            total_api_units_used += api_units_needed
            print("Total units used: %d" % total_api_units_used)

            if total_api_units_used + api_units_needed <= threshold_api_units:
            # Check for more pages of results
                next_page_token = search_results.get('nextPageToken')
                total_api_units_used += api_units_needed
                print("Total units used: %d" % total_api_units_used)
                if not next_page_token:
                    break
                kwargs['pageToken'] = next_page_token
            else:
                print("Reached API unit threshold. Stopping requests.")
                break
        else:
            print("Reached API unit threshold. Stopping requests.")
            break

    return all_results

# Function to retrieve video details
def get_video_details(service, video_id):
    video_details = service.videos().list(part='snippet,statistics', id=video_id).execute()
    return video_details.get('items', [])[0] if video_details.get('items', []) else None

if __name__ == '__main__':

    KEYWORD = "vegan"
    START_DATE = "2022-12-01T00:00:00Z"
    END_DATE = "2023-03-01T00:00:00Z"

    youtube = youtube_authenticate()

    # Step 1: Search for videos based on the keyword
    search_results = search_videos(youtube, threshold_api_units = 8000, q=KEYWORD, publishedAfter=START_DATE, publishedBefore=END_DATE, relevanceLanguage="en", type="video", part='id', maxResults=50, order="date")

    video_data = []

    for video in search_results:
        video_id = video['id']['videoId']

        # Step 2: Retrieve video details
        video_details = get_video_details(youtube, video_id)

        if video_details:
            video_title = video_details['snippet']['title']
            video_description = video_details['snippet']['description']
            video_timestamp = video_details['snippet']['publishedAt']
            video_likes = video_details['statistics']['likeCount']

            video_data.append({
                'Video ID': video_id,
                'Video Title': video_title,
                'Video Timestamp': video_timestamp,
                'Video Description': video_description,
                'Video Likes': video_likes
            })

    # Create a DataFrame-like structure using pandas
    df = pd.DataFrame(video_data)

    print(df.head())
    print(df["Video Timestamp"].min())
    print(df.shape)

    # get transcripts if automatic caption is available
    video_ids = list(df["Video ID"].values)

    transcript_list, unretrievable_videos = YouTubeTranscriptApi.get_transcripts(video_ids, continue_after_error=True)

    list_transcripts = []

    for video_id in video_ids:

        if video_id in transcript_list.keys():

            srt = transcript_list.get(video_id)

            text_list = []
            for i in srt:
                text_list.append(i['text'])

            text = '.'.join(text_list)
            list_transcripts.append(text)

        else:
            list_transcripts.append(None)

    df["Video Transcript"] = list_transcripts

    retrieved_videos = df

    with open("./data/retrieved_video_2022_key_"+str(KEYWORD)+".pickle", "wb") as token:
        pickle.dump(retrieved_videos, token)


from http import HTTPStatus
from typing import Optional
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, Query

from models.filmwork import FilmworkBase
from models.genre import GenreBase, GenreDetail
from services.filmwork import FilmworkService, get_film_service
from services.genre import GenreService, get_genre_service

router = APIRouter()

@router.get(
    "",
    response_model=list[GenreBase],
    summary="Genres list.",
    description="Genres list with pagination.",
    response_description="Name and id.",
    tags=["genre", "objects list"],
)
async def genre_list(
    page: Optional[int] = Query(default=1, alias="page[number]"),
    size: Optional[int] = Query(default=50, alias="page[size]"),
    genre_service: GenreService = Depends(get_genre_service),
) -> list[GenreBase]:
    return await genre_service.get_genres_list(page=page, size=size)

@router.get(
    "/{uuid}/",
    response_model=GenreDetail,
    summary="Get genre by ID.",
    description="Get genre by ID.",
    response_description="Name and id.",
    tags=["genre", "get by id"],
)
async def genre_info(
    uuid: UUID,
    genre_service: GenreService = Depends(get_genre_service),
) -> GenreDetail:
    genre_detail = await genre_service.get_genre(uuid=uuid)
    if not genre_detail:
        raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Genre not found")
    return genre_detail

@router.get(
    "/{name}/film",
    response_model=list[FilmworkBase],
    summary="Get list of movies by genre name.",
    description="Get list of movies by genre name.",
    response_description="Movies name, rating and id.",
    tags=["genre", "film", "objects list"],
)
async def genre_popular_films(
    name: str,
    page: Optional[int] = Query(default=1, alias="page[number]"),
    size: Optional[int] = Query(default=50, alias="page[size]"),
    film_service: FilmworkService = Depends(get_film_service),
) -> list[FilmworkBase]:
    return await film_service.get_filmworks_list(page=page, size=size, filter_genre=name)


import sqlite3
DataPath="FoodDataBase.db"
SchemaPath="Schema.py"
Folder="DataB\\"
class Refrence:
	def __init__(self,CTFK,FT,FTPK):
		self.TableForeignKey=CTFK
		self.ForeignTable=FT
		self.ForeignTablePrimaryKey=FTPK
	def __str__(self):
		return '''FOREIGN KEY ({0}) REFERENCES {1}({2}) ON UPDATE CASCADE ON DELETE CASCADE'''.format(self.TableForeignKey,self.ForeignTable,self.ForeignTablePrimaryKey)
	__repr__ = __str__

class Table:

	def __init__(self,tablename):
		self.TableName=tablename
		self.col={}
		self.ref=[]

	def AddCol(self, ColAsStr):
		c = str.split(ColAsStr," ")
		#print (c)
		if len(c)>=2:
			return self.AddColByParts(c[0],c[1])
		else:
			return None
	def AddColByParts(self,ColName, ColType):
		if self != None:
			self.col[ColName]=ColType
		return self
	def AddReff(self,TableForeignKey,ForeignTable):
		if self != None:
			self.ref.append(Refrence(TableForeignKey,ForeignTable,"ID"))
			#print(self)
			self.AddColByParts(TableForeignKey,"integer")
		return self
	def __str__(self):
		if self != None:
			c= []
			for clm in self.col.keys():
				c.append(clm +" "+self.col[clm])
			s= '''CREATE TABLE IF NOT EXISTS {0} (ID integer PRIMARY KEY AUTOINCREMENT, {1}'''.format(self.TableName,", ".join(c))
		#	print (c)
			for x in self.ref:
				s+=", "+str(x)
			s+=");"
			return s
		else:
			return "error"
	__repr__ = __str__

def Check():
	global DataPath
	global SchemaPath
	global Folder
	print (DataPath+" "+Folder+SchemaPath)
	conn = sqlite3.connect(DataPath)
	c= conn.cursor()
	Company = Table("Company")
	Company.AddCol("CompanyName text")
	c.execute(str(Company))
	Tutor = Table("Tutor")
	Tutor.AddCol("TutorGroup integer").AddCol("TutorTeacher text").AddReff("Company",Company.TableName)
	c.execute(str(Tutor))
	Customer= Table("Customer")
	Customer.AddCol("CustomerName text").AddReff("Tutor",Tutor.TableName)
	c.execute(str(Customer))
	Transac = Table("Transac")
	Transac.AddCol("Time timestamp").AddReff("Customer",Customer.TableName)
	c.execute(str(Transac))
	FoodSupplyer= Table("FoodSupplyer")
	FoodSupplyer.AddCol("SupplyerName Text").AddCol("Address text").AddCol("Email text").AddCol("Tell text")
	c.execute(str(FoodSupplyer))
	FoodIngredent = Table("FoodIngredent")
	FoodIngredent.AddCol("Ingredent Name").AddCol("PricePerUnit integer").AddReff("Supplyer",FoodSupplyer.TableName)
	c.execute(str(FoodIngredent))
	FoodOrder = Table("FoodOrder")
	FoodOrder.AddReff("Transac",Transac.TableName)
	FoodOrder.AddReff("FoodIngredent",FoodIngredent.TableName)
	c.execute(str(FoodOrder))
	c.close()
	conn.commit()
	f = open(Folder+SchemaPath,"wb")
	s="#{0}\r\n#{1}\r\n#{2}\r\n#{3}\r\n#{4}\r\n#{5}\r\n#{6}\r\n".format(str(Company),str(Tutor),str(Customer),str(Transac),str(FoodSupplyer),str(FoodIngredent),str(FoodOrder))
	s+=LoadImports()
	s+=CreatePyClass(Company)
	s+=CreatePyClass(Tutor)
	s+=CreatePyClass(Customer)
	s+=CreatePyClass(Transac)
	s+=CreatePyClass(FoodSupplyer)
	s+=CreatePyClass(FoodIngredent)
	s+=CreatePyClass(FoodOrder)
	f.write(bytes(s, 'UTF-8'))
	f.close()
	print ("checked")
def LoadImports():
	global DataPath
	global SchemaPath
	global Folder
	return '''import sqlite3\r\nimport itertools\r\nimport functools\r\nDataPath="{0}"\r\n'''.format(DataPath)
def addTestData():
	global DataPath
	conn = sqlite3.connect(DataPath)
	c= conn.cursor()
	for x in range(20):
		print("3")
		c.execute('''INSERT INTO Company(CompanyName) VALUES (?);''',("test"+str(x),))
		print("4")
		c.execute('''INSERT INTO Tutor(Company,TutorGroup,TutorTeacher) VALUES (?,?,?);''',(int(x/2),x,"dave"+str(x)))
	c.close()
	conn.commit()
def getTestTableDB():
	global DataPath
	conn = sqlite3.connect(DataPath)
	c= conn.cursor()
	c.execute('''SELECT CompanyName,TutorGroup,TutorTeacher FROM Company INNER JOIN Tutor on Tutor.Company= Company.ID WHERE Company.ID==1;''')
	vals = c.fetchall()
	c.close()
	return vals

def CreatePyClass(_Table):
	rs='''class {0}:\r\n\tdef __init__(self,ID):\r\n\t\t"""{1}"""\r\n\t\tself.ID=ID\r\n{2}'''
	doc=_Table.TableName+ " Table Contains columns: "
	Atributes="\t@classmethod\r\n\tdef GetAllKeys(cls):\r\n\t\tglobal DataPath\r\n\t\tconn = sqlite3.connect(DataPath)\r\n\t\tc= conn.cursor()\r\n\t\tc.execute('''SELECT ID FROM {0}''')\r\n\t\tVal= c.fetchall()\r\n\t\tc.close()\r\n\t\tif len(Val)>0:\r\n\t\t\treturn list(functools.reduce(itertools.chain,Val))\r\n\t\telse:\r\n\t\t\treturn []\r\n".format(_Table.TableName)
	no_of_col=len(_Table.col.keys())
	Atributes+='''\t@classmethod\r\n\tdef CreateNode(cls):\r\n\t\tglobal DataPath\r\n\t\tconn = sqlite3.connect(DataPath)\r\n\t\tc= conn.cursor()\r\n\t\tc.execute("INSERT INTO {0}({1}) VALUES ({2})",({3},))\r\n\t\tNewID=c.lastrowid\r\n\t\tc.close()\r\n\t\tconn.commit()\r\n\t\treturn cls(NewID)\r\n\tdef Remove(self):\r\n\t\tglobal DataPath\r\n\t\tconn = sqlite3.connect(DataPath)\r\n\t\tc= conn.cursor()\r\n\t\tc.execute("DELETE FROM {0} WHERE ID=?;",(self.ID,))\r\n\t\tc.close()\r\n\t\tconn.commit()\r\n\t\tself.ID=None\r\n'''.format(_Table.TableName,",".join(_Table.col.keys()),"?"+",?"*(no_of_col-1),"None"+",None"*(no_of_col-1))
	strcast='''\tdef TableJson(self):\r\n\t\tr={"ID":self.ID}\r\n'''
	expectedkeys='''\t@classmethod\r\n\tdef expectedkeys(cls):\r\n\t\tr=["ID"]\r\n'''
	for x in _Table.col.keys():
		doc+=x+" of type "+_Table.col[x]+" || "
		Atributes+="\t@property\r\n\tdef {0}(self):\r\n\t\tglobal DataPath\r\n\t\tconn = sqlite3.connect(DataPath)\r\n\t\tc= conn.cursor()\r\n\t\tc.execute('''SELECT {0} FROM {1} WHERE ID=?''',(self.ID,))\r\n\t\tVal= c.fetchone()\r\n\t\tc.close()\r\n\t\tif Val!=None:\r\n\t\t\treturn Val[0]\r\n\t\treturn None\r\n\t@{0}.setter\r\n\tdef {0}(self,value):\r\n\t\tglobal DataPath\r\n\t\tconn = sqlite3.connect(DataPath)\r\n\t\tc= conn.cursor()\r\n\t\tc.execute('''UPDATE {1} SET {0}=? WHERE ID=?''',(value,self.ID))\r\n\t\tc.close()\r\n\t\tconn.commit()\r\n".format(x,_Table.TableName)
		strcast+='''\t\tr["{0}"]=self.{0}\r\n'''.format(x)
		expectedkeys+='''\t\tr.append("{0}")\r\n'''.format(x)
	strcast+='''\t\treturn r\r\n'''
	expectedkeys+='''\t\treturn r\r\n'''
	Atributes+=strcast
	Atributes+=expectedkeys
	Atributes+='''\tdef __str__(self):\r\n\t\treturn str(self.TableJson())\r\n'''
	doc+="Foreign Keys: "
	for x in _Table.ref:
		doc+=_Table.TableName+"."+x.TableForeignKey+" refrences "+x.ForeignTable+"."+x.ForeignTablePrimaryKey
	return rs.format(_Table.TableName,doc,Atributes)
#Check()

#addTestData()

#print(getTestTableDB())


"""remove_pro_show_invoices_on_pro_portal
"""
from alembic import op

# revision identifiers, used by Alembic.
revision = "01e4e1b7f714"
down_revision = "0511102bcb21"
branch_labels = None
depends_on = None

def upgrade() -> None:
    op.execute("DELETE FROM feature WHERE name = 'SHOW_INVOICES_ON_PRO_PORTAL'")

def downgrade() -> None:
    op.execute(
        """
        INSERT INTO feature (name, description, "isActive")
        VALUES ('SHOW_INVOICES_ON_PRO_PORTAL', 'Activer l''affichage des remboursements sur le portail pro', True)
        """
    )


import pytest
import pytz
import copy
import time
from datetime import date, timedelta, datetime as Datetime

import maya
from maya.core import _seconds_or_timedelta  # import private function

def test_rfc2822():
    r = maya.parse('February 21, 1994').rfc2822()
    d = maya.MayaDT.from_rfc2822(r)
    assert r == 'Mon, 21 Feb 1994 00:00:00 GMT'
    assert r == d.rfc2822()

def test_iso8601():
    r = maya.parse('February 21, 1994').iso8601()
    d = maya.MayaDT.from_iso8601(r)
    assert r == '1994-02-21T00:00:00Z'
    assert r == d.iso8601()

def test_parse_iso8601():
    string = '20161001T1430.4+05:30'
    expected = '2016-10-01T09:00:00.400000Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

    string = '2016T14'
    expected = '2016-01-01T14:00:00Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

    string = '2016-10T14'
    expected = '2016-10-01T14:00:00Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

    string = '2012W05'
    expected = '2012-01-30T00:00:00Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

    string = '2012W055'
    expected = '2012-02-03T00:00:00Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

    string = '2012007'
    expected = '2012-01-07T00:00:00Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

    string = '2016-W07T09'
    expected = '2016-02-15T09:00:00Z'
    d = maya.MayaDT.from_iso8601(string)

    assert expected == d.iso8601()

def test_struct():
    ts = time.gmtime()
    m = maya.MayaDT.from_struct(ts)
    dt = Datetime.fromtimestamp(time.mktime(ts), pytz.UTC)
    assert m._epoch != None
    assert m.datetime() == dt

    ts = time.localtime()
    m = maya.MayaDT.from_struct(ts)
    dt = Datetime.fromtimestamp(time.mktime(ts), pytz.UTC)
    assert m._epoch != None
    assert m.datetime() == dt

def test_human_when():
    r1 = maya.when('yesterday')
    r2 = maya.when('today')

    assert (r2.day - r1.day) in (1, -30, -29, -28, -27)

def test_machine_parse():
    r1 = maya.parse('August 14, 2015')
    assert r1.day == 14

    r2 = maya.parse('August 15, 2015')
    assert r2.day == 15

def test_dt_tz_translation():
    d1 = maya.now().datetime()
    d2 = maya.now().datetime(to_timezone='EST')
    assert (d1.hour - d2.hour) % 24 == 5

def test_dt_tz_naive():
    d1 = maya.now().datetime(naive=True)
    assert d1.tzinfo is None

    d2 = maya.now().datetime(to_timezone='EST', naive=True)
    assert d2.tzinfo is None
    assert (d1.hour - d2.hour) % 24 == 5

def test_random_date():

    # Test properties for maya.when()
    d1 = maya.when('11-17-11 08:09:10')
    assert d1.year == 2011
    assert d1.month == 11
    assert d1.day == 17
    assert d1.week == 46
    assert d1.weekday == 4
    assert d1.hour == 8
    assert d1.minute == 9
    assert d1.second == 10
    assert d1.microsecond == 0

    # Test properties for maya.parse()
    d2 = maya.parse('February 29, 1992 13:12:34')
    assert d2.year == 1992
    assert d2.month == 2
    assert d2.day == 29
    assert d2.week == 9
    assert d2.weekday == 6
    assert d2.hour == 13
    assert d2.minute == 12
    assert d2.second == 34
    assert d2.microsecond == 0

def test_print_date(capsys):
    d = maya.when('11-17-11')

    print(d)
    out, err = capsys.readouterr()

    assert out == 'Thu, 17 Nov 2011 00:00:00 GMT\n'
    assert repr(d) == '<MayaDT epoch=1321488000.0>'

def test_invalid_date():
    with pytest.raises(ValueError):
        maya.when('another day')

def test_slang_date():
    d = maya.when('tomorrow')
    assert d.slang_date() == 'tomorrow'

def test_slang_time():
    d = maya.when('one hour ago')
    assert d.slang_time() == 'an hour ago'

def test_parse():
    d = maya.parse('February 21, 1994')
    assert format(d) == '1994-02-21 00:00:00+00:00'

    d = maya.parse('01/05/2016')
    assert format(d) == '2016-01-05 00:00:00+00:00'

    d = maya.parse('01/05/2016', day_first=True)
    assert format(d) == '2016-05-01 00:00:00+00:00'

    d = maya.parse('2016/05/01', year_first=True, day_first=False)
    assert format(d) == '2016-05-01 00:00:00+00:00'

    d = maya.parse('2016/01/05', year_first=True, day_first=True)
    assert format(d) == '2016-05-01 00:00:00+00:00'

    d = maya.parse('01/05/2016', timezone='UTC')
    assert format(d) == '2016-01-05 00:00:00+00:00'

    d = maya.parse('01/05/2016', timezone='US/Central')
    assert format(d) == '2016-01-05 06:00:00+00:00'

def test_when_past():
    next_month = str(maya.now().add(months=1).month)
    this_year = maya.now().year
    last_year = this_year - 1

    future_date = maya.when(next_month)
    past_date = maya.when(next_month, prefer_past=True)

    assert future_date.year == this_year
    if next_month == '1':
        assert past_date.year == this_year
    else:
        assert past_date.year == last_year

def test_datetime_to_timezone():
    dt = maya.when('2016-01-01').datetime(to_timezone='US/Eastern')
    assert dt.tzinfo.zone == 'US/Eastern'

def test_rfc3339():
    mdt =  maya.when('2016-01-01')
    out = mdt.rfc3339()
    mdt2 = maya.MayaDT.from_rfc3339(out)
    assert mdt.epoch == mdt2.epoch

def test_comparison_operations():
    now = maya.now()
    now_copy = copy.deepcopy(now)
    tomorrow = maya.when('tomorrow')

    assert (now == now_copy) is True
    assert (now == tomorrow) is False

    assert (now != now_copy) is False
    assert (now != tomorrow) is True

    assert (now < now_copy) is False
    assert (now < tomorrow) is True

    assert (now <= now_copy) is True
    assert (now <= tomorrow) is True

    assert (now > now_copy) is False
    assert (now > tomorrow) is False

    assert (now >= now_copy) is True
    assert (now >= tomorrow) is False

    # Check Exceptions
    with pytest.raises(TypeError):
        now == 1
    with pytest.raises(TypeError):
        now != 1
    with pytest.raises(TypeError):
        now < 1
    with pytest.raises(TypeError):
        now <= 1
    with pytest.raises(TypeError):
        now > 1
    with pytest.raises(TypeError):
        now >= 1

def test_seconds_or_timedelta():
    # test for value in seconds
    assert _seconds_or_timedelta(1234) == timedelta(0, 1234)
    # test for value as `datetime.timedelta`
    assert _seconds_or_timedelta(timedelta(0, 1234)) == timedelta(0, 1234)
    # test for invalid value
    with pytest.raises(TypeError):
        _seconds_or_timedelta('invalid interval')

def test_intervals():
    now = maya.now()
    tomorrow = now.add(days=1)

    assert len(list(maya.intervals(now, tomorrow, 60*60))) == 24

def test_dunder_add():
    now = maya.now()
    assert now + 1 == now.add(seconds=1)
    assert now + timedelta(seconds=1) == now.add(seconds=1)

def test_dunder_radd():
    now = maya.now()
    assert now.add(seconds=1) == now + 1
    assert now.add(seconds=1) == now + timedelta(seconds=1)

def test_dunder_sub():
    now = maya.now()
    assert now - 1 == now.subtract(seconds=1)
    assert now - timedelta(seconds=1) == now.subtract(seconds=1)

def test_core_local_timezone(monkeypatch):
    @property
    def mock_local_tz(self):
        class StaticTzInfo(object):
            zone = 'local'
            def __repr__(self):
                return "<StaticTzInfo 'local'>"
        return StaticTzInfo()
    monkeypatch.setattr(maya.MayaDT, '_local_tz', mock_local_tz)
    mdt = maya.MayaDT(0)
    assert mdt.local_timezone == 'UTC'


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from app.models import Publisher, Author, Book

from django.contrib import admin

# Register your models here.
class PublisherAdmin(admin.ModelAdmin):
    list_display = ('name', 'address', 'city', 'state_province', 'country', 'website')
    list_filter = ('city', 'state_province', 'country')

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('salutation', 'first_name', 'last_name', 'email')
    list_filter = ('salutation',)

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    ordering = ('-publication_date',)
    search_fields = ('title',)

admin.site.register(Publisher, PublisherAdmin)
admin.site.register(Author, AuthorAdmin)
admin.site.register(Book, BookAdmin)