from numba import jit
from jit_talib import jit_ma
import numpy as np
from datetime import datetime

@jit(nopython=True)
def jit_ttm_strategy(tick, chart, position, global_data):
    now_pos = global_data['chart_pos']
    open_volume = 0.05
    open_array, high_array, low_array, close_array = chart[1][:
                                                              ], chart[2][:], chart[3][:], chart[4][:]
    ret_signal = np.zeros((4))
    #signal = None
    hp = -9999
    pos = position
    if tick[0] < 1e-5:
        return ret_signal
    if pos['status'] > 0:  # holding
        direction = pos['direction']
        op = pos['avg_price']
        index = now_pos
        hp = direction * (close_array[index] - op)
        [para1, para2, para3, para4, para5, atr_stop_gain] = [0.2, 0.55, 0.33, 90, 90, 3]
        para30 = 30
        if 0:
            print(datetime.now().strftime('%H:%M:%S'), ' hp / op %.5f' % (hp / op), 'open_price:', op, 'last:',
                  close_array[index])
        if now_pos < 1440 + para30:
            return ret_signal
        open_distance = int((tick[0] - pos['entry_time']) / 60)
        peak_price = np.max(high_array[now_pos - open_distance: now_pos + 1]) if direction > 0 else np.min(
           high_array[now_pos - open_distance: now_pos + 1])

        last_30_index = int(now_pos / para30) * para30
        min_30_high = np.max(high_array[last_30_index - para30:last_30_index])
        min_30_low = np.min(low_array[last_30_index - para30:last_30_index])
        min_30_close = close_array[last_30_index - 1]
        Ssetup = min_30_high + para1 * (min_30_close - min_30_low)
        Bsetup = min_30_low - para1 * (min_30_high - min_30_close)
        Senter = (1 + para3) / 2 * (min_30_high +
                                    min_30_low) - para3 * min_30_low
        Benter = (1 + para3) / 2 * (min_30_high +
                                    min_30_low) - para3 * min_30_high
        Sbreak = Bsetup - para2 * (Ssetup - Bsetup)
        Bbreak = Ssetup + para2 * (Ssetup - Bsetup)

        #long stop gain
        if direction > 0 and close_array[now_pos] > op + direction * chart[9][now_pos-1] * atr_stop_gain:# and hp/op > 0.01:
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
                                                                             1, (-1) * direction, pos['volume'], \
                                                                         close_array[now_pos]
            return ret_signal

        if direction < 0 and close_array[now_pos] < op + direction * chart[9][now_pos-1] * atr_stop_gain:# and hp/op > 0.01:
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
                                                                             1, (-1) * direction, pos['volume'], \
                                                                         close_array[now_pos]
            return ret_signal

        # if direction > 0 and close_array[now_pos] < peak_price - chart[9][now_pos - 1] * atr_stop_gain:
        #     ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
        #                                                                          1, (-1) * direction, pos['volume'], \
        #                                                                      close_array[now_pos]
        #     return ret_signal
        #
        # if direction < 0 and close_array[now_pos] > peak_price + chart[9][now_pos - 1] * atr_stop_gain:
        #     ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
        #                                                                          1, (-1) * direction, pos['volume'], \
        #                                                                      close_array[now_pos]
        #     return ret_signal

        if direction < 0 and close_array[now_pos] > np.max(high_array[now_pos-60:now_pos]):# and hp/op < -0.005:
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
                                                                             1, (-1) * direction, pos['volume'], \
                                                                         close_array[now_pos]
            return ret_signal

        if direction > 0 and close_array[now_pos] < np.min(low_array[now_pos-60:now_pos]):# and hp/op < -0.005:
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
                                                                             1, (-1) * direction, pos['volume'], \
                                                                         close_array[now_pos]
            return ret_signal

        # if  hp / op < -0.01:
        #     ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
        #         1, (-1) * direction, pos['volume'], close_array[now_pos]
        #     return ret_signal
        #
        if (tick[0] - pos['entry_time'] >= 60 * 60):
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = - \
                1, (-1) * direction, pos['volume'], close_array[now_pos]
            return ret_signal

    else:
        if now_pos < 1440 + 100:
            return ret_signal
        k_center = chart[10][:]
        k_low_now = k_center[now_pos] - 1.5 * chart[9][now_pos - 1]
        k_high_now = k_center[now_pos] + 1.5 * chart[9][now_pos - 1]
        k_low_last = k_center[now_pos - 1] - 1.5 * chart[9][now_pos - 2]
        k_high_last = k_center[now_pos - 1] + 1.5 * chart[9][now_pos - 2]
        b_center = k_center
        b_std_now = np.std(close_array[now_pos - 19:now_pos+1])
        b_std_last = np.std(close_array[now_pos - 20:now_pos])
        b_high_now = b_center[now_pos] + 2 * b_std_now
        b_low_now = b_center[now_pos] - 2 * b_std_now
        b_high_last = b_center[now_pos - 1] + 2 * b_std_last
        b_low_last = b_center[now_pos - 1] - 2 * b_std_last
        if b_high_now > k_high_now and b_high_last < k_high_last and close_array[now_pos] > close_array[now_pos - 5]:
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = 1, 1, open_volume, \
                                                                         tick[1]
        if b_low_now < k_low_now and b_low_last > k_low_last and close_array[now_pos] < close_array[now_pos - 5]:
            ret_signal[0], ret_signal[1], ret_signal[2], ret_signal[3] = 1, -1, open_volume, \
                                                                         tick[1]

    return ret_signal


from . import views
from django.urls import path

"""
    Url paths extended from from django.urls
    BUG: enabling app_name causes a django.urls.exceptions.NoReverseMatch error 500.
"""
app_name = 'blog'
urlpatterns = [
    path('blog/', views.PostList.as_view(), name='blog'),
    path("blog/<slug:slug>/", views.post_detail, name="post_detail")
]


import fnmatch
import os
import argparse
import uuid

# PARAMETERS
parser = argparse.ArgumentParser(description='Rearrange a Unity\'s project folder guids.')
parser.add_argument('-i, --input',  metavar='FOLDER', type=str, nargs=1, required=True, dest='input_folder',
    help='input folder')
args = parser.parse_args()
input_folder = None if args.input_folder is None else args.input_folder[0]
if not os.path.isdir(input_folder):
    print('ERROR: Path not found.')
    quit(1)

# SCAN FILES

register_list = []
print('')
metas = dict()
mats = []
prefabs = []
controllers = []
scenes = []
anims = []
spriteAtlases = []
scriptableObjects = []

for root, folders, files in os.walk(input_folder):
    for fname in files:
        if fnmatch.fnmatch(fname, '*.meta'):
            metaname = root + os.sep + fname
            file = open(metaname, 'r')
            for line in file:
                elements = line.split(': ')
                if elements[0] == 'guid':
                    id = elements[1].replace('\n', '')
                    metas.update({id: [metaname, uuid.uuid4().hex]})
            file.close()
        if fnmatch.fnmatch(fname, '*.mat'):
            mats += [root + os.sep + fname]
        if fnmatch.fnmatch(fname, '*.prefab'):
            prefabs += [root + os.sep + fname]
        if fnmatch.fnmatch(fname, '*.controller'):
            controllers += [root + os.sep + fname]
        if fnmatch.fnmatch(fname, '*.unity'):
            scenes += [root + os.sep + fname]
        if fnmatch.fnmatch(fname, '*.anim'):
            anims += [root + os.sep + fname]
        if fnmatch.fnmatch(fname, '*.spriteatlas'):
            spriteAtlases += [root + os.sep + fname]
        if fnmatch.fnmatch(fname, '*.asset'):
            scriptableObjects += [root + os.sep + fname]

# CHANGE METAS

for k, v in metas.items():
    file = open(v[0], 'r')
    met = file.readlines()
    for i, l in enumerate(met):
        if 'guid:' in l:
            met[i] = l.replace(k, v[1])

    file.close()
    file = open(v[0], 'w')
    file.writelines(met)
    file.close()

#CHANGE EVERYTHING [Prefab,Texture,Sound,Material,Animation:Controller+File+Keyframes,Scene,SpriteAtlas,ScriptableObject]

for pname in prefabs + mats + controllers + scenes + anims + spriteAtlases + scriptableObjects:
    file = open(pname, 'r')
    changed = False
    segregate = file.readlines()
    for i, l in enumerate(segregate):
        if 'guid:' in l:
            key = None
            for k in metas.keys():
                if k in l:
                    key = k
                    changed = True
            if key is not None:
                segregate[i] = l.replace(key, metas[key][1])
                print(segregate[i], end='')
                print(key, '->', metas[key][1])
            else:
                print(segregate[i])
    file.close()
    if changed:
        file = open(pname, 'w')
        file.writelines(segregate)
        file.close()


from django.views.decorators.csrf import ensure_csrf_cookie
import time
from urllib import request
from django.http import JsonResponse
from django.shortcuts import render
from django.views.generic import ListView, CreateView, TemplateView, View
from django.utils.translation import gettext_lazy  as _
from .models import *
from TolgobolVillage.utils import *
import json
from .utils import TmpFileStorage
from datetime import datetime
from django.utils import timezone
from Forum.models import *
import logging
from django.urls.base import reverse_lazy
from .logger import *
import pandas as pd
from django.views.static import serve

class HomePage( DataMixin, TemplateView ):
    #form = ProductForm
    template_name = 'MainService/index.html'
    #model = Product
    title = _("Поселок Толгоболь")

    @logger
    def get_context_data( self, *, object_list=None, **kwargs ):

        c_super = super().get_context_data(**kwargs)
        c_def = self.get_user_context()
        c_def[ 'title' ] = self.title
        c_def[ 'news' ] = self.get_news_context()
        c_def.update( c_super )
        return c_def

    def get_news_context( self ):
        result = []
        news = Section.objects.filter(is_news=True)
        if news.count():
            for i in news[0].post_set.filter(is_delet=False):
                item = {}
                item['title'] = i.title
                item['preview_text'] = i.text
                item['date'] = i.date
                item['id'] = i.id
                item['url'] = reverse_lazy( 'post', kwargs={'section_id':str(news[0].id), 'post_id':str(i.id) }  )
                result.append( item )
        return result

class ImportantPage( DataMixin, TemplateView ):
    #form = ProductForm
    template_name = 'MainService/important.html'
    model = AnyContact
    title = _("Поселок Толгоболь / Важное / Контакты")

    @logger
    def get_context_data( self, *, object_list=None, **kwargs ):
        c_super = super().get_context_data(**kwargs)
        c_def = self.get_user_context()
        c_def['chifs'] = self.get_contact( is_chief=True )
        c_def['anys'] = self.get_contact( is_chief=False )
        c_def[ 'title' ] = self.title
        c_def[ 'votings' ] = self.get_votings_context()
        c_def.update( c_super )
        return c_def

    def get_contact( self, is_chief ):
        contacts = AnyContact.objects.filter( is_chief=is_chief )
        res = []
        for i in contacts:
            item = {}
            item['title'] = i.title
            if i.comment != '':
                item['comment'] = i.comment
            items = []
            for it in i.contactfield_set.all():
                items.append( {'key':it.key, 'value': it.value} )
            item['items'] = items
            res.append( item )
        return res
    def get_votings_context( self ):
        result = []
        votings = Voting.objects.all()
        for voting in votings:
            item = {}
            if voting.is_non_auth:
                if self.request.user.is_authenticated:
                    if voting.votingitemusernonauth_set.all().filter(csrf=str(self.request.user.id)).count():
                        item['is_disabled'] = 'disabled'
                else:
                    csrf = self.request.COOKIES.get( 'csrftoken', None )
                    if voting.votingitemusernonauth_set.all().filter(csrf=csrf).count():
                        item['is_disabled'] = 'disabled'
                if voting.is_finish:
                    item['is_disabled'] = 'disabled'
                if voting.finish_data is not None:
                    if voting.finish_data < timezone.now().date():
                        item['is_disabled'] = 'disabled'
                item['id'] = voting.id
                item['is_non_auth'] = voting.is_non_auth
                item['title'] = voting.title
                item['comment'] = voting.comment
                item['finish_data'] = voting.finish_data if voting.finish_data else 'Без срока'
                total_count = voting.votingitemusernonauth_set.count()
                persent = total_count / 100
                item['voting_items'] = [ dict( [( 'name', i.name ),
                                                ( 'id', i.id ),
                                                ( 'voting_persent', int(i.votingitemusernonauth_set.count() / persent) if persent > 0 else 0 ),
                                                ( 'voting_piople', i.votingitemusernonauth_set.count() ) ]
                                            ) for i in voting.votingitem_set.all() ]
            else:
                if self.request.user.is_authenticated:
                    if voting.votingitemuser_set.all().filter(user_id=self.request.user.id).count():
                        item['is_disabled'] = 'disabled'
                if voting.is_finish:
                    item['is_disabled'] = 'disabled'
                if voting.finish_data is not None:
                    if voting.finish_data < timezone.now().date():
                        item['is_disabled'] = 'disabled'
                item['id'] = voting.id
                item['is_non_auth'] = voting.is_non_auth
                item['title'] = voting.title
                item['comment'] = voting.comment
                item['finish_data'] = voting.finish_data if voting.finish_data else 'Без срока'
                total_count = voting.votingitemuser_set.count()
                persent = total_count / 100
                item['voting_items'] = [ dict( [( 'name', i.name ),
                                                ( 'id', i.id ),
                                                ( 'voting_persent', int(i.votingitemuser_set.count() / persent) if persent > 0 else 0 ),
                                                ( 'voting_piople', i.votingitemuser_set.count() ) ]
                                            ) for i in voting.votingitem_set.all() ]
            item['total_count'] = total_count
            result.append( item )
        return result

class CollectionPage( DataMixin, TemplateView ):
    #form = ProductForm
    template_name = 'MainService/collection.html'
    #model = Product
    title = _("Поселок Толгоболь / Важное / Голосования")

    @logger
    def get_context_data( self, *, object_list=None, **kwargs ):
        c_super = super().get_context_data(**kwargs)
        c_def = self.get_user_context()
        c_def[ 'title' ] = self.title
        c_def[ 'collects' ] = self.get_collect_context()
        c_def[ 'changes' ] = self.get_change_context()
        c_def.update( c_super )
        return c_def

    def get_collect_context( self ):
        result = []
        collects = CollectMoney.objects.all()
        self.request.user.is_authenticated
        for collect in collects:
            item = {}
            item['id'] = collect.id
            item['on_months'] = 1 if collect.on_months else 0
            item['title'] = collect.title
            item['comment'] = collect.comment
            item['finish_data'] = collect.finish_data if collect.finish_data is not None else ''
            if self.request.user.is_authenticated:
                item['total_sum'] = collect.get_total_sum()
                item['need_total_summ'] = collect.need_total_summ if collect.need_total_summ else 'Не ограниченно'
                item['available'] = item['total_sum'] - collect.get_sum_charge()
            else:
                item['total_sum'] = 'Авторизуйтесь'
                item['need_total_summ'] = 'Авторизуйтесь'
                item['available'] = 'Авторизуйтесь'

            item['need_summ_on_user'] = collect.need_summ_on_user
            item['files'] = collect.get_files()

            if collect.on_months:
                if self.request.user.is_authenticated:
                    item['filter_from_strit'] = collect.filter_from_strit()
            result.append( item )
        return result

    def get_change_context( self ):
        result = []
        charges = FinanceCharge.objects.all()
        for charge in charges:
            item = {}
            item['title'] = charge.title
            item['comment'] = charge.comment
            item['data'] = charge.data if charge.data is not None else ''
            if self.request.user.is_authenticated:
                item['sum'] = charge.charge
            else:
                item['sum'] = 'Авторизуйтесь'
            item['collect_money'] = charge.collect.title
            item['files'] = charge.get_files()
            result.append( item )
        return result

class Mainservice( View ):

    mainservice_method_alias = {
        'MainService.Voting': 'voting',
        'MainService.FeedbackAdres': 'feedback_adres',
        'MainService.InsertCollectOnMonths': 'insert_collect_on_months',
        'MainService.GetExcelCollect': 'get_excel_collect',
    }

    def dispatch(self, request, *args, **kwargs):
        service_method = request.headers.get( 'X-Requested-MethodName', None )
        handler_name = self.mainservice_method_alias.get( service_method, None )
        INFO( service_method, request.POST )
        if handler_name:
            handler = getattr(
                self, handler_name, self.http_method_not_allowed
            )
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

    @logger
    def voting( self, reqest, *args, **kwargs ):
        respons = {}
        voting_id = reqest.POST['voting_id']
        voting = Voting.objects.get(id=voting_id)
        if voting.is_non_auth:
            return self.voting_non_auth( reqest, voting )

        voting_item_id = reqest.POST['voting_item_id']
        comment = reqest.POST['comment']
        if reqest.user.is_authenticated:
            user_id = reqest.user.id
            if not voting.votingitemuser_set.all().filter(user_id=user_id).count():
                VotingItemUser.objects.create( user_id=user_id, voting_id=voting_id, votingitem_id=voting_item_id, comment=comment, data=timezone.now() )
                respons['success'] = 'Ваш голос учтен'
            else:
                respons['error'] = 'Вы уже проголосовали'
            return JsonResponse( respons )
        else:
            respons['error'] = 'Авторизуйтесь'
            return JsonResponse( respons )

    def voting_non_auth( self, reqest, voting ):
        respons = {}
        voting_id = reqest.POST['voting_id']
        voting_item_id = reqest.POST['voting_item_id']
        comment = reqest.POST['comment']
        csrf = reqest.COOKIES.get( 'csrftoken', None )
        if not voting.votingitemusernonauth_set.all().filter(csrf=csrf).count():
            if reqest.user.is_authenticated:
                VotingItemUserNonAuth.objects.create( csrf=str( reqest.user.id ), voting_id=voting_id, votingitem_id=voting_item_id, comment=comment, data=timezone.now() )
            else:
                VotingItemUserNonAuth.objects.create( csrf=csrf, voting_id=voting_id, votingitem_id=voting_item_id, comment=comment, data=timezone.now() )
            respons['success'] = 'Ваш голос учтен'
        else:
            respons['error'] = 'Вы уже проголосовали'
        return JsonResponse( respons )

    @logger
    def feedback_adres( self, respons ):
        param = {}
        for i in respons.POST:
            param[i] = respons.POST.get( i )
        FeedbackAdres.objects.create(**param)
        return JsonResponse({})

    @logger
    def insert_collect_on_months( self, respons ):
        collect_id = respons.POST.get( 'collect_id', None)
        adres_id = respons.POST.get( 'adres_id', None)
        insert_list = respons.POST.get( 'insert_list', None)
        log = {'collect_id':collect_id,'adres_id': adres_id, 'insert_list':insert_list  }
        INFO( '[insert_collect_on_months] ', log )
        if insert_list:
            insert_list = json.loads( insert_list )

        if not adres_id:
            return JsonResponse( {'error': 'Не указан адрес, обратитесь к администратору'}, status=500 )
        if not adres_id.isdigit():
            return JsonResponse( {'error': 'адрес не является числом, обратитесь к администратору'}, status=500 )
        else:
            adres_id = int(adres_id)

        if not collect_id:
            return JsonResponse( {'error': 'Не указан collect_id, обратитесь к администратору'}, status=500 )
        if not collect_id.isdigit():
            return JsonResponse( {'error': 'collect_id не является числом, обратитесь к администратору'}, status=500 )
        else:
            collect_id = int(collect_id)
        try:
            adres = Adres.objects.get( id=int(adres_id) )
            for i in insert_list:
                months = i['months']
                summ = i['summ']
                year = i['year']
                if not months.isdigit():
                    return JsonResponse( {'error': 'months не является числом, обратитесь к администратору'}, status=500 )
                if not summ.isdigit():
                    return JsonResponse( {'error': 'summ не является числом, обратитесь к администратору'}, status=500 )
                if not year.isdigit():
                    return JsonResponse( {'error': 'year не является числом, обратитесь к администратору'}, status=500 )
                date_insert = datetime(int(year), int(months), 1)
                el = CollectMoneyMonth.objects.create(collect_id=collect_id, adres=adres, strit=adres.strit, month=date_insert, maney=summ)
                if not el:
                    return JsonResponse( {'error': 'Данные не внесены, обратитесь к администратору'}, status=500 )
        except Exception as e:
            EXCEPT( e )
            return JsonResponse( {'error': ['Не верные параметры, переданы параметры', respons.POST]}, status=500 )
        return JsonResponse({})

    def get_excel_collect( self, reqest ):
        collect_id = reqest.POST.get( 'collect_id', None)
        if not collect_id:
            return JsonResponse( {'error': 'Не указан collect_id'}, status=500 )
        collect = CollectMoney.objects.get( id=int(collect_id) )
        if collect.on_months:
            data = {}
            collect_money = collect.collectmoneymonth_set.all()
            adres_set = collect_money.values('adres')
            adres_set = set( [ i['adres'] for i in adres_set ] )
            moynth_set = collect_money.values('month')
            moynth_set = list( set( [ i['month'] for i in moynth_set ] ) )
            adres_column = {}
            for i in adres_set:
                adr = Adres.objects.get(id=i)
                adres_column[( str(adr) )] = adr
            data['Адрес'] = adres_column.keys()
            moynth_set.sort()
            for month in moynth_set:
                month_column = []
                for ad in adres_column.values():
                    sum = collect_money.filter(month=month, adres_id=ad.id )
                    if sum:
                        month_column.append(sum[0].maney)
                    else:
                        month_column.append(0)
                data[month] = month_column
            df = pd.DataFrame( data )
            file_path = os.path.join( TmpFileStorage.get_tmp_folder(reqest.user.id), f'{collect.title}.xlsx')
            writer = pd.ExcelWriter( file_path )
            df.to_excel(writer)
            writer.save()
            path = TmpFileStorage.save_file( file_path )
            return JsonResponse( {'url': reverse_lazy('media', kwargs={ 'path':path })}, status=200 )

class UploadServise( View ):

    mainservice_method_alias = {
        #'UploadingFiles.Upload': 'upload',
        'UploadingFiles.StartUpload': 'start_upload',
        'UploadingFiles.Upload': 'upload',
        'UploadingFiles.FinishUpload': 'finish_upload',
        'UploadingFiles.CancelUpload': 'cancel_upload',
    }

    def dispatch(self, request, *args, **kwargs):
        service_method = request.headers.get( 'X-Requested-MethodName', None )
        handler_name = self.mainservice_method_alias.get( service_method, None )
        if handler_name:
            handler = getattr(
                self, handler_name, self.http_method_not_allowed
            )
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)

    @logger
    def start_upload( self, request ):
        if not request.user.is_authenticated:
            return JsonResponse({'error':'Авторизуйтесь'}, status=500)
        error = []
        file_name = request.POST.get( 'file_name', None )
        size = request.POST.get( 'size', None )
        if not file_name or not size:
            error.append( 'Не верные параметры запроса' + str(request.POST) )
            error.append( request.POST )
        if error:
            return JsonResponse({'error':'Не верные параметры запроса' + str(request.POST)}, status=500)

        tmp_name = TmpFileStorage().start_upload( file_name, size, request.user )
        if not tmp_name:
            return JsonResponse({'error':'Ошибка при сохранении файла'}, status=500)
        return JsonResponse({'success':tmp_name})

    @logger
    def upload( self, request ):
        strim = request.FILES.get( 'file', None )
        tmp_name= request.POST.get( 'tmp_name', None )
        error = []
        if not strim or not tmp_name:
            error.append( 'Не верные параметры запроса' )
            error.append( request.POST )
            return JsonResponse({'error':error}, status=500)
        try:
            TmpFileStorage().upload( tmp_name, strim.read() )
            return JsonResponse({'success':tmp_name})
        except:
            return JsonResponse({'error':'Ошибка при частичном сохранении файла'}, status=500)

    @logger
    def finish_upload( self, request ):
        tmp_name= request.POST.get( 'tmp_name', None )
        error = []
        if  not tmp_name:
            error.append( 'Не верные параметры запроса' )
            error.append( request.POST )
            return JsonResponse({'error':error}, status=500)
        try:
            id = TmpFileStorage().finish_upload( tmp_name )
            return JsonResponse({'success':id})
        except:
            return JsonResponse({'error':'Ошибка при частичном сохранении файла'}, status=500)

    @logger
    def cancel_upload( self, request ):
        tmp_name= request.POST.get( 'tmp_name', None )
        error = []
        if  not tmp_name:
            error.append( 'Не верные параметры запроса' )
            error.append( request.POST )
            return JsonResponse({'error':error}, status=500)
        TmpFileStorage().cancel_upload( tmp_name )
        return JsonResponse({'success':"OK"})


import json
from pathlib import Path

import numpy as np
import argparse
from typing import Text, Optional, List, Dict, Any, Set, BinaryIO

class Codebook:

    def __init__(self, directoryname: Text):
        codebook_filename = Path(directoryname) / "codebook.bin"
        print(f"Reading codebook from {codebook_filename}")
        with open(codebook_filename, "br") as codebook:
            self.format = int(np.fromfile(codebook, dtype=np.uint8, count=1)[0])
            assert self.format == 0
            self.height = int(np.fromfile(codebook, dtype=np.uint64, count=1)[0])
            self.width = int(np.fromfile(codebook, dtype=np.uint64, count=1)[0])
            self.vocab_size = int(np.fromfile(codebook, dtype=np.uint64, count=1)[0])
            self._codebook = np.reshape(
                np.fromfile(codebook, dtype=np.float32, count=-1),
                (self.height, self.width, self.vocab_size)
            )
        readme_filename = Path(directoryname) / "README.md"
        print(f"Reading README from {readme_filename}")
        self.readme = ""
        with open(readme_filename, "r") as readme:
            for line in readme:
                self.readme += line
                if line.startswith("Local topology:"):
                    self.local_topology = line[len("Local topology:"):].strip()
                elif line.startswith("Global topology:"):
                    self.global_topology = line[len("Global topology:"):].strip()

    def __str__(self) -> str:
        return f"Codebook({np.shape(self._codebook)})"

    def fingerprint(self, i: int, size: int) -> List[int]:
        assert 0 <= i < self.vocab_size
        assert 0 < size < self.vocab_size
        weights = np.reshape(
            self._codebook[:, :, i],
            (-1, )
        )
        # Return the `size` largest values
        return np.argsort(weights)[:size].tolist()

def run(
    codebook_filename: Text,
    vocabulary_filename: Text,
    output_filename: Text,
    density: Optional[int] = None,
) -> None:
    codebook = Codebook(codebook_filename)
    vocab: List[Text] = []
    with open(vocabulary_filename, "r", encoding="utf-8") as file:
        for word in file:
            vocab.append(word.strip())
    print("Extracting semantic map...")
    semantic_map = dict()
    if density:
        size = max(int(density * codebook.width * codebook.height), 1)
    else:
        size = max(codebook.width * codebook.height // 50, 5)
    for i, word in enumerate(vocab):
        semantic_map[word] = codebook.fingerprint(i, size)
    print(f"Exporting to {output_filename}")
    with open(output_filename, "w+") as file:
        json.dump(
            {
                "Note": "",
                "Height": codebook.height,
                "Width": codebook.width,
                "AssumeLowerCase": all([word.islower() for word in vocab]),
                "GlobalTopology": codebook.global_topology,
                "LocalTopology": codebook.local_topology,
                "CreationReadme": codebook.readme,
                "CreationOptions": {"MaxActiveCells": size, "Executor": "PythonScript"},
                "Embeddings": semantic_map,
            },
            file
        )

def float_between_0_and_1_or_None(x) -> Optional[float]:
    if x is None:
        return None
    try:
        x = float(x)
    except ValueError:
        raise argparse.ArgumentTypeError("%r not a floating-point literal" % (x,))

    if x < 0.0 or x > 1.0:
        raise argparse.ArgumentTypeError("%r not in range [0.0, 1.0]"%(x,))
    return x

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Convert semantic map binary codebook into json"
    )
    parser.add_argument(
        "--codebook",
        type=str,
        help="Path to codebook binary",
    )
    parser.add_argument(
        "--vocabulary",
        type=str,
        help="Path to vocabulary list",
    )
    parser.add_argument(
        "--out",
        type=str,
        help="Name of the json file to create",
    )
    parser.add_argument(
        "--density",
        type=float_between_0_and_1_or_None,
        help="(Optional) Approximate density of the map",
    )

    args = parser.parse_args()

    run(
        args.codebook,
        args.vocabulary,
        args.out,
        args.density,
    )


from fastapi import APIRouter, Response, HTTPException, status

from models import ProductSchema
from controllers import read_products, read_category, write_product, read_product, purge_product

from datetime import date

router = APIRouter()

@router.get('/', response_model=list[ProductSchema])
async def get_products(read_all: bool, sorting_by_price_from_exp_to_cheap: bool = None,
                       select_by_date: date = None, select_by_category: str = None):
    try:
        return await read_products(read_all=read_all, sorting_by_price_from_exp_to_cheap=sorting_by_price_from_exp_to_cheap,
                                   select_by_date=select_by_date, select_by_category=select_by_category)
    except BaseException:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

@router.post('/', response_model=ProductSchema)
async def add_product(name: str, price: float, category_name: str):
    check_category = await read_category(name=category_name)
    if check_category:
        return await write_product(name=name, price=price, category=check_category)
    raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Category does not exist')

@router.delete('/')
async def delete_product(product_id: int):
    check_product = await read_product(product_id=product_id)
    if check_product:
        await purge_product(product_id=product_id)
        return Response(status_code=status.HTTP_200_OK)
    raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Product does not exist')


from flask import *
import requests, subprocess, json, re

app = Flask(__name__)

@app.route("/")
async def start():
    return """
    <form action="/get">
        <input name="username" id="username">
        <label for="username">Username</label>
    </form>
    """

@app.route("/get")
async def getRender():
    id = request.args.get("username") or abort(400)
    video_list = requests.get(f"https://recoverplays.tv/GetUserInfo.php?username={id}&sort=date").json()
    video_ids = []
    for video in video_list[1]:
        #rawdll = requests.get(f"https://web.archive.org/web/20191210043532/https://plays.tv/video/{id}").text
        #matched_lines = [line for line in rawdll.split('\n') if "720.mp4" in line]
        #assert len(matched_lines) == 1
        #p = Popen(["grep", "-Po", 'src="\k[^"]+/720\.mp4(?=")'], stdin=PIPE, stdout=PIPE)
        #dll = p.communicate(input=matched_lines[0])[0]
        video_ids.append({'id': video['id'], 'title': f"{video['name']}, {video['date']}"})
    return render_template("render.html", ids=video_ids, len=len)

@app.route("/get/<videoid>")
async def get(videoid):
    rawdll = requests.get(f"http://web.archive.org/web/20191210043532id_/https://plays.tv/video/{videoid}").text
    matched_lines = [line for line in rawdll.split('\n') if "720.mp4" in line]
    assert len(matched_lines) == 1
    dll = re.sub(
           "^//",
           "https://",
           re.search('src=\"([^\"]+/720\.mp4)(?=\")', matched_lines[0]).group(1)
    )
    return {"lien": dll, "isOk": True}


#--------------------------JoyBot - Python Branch-------------------------#

import os,random,discord,pickle,json,io,contextlib,itertools
from discord.ext.tasks import asyncio
from discord.ext import commands
from discord.utils import find
from datetime import datetime
from decimal import Decimal
from shutil import copyfile
from heapq import nlargest
from pathlib import Path

#--------------------------Options-------------------------#

prefix="."
client = commands.Bot(command_prefix = prefix)
tabGoal = 25

cross = "❌"

yes = "👍"
no = "👎"

one = "1⃣"
two = "2⃣"
three = "3⃣"
four = "4⃣"
five = "5⃣"
six = "6⃣"
seven = "7⃣"
eight = "8⃣"
nine = "9⃣"
ten = "🔟"

admins_ids = [
246862123328733186,
202513952406503425,
253059354331316224
]

errorcharacter = "\u001b[31m"
resetcharacter = "\u001b[0m"

#--------------------------Variables-------------------------#

facesList={}
facesAmount={}
pollDict={}
scoreDict={}

allGifs = ["hugs","kisses","marry"]
gifsList={}
gifsAmount={}

ynpoll = [yes,no,cross]
numpoll = {

	1: one,
	2: two,
	3: three,
	4: four,
	5: five,
	6: six,
	7: seven,
	8: eight,
	9: nine,
	10: ten
}

with open('./data/token.txt', 'r') as file:
	botToken = file.read().replace('\n', '')

#--------------------------Functions-------------------------#

def inch_cm(convert):
	#CM
	try:
		if convert.isnumeric():
			inches = int(convert) / 2.54
			feet = 0
			while inches >= 13:
				feet += 1
				inches -= 12
			return str(feet)+"'"+str(round(inches))

		#Inches
		else:
			if "'" in convert:
				split = convert.split("'")
				if split[0].isnumeric():
					if split[1].isnumeric():
						inches = int(split[0]) * 12
						inches += int(split[1])
						cm = inches * 2.54
						return str(round(cm))+"cm"
					else:
						return False
				else:
					return False
			#Meters
			elif "." in convert:
				split = convert.split(".")
				if split[0].isnumeric():
					if split[1].isnumeric():
						return str(round(Decimal(convert)*100))+"cm"
					else:
						return False
				else:
					return False

			else:
				return False

	#CM again but the provided argument was a number
	except AttributeError:
		inches = int(convert) / 2.54
		feet = 0
		while inches >= 13:
			feet += 1
			inches -= 12
		return str(feet)+"'"+str(round(inches))

def stringPOP(string, pop):
	popped = ""
	for i in range(len(string)):
		if i != pop:
			popped = popped + string[i]
	return popped

#This spacifies
def spacifyFunction(text):
	endString=""
	for x in range(0,len(text)):
		endString=(endString+text[x]+" ")
	return endString

#Edit the poll dict
def pollDictMod(type, author, message):
	if type == "add":
		try:
			oldDict = pollDict[author]
		except KeyError:
			oldDict = []

		oldDict.append(message)
		pollDict[author] = oldDict

	elif type == "remove":
		try:
			oldDict = pollDict[author]
		except KeyError:
			return

		if message in oldDict:
			oldDict.remove(message)
			return True
	elif type == "list":
		return pollDict

	else:
		raise Exception(f"Invalid type of '{type}'!")

def scoreDictMod(type, author, amount=0):
	try:
		global scoreDict
		if type == "add":
			try:
				oldDict = scoreDict[author]
			except KeyError:
				oldDict = 0

			oldDict += amount
			scoreDict[author] = oldDict

		elif type == "minus":
			try:
				oldDict = scoreDict[author]
			except KeyError:
				return

			oldDict -= amount
			if oldDict <= 0:
				scoreDict.pop(author)

			else:
				scoreDict[author] = oldDict
		elif type == "one":
			try:
				oldDict = scoreDict[author]
			except KeyError:
				return 0
			return oldDict

		elif type == "list":
			return scoreDict

		else:
			raise Exception(f"Invalid type of '{type}'!")
	finally:
		with open("./data/bumpscores.pkl", "wb") as fp:
			pickle.dump(scoreDict, fp)

#Import all the faces from folder
def updateFaces(whichFolder=None):
	global facesAmount,facesList
	totalFaces=[]

	if whichFolder == None:
		print("Updating all faces...")

		facesList={}
		facesAmount={}

		for folder in os.listdir("./faces"):
			for filename in sorted(os.listdir("./faces/"+folder)):
				if filename.endswith(".png"):
					if filename[:-4].isdigit():
						totalFaces.append(filename)
					else:
						print(f"{errorcharacter}The file '{filename}' in folder '{folder}' was not named correctly!{resetcharacter}")
				else:
					print(f"{errorcharacter}The file '{filename}' in folder '{folder}' was not named correctly!{resetcharacter}")

			if len(totalFaces) != 0:
				facesList[folder] = totalFaces
				facesAmount[folder] = len(totalFaces)
				totalFaces=[]
			else:
				print(f"{errorcharacter}The folder {folder} did not have any valid pictures!{resetcharacter}")

		if facesAmount == {}:
			print(f"{errorcharacter}No faces loaded!{resetcharacter}\n")

	else:
		if os.path.exists(f"./faces/{whichFolder}"):
			print(f"Updating the '{whichFolder}' folder...")
			for filename in sorted(os.listdir("./faces/"+whichFolder)):
				if filename.endswith(".png"):
					if filename[:-4].isdigit():
						totalFaces.append(filename)
					else:
						print(f"{errorcharacter}The file '{filename}' in folder '{whichFolder}' was not named correctly!{resetcharacter}")
				else:
					print(f"{errorcharacter}The file '{filename}' in folder '{whichFolder}' was not named correctly!{resetcharacter}")

			if len(totalFaces) != 0:
				facesList[whichFolder] = totalFaces
				facesAmount[whichFolder] = len(totalFaces)
				totalFaces=[]
			else:
				print(f"{errorcharacter}The folder '{whichFolder}' did not have any valid pictures!{resetcharacter}")

		else:
			raise Exception(f"Tried to access the folder './faces/{whichFolder}, but it does not exist!'")

def updateGifs(whichGifs=None):
	global gifsList,gifsAmount
	totalGifs=[]

	if whichGifs == None:
		for gifType in allGifs:
			for filename in os.listdir(f"./gifs/{gifType}"):
				if filename.endswith(".gif"):
					if filename[:-4].isdigit():
						totalGifs.append(filename)
					else:
						print(f"{errorcharacter}The gif '{filename}' in folder '{gifType}' was not named correctly!{resetcharacter}")
				else:
					print(f"{errorcharacter}The gif '{filename}' in folder '{gifType}' was not named correctly!{resetcharacter}")

			if len(totalGifs) != 0:
				gifsList[gifType] = totalGifs
				gifsAmount[gifType] = len(totalGifs)
				totalGifs=[]
			else:
				print(f"{errorcharacter}The folder '{gifType}' did not have any valid gifs!{resetcharacter}")

	elif whichGifs in allGifs:
		for filename in os.listdir(f"./gifs/{whichGifs}"):
			if filename.endswith(".gif"):
				if filename[:-4].isdigit():
					totalGifs.append(filename)
				else:
					print(f"{errorcharacter}The gif '{filename}' in folder '{whichGifs}' was not named correctly!{resetcharacter}")
			else:
				print(f"{errorcharacter}The gif '{filename}' in folder '{whichGifs}' was not named correctly!{resetcharacter}")

		if len(totalGifs) != 0:
			gifsList[whichGifs] = totalGifs
			gifsAmount[whichGifs] = len(totalGifs)
			totalGifs=[]

		else:
			print(f"{errorcharacter}The folder '{whichGifs}' did not have any valid gifs!{resetcharacter}")
	else:
		raise Exception(f"The type '{whichGifs}' can't be used in this function! (updateGifs)")

def randomGif(whichGifs):
	if whichGifs in allGifs:
		return random.choice(gifsList[whichGifs])
	else:
		return False

#Prints a person and their total pictures nicely.
def printPerson(person,endnum):
	if len(person) > tabGoal-1:
		person="Folder name too long"

	while len(person) != tabGoal:
		person = person+" "

	print(person+endnum)

#--------------------------Events-------------------------#

#Triggers when bot starts
#Updates the presence and prints to console we've connected
@client.event
async def on_ready():
	await client.change_presence(activity=discord.Game("Just JoyBot things :)"))
	print(f"Logged in as the bot ({client.user})!")

@client.event
async def on_message(message):
	if message.content == "<@!504030703264989194>":
		if message.author.id != 504030703264989194:
			await message.channel.send("My prefix is `.` and `^`!\nType `.help` and `^help`!")
	await client.process_commands(message)
	if message.author.id == 302050872383242240:
		for embed in message.embeds:
			if "Bump done" in embed.description:
				bumpID = embed.description
				bumpID = stringPOP(bumpID,0)
				bumpID = stringPOP(bumpID,0)
				bumpID, _ = bumpID.split(">")
				scoreDictMod("add",int(bumpID),1)
				top = str(getTopDict(scoreDict, 1))
				top = stringPOP(top, 0)
				top = stringPOP(top, 0)
				top, _ = top.split(",")

				header = f"<@{bumpID}>, your bump score has been increased by one!\nType `.bumpscore` to view your current bump score!"
				if int(top) == int(bumpID):
					role = discord.utils.find(lambda r: r.id == 760719803844788235, message.guild.roles)
					member = message.guild.get_member(int(bumpID))

					if not role in member.roles:
						await message.channel.send(f"{header}\nYou also managed to get the top spot! Nice!")
						await member.add_roles(role)

						with open("./data/roletop.txt", "r") as fp:
							oldID = int(fp.read().replace('\n', ''))

						with open("./data/roletop.txt", "w") as fp:
							fp.write(str(bumpID))

						oldMember = message.guild.get_member(int(oldID))
						await oldMember.remove_roles(role)
						await message.channel.send(f"{oldMember.mention}, you've lost your top spot!")
					else:
						await message.channel.send(header)
				else:
					await message.channel.send(header)

	#testing
	if "do testbump now" == message.content:
		bumpID = message.author.id
		scoreDictMod("add",int(bumpID),0)
		top = str(getTopDict(scoreDict, 1))
		top = stringPOP(top, 0)
		top = stringPOP(top, 0)
		top, _ = top.split(",")
		header = f"<@{bumpID}>, your bump score has been increased by none (test bump!)!\nType `.bumpscore` to view your current bump score!"
		if int(top) == int(bumpID):
			role = discord.utils.find(lambda r: r.id == 760719803844788235, message.guild.roles)
			member = message.guild.get_member(bumpID)

			print(member, member.roles)
			print(type(bumpID), bumpID)

			if not role in member.roles:
				await message.channel.send(f"{header}\nYou also managed to get the top spot! Nice!")
				await member.add_roles(role)

				with open("./data/roletop.txt", "r") as fp:
					oldID = int(fp.read().replace('\n', ''))

				with open("./data/roletop.txt", "w") as fp:
					fp.write(str(bumpID))

				oldMember = message.guild.get_member(oldID)
				await oldMember.remove_roles(role)
				await message.channel.send(f"{oldMember.mention}, you've lost your top spot!")
			else:
				await message.channel.send(header)
		else:
			await message.channel.send(header)

#Triggers on any command
#Stops the error from appearing if it's any command not found error
@client.event
async def on_command_error(ctx, error):
	if isinstance(error, discord.ext.commands.errors.CommandNotFound):
		return
	raise error

#-------------------------Backwords-----------------------#

def function_backwords(passthrough):
	endString=""
	for x in passthrough:
		endString = x + endString
	return endString

@client.command(name="backwords",description="returns the string backwords!")
async def backwords(ctx, *, text):

	convert = function_backwords(text)
	if convert != "":
		await ctx.send(f"{ctx.author.mention}, here is your backwords string: {convert}")
	else:
		await ctx.send(f"{ctx.author.mention}, please provide something to return backwords!")

#-------------------------Reversecaps----------------------------#

@client.command(name="reversecaps",description="reverses the caps in the provided argument!")
async def reversecaps(ctx, *, text=None):
	if text == None:
		await ctx.send(f"{ctx.author.mention}, please suppy an argument to reversecaps!")
		return

	await ctx.send(f"{ctx.author.mention}, here is your reversecaps:\n{text.swapcase()}")

#---------------------------Evaluate-------------------------------#

@client.command(name="evaluate",description="evaluates some provided python code!",aliases=["e","eval"])
async def evaluate(ctx, *, code=None):
	if not ctx.author.id in admins_ids:
		await ctx.send(f"{ctx.author.mention}, you can't use this command!")
		return
	if code == None:
		await ctx.send(f"Please supply some code!")
		return

	str_obj = io.StringIO() #Retrieves a stream of data
	try:
		with contextlib.redirect_stdout(str_obj):
			exec(code)
	except Exception as e:
		return await ctx.send(f"{ctx.author.mention}, An exception occured!\n```{e.__class__.__name__}: {e}```")
	if str_obj.getvalue() == "":
		await ctx.send(f'{ctx.author.mention}, the run completed succesfully with no output!')
	else:
		try:
			await ctx.send(f'{ctx.author.mention}, the run completed succesfully, heres the output:\n```{str_obj.getvalue()}```')
		except discord.errors.HTTPException:
			await ctx.send(f"{ctx.author.mention}, the run completed succesfully but the output was too long to send!")

#--------------------------Bumpscore--------------------------#

@client.command(name="bumpscore", description="gets the bumpscore of you or someone else")
async def bumpscore(ctx, person : discord.Member = None):
	if person == None:
		curScore = scoreDictMod("one",ctx.author.id,0)

		if curScore == 0:
			await ctx.send("You haven't bumped disboard yet!")
		else:
			await ctx.send(f"Your current bump score is `{curScore}`")

	else:
		curScore = scoreDictMod("one",person.id)

		if curScore == 0:
			await ctx.send(f"{person} hasn't bumped disboard yet!")
		else:
			await ctx.send(f"{person}'s current bump score is `{curScore}`")

@bumpscore.error
async def bumpscore_error(ctx, error):
	if isinstance(error, commands.errors.BadArgument):
		await ctx.send("That's not a valid member!")

#-------------------------Top bumpscore----------------------------#

def getTopDict(dictionary, num=10000000000000000):
	topx = nlargest(num, dictionary, key=dictionary.get)
	returnList = []
	for key in topx:
		returnList.append((key, dictionary[key]))
	return returnList

@client.command(name="topbumpscore", description="gets the top bumpers")
async def topbumpscore(ctx):
	topbumps = getTopDict(scoreDict, 10)
	printstring=""

	message = await ctx.send("Getting the top 10 bumpers...")

	for num, x in enumerate(topbumps):
		user = await client.fetch_user(x[0])
		username = f"{user.name}#{user.discriminator}"

		if int(x[1]) == 69:
			if num >= 9:
				printstring += f"{num+1})   {username} — {x[1]} — Nice.\n"
			else:
				printstring += f"{num+1})    {username} — {x[1]} — Nice.\n"

		elif int(x[1]) == 420:
			if num >= 9:
				printstring += f"{num+1})   {username} — {x[1]} — Blaze it!.\n"
			else:
				printstring += f"{num+1})    {username} — {x[1]} — Blaze it!.\n"
		else:
			if num >= 9:
				printstring += f"{num+1})   {username} — {x[1]}\n"
			else:
				printstring += f"{num+1})    {username} — {x[1]}\n"

	if printstring == "":
		await message.edit(content = f"{ctx.author.mention}, looks like nobody has bumped disboard!\n(this is strange, contact Joyte#0001 maybe?)")
		return

	await message.edit(content = f"{ctx.author.mention}, here are the top 10 bumpers:\n```{printstring}```")

#-----------------------Bumpscore json--------------------#

@client.command(name="dictjson", description="returns a dict in json format")
async def dictjson(ctx, whichDict=None):
	if not ctx.author.id in admins_ids:
		await ctx.send(f"{ctx.author.mention}, you can't use this command!")
		return

	#i'm genuinely sorry for this code
	beforetext = "Hey, just warning you there's no use for this command as it's not stored in json anymore, it's pickled.\n"

	if whichDict == "facesList":
		message = await ctx.send(f"{beforetext}Loading dict...")
		jsonText = json.dumps(facesList, indent=4)
		await message.edit(content = f"{beforetext}Faces list dict:```json\n{jsonText}```")

	elif whichDict == "facesAmount":
		message = await ctx.send(f"{beforetext}Loading dict...")
		jsonText = json.dumps(facesAmount, indent=4)
		await message.edit(content = f"{beforetext}Faces amount dict:```json\n{jsonText}```")

	elif whichDict == "pollDict":
		message = await ctx.send(f"{beforetext}Loading dict...")
		jsonText = json.dumps(pollDict, indent=4)
		await message.edit(content = f"{beforetext}Poll owner list dict:```json\n{jsonText}```")

	elif whichDict == "scoreDict":
		message = await ctx.send(f"{beforetext}Loading dict...")
		jsonText = json.dumps(scoreDict, indent=4)
		await message.edit(content = f"{beforetext}Bump score dict:```json\n{jsonText}```")

	else:
		await ctx.send("That's not a valid dict, please choose one of these:\n`facesList`\n`facesAmount`\n`pollDict`\n`scoreDict`")

#-----------------------Bumpscore pkl--------------------#

@client.command(name="dictpkl", description="returns a dict in pkl format")
async def dictpkl(ctx, whichDict=None):
	if not ctx.author.id in admins_ids:
		await ctx.send(f"{ctx.author.mention}, you can't use this command!")
		return

	beforetext = ""
	try:
		if whichDict == "facesList":
			message = await ctx.send(f"{beforetext}Loading dict...")
			pklText = pickle.dumps(facesList)
			dictName = "Faces list dict"
			await message.edit(content = f"{beforetext}{dictName}:```json\n{pklText}```")

		elif whichDict == "facesAmount":
			message = await ctx.send(f"{beforetext}Loading dict...")
			pklText = pickle.dumps(facesAmount)
			dictName = "Faces amount dict"
			await message.edit(content = f"{beforetext}{dictName}:```json\n{pklText}```")

		elif whichDict == "pollDict":
			message = await ctx.send(f"{beforetext}Loading dict...")
			pklText = pickle.dumps(pollDict)
			dictName = "Poll owner list dict"
			await message.edit(content = f"{beforetext}{dictName}:```json\n{pklText}```")

		elif whichDict == "scoreDict":
			message = await ctx.send(f"{beforetext}Loading dict...")
			pklText = pickle.dumps(scoreDict)
			dictName = "Bump score dict"
			await message.edit(content = f"{beforetext}{dictName}:```json\n{pklText}```")

		else:
			await ctx.send("That's not a valid dict, please choose one of these:\n`facesList`\n`facesAmount`\n`pollDict`\n`scoreDict`")
	except discord.errors.HTTPException:
		await message.delete()
		split_1, split_2 = pklText[:len(pklText)//2], pklText[len(pklText)//2:]
		try:
			await ctx.send(f"{beforetext}{dictName}:```\n{split_1}```")
			await ctx.send(f"```{split_2}```")
		except discord.errors.HTTPException:
			try:
				split_again1, split_again2 = split_1[:len(split_1)//2], split_1[len(split_1)//2:]
				split_again3, split_again4 = split_2[:len(split_2)//2], split_2[len(split_2)//2:]
				await ctx.send(f"{beforetext}{dictName}:```\n{split_again1}```")
				await ctx.send(f"```{split_again2}```")
				await ctx.send(f"```{split_again3}```")
				await ctx.send(f"```{split_again4}```")
			except discord.errors.HTTPException:
				await ctx.send("Sorry, but the data is too long to send!")

#-----------------------Add/Remove bumpscore--------------------#

@client.command(name="changebumpscore", description="changes the bumpscore of a user")
async def changebumpscore(ctx, amount = None, person : discord.Member = None):
	if not ctx.author.id in admins_ids:
		await ctx.send(f"{ctx.author.mention}, you can't use this command!")
		return

	if amount == None:
		await ctx.send(f"{ctx.author.mention}, Please supply an amount to change by!")
		return

	if person == None:
		if str(amount)[0] == "-":
			amount = stringPOP(amount,0)
			if amount.isnumeric():
				scoreDictMod("minus",ctx.author.id,int(amount))
				await ctx.send(f"Changed your bump score by -{amount}")
			else:
				await ctx.send(f"{ctx.author.mention}, Please give a valid amount!")
		else:
			if amount.isnumeric():
				scoreDictMod("add",ctx.author.id,int(amount))
				await ctx.send(f"Changed your bump score by {amount}")
			else:
				await ctx.send(f"{ctx.author.mention}, Please give a valid amount!")
	else:
		if str(amount)[0] == "-":
			amount = stringPOP(amount,0)
			if amount.isnumeric():
				scoreDictMod("minus",person.id,int(amount))
				await ctx.send(f"Changed {person}'s bump score by -{amount}")
			else:
				await ctx.send(f"{ctx.author.mention}, Please give a valid amount!")
		else:
			if amount.isnumeric():
				scoreDictMod("add",person.id,int(amount))
				await ctx.send(f"Changed {person}'s bump score by {amount}")
			else:
				await ctx.send(f"{ctx.author.mention}, Please give a valid amount!")

@changebumpscore.error
async def changebumpscore_error(ctx, error):
	if isinstance(error, commands.errors.BadArgument):
		await ctx.send("That's not a valid member!")

#--------------------------Convert-------------------------#

#Number poll
@client.command(name="convert",description="Converts height!")
async def convert(ctx, text=None):
	if text == None:
		await ctx.send("Please convert either:\nFeet'inches to CM\nCM to Feet'inches\nMetres to CM")
		return

	convert = inch_cm(text)
	if convert != False:
		await ctx.send(f"{ctx.author.mention}, here is your conversion: {convert}")
	else:
		await ctx.send(f"{ctx.author.mention}, that's not a valid conversion!")

#--------------------------Random Face-------------------------#

#Get a random face and print it to discord.
@client.command(name="randomface",description="Gets a random face!")
async def randomface(ctx, person=None):
	try:
		if person == None: #Nobody specified
			printFaces = ""
			for person in facesList.keys():
				printFaces = (printFaces+"`"+person+"` **—** `"+str(facesAmount[person])+"`\n")
			await ctx.send(f"{ctx.author.mention}, Please specify a valid person!\nList:\n"+printFaces)
			return

		else:
			if person in facesList: #we got him bois!
				fileName = (str(random.choice(range(1,facesAmount[person]+1)))+".png")
				validPicture = (os.getcwd()+"/faces/"+person+"/"+fileName)

				if fileName == "69.png":
					nice = " | Nice."
				else:
					nice = ""

				with open(validPicture, 'rb') as fp:
					await ctx.send(f"{ctx.author.mention}, Here's your picture! `{fileName}`{nice}",file=discord.File(fp, fileName))

			else: #Invalid person
				printFaces = ""
				for person in facesList:
					printFaces = (printFaces+"`"+person+"` **—** `"+str(facesAmount[person])+"`\n")

				await ctx.send(f"{ctx.author.mention}, Please specify a valid person!\nList:\n"+printFaces)
				return

	except FileNotFoundError:
		message = await ctx.send(f"{ctx.author.mention}, An error occured!")
		updateFaces(person)

		if os.path.exists(f"./faces/{person}/{fileName}"):
			await message.edit(content = f"{ctx.author.mention}, An error occured, but i've managed to fix it!")
			return

		if int(fileName[:-4]) > facesAmount[person]:
			await message.edit(content = f"{ctx.author.mention}, An error occured, but i've managed to fix it!")
			return

#--------------------------Addpic-------------------------#

#Adds a picture to either the faces command or the gifs.
@client.command(name="addpic",description="Adds a picture!")
async def addpic(ctx, type=None, person=None):
	if not int(ctx.author.id) in admins_ids:
		await ctx.send(f"{ctx.author.mention}, hey you can't use this command!")
		return

	if ctx.message.attachments == []:
		await ctx.send(f"{ctx.author.mention}, please use this command with an attached file!")
		return

	if type == None:
		await ctx.send(f"{ctx.author.mention}, please give a type!\n**List:**\n`gifs`\n`faces`")
		return

	if person == None:
		if type == "faces":
			await ctx.send(f"{ctx.author.mention}, please give a person to add the face to!")
		elif type == "gifs":
			await ctx.send(f"{ctx.author.mention}, please specify which type of gif this is!\n**List:**\n`marry`\n`kisses`\n`hugs`")
		else:
			await ctx.send(f"{ctx.author.mention}, please specify argument two!")
		return

	if not person.isalpha():
		await ctx.send(f"{ctx.author.mention}, please limit your person name to alphabetical characters only!")
		return

	if type == "faces":
		for file in ctx.message.attachments:
			try:
				await file.save(f"./faces/{person}/{facesAmount[person]+1}.png")
				await ctx.send(f"{ctx.author.mention}, Added the picture to the `{person}` folder!")
			except KeyError:
				try:
					os.mkdir(f"./faces/{person}")
					await file.save(f"./faces/{person}/1.png")
					await ctx.send(f"{ctx.author.mention}, Made the `{person}` folder, and added the picture to it!")
				except FileExistsError:
					await file.save(f"./faces/{person}/1.png")
					await ctx.send(f"{ctx.author.mention}, The `{person}` folder already existed without any pictures, so i just added the picture to it!")
		updateFaces(person)
	elif type == "gifs":
		if person in allGifs:
			for file in ctx.message.attachments:
				await file.save(f"./gifs/{person}/{gifsAmount[person]+1}.png")
				await ctx.send(f"{ctx.author.mention}, Added the gif to the `{person}` folder!")

		else:
			await ctx.send(f"{ctx.author.mention}, please specify a valid gif type!\n**List:**\n`marry`\n`kisses`\n`hugs`")
	else:
		await ctx.send(f"{ctx.author.mention}, that's not a valid type!\n**List:**\n`gifs`\n`faces`")

#------------------------Addpic history------------------#

#TODO:	This command, make it scan the last {amount} messages and
#		add them all to the {person} folder. there should be an
#		optional {replace} argument, where a backup of the {person}
#		folder is made, (with the timestamp and person as the name)
#		and everything is deleted and replaced with the attachments
#		provided using addpic-history.
#		format: .addpic-history <amount> <person> [replace]
#		or maybe add arguments onto the addpic command, with the format
#		.addpic <person> [<history> <amount> <replace>]
#		which would be better, as it is only one command
#		will decide later

#@client.command(name=".addpic_history",description="Adds the picture history to a person or face")
#async def addpic_history(ctx, person=None, amount=100, replace=None):
#	messagehistory = await ctx.channel.history(limit=amount,).flatten()

#--------------------------History------------------------#

@client.command()
async def history(ctx, limit: int = 100):
	if not ctx.author.id in admins_ids:
		await ctx.send(f"{ctx.author.mention}, hey you can't use this command!")
		return

	editmsg = await ctx.send(f"{ctx.author.mention}, getting the message history...")
	messages = await ctx.channel.history(limit=limit).flatten()

	try:
		with open(f"history-{ctx.channel.id}.txt", "a") as f:
			print(f"Requested {limit} lines by {ctx.author.name}#{ctx.author.discriminator} ({ctx.author.id})\n\n", file=f)
			for message in messages:
				print(f"#{message.channel.name} ({message.channel.id}): @{message.author.name}#{message.author.discriminator} ({message.author.id}): {message.content}", file=f)
	except ssl.SSLError:
		pass

	with open(f"history-{ctx.channel.id}.txt", "rb") as fp:
		await editmsg.edit(content = f"{ctx.author.mention}, here's the history of the channel, up to {limit}:")
		await ctx.send(file = discord.File(fp, f"history-{ctx.channel.id}.txt"))

	os.remove(f"history-{ctx.channel.id}.txt")

#---------------------Delface------------------------------#

#TODO: Convert to delpic

@client.command(name="delface",description="deletes a face")
async def delface(ctx, num, person=None):

	if not int(ctx.author.id) in admins_ids:
		await ctx.send(f"{ctx.author.mention}, hey you can't use this command!")
		return

	if person == None:
		await ctx.send(f"{ctx.author.mention}, please give a person to delete the face of!")
		return

	if not person.isalpha():
		await ctx.send(f"{ctx.author.mention}, please limit your person name to alphabetical characters only!")
		return

	if not num.isnumeric():
		await ctx.send(f"{ctx.author.mention}, please make the first argument a number!")
		return
	else:
		num = int(num)

	if num == 0:
		await ctx.send(f"{ctx.author.mention}, okay, i deleted no faces for you :)")
		return

	try:
		if num > facesAmount[person]:
			if facesAmount[person] == 1:
				await ctx.send(f"{ctx.author.mention}, {person} only has one face!")
				return
			else:
				await ctx.send(f"{ctx.author.mention}, {person} only has {facesAmount[person]} faces!")
			return

		if not os.path.exists(f"./faces/{person}/{num}.png"):
			if num == facesAmount[person]:
				await ctx.send(f"{ctx.author.mention}, this file has already been deleted, contact <@246862123328733186> to help!\ndebug info:\nperson: {person}\nnum: {num}")
				print(f"{errorcharacter}file already deleted, debug info:\nperson: {person}\nnum: {num}\nfaces list:{facesList[person]}{resetcharacter}")
				return

			await ctx.send(f"{ctx.author.mention}, this file has already been deleted, but i'll try to fix the corruption!")
			if os.path.exists(f"./faces/{person}/{facesAmount[person]}.png"):
				if num == facesAmount[person]:
					updateFaces(person)
					await ctx.send("Okay, i've fixed it!")
					return

				copyfile(f"./faces/{person}/{facesAmount[person]}.png",f"./faces/{person}/{num}.png")
				os.remove(f"./faces/{person}/{facesAmount[person]}.png")
				await ctx.send(f"Hopefully i've fixed it!")
				updateFaces(person)
				return

			else:
				await ctx.send(f"I couldn't fix it, but contact <@246862123328733186> to help!\ndebug info:\nperson: {person}\nnum: {num}")
				print(f"{errorcharacter}file already deleted, debug info:\nperson: {person}\nnum: {num}\nfaces list:{facesList[person]}{resetcharacter}")
				return

		if facesAmount[person] == 1:
			os.remove(f"./faces/{person}/{num}.png")
			os.rmdir(f"./faces/{person}")
			await ctx.send(f"{ctx.author.mention}, deleted `{person}`'s folder!")
			updateFaces(person)
			return

		if num == facesAmount[person]:
			os.remove(f"./faces/{person}/{num}.png")
			await ctx.send(f"{ctx.author.mention}, deleted `{person}`'s `{num}.png`!")
			updateFaces(person)
			return

		os.remove(f"./faces/{person}/{num}.png")
		copyfile(f"./faces/{person}/{facesAmount[person]}.png",f"./faces/{person}/{num}.png")
		os.remove(f"./faces/{person}/{facesAmount[person]}.png")

		await ctx.send(f"{ctx.author.mention}, deleted `{person}`'s `{num}.png`!")
		updateFaces(person)
		return

	except KeyError:
		await ctx.send(f"{ctx.author.mention}, that's not a valid person!")
		return
#--------------------------update all-------------------------#

@client.command(name="updateall",description="Updates all the faces")
async def updateallfaces(ctx):
	if not int(ctx.author.id) in admins_ids:
		await ctx.send(f"{ctx.author.mention}, hey you can't use this command!")
		return

	message = await ctx.send(f"{ctx.author.mention}, updating all the faces and gifs...")
	updateFaces()
	updateGifs()
	await message.edit(content = "Faces updated!")

#--------------------------Marry command-------------------------#

#TODO: finish this

"""
@client.command(name="marry", description="give someone a marry (what's a english)")
async def marry(ctx, person : discord.Member = None):
	await ctx.send("nothing :)")

@kiss.error
async def marry_error(ctx, error):
	if isinstance(error, commands.errors.BadArgument):
		await ctx.send("That's not a valid member!")
"""

#--------------------------Kiss command-------------------------#

@client.command(name="kiss", description="give someone a kiss")
async def kiss(ctx, person : discord.Member = None):
	if person == None:
		await ctx.send("I need to know who you are kissing!")
		return
	if person.id == ctx.author.id:
		await ctx.send("You can't kiss yourself!")
		return
	random_gif = randomGif("kisses")
	fileName = f"./gifs/kisses/{random_gif}"
	with open(fileName, 'rb') as fp:
		await ctx.send(f"{ctx.author.mention} has kissed {person.mention}",file=discord.File(fp, fileName))

@kiss.error
async def kiss_error(ctx, error):
	if isinstance(error, commands.errors.BadArgument):
		await ctx.send("That's not a valid member!")

#--------------------------Hug command-------------------------#

@client.command(name="hug", description="give someone a hug")
async def hug(ctx, person : discord.Member = None):
	if person == None:
		await ctx.send("I need to know who you are hugging!")
		return
	if person.id == ctx.author.id:
		await ctx.send("You can't hug yourself!")
		return
	random_gif = randomGif("hugs")
	fileName = f"./gifs/hugs/{random_gif}"
	with open(fileName, 'rb') as fp:
		await ctx.send(f"{ctx.author.mention} has hugged {person.mention}",file=discord.File(fp, fileName))

@hug.error
async def hug_error(ctx, error):
	if isinstance(error, commands.errors.BadArgument):
		await ctx.send("That's not a valid member!")

#--------------------------Polls-------------------------#

#Yes/No poll
@client.command(name="yesnopoll",description="Makes a yes no poll!",aliases=["yesnovote"])
async def yesnopoll(ctx, *, question=None):
	await ctx.message.delete()
	if question == None:
		error = await ctx.send(f"{ctx.author.mention}, Please supply arguments!\nExample:\t`.numberpoll This is the question`")
		await error.add_reaction(cross)
		pollDictMod("add",ctx.author.id,error.id)
		return

	poll = await ctx.send(f"{ctx.author.mention} wants to know:\n**Yes/No** `{question}`")
	for reaction in ynpoll:
		await poll.add_reaction(reaction)
	pollDictMod("add",ctx.author.id,poll.id)

#Spacify
@client.command(name="spacify",description="Spacifies")
async def spacify(ctx, *, text):
	spacedText = spacifyFunction(text)
	await ctx.send(f"{ctx.author.mention}, here is your message:\n{spacedText}")

#Number poll
@client.command(name="numberpoll",description="Makes a number poll!",aliases=["numbervote"])
async def numberpoll(ctx, *, text=None):
	await ctx.message.delete()
	if text == None:
		error = await ctx.send(f"{ctx.author.mention}, Please supply arguments!\nExample:\t`.numberpoll This is the question, This is answer one, This is answer two, etc`")
		await error.add_reaction(cross)
		pollDictMod("add",ctx.author.id,error.id)
		return

	split = text.split(",")

	if len(split) == 1:
		error = await ctx.send(f"{ctx.author.mention}, Please supply some answers, not just the question!\n`{text}`")
		await error.add_reaction(cross)
		pollDictMod("add",ctx.author.id,error.id)
		return

	if len(split) > 11:
		error = await ctx.send(f"{ctx.author.mention}, Please limit your poll to 10 options or less!\n`{text}`")
		await error.add_reaction(cross)
		pollDictMod("add",ctx.author.id,error.id)
		return

	popsplit = []
	for string in split:
		beforepop = string
		while string[0] == " ":
			string = stringPOP(string,0)

		while string[len(string)-1] == " ":
			string = stringPOP(string,len(string)-1)

		popsplit.append(string)

	header = popsplit[0]
	popsplit.pop(0)

	sendmessage = f"{ctx.author.mention} asks `{header}`:\n"
	curnum = 1
	for string in popsplit:
		if curnum == len(popsplit)+1:
			break
		sendmessage = sendmessage + f"{numpoll[curnum]} — {string}\n"
		curnum += 1

	poll = await ctx.send(sendmessage)

	curnum = 1
	for string in popsplit:
		if curnum == len(popsplit)+1:
			break
		await poll.add_reaction(numpoll[curnum])
		curnum += 1

	await poll.add_reaction(cross)

	pollDictMod("add",ctx.author.id,poll.id)

#Remove if x
@client.event
async def on_reaction_add(reaction, user):
	if str(reaction.emoji) == cross:
		state = pollDictMod("remove",user.id,reaction.message.id)
		if state == True:
			await reaction.message.delete()

#--------------------------------------Say----------------------------------#

@client.command(name="say", description="says something from the bot's perspective")

async def say(ctx, *, saying):
	if not ctx.author.id in admins_ids:
		await ctx.send(f"{ctx.author.mention}, Nice try Buddy.")
		return
	await ctx.message.delete()
	await ctx.send(saying)
#------------------------------Final bootstrap------------------------------------#

print(f"{resetcharacter}Booting up...")

#Update the faces
updateFaces()
if facesAmount != {}:
	print("\nLoaded faces:\n")
	for person in facesList:
		printPerson(person,str(facesAmount[person]))
	print("\n")

#Updating gifs
print("Updating gifs...")
updateGifs()
if gifsAmount != {}:
	print("\nLoaded gifs:\n")
	for gif in gifsList:
		printPerson(gif,str(gifsAmount[gif]))
	print("\n")

#Load the bumpscores
if os.path.exists("./data/bumpscores.pkl"):
	#try:
	print("Loading pickle bump scores...")
	try:
		with open('./data/bumpscores.pkl', 'rb') as fp:
			scoreDict = pickle.load(fp)
	except (EOFError, pickle.UnpicklingError):
		print(f"{errorcharacter}Pickle decoder error, the pkl file has been reset, and a backup has been made.{resetcharacter}")
		copyfile("./data/bumpscores.pkl", f"./data/bumpscores.pkl.{datetime.utcnow()}")
		os.remove("./data/bumpscores.pkl")

#------------------------------------Log into discord-------------------------------------#
print("Logging into discord...")
client.run(botToken)


import json
import logging

from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
from rest_framework.response import Response

from .tasks import fetch_fastq

logger = logging.getLogger(__name__)

@csrf_exempt
def test(request):
    return HttpResponse("Data Collection API Test Page.")

@csrf_exempt
def handle_request(request):
    logger.info('Received request.')

    if request.method != 'POST':
        logger.info('Received invalid request.')
        return JsonResponse({'task_id': '', 'error': 'Request must be a POST request.'})

    request_body = json.loads(request.body)

    run_id = request_body.get('run_id', None)

    if run_id is None:
        print('Invalid run ID.')
        logger.error(f'No run id found!')
        return JsonResponse({'task_id': '', 'error': 'No run id found!'})

    logger.info(f'Run id is {run_id}')
    print(f'Run ID: {run_id}')

    try:
        worker = fetch_fastq.delay(run_id)
    except Exception as e:
        print(str(e))
        logger.error(str(e))
        return JsonResponse({'task_id': '', 'error': 'Error in fetching the fastq files.'})

    res = JsonResponse({'task_id': worker.task_id})

    res.headers['Access-Control-Allow-Origin'] = '*'

    return res


# -*- coding: utf-8 -*-

import base64
import json

from odoo import fields, models, api

from ..utils.utils import make_signature

class PaymentAcquirer(models.Model):
    _inherit = 'payment.acquirer'

    provider = fields.Selection(selection_add=[('liqpay', 'Liqpay')])
    liqpay_public_key = fields.Char(
        'Liqpay Public Key', required_if_provider='liqpay')
    liqpay_private_key = fields.Char(
        'Liqpay Private Key', required_if_provider='liqpay')
    liqpay_base_url = fields.Char(
        'Base callback url', required_if_provider='liqpay')
    liqpay_server_side =  fields.Char(
        default='https://www.liqpay.ua/api/request',
        help="If you don't sure don't change it",
        string='Server Side', required_if_provider='liqpay')
    liqpay_client_side =  fields.Char(
        default='https://www.liqpay.ua/api/3/checkout',
        help="If you don't sure don't change it",
        string='Client Side', required_if_provider='liqpay')

    def liqpay_form_generate_values(self, values):
        """
            Method to generate values for liqpay acquirer payment
        :param values: values to generate payment from
        :return: updated values dict with:
                liqpay_data - request data in json encoded to base64
                liqpay_signature - {private_key}{data_in_base64}{private_key}
                signature for sending to liqpay for transactions verification
        """

        self.ensure_one()

        base_url = self.liqpay_base_url
        return_url = '{}/shop/confirmation'.format(base_url)
        callback_url = '{}/liqpay/callback'.format(base_url)
        partner_lang = 'ru'

        # Fill in request data for liqpay transaction
        request = {
          'version': '3',
          'public_key': self.liqpay_public_key,
          'action': 'pay',
          'amount': values['amount'],
          'currency': values['currency'] and values['currency'].name or 'UAH',
          'description': 'Order payment: {}'.format(values['reference']),
          'order_id': values['reference'],
          'language': partner_lang,
          'sandbox': '1' if self.environment == 'test' else '',
          'server_url': callback_url,
          'result_url': return_url,
          'sender_first_name': values['billing_partner_name'] or '',
          'sender_city': values['billing_partner_city'] or '',
          'sender_address': values['billing_partner_address'] or '',
          'sender_postal_code': values['billing_partner_zip'] or '',
        }

        # Dump request data to json and encode it to base64
        data = base64.b64encode(json.dumps(request))

        # Make signature for current transaction
        signature = make_signature(
            self.liqpay_private_key, data, self.liqpay_private_key)

        values.update({
            'liqpay_data': data,
            'liqpay_signature': signature,
        })
        return values

    def liqpay_get_form_action_url(self):
        """
        :return: LiqPay checkout API method route
        """
        return self.liqpay_client_side

    @api.multi
    def show_liqpay_journal(self):
        """
        :return: Window action to open liqpay_journal view
        """
        tree_view_id = self.env.ref(
            'liqpay_acquirer.liqpay_journal_tree_view').id
        form_view_id = self.env.ref(
            'liqpay_acquirer.liqpay_journal_form_view').id

        return {
            'name': 'LiqPay journal',
            'view_type': 'form',
            'view_mode': 'tree, form',
            'views': [(tree_view_id, 'tree'), (form_view_id, 'form')],
            'res_model': 'liqpay.journal',
            'type': 'ir.actions.act_window',
            'context': self.env.context,
        }


"""Backend supported: tensorflow.compat.v1, tensorflow, pytorch, paddle"""
import os

os.environ["DDEBACKEND"] = "pytorch"
import numpy as np

import deepxde as dde

# For plotting
import matplotlib.pyplot as plt

x_lower = -5
x_upper = 5
t_lower = 0
t_upper = np.pi / 2
nx = 256
nt = 201
# Creation of the 2D domain (for plotting and input)
x = np.linspace(x_lower, x_upper, nx)
t = np.linspace(t_lower, t_upper, nt)
X, T = np.meshgrid(x, t)

# The whole domain flattened
X_star = np.hstack((X.flatten()[:, None], T.flatten()[:, None]))

# Space and time domains/geometry (for the deepxde model)
space_domain = dde.geometry.Interval(x_lower, x_upper)  # 先定义空间
time_domain = dde.geometry.TimeDomain(t_lower, t_upper)  # 再定义时间
geomtime = dde.geometry.GeometryXTime(space_domain, time_domain)  # 结合一下，变成时空区域

# The "physics-informed" part of the loss
def pde(x, y):  # 这里x其实是x和t，y其实是u和v
    """
    INPUTS:
        x: x[:,0] is x-coordinate
           x[:,1] is t-coordinate
        y: Network output, in this case:
            y[:,0] is u(x,t) the real part
            y[:,1] is v(x,t) the imaginary part
    OUTPUT:
        The pde in standard form i.e. something that must be zero
    """

    u = y[:, 0:1]
    v = y[:, 1:2]

    # In 'jacobian', i is the output component and j is the input component
    u_t = dde.grad.jacobian(u, x, i=0, j=1)  # 一阶导用jacobian，二阶导用hessian
    v_t = dde.grad.jacobian(v, x, i=0, j=1)

    u_x = dde.grad.jacobian(u, x, i=0, j=0)
    v_x = dde.grad.jacobian(v, x, i=0, j=0)

    u_xx = dde.grad.jacobian(u_x, x, i=0, j=0)
    v_xx = dde.grad.jacobian(v_x, x, i=0, j=0)

    f_u = u_t + 0.5 * v_xx + (u**2 + v**2) * v
    f_v = v_t - 0.5 * u_xx - (u**2 + v**2) * u

    return [f_u, f_v]

# Boundary and Initial conditions

# Periodic Boundary conditions
bc_u_0 = dde.icbc.PeriodicBC(
    geomtime, 0, lambda _, on_boundary: on_boundary, derivative_order=0, component=0
)
bc_u_1 = dde.icbc.PeriodicBC(
    geomtime, 0, lambda _, on_boundary: on_boundary, derivative_order=1, component=0
)
bc_v_0 = dde.icbc.PeriodicBC(
    geomtime, 0, lambda _, on_boundary: on_boundary, derivative_order=0, component=1
)
bc_v_1 = dde.icbc.PeriodicBC(
    geomtime, 0, lambda _, on_boundary: on_boundary, derivative_order=1, component=1
)

# x=x[:, 0:1]
# t=x[:, 1:2]
# Initial conditions
def init_cond_u(x):
    "2 sech(x)"
    return 2 / np.cosh(x[:, 0:1])

def init_cond_v(x):
    return 0

ic_u = dde.icbc.IC(
    geomtime, init_cond_u, lambda _, on_initial: on_initial, component=0
)  # 所有初始条件上的点都应用初始条件
ic_v = dde.icbc.IC(
    geomtime, init_cond_v, lambda _, on_initial: on_initial, component=1
)  # 所有初始条件上的点都应用初始条件
# 初始条件满足init_cond_u或init_cond_v函数
data = dde.data.TimePDE(
    geomtime,
    pde,
    [bc_u_0, bc_u_1, bc_v_0, bc_v_1, ic_u, ic_v],
    num_domain=10000,
    num_boundary=20,
    num_initial=200,
    train_distribution="pseudo",
)  # 在内部取10000个点，在边界取20个点，在初始取200个点

# Network architecture
net = dde.nn.FNN([2] + [64] * 4 + [2], "tanh", "Glorot normal")

model = dde.Model(data, net)
# To employ a GPU accelerated system is highly encouraged.

model.compile("adam", lr=0.001, loss="MSE")
losshistory, train_state = model.train(iterations=8000, display_every=100)

dde.optimizers.config.set_LBFGS_options(
    maxcor=50,
    ftol=1.0 * np.finfo(float).eps,
    gtol=1e-08,
    maxiter=2000,
    maxfun=None,
    maxls=50,
)
model.compile("L-BFGS")
model.train(display_every=100)

# Make prediction
prediction = model.predict(X_star, operator=None)

u = prediction[:, 0].reshape(nt, nx)
v = prediction[:, 1].reshape(nt, nx)

h = np.sqrt(u**2 + v**2)

# Plot predictions
fig, ax = plt.subplots(3)

ax[0].set_title("Results")
ax[0].set_ylabel("Real part")
ax[0].imshow(
    u.T,
    interpolation="nearest",
    cmap="jet",
    extent=[t_lower, t_upper, x_lower, x_upper],
    origin="lower",
    aspect="auto",
)
ax[1].set_ylabel("Imaginary part")
ax[1].imshow(
    v.T,
    interpolation="nearest",
    cmap="jet",
    extent=[t_lower, t_upper, x_lower, x_upper],
    origin="lower",
    aspect="auto",
)
ax[2].set_ylabel("Amplitude")
ax[2].imshow(
    h.T,
    interpolation="nearest",
    cmap="jet",
    extent=[t_lower, t_upper, x_lower, x_upper],
    origin="lower",
    aspect="auto",
)

fig5 = plt.figure("预测演化图", dpi=130, facecolor=None, edgecolor=None)
ax = fig5.add_subplot(projection="3d")
surf = ax.plot_surface(
    X,
    T,
    h,
    rstride=3,  # 指定行的跨度
    cstride=3,  # 指定列的跨度
    cmap="coolwarm",  # 设置颜色映射（这里是绿化的意思）
    linewidth=0,
    antialiased=False,
)  # 抗锯齿
# ax.grid(False)#关闭背景的网格线
ax.set_xlabel("$x$")
ax.set_ylabel("$t$")
ax.set_zlabel("$|h(x,t)|$")

dde.saveplot(losshistory, train_state, issave=True, isplot=True)
# model.save(save_path = "./ddexuedinge_model/model")

plt.show()

src/PINN/标准非线性薛定谔方程/deepxde-非线性薛定谔-呼吸子.py


import logging
import time
from datetime import timedelta

import numpy as np
from tqdm import tqdm

import src.cfg as cfg
import src.data as data
import src.models as models
import src.processing as processing
import src.filters as fltr

"""
parameters = dict(years_train=list(range(2010, 2014)),
                  years_test=[2014, 2015],
                  X_vars=['ice_conc', 'icethic_cea', 'tair', 'vosaline', 'radlw'],
                  y_var='thick_cr2smos',
                  bounds=[0, 400, 0, 400],
                  step=[20, 20]
                  )
"""
parameters = dict(years_train=list(range(2010, 2012)),
                  years_test=[2014],
                  X_vars=['icethic_cea', 'vosaline', 'radlw'],
                  y_var='thick_cr2smos',
                  bounds=[0, 400, 0, 400],
                  step=[20, 20]
                  )

reg_params = dict(model='lasso',
                  dx=5,
                  dy=5,
                  dt=5
                  )
filters = dict(partial_pca=5)

logging.basicConfig(format='%(asctime)s - %(message)s',
                    level=logging.INFO)
logging.getLogger('suds').setLevel(logging.INFO)  # set INFO level for all modules

logging.info('Loading test and train data...')
y_arr_train, X_arr_train = data.load_features(parameters['y_var'],
                                              parameters['X_vars'],
                                              parameters['years_train'])

y_arr_test, X_arr_test = data.load_features(parameters['y_var'],
                                            parameters['X_vars'],
                                            parameters['years_test'])
mask = np.load(cfg.mask_path, allow_pickle=True)
logging.info('Data is loaded')

bounds = parameters['bounds']
step = parameters['step']
indices = processing.gen_indices(bounds=bounds, step=step, mask=mask)
start = time.time()
logging.info('{} points'.format(len(indices)))
logging.info('Starting iterating')

ft = fltr.FeatureTable(dx=reg_params['dx'],
                       dy=reg_params['dy'],
                       dt=reg_params['dt'])

res = []
for idx, point in tqdm(enumerate(indices), total=len(indices)):

    y_train = y_arr_train[:, point[0], point[1]]
    y_test = y_arr_test[:, point[0], point[1]]
    X_train = ft.gen_matrix(data=X_arr_train, x=point[0], y=point[1], filters=filters)
    X_test = ft.gen_matrix(data=X_arr_test, x=point[0], y=point[1], filters=filters)
    if idx == 0:
        lstm = models.MyLSTM()
        lstm.fit(X_train, y_train)
    res.append(lstm.predict(X_test))

template = np.empty_like(y_arr_test)
template[:] = np.nan
out = processing.restore_array(template=template, array_in=res, indices=indices)

for idx, val in enumerate(indices):
    (i, j) = indices[idx]
elapsed = (time.time() - start)

logging.info('Processed {} points in {} ({} points/sec)'.format(len(indices),
                                                                str(timedelta(seconds=elapsed)),
                                                                round(len(indices) / elapsed), 5))


from http.server import BaseHTTPRequestHandler
import json
import debugserver

def capitalize(string, lower_rest=False):
  return string[:1].upper() + (string[1:].lower() if lower_rest else string[1:])

class handler(BaseHTTPRequestHandler):

    def do_GET(self):
      path = self.path
      print('path is ', path)

      self.send_response(200)
      self.send_header("Content-type", "application/json")
      self.end_headers()

      response = {"output": capitalize('diabolical')}
      self.wfile.write(json.dumps(response).encode("utf-8"))

      return

if __name__ == '__main__':
    debugserver.serve(handler)


from typing import Dict
from tqdm import tqdm

from towhee.utils.log import engine_log
from towhee.runtime import ops, AcceleratorConf
from towhee.operator import NNOperator
from towhee.serve.triton import constant
from towhee.serve.triton.model_to_triton import ModelToTriton
from towhee.serve.triton.pipe_to_triton import PipeToTriton

class Builder:
    """
    Build triton models from towhee pipeline.
    """

    def __init__(self, dag_repr: 'DAGRepr', model_root: str, conf: Dict):
        self.dag_repr = dag_repr
        self._server_conf = conf
        self._model_root = model_root

    @staticmethod
    def _load_op(op_name: str, init_args: tuple, init_kws: Dict) -> 'Operator':
        """
        load operator
        """
        name = op_name.split('/')
        if len(name) == 2:
            hub_id, name = name[0], name[1]
        else:
            hub_id, name = 'towhee', name[0]
        try:
            hub = getattr(ops, hub_id)
            init_args = () if init_args is None else init_args
            init_kws = {} if init_kws is None else init_kws
            return getattr(hub, name)(*init_args, **init_kws).get_op()
        except Exception as e:  # pylint: disable=broad-except
            engine_log.error('Load operator: %s by init args: [%s] and kws: [%s] failed, error: %s', op_name, init_args, init_kws, e)
            return None

    def _model_convert(self, node_repr: 'NodeRepr'):
        op_name = node_repr.op_info.operator
        op_init_args = node_repr.op_info.init_args
        op_init_kws = node_repr.op_info.init_kws
        op = self._load_op(op_name, op_init_args, op_init_kws)
        if op is None:
            return False

        if isinstance(op, NNOperator):
            if not hasattr(op, 'supported_formats'):
                return True
            model_name = node_repr.name.replace('/', '.')
            converter = ModelToTriton(self._model_root, op, model_name, node_repr.config, self._server_conf)
            status = converter.to_triton()
            if status == -1:
                return False
            elif status == 0:
                return True
            inputs, outputs = converter.get_model_in_out()
            acc_conf = {'model_name': model_name, 'inputs': inputs, 'outputs': outputs}
            node_repr.config.acc_info = AcceleratorConf(type='triton', params=acc_conf)
        return True

    def build(self) -> bool:
        progress_bar = tqdm(total=len(self.dag_repr.nodes)+1, desc='Building model and pipeline')
        for node_id, node in self.dag_repr.nodes.items():
            if node_id in ['_input', '_output'] or node.op_info.type != 'hub':
                progress_bar.update(1)
                continue
            if not self._model_convert(node):
                return False
            progress_bar.update(1)
        status = PipeToTriton(self.dag_repr, self._model_root, constant.PIPELINE_NAME, self._server_conf).process()
        progress_bar.update(1)
        return status

# pylint: disable=import-outside-toplevel
def main():
    from towhee.utils.thirdparty.dill_util import dill as pickle
    import sys
    import json
    if len(sys.argv) != 4:
        engine_log.error('The args is invalid, it must has three parameters in [dag_file_path, mode_root_dir, config_file_path]')
        sys.exit(-1)

    dag_file, model_root, config_file = sys.argv[1], sys.argv[2], sys.argv[3]
    with open(dag_file, 'rb') as f_dag, open(config_file, 'rb') as f_conf:
        dag_repr = pickle.load(f_dag)
        config = json.load(f_conf)
        if not Builder(dag_repr, model_root, config).build():
            sys.exit(-1)
    sys.exit(0)

if __name__ == '__main__':
    main()


import os
import glob
import re
from datetime import datetime, timedelta, time

import fitz
from openpyxl import Workbook

from dataclasses import dataclass

# ------ CHANGE ME ---------
folder_path = "C:\\Users\\majona\\GitHub\\iko-tools\\Python\\antwerpTimeConverter\\input"
save_path = f'C:\\Users\\majona\\GitHub\\iko-tools\\Python\\antwerpTimeConverter\\{datetime.now().strftime("%d-%m-%Y_%H-%M-%S")}.xlsx'
year = '2023'

@dataclass
class person:
    include: bool = False
    laborcode: str = "blank"

# add more Nummer to personid codes as necessary
people = {
    "21592": person(True, "BEANJBRU"),
    "21616": person(True, "BEANDCAR"),
    "21612": person(True, "BEANDHOS"),
    "21545": person(True, "BEANPJOR"),
    "21263": person(True, "BEANBMAE"),
    "21368": person(True, "BEANPMAE"),
    "21457": person(True, "BEANAMAR"),
    "21547": person(True, "BEANNPAT"),
    "20746": person(True, "BEANDROO"),
    "21328": person(True, "BEANPVHA"),
    "20889": person(True, "BEANBVRI"),
    "21193": person(True, "BEANBWIN"),
}

converted_wb = Workbook()
converted_ws = converted_wb.create_sheet("Sheet1", 0)
converted_ws.append(
    [
        "Empl#",
        "Employee Name",
        "Day",
        "Time In",
        "Time Out",
        "Hours",
        "LL1",
        "LL2",
        "LL3",
        "LL4",
        "LL5",
        "LL6",
        "LL7",
        "Reg",
        "O/T",
    ]
)

date_regex = r"^\d{2}/\d{2}/\d{4}"
time_regex = r"\b\d{1,2}:\d{2}\b"

for filepath in glob.glob(os.path.join(folder_path, "*.pdf")):
    doc = fitz.open(filepath)
    print(f'Reading: {filepath}')
    employee = person()
    for page in doc:
        # the blocks option seems to give best result where lines are kept together
        text = page.get_text('blocks')
        # print(text)
        for row in text:
            # see if employee is defined if the row is a employee definition
            if (row[4].find('Nummer') > 0):
                person_num = row[4][row[4].find('Nummer') + 7:row[4].find('Badge')]
                # print(person_num)
                employee = people.get(person_num.strip())
                if (not(employee.include)):
                    print(f'Not Found: {person_num.strip()}')
                continue
            if (employee.include):
                match = re.findall(date_regex, row[4])
                if (match):
                    # print(match)
                    time_matches = re.findall(time_regex, row[4])
                    hours = row[4][row[4].find(time_matches[1])+len(time_matches[1]):].split('\n')
                    # print(hours)
                    start_time = datetime.strptime(f'{match[0]} {time_matches[0]}', "%d/%m/%Y %H:%M")
                    end_time = start_time + timedelta(hours=float(hours[1].replace(',','.')))
                    converted_ws.append(
                        [
                            person_num.strip(),
                            employee.laborcode,
                            start_time.strftime('%A').upper(),
                            start_time.strftime('%Y-%m-%d %H:%M'),
                            end_time.strftime('%Y-%m-%d %H:%M'),
                            hours[1].replace(',','.'),
                            None,
                            None,
                            None,
                            None,
                            None,
                            None,
                            None,
                            hours[1].replace(',','.'),
                            0,
                        ]
                    )
                else:
                    print(f'Skipping row: {row[4]}')
                    continue

converted_wb.save(save_path)