import asyncio
import random

import discord
import yt_dlp
from discord import FFmpegPCMAudio
from discord.ext import commands, bridge
from discord.utils import get

from ...log import logs

from ...fileio import botconfig
from .lib.main import musicss

# seting = open('config/botsetting.yaml')
# # # a = open('botsetting.yaml')
# botconfig = yaml.load(seting, Loader=yaml.FullLoader)

music = musicss()

autoleave = {}
vctimmer = {}
# coding:utf-8

_loop = asyncio.get_event_loop()

timeouttime = botconfig['bot_setting']['disconnecttime']
adminacc = list(botconfig['bot_setting']['botadminacc'])
hexcolour = int(botconfig['bot_setting']['colour'],16)

class Music(commands.Cog):
    def __init__(self, client):
        self.client = client

    @commands.Cog.listener()
    async def on_ready(self):
        logs.info('music module online')
        for guild in self.client.guilds:
            guildid = str(guild.id)
            music.isinfiteloop[guildid] = False
            autoleave[guild.id] = False

    @commands.Cog.listener()
    async def on_voice_state_update(self, member, before, after):
        # if after.channel == None:
        if after.channel == None and member.id == self.client.user.id: #replce this when torcher test fail
            voice = get(self.client.voice_clients, channel__guild__id = before.channel.guild.id)
            logs.debug('clearing playlist requirement meet')
            music.clearlist(guildid=str(before.channel.guild.id))
            if music.isinfiteloop.get(str(before.channel.guild.id)) == True:
                music.isinfiteloop[str(before.channel.guild.id)] = False
            return

        if member.id == self.client.user.id:
            return
        if before.channel != None:
            voice = get(self.client.voice_clients, channel__guild__id = before.channel.guild.id)
            if voice == None:
                return
            if voice.channel.id != before.channel.id:
                return
            if len(voice.channel.members) <= 1:
                if autoleave.get(before.channel.guild.id) == False:
                    vctimmer[before.channel.guild.id] = 0

                    while True:
                        logs.debug(f"time {str(vctimmer[before.channel.guild.id])}")

                        await asyncio.sleep(1)

                        vctimmer[before.channel.guild.id] += 1

                        if len(voice.channel.members) >= 2:
                            vctimmer[before.channel.guild.id] = 0
                            return
                        if vctimmer[before.channel.guild.id] >= int(timeouttime):
                            await voice.disconnect()
                            vctimmer[before.channel.guild.id] = 0
                            music.clearlist(guildid=str(before.channel.guild.id))
                            if music.isinfiteloop.get(str(before.channel.guild.id)) == True:
                                music.isinfiteloop[str(before.channel.guild.id)] = False
                            return

    @bridge.bridge_command(aliases=['come', 'cum'])
    async def join(self, ctx):
        await self.njoin(ctx)

    # pycord framework bug workaround
    async def njoin(self,ctx):
        channels = ctx.author.voice.channel
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice and voice.is_connected():
            await voice.move_to(channels)
        else:
            voice = await channels.connect()

    @bridge.bridge_command(aliases=['fuckoff'])
    async def leave(self, ctx):
        guildid = str(ctx.guild.id)
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice.is_playing():
            if ctx.invoked_with == 'fuckoff':
                await ctx.send(random.choice(botconfig['bot_reply']['leavef']))
            else:
                await ctx.send(random.choice(botconfig['bot_reply']['leave2']))
        else:
            if ctx.invoked_with == 'fuckoff':
                await ctx.send(random.choice(botconfig['bot_reply']['leavef']))
            else:
                await ctx.send(random.choice(botconfig['bot_reply']['leave']))
        await ctx.guild.voice_client.disconnect()
        music.clearlist(guildid=guildid)
        if music.isinfiteloop.get(guildid) == True:
            music.isinfiteloop[guildid] = False

    @bridge.bridge_command(aliases=['p'])
    async def play(self, ctx, *, url= None):
        await self.njoin(ctx)
        guildid = str(ctx.guild.id)
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if url == None:
            await ctx.send('are we suppose to be playing something here?')
        else:
            a = music.add_song(guildid=guildid,url=url)
            if a != None:
                await ctx.send(a)
            else:
                if not voice.is_playing():
                    self.player(guildid=guildid,ctx=ctx)
                else:
                    await ctx.send('this song had been added to the queue')

    @bridge.bridge_command(aliases=['pnext'])
    async def playnext(self, ctx, *, url = None):
        await self.njoin(ctx)
        guildid = str(ctx.guild.id)
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if url == None:
            await ctx.send('are we suppose to be playing something here?')
        else:
            a = music.insert_song(guildid=guildid, url=url)
            if a != None:
                await ctx.send(a)
            else:
                if not voice.is_playing():
                    self.player(guildid=guildid,ctx=ctx)
                else:
                    await ctx.send('Ok this song will be play next')

    @bridge.bridge_command(aliases=['pnow'])
    async def playnow(self, ctx, *, url= None):
        await self.njoin(ctx)
        guildid = str(ctx.guild.id)
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if url == None:
            await ctx.send('are we suppose to be playing something here?')
        else:
            a = music.insert_song(guildid=guildid,url=url)
            if a != None :
                await ctx.send(a)
            else:
                if not voice.is_playing():
                    self.player(guildid=guildid,ctx=ctx)
                else:
                    voice.stop()
                    voice.is_playing()
                    self.player(guildid,ctx, ignore=True)

    @bridge.bridge_command()
    async def ytmusic(self, ctx, * ,url = None):
        await self.njoin(ctx)
        guildid = str(ctx.guild.id)
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if url == None:
            await ctx.send('are we suppose to be playing something here?')
        else:
            a = music.add_song(guildid=guildid,url=url,platform='ytmusic')
            if a != None:
                await ctx.send(a)
            else:
                if not voice.is_playing():
                    self.player(guildid=guildid,ctx=ctx)
                else:
                    await ctx.send('Ok this song had been added to the queue')

    @bridge.bridge_command(aliases=['current','song','currentsonginfo'])
    async def info(self, ctx, index=0):
        guildid = str(ctx.guild.id)
        song = music.get_song_data(index=index,guildid=guildid)
        if song == None:
            await ctx.send('no song had been played yet')
        elif index == 0:
            await ctx.send(f'''song in queue number {index}
the current song playing is: {song['videoname']}
...and it has been viewed {song['view']} times!
also here's the link! --> {song["url"]}
which have {song["like"]} like
... and a {song["dislike"]}''')
        else:
            await ctx.send(f'''song in queue number {index}
{song['videoname']}
...and it has been viewed {song['view']} times!
also here's the link! --> {song["url"]}
which have {song["like"]} like
... and a {song["dislike"]}''')

    @bridge.bridge_command()
    async def beforeinfo(self, ctx):
        guildid = str(ctx.guild.id)
        song = music.beforeinfo(guildid=guildid)
        await ctx.send(f'''the song that just played is {song['videoname']}
...and it has been viewed {song['view']} times!
also here's the link! --> {song["url"]}
which have {song["like"]} like
... and a {song["dislike"]}''')

    @bridge.bridge_command(aliases=['is24/7'])
    async def isafk(self, ctx):
        guildid = ctx.guild.id
        if autoleave.get(guildid) == True:
            await ctx.send('24/7 is enable')
        else:
            await ctx.send('24/7 is disable')

    @bridge.bridge_command(aliases=['24/7'])
    async def toggleafk(self, ctx):
        guildid = ctx.guild.id
        userid = ctx.author.id
        if userid in adminacc:
            if autoleave.get(guildid) == False:
                autoleave[guildid] = True
                await ctx.send('Ok I will be standby in this vc 24/7')
                return
            if autoleave.get(guildid) == True:
                autoleave[guildid] = False
                await ctx.send('Ok I will not afk here')
                return
        else:
            await ctx.send('you aint my dad fam')

    @bridge.bridge_command(aliases=['clear'])
    async def clearlist(self, ctx):
        music.clearlist(guildid=str(ctx.guild.id))
        await ctx.send('gotchu, list cleared!')

    @bridge.bridge_command()
    async def queue(self, ctx):
        msg, a = music.list_queue(guildid=str(ctx.guild.id))
        embeds = discord.Embed(title='Song in queue', description=msg ,type='link', color=hexcolour)
        if a == True:
            embeds.add_field(name='and more playing', value='\u200b')
        elif a == False:
            pass
        else:
            await ctx.send('No song in queue')
            return
        await ctx.send(embed=embeds)

    @bridge.bridge_command()
    async def shuffle(self, ctx):
        music.shuffle(guildid=str(ctx.guild.id))
        await ctx.send(random.choice(botconfig['bot_reply']['shuffle']))

    @bridge.bridge_command()
    async def lremove(self, ctx):
        music.removelast(guildid=str(ctx.guild.id))
        await ctx.send('Ok, removed last song in queue')

    @bridge.bridge_command(pass_context=True)
    async def remove(self, ctx, songnum=None):
        if songnum == None:
            await ctx.send('give me the song number to be remove from queue')
            await self.queue(ctx)
        else:
            songnuma = int(songnum)
            a, b = music.remove_song(guildid=str(ctx.guild.id),index=songnuma)
            embeds = discord.Embed(title=f'Ok removed song number {b}', description=a ,type='link', color=hexcolour)
            await ctx.send(embed=embeds)

    @bridge.bridge_command(aliases=['sauce'])
    async def warp(self, ctx):
        await ctx.send(music.sauce(guildid=str(ctx.guild.id)))

    @bridge.bridge_command(aliases=['next','kingcrimson!','foward'])
    async def skip(self, ctx):
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice.is_playing():
            voice.stop()
            await ctx.send(random.choice(botconfig['bot_reply']['skip']))

    @bridge.bridge_command()
    async def resume(self, ctx):
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if not voice.is_playing():
            voice.resume()
            await ctx.send(random.choice(botconfig['bot_reply']['resume']))

    @bridge.bridge_command()
    async def pause(self, ctx):
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice.is_playing():
            voice.pause()
            await ctx.send(random.choice(botconfig['bot_reply']['pause']))

    @bridge.bridge_command(aliases=['songcount', 'total'])
    async def count(self, ctx):
        guildid = str(ctx.guild.id)
        await ctx.send("counting...")
        await ctx.send(f" {len(music.queue[guildid])} songs are in this queue")

    @bridge.bridge_command()
    async def seek(self, ctx, timestamp=None):
        voice = get(self.client.voice_clients, guild=ctx.guild)
        guildid = str(ctx.guild.id)
        if timestamp == None:
            await ctx.send('give me the time to seek the play head too')
        else:
            music.queue.setdefault(guildid, []).insert(1,music.currentsong[guildid])
            voice.stop()
            voice.is_playing()
            logs.info(f'seeking play head to {timestamp}')
            self.player(guildid,ctx,timestamp, ignore=True)
            await ctx.send(f'skiped to {timestamp}')

    @bridge.bridge_command(aliases=['bitethedust!','backward','previous'])
    async def again(self, ctx):
        guildid = str(ctx.guild.id)
        music.queue.setdefault(guildid, []).insert(1,music.history[guildid][0])
        await ctx.send('Ok that song will be play again next')

    @bridge.bridge_command()
    async def addbefore (self, ctx):
        guildid = str(ctx.guild.id)
        music.queue.setdefault(guildid, []).append(music.history[guildid][0])
        await ctx.send("The previous song has now added to the queue!")

    @bridge.bridge_command(aliases=['looplist'])
    async def loopplaylist(self, ctx, a=None):
        if a == None:
            await ctx.send('give me ammount of time to loop the playlist')
        elif int(a) <= 1000:
            guildid = str(ctx.guild.id)
            adda = music.queue[guildid]
            for n in range(int(a)):
                music.queue.setdefault(guildid, []).extend(adda)
                logs.info(f"looped playlist {n} times")
            await ctx.send(f"Alright, the entire playlist will be looped {a} times!")
            del adda
        else:
            await ctx.send('Give me something say less that a 1000')

    @bridge.bridge_command()
    async def loop(self, ctx, a=None):
        guildid = str(ctx.guild.id)
        logs.debug('i have been run')
        if a == None:
            logs.debug('ok at lease ')
            logs.debug(music.isinfiteloop[guildid])
            if music.isinfiteloop.get(guildid) == True:
                music.isinfiteloop[guildid] = False
                await ctx.send('ok I had stopped the loop')
                return
            if music.isinfiteloop.get(guildid) == False:
                music.isinfiteloop[guildid] = True
                await ctx.send('ok looping this song infinitely')
                return

        elif int(a) <= 1000:
            for n in range(int(a)):
                music.queue.setdefault(guildid, []).append(music.currentsong[guildid])
                logs.info(f"looped song {n} times")
            await ctx.send(f"Alright, this song will be looped {a} times!")
        else:
            await ctx.send("Give me something say less than 1000")

    @bridge.bridge_command(aliases=['isloop'])
    async def isitloop(self, ctx):
        guildid = str(ctx.guild.id)
        if music.isinfiteloop.get(guildid) == True:
            await ctx.send('I am in an loop')
        if music.isinfiteloop.get(guildid) == False:
            await ctx.send('I am not in a loop')

    @bridge.bridge_command()
    async def playpooh(self, ctx):
        guildid = str(ctx.guild.id)
        channels = ctx.author.voice.channel
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice and voice.is_connected():
            await voice.move_to(channels)
        else:
            voice = await channels.connect()
        url = ['https://music.youtube.com/playlist?list=OLAK5uy_kIa_eK4TM_gMkf44jFK118aDSnxYSgVxI',
        'https://www.youtube.com/playlist?list=PLKu0PlxNFnZUjUzSxccTzHOgEYYGlSJk5']
        music.clearlist(guildid=guildid)
        respond = ['Playing father playlist','daddy favorite playlist music','Ok good pick I see you have a shit taste here']
        for a in url:
            music.add_song(guildid=guildid,url=a)
        music.shuffle(guildid=guildid)
        self.player(guildid=guildid,ctx=ctx)
        await ctx.send(random.choice(respond))

    @bridge.bridge_command()
    async def playjag(self, ctx):
        guildid = str(ctx.guild.id)
        channels = ctx.author.voice.channel
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice and voice.is_connected():
            await voice.move_to(channels)
        else:
            voice = await channels.connect()
        music.clearlist(guildid=guildid)
        respond = ['Playing jag playlist on spotify \n might take a while to start since i have to convert spotify link to yotube']
        music.add_song(guildid=guildid,url='https://open.spotify.com/playlist/37i9dQZF1EprefcXJEAqWX?si=1713c2c44b384d72')
        music.shuffle(guildid=guildid)
        self.player(guildid=guildid,ctx=ctx)
        await ctx.send(random.choice(respond))

    @bridge.bridge_command()
    async def playitchys(self, ctx):
        guildid = str(ctx.guild.id)
        channels = ctx.author.voice.channel
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice and voice.is_connected():
            await voice.move_to(channels)
        else:
            voice = await channels.connect()
        music.clearlist(guildid=guildid)
        respond = ['Playing father playlist','daddy favorite playlist music','Ok good pick I see you have a shit taste here']
        music.add_song(guildid=guildid,url='https://www.youtube.com/playlist?list=PLSJh9S2IPebGSSqkXACtbCJJcYc26Iy3i')
        music.shuffle(guildid=guildid)
        self.player(guildid=guildid,ctx=ctx)
        await ctx.send(random.choice(respond))

    @bridge.bridge_command()
    async def playitchy2019 (self,ctx):
        guildid = str(ctx.guild.id)
        channels = ctx.author.voice.channel
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice and voice.is_connected():
            await voice.move_to(channels)
        else:
            voice = await channels.connect()
        url = [ 'https://www.youtube.com/playlist?list=PLQJHbSBLRWJQS-q5yFzhxo3ibjFYREuvI',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJTPyj6wUe72-UdJEBEcQW2_',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJQfxi0ry3VnnioDvOCfODgF',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJRpoPK3MMtNy2JkxhbjRAE3',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJQZo3ab7BEZW4gDWyaSKmWn',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJR4AHkFx4sK8QKU5lWBiioU',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJRX8mSWWwtLgSVy5sf_2GnH']
        music.clearlist(guildid=guildid)
        respond = ["Playing itchy’s act 1!", "wow, a classic!", "itchy's first playlist huh?\ngotchu!"]
        for i in url:
            music.add_song(guildid=guildid,url=i)
        music.shuffle(guildid=guildid)
        self.player(guildid=guildid,ctx=ctx)
        await ctx.send(random.choice(respond))

    @bridge.bridge_command()
    async def playitchy2020 (self,ctx):
        guildid = str(ctx.guild.id)
        channels = ctx.author.voice.channel
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if voice and voice.is_connected():
            await voice.move_to(channels)
        else:
            voice = await channels.connect()
        url = ['https://www.youtube.com/playlist?list=PLQJHbSBLRWJSPZjTDPaIaLXpM7-JMI7RG',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJQuWq0QTB02dcemPwQlMUTJ',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJSV2Ocjftmp1ekoIXBFjXTs',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJT5mm_k0kfgzF0jEBaJOGAK',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJR75XSSvSSv7SlA6BY-ZZsd',
            'https://www.youtube.com/playlist?list=PLQJHbSBLRWJRyfU8N23zI59rq-FaGGQOW',
            'https://youtube.com/playlist?list=PLQJHbSBLRWJQgrteRNu9e6317iTUcSCUh']
        music.clearlist(guildid=guildid)
        respond = ["Playing itchy’s act 2!", "Ooo, my favorite!", "itchy's playlist huh?\ngotchu!"]
        for i in url:
            music.add_song(guildid=guildid,url=i)
        music.shuffle(guildid=guildid)
        self.player(guildid=guildid,ctx=ctx)
        await ctx.send(random.choice(respond))

    def player(self , guildid, ctx, timestamp='00:00',ignore=False):
        YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
        FFMPEG_OPTIONS = {
            'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5 ', 'options': f'-vn -ss {timestamp}'}
        voice = get(self.client.voice_clients, guild=ctx.guild)
        if not voice.is_playing() and ignore == False:
            guildid = str(ctx.guild.id)
            if music.queue[guildid]:
                a = music.queue[guildid][0]
                music.set_current_song(url=a,guildid=guildid)
                try:

                    with yt_dlp.YoutubeDL(YDL_OPTIONS) as ydl:
                        info = ydl.extract_info(a, download=False)

                    URL = info['url']
                    voice.play(FFmpegPCMAudio(source=URL, **FFMPEG_OPTIONS), after=lambda e: self.play_next(ctx))
                    voice.is_playing()
                    logs.debug('playing')
                except:
                    logs.info('video error')
                    asyncio.run_coroutine_threadsafe(self.sendthing(guildid=guildid, ctx=ctx,message='video error'), _loop)
            else:
                logs.info('no more music in playlist')
                asyncio.run_coroutine_threadsafe(self.sendthing(guildid=guildid, ctx=ctx,message='empty list'), _loop)
        else:
            logs.debug('seek or insert function in use')

    def play_next(self,ctx):
        guildid = str(ctx.guild.id)
        music.progess_song(guildid=guildid)
        voice = get(self.client.voice_clients, guild=ctx.guild)
        try:
            if not voice.is_playing():
                self.player(ctx=ctx,guildid=guildid)
        except AttributeError:
            pass

    async def sendthing(self, guildid, ctx, message:str):
        if message in 'video error':
            await ctx.send('This video is not accessable or age restriceted. Please check if the video is publicly accessable without account')
            asyncio.run_coroutine_threadsafe(self.play_next(ctx), _loop)
            return
        elif message in 'empty list':
            await ctx.send('No more music in the playlist')
            return
        elif message in 'disconnected':
            await ctx.send('Geez just ask me to leave nicely and i will do so ok')
            music.clearlist(guildid=guildid)
            if music.isinfiteloop.get(guildid) == True:
                music.isinfiteloop[guildid] = False
            return

def setup(client):
    client.add_cog(Music(client))


from multiprocessing import context
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import ProductReview,ProductRating
from django.conf import settings
from django.core.mail import send_mail
from django.template.loader import render_to_string

@receiver(post_save,sender=ProductReview)
def user_save(sender,instance,created , **kwargs):
    # if created:
        # send message
        try:
            print("insatance",type(instance))
            print("insatance",instance)
            value = float(instance.rating_star)
            prodcut_revie_count = ProductReview.objects.filter(product = instance.product)
            total_review = 0
            for each in prodcut_revie_count:
                total_review += each.rating_star
            count = prodcut_revie_count.count()
            print('total_review',total_review)
            print('****************',value)
            print('****************',prodcut_revie_count)

            try:

                product_rating_old = ProductRating.objects.get(product = instance.product)
                product_rating_old.rating_star = (total_review + value )/(count+1)
                product_rating_old.save()
                print('(((((((((((((((',product_rating_old.rating_star)

            except Exception as e:
                print('>>>>>>>',e)
                product_rating_new = ProductRating.objects.create(
                    product = instance.product,
                    )
                product_rating_new.rating_star = value
                product_rating_new.save()
                print('(((((((((((((((',product_rating_new.rating_star)
        except Exception as e:
            print('>>>>>>>',e)
            pass


#!/usr/bin/env python3

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

import logging

from cliff import command

from goal_tools import gerrit
from goal_tools import governance

LOG = logging.getLogger(__name__)

class QueryChanges(command.Command):
    "Query gerrit for a set of changes and build a review ID file."

    def get_parser(self, prog_name):
        parser = super().get_parser(prog_name)
        parser.add_argument(
            '--governance-project-list',
            default=governance.PROJECTS_LIST,
            help='location of governance project list',
        )
        parser.add_argument(
            '--include-unofficial',
            default=False,
            action='store_true',
            help='include projects not under governance in the output',
        )
        parser.add_argument(
            'query_string',
            help='gerrit query string',
        )
        parser.add_argument(
            'review_list',
            help='name output file to create',
        )
        return parser

    def take_action(self, parsed_args):
        team_data = governance.Governance(
            url=parsed_args.governance_project_list)

        review_ids = []

        cache = self.app._load_cache_file(preload=False)

        factory = gerrit.ReviewFactory(cache)

        review_source = factory.query(parsed_args.query_string)
        for review in review_source:
            team_name = team_data.get_repo_owner(review.project)
            if not parsed_args.include_unofficial and not team_name:
                LOG.debug(
                    'filtered out %s based on repo governance status',
                    review.project,
                )
                continue
            review_ids.append(review.id)

        with open(parsed_args.review_list, 'w', encoding='utf-8') as f:
            f.write('# QUERY: {}\n'.format(
                parsed_args.query_string.replace('\n', ' ')))
            for rid in sorted(review_ids):
                f.write('{}\n'.format(rid))


import requests
try:
    import ujson as json
except:
    import json
from typing import List, Union, Iterable, Sequence
try:
    import regex as re
except:
    import re
import datetime
import traceback

URL_REGEX = re.compile(r"^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$")
URL_WITH_PROTOCOL_REGEX = re.compile(r"https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#()?&//=]*)")

def send_rich_msg(data: dict, endpoint: str, auth: str, verbose: bool = True):
    r = requests.post(endpoint+"?format=full",
        data=json.dumps(data),
        headers = {
            'Authorization': auth,
            'Content-Type': 'application/json'
        }
    )
    try:
        r.raise_for_status()
    except:
        if verbose:
            traceback.print_exc()
            print("Response: " + r.text)
        else:
            r.raise_for_status()

def check_text(text: str):
    if isinstance(text, str) and not bool(text):
        raise ValueError("Any text cannot be an empty string. Use a space instead?")

def check_url(url: str, mode: str = "any"):
    return isinstance(url, str) and (mode == "with-prefix" or re.match(URL_REGEX, url) != None) and (mode == "any" or re.match(URL_WITH_PROTOCOL_REGEX, url) != None)

class Style:
    def __init__(self, color: str = None, bold: bool = False, italic: bool = False):
        self.color = color # Hex color with '#' symbol
        self.bold = bold
        self.italic = italic

    def to_dict(self):
        ret = {'bold': self.bold, 'italic': self.italic}
        if self.color != None:
            ret['color'] = self.color

        return ret

class exceptions:

    class MissingComponentError(BaseException):
        """
        Raised when an optional argument is provided that depends on another optional argument that is not provided.
        """
        pass

class bodyElements:

    class Text:
        # In Zoom's docs, this type is called "message"
        def __init__(self, text: str, link: str = None, style: Style = None, editable: bool = False):
            self.text = text
            self.style = style
            self.editable = editable
            self.link = link

            self.validate()

        def validate(self):
            check_text(self.text)

            if isinstance(self.link, str):
                if (not self.link.startswith("http://")) and (not self.link.startswith("https://")):
                    self.link = "http://" + self.link
                if not check_url(self.link, mode="with-prefix"):
                    raise ValueError("Text link must be a valid URL with protocol; was given \"{}\"".format(self.link))

            elif self.link != None:
                raise TypeError("Text link must be a string")

            if self.style != None and not isinstance(self.style, Style):
                raise TypeError("Text style must be a Style object")

            if not isinstance(self.editable, bool):
                raise TypeError("Text editability must be a boolean")

        def to_dict(self):
            self.validate()

            ret = {'type': 'message', 'text': self.text, 'editable': self.editable}
            if self.style != None:
                ret['style'] = self.style.to_dict()

            if self.link != None:
                ret['link'] = self.link

            return ret

    class Attachment:
        def __init__(self, resource_url: str, img_url: str, title: str, titleStyle: Style = None, description: str = None, descriptionStyle: str = None, ext: str = None, size: int = None):
            self.resource_url = resource_url
            self.img_url = img_url
            self.title = title
            self.titleStyle = titleStyle
            self.description = description
            self.descriptionStyle = descriptionStyle
            self.ext = ext
            if isinstance(self.ext, str):
                self.ext = self.ext.lower()
            self.size = size # In bytes

            self.validate()

        def validate(self):

            if (not check_url(self.resource_url)) or (not check_url(self.img_url)):
                raise ValueError("resource_url and img_url must be valid URLs")

            if self.ext != None and not isinstance(self.ext, str):
                raise TypeError("Attachment extension must be a string")

            VALID_EXTENSIONS = ['pdf', 'txt', 'doc', 'xlsx', 'zip', 'jpeg', 'png']
            if self.ext != None and (self.ext not in VALID_EXTENSIONS):
                raise ValueError("Attachment extension must be one of the following strings: " + str(VALID_EXTENSIONS))

            if self.descriptionStyle != None and self.description == None:
                raise exceptions.MissingComponentError("Style for a description was given, but no description was provided")

            if not isinstance(self.title, str):
                raise TypeError("Attachment title must be a string")

            if self.description != None and not isinstance(self.description, str):
                raise TypeError("Attachment description must be a string")

            if self.titleStyle != None and not isinstance(self.titleStyle, Style):
                raise TypeError("Attachment title style must be a Style object")

            check_text(self.title)
            if isinstance(self.description, str):
                check_text(self.description)

            if self.descriptionStyle != None and not isinstance(self.descriptionStyle, Style):
                raise TypeError("Attachment description style must be a Style object")

            if self.size != None and not isinstance(self.size, int):
                raise TypeError("Attachment size must be an integer")

        def to_dict(self):
            self.validate()

            ret = {'type': 'attachments', 'resource_url': self.resource_url, 'img_url': self.img_url, 'information': {'title': {'text': self.title} } }

            if self.titleStyle != None:
                ret['information']['title']['style'] = self.titleStyle.to_dict()

            if self.description != None:
                ret['information']['description'] = {}
                ret['information']['description']['text'] = self.description

                if self.descriptionStyle != None:
                    ret['information']['description']['style'] = self.descriptionStyle.to_dict()

            if self.ext != None:
                ret['information']['ext'] = self.ext

            if self.size != None:
                ret['information']['size'] = self.size

            return ret

    class Section:
        def __init__(self, elements: Sequence['bodyElements'], sidebar_color: str = None, footer: 'bodyElements.Section.Footer' = None):
            self.elements = elements
            if any(isinstance(x, type(self)) for x in self.elements):
                raise ValueError("Section elements cannot be sections")
            self.sidebar_color = sidebar_color
            self.footer = footer

            self.validate()

        class Footer:
            def __init__(self, text: str = None, icon_url: str = None, unix_timestamp: Union[datetime.datetime, int, float] = None):
                self.text = text
                self.icon_url = icon_url
                self.unix_timestamp = unix_timestamp

                self.validate()

            def validate(self):
                check_text(self.text)
                if self.icon_url != None and not check_url(self.icon_url):
                    raise ValueError("Section footer icon url must be a valid URL")

                if self.unix_timestamp != None and (not isinstance(self.unix_timestamp, int)) and (not isinstance(self.unix_timestamp, float)):
                    if isinstance(self.unix_timestamp, datetime.datetime):
                        pass
                    else:
                        try:
                            test_timestamp = int(float(self.unix_timestamp))
                        except:
                            raise TypeError("Section footer timestamp must be a datetime.datetime or an integer (date in milliseconds)")

            def to_dict(self):
                self.validate()

                ret = {}

                if self.text != None:
                    ret['footer'] = self.text

                if self.icon_url != None:
                    ret['footer_icon'] = self.icon_url

                if self.unix_timestamp != None:
                    if not isinstance(self.unix_timestamp, datetime.datetime):
                        ret['ts'] = int(float(self.unix_timestamp))
                    else:
                        ret['ts'] = int(datetime.datetime.timestamp(self.unix_timestamp) * 1000)

                return ret

        def validate(self):
            if (not isinstance(self.elements, Sequence)) or isinstance(self.elements, str):
                raise TypeError("Section elements must be a sequence of bodyElements subclasses")

            else:
                if len(self.elements) < 1:
                    raise ValueError("Sections require at least one element")

            VALID_SECTION_ELEMENTS = [bodyElements.Text, bodyElements.Attachment, bodyElements.Fields]
            if any(x not in VALID_SECTION_ELEMENTS for x in VALID_SECTION_ELEMENTS):
                raise TypeError("Section elements must be one of the following: " + ', '.join([str(z) for z in VALID_SECTION_ELEMENTS]))

            if self.footer != None:
                if not isinstance(self.footer, bodyElements.Section.Footer):
                    raise TypeError("Section footer must be an instance of bodyElements.Section.Footer")

                self.footer.validate()

        def to_dict(self):
            self.validate()

            ret = {'type': 'section', 'sections': []}

            if self.sidebar_color != None:
                ret['sidebar_color'] = self.sidebar_color

            if self.footer != None:
                ret.update(self.footer.to_dict())

            for x in self.elements:
                ret['sections'].append(x.to_dict())

            return ret

    class Fields:
        def __init__(self, items: Sequence['bodyElements.Fields.Field'] = []):
            self.items = items

        class Field:
            def __init__(self, key, value, short: bool = None, editable: bool = False, style: Style = None):
                self.key = key
                self.value = value
                self.short = short # Unsure what this does, but it is in Zoom's documentation
                self.editable = editable
                self.style = style

            def to_dict(self):
                ret = {'key': self.key, 'value': self.value, 'editable': self.editable}

                if self.short != None:
                    ret['short'] = self.short

                if self.style != None:
                    ret['style'] = self.style.to_dict()

                return ret

        def to_dict(self):
            ret = {'type': 'fields', 'items': []}
            for x in self.items:
                ret['items'].append(x.to_dict())

            return ret

class messageElements:

    class SubHead:
        def __init__(self, text: str, style: Style = None):
            self.text = text
            self.style = style

        def to_dict(self):
            ret = {'text': self.text}
            if self.style != None:
                ret['style'] = self.style.to_dict()

            return ret

    class Head:
        def __init__(self, text: str, style: Style = None, sub_head: 'messageElements.SubHead' = None):
            self.text = text
            self.style = style
            self.sub_head = sub_head

        def to_dict(self):
            ret = {'text': self.text}
            if self.style != None:
                ret['style'] = self.style.to_dict()

            if self.sub_head != None:
                ret['sub_head'] = self.sub_head.to_dict()

            return ret

    class Body:
        def __init__(self, elements: Sequence[bodyElements] = []):
            self.elements = elements

        def to_dict(self):
            ret = []
            for x in self.elements:
                ret.append(x.to_dict())

            return ret

class Message:
    def __init__(self, allow_markdown: bool = False, head: messageElements.Head = None, body: messageElements.Body = None):
        self.allow_markdown = allow_markdown
        self.head = head
        self.body = body

    def to_dict(self):
        ret = {'content': {}}
        if self.head != None:
            ret['content']['head'] = self.head.to_dict()

        if self.allow_markdown == True:
            ret['is_markdown_support'] = True

        if self.body != None:
            body = []
            for x in self.body.elements:
                body.append(x.to_dict())
            ret['content']['body'] = body

        return ret

class WebhookClient:
    def __init__(self, endpoint: str, auth: str):
        if not check_url(endpoint):
            raise ValueError("Endpoint is not a valid URL")

        self.endpoint = endpoint
        self.auth = auth

    def send(self, message: Message):

        #if isinstance(message.body, messageElements.Body) and message.head == None and any(isinstance(x, bodyElements.Fields) for x in message.body.elements):
        #    raise ValueError("Fields element requires a message header")

        send_rich_msg(message.to_dict(), self.endpoint, self.auth)

    def send_raw(self, message: dict):
        send_rich_msg(message, self.endpoint, self.auth)


import glob
import re
import json

import pandas as pd
import numpy as np

import great_expectations as ge

from get_champions import marshall_champion_data

# Variables

OUTPUT_FILE = "lol_game_data"
CHAMPION_FILE = "lol_classes"

USECOL = [
    "date",
    "game",
    "playerid",
    "position",
    "player",
    "team",
    "champion",
    "result",
    "golddiffat10",
    "golddiffat15",
]

VALID_ENTRY = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 200]

TEAMGOLDDIFF = ["teamgolddiffat10", "teamgolddiffat15"]

# Functions

def return_filenames_in_directory(extension="csv"):
    print("Reading csv data from disk")
    csv_filenames = [
        i
        for i in glob.glob(f"*.{extension}")
        if not (re.search(OUTPUT_FILE, i) or re.search(CHAMPION_FILE, i))
    ]
    csv_filenames.sort()
    print("Current csv files to be combined:")
    [print(name) for name in csv_filenames]
    return csv_filenames

def combine_lol_files(csv_filenames):
    print("Combining csv data into a single dataframe")
    dataframes = [pd.read_csv(f, usecols=USECOL) for f in csv_filenames]
    df = pd.DataFrame(np.concatenate([df.values for df in dataframes]), columns=USECOL)
    print(f"The size of the combined csv files is: {df.size}")
    return df

def add_team_gold(df):

    df = df.copy().reset_index()

    # Get team values
    golddiff10_team_1 = df.loc[10, "golddiffat10"]
    golddiff10_team_2 = df.loc[11, "golddiffat10"]
    golddiff15_team_1 = df.loc[10, "golddiffat15"]
    golddiff15_team_2 = df.loc[11, "golddiffat15"]

    # Drop unecessary rows
    df.drop([10, 11], inplace=True)

    teamgolddiff10 = pd.Series(
        np.repeat([golddiff10_team_1, golddiff10_team_2], [5, 5])
    ).astype(int)

    teamgolddiff15 = pd.Series(
        np.repeat([golddiff15_team_1, golddiff15_team_2], [5, 5])
    ).astype(int)

    # Create new columns
    df[TEAMGOLDDIFF[0]] = teamgolddiff10
    df[TEAMGOLDDIFF[1]] = teamgolddiff15

    return df

def get_starting_index_value(df):
    indexes_of_one = df.index[df.loc[:, "playerid"] == 1].tolist()
    return indexes_of_one

def check_if_entry_is_valid(df_entry_to_check):
    player_positions_to_check = df_entry_to_check.loc[:, "playerid"].values

    is_index_valid = player_positions_to_check == VALID_ENTRY
    is_missing_values_gold10 = (
        df_entry_to_check.loc[:, "golddiffat10"].isnull().values.any()
    )
    is_missing_values_gold15 = (
        df_entry_to_check.loc[:, "golddiffat15"].isnull().values.any()
    )
    is_containing_unknown = (
        df_entry_to_check.loc[:, "team"].str.contains("unknown_team").any()
    )

    is_valid_entry = (
        is_index_valid.all()
        and not is_missing_values_gold10
        and not is_missing_values_gold15
        and not is_containing_unknown
    )

    return is_valid_entry

def return_valid_entries(df, indexes_of_one):
    print("Processing data to find valid entries")
    valid_length = len(VALID_ENTRY)
    valid_entries = []

    for idx in indexes_of_one:
        ending_index = idx + valid_length
        entry_to_check = df.iloc[idx:ending_index]

        is_valid_entry = check_if_entry_is_valid(entry_to_check)

        if is_valid_entry:
            entry_with_team_gold = add_team_gold(entry_to_check)
            valid_entries.append(entry_with_team_gold)

            if len(valid_entries) % 1000 == 0:
                print(f"Current valid entries : {len(valid_entries)}")

    print(f"Total valid entries : {len(valid_entries)}")
    return valid_entries

def combine_valid_entries(valid_entries):
    print("Combining all valid entries into a single dataframe")

    usecol_with_teamgold = USECOL + TEAMGOLDDIFF

    dataframes = [
        pd.DataFrame(entry, columns=usecol_with_teamgold) for entry in valid_entries
    ]

    df = pd.DataFrame(
        np.concatenate([df.values for df in dataframes]), columns=usecol_with_teamgold
    )

    return df

def add_champion_metadata(df) -> pd.DataFrame:
    champ_dict = marshall_champion_data()
    classes = df.loc[:, "champion"].map(champ_dict)
    df.insert (8, "classes", classes)
    return df

def move_column_to_end(df, column_name):
    cols = df.columns.tolist()
    cols.pop(cols.index(column_name))
    cols = cols + [column_name]

    return df.reindex(columns=cols)

def test_uniqueness_of_dataframe(df):
    """
    Check if each row in the dataframe is unique
    """
    duplicated_rows = df[df.duplicated()]

    if not duplicated_rows.empty:
        print("Duplicate Rows except first occurrence based on all columns are:")
        print(duplicated_rows)
        raise ValueError

    print("No duplicated values")

def test_dataframe(df):
    """
    Test the resulting dataframe to ensure data integrity. Can be expanded
    if further tests are needed.
    """
    print("Performing final validation test on dataframe")
    ge_df = ge.from_pandas(df)

    # Check nulls

    columns_not_null = df.columns

    for column in columns_not_null:
        result = ge_df.expect_column_values_to_not_be_null(column)
        assert (
            result["success"] == True
        ), "Coluns contain null value. Please check data."

    # Ensure result is only between 0 and 1
    result = ge_df.expect_column_values_to_be_between(
        "result", min_value=0, max_value=1
    )

    assert result["success"] == True, "Results not between 0 and 1, please check data"

    # Make sure the gold delta does not have outliders
    gold_delta = [
        "golddiffat10",
        "golddiffat15",
        "teamgolddiffat10",
        "teamgolddiffat15",
    ]

    for column in gold_delta:
        result = ge_df.expect_column_values_to_be_between(
            column, min_value=-20000, max_value=20000
        )
        assert result["success"] == True, "Gold diff values too high, please check data"

    print("Data validation passed.")
    return df

def write_dataframe_to_disk(df):
    print("Writing to disk")
    df.to_csv("lol_game_data.csv")

def app():
    print("Starting processing")

    files = return_filenames_in_directory()
    df = combine_lol_files(files)
    indexes_of_one = get_starting_index_value(df)
    valid_entries = return_valid_entries(df, indexes_of_one)
    df_combined = combine_valid_entries(valid_entries)
    df_metadata = add_champion_metadata(df_combined)
    df_reindexed = move_column_to_end(df_metadata, "result")
    test_uniqueness_of_dataframe(df_reindexed)
    df_final = test_dataframe(df_reindexed)
    write_dataframe_to_disk(df_final)

    print("Finishied processing. Closing app.")

if __name__ == "__main__":
    app()


import json

def dec_movies(movies):
    path = 'data/movies/'
    id_list = []
    dict_list = []
    for i in range(len(movies)):
        id_list.append(movies[i]['id'])
    for i in id_list:
        movies_json = open(f'data/movies/{i}.json', encoding='UTF8')
        movies_list = json.load(movies_json)
        dict_list.append(movies_list)
    release_list = []
    for i in range(len(dict_list)):
        release_list.append(dict_list[i]['release_date'])

    month = []
    for i in range(len(release_list)):
        if release_list[i][5:7] == '12':
            month.append(dict_list[i]['title'])
    print(month)
    #         month.append(release_list[i])
    # print(month)
    # s = []
    # for j in range(len(month)):
    #     for i in range(len(dict_list)):
    #         if month[j] == dict_list[i]['release_date'][5:7]:
    #             s.append(dict_list[i]['title'])

# 아래의 코드는 수정하지 않습니다.
if __name__ == '__main__':
    movies_json = open('data/movies.json', encoding='UTF8')
    movies_list = json.load(movies_json)

    print(dec_movies(movies_list))


import numpy as np
import os
import faiss
import time

dataset_list = [
    '/home/y/yujianfu/similarity_search/datasets/ANN_SIFT10K/SIFT10K_base.npy',
]

entropy_list = [
    '/home/y/yujianfu/similarity_search/datasets/ANN_SIFT10K/entropy.npy'
]

save_path = '/home/y/yujianfu/similarity_search/datasets/'
k_list = [3, 5, 10, 50]

for dataset_index in range(len(dataset_list)):
    dataset_path = dataset_list[dataset_index]
    dataset_name = 'ANN_SIFT10K'
    #dataset_path.split('/')[-1].split('_')[0]
    entropy_path = entropy_list[dataset_index]

    dataset = np.ascontiguousarray(np.load(dataset_path).astype('float32'))
    instances = dataset.shape[0]
    dimension = dataset.shape[1]
    dataset = np.ascontiguousarray(np.transpose(dataset))

    entropy = np.load(entropy_path)
    performance = np.zeros((dimension, 9))
    index_brute = faiss.IndexFlatL2(instances)
    index_brute.add(dataset)
    quantilizer = faiss.IndexFlatL2(instances)
    index = faiss.IndexHNSWFlat(instances, 12)
    index.hnsw.efConstruction = 100
    index.hnsw.efSearch = 40
    index.add(dataset)

    for i in range(dimension):
        performance[i, 0] = entropy[i, 0]
        dis_truth, id_truth = index_brute.search(dataset[i, :].reshape(1, -1), k_list[-1])
        for j in range(len(k_list)):
            k = k_list[j]
            time_start = time.time()
            dis_search, ID_search = index.search(dataset[i, :].reshape(1, -1), k)
            time_end = time.time()
            qps = 1 / (time_end - time_start)
            dis_truth, id_truth = index_brute.search(dataset[i, :].reshape(1, -1), k)
            recall = len(set(id_truth[0,:]) & set(ID_search[0,:]))/len(set(id_truth[0, :]))
            #print(id_truth, ID_search)
            performance[i, 2*j+1] = recall
            performance[i, 2*j+2] = qps
            print('the result now is: ', i, k, recall, qps)

    np.save(os.path.join(save_path, dataset_name, 'entropy_performance.npy'),performance)


from collections import defaultdict
from itertools import repeat
import json
import os
import re
import sys

def r(s):
    for i in range(len(s)):
        i += 1
        yield s[-i]

def d(l):
    return dict(zip(iter(l), repeat(0)))

def e(a):
    return (i for i in a if i % 2)

def m(f):
    f.data = {}
    def wrapper(*args):
        try:
            rv = f.data[args]
        except KeyError:
            rv = f.data[args] = f(*args)
        return rv
    return wrapper

def t(pred, iterator):
    for x in iterator:
        if pred(x):
            yield x
        else:
            break

def f(l):
    for i in l:
        if isinstance(i, collections.Iterable) and not isinstance(i, basestring):
            f(i)
        else:
            yield i


#!/usr/bin/env python3
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
"""
Variety quotes plugin sourcing programming jokes from JokeAPI https://sv443.net/jokeapi/v2/
@author: p-ja
"""

import logging
import random

from locale import gettext as _
from variety.plugins.IQuoteSource import IQuoteSource
from variety.Util import Util
from variety.Util import cache

logger = logging.getLogger("variety")

class ProgrammingJokesSource(IQuoteSource):

    def __init__(self):
        super(IQuoteSource, self).__init__()
        self.jokes = []

    @classmethod
    def get_info(cls):
        return {
            "name": "Programming jokes",
            "description": _("Jokes about programmers and programming"),
            "version": "0.1",
            "author": "p-ja"
        }

    def activate(self):
        if self.active:
            return
        super(ProgrammingJokesSource, self).activate()
        self.active = True

    def deactivate(self):
        self.active = False
        self.jokes = []

    def needs_internet(self):
        return True

    def supports_search(self):
        return False

    def get_random(self):
        joke = self._get_joke()
        return self._map_joke(joke)

    def _map_joke(self, joke):
        return [
            {
                "quote": joke.get('joke', "Can't load joke. It's not funny..."),
                "author": None,
                "sourceName": 'JokeAPI',
                "link": None
            }
        ]

    def _get_joke(self):
        if self.jokes:
            joke = random.choice(self.jokes)
            self.jokes.remove(joke)
            return joke

        if not Util.internet_enabled:
            return {}

        try:
            jokes = self._fetch_jokes()
        except Exception as err:
            logger.warning("Failed to fetch jokes {}".format(err))
            return {}

        if not isinstance(jokes, dict):
            return {}

        if 'jokes' not in jokes:
            logger.warning("Invalid response. No jokes.")
            return {}

        self.jokes.extend(jokes['jokes'])

        return self.jokes[0]

    @cache(ttl_seconds=30, debug=True)
    def _fetch_jokes(self):
        logger.debug("Fetching jokes...")
        URL = "https://v2.jokeapi.dev/joke/Programming?type=single&amount=10"
        return Util.fetch_json(URL)


import configparser
import argparse
import os, sys
project_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
print(project_dir)
sys.path.append(project_dir)
from objective_function.low_dim_function import function_dict
from objective_function.base_function import set_optimal_position, append_all_epoch, get_all_epoch
from zoopt import Opt, Objective, Dimension2, ValueType, Parameter, Dimension
# from zoopt import Opt, Objective, Parameter, Dimension

from zoopt.utils.zoo_global import gl
import numpy as np
import os

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--objective', default='ackley', help='only support ackley, sphere, rastrigin and schwefel')
    args = parser.parse_args()
    obj_name = args.objective

    config = configparser.ConfigParser()
    config_name = os.path.join(project_dir, 'objective_function/config/low_dim.ini')
    config.read(config_name, encoding='utf-8')
    print(config.sections())

    optimal_position_address = os.path.join(project_dir,  config.get(obj_name, 'optimal_position_address'))
    dim_size = config.getint(obj_name, 'dim_size')
    dim_regs = eval(config.get(obj_name, 'dim_regs'))
    budget = config.getint(obj_name, 'budget')

    repeat = 30
    set_optimal_position(optimal_position_address)
    seed = 0
    gl.set_seed(seed)
    for i in range(repeat):
        dim = Dimension2([(ValueType.CONTINUOUS, dim_regs, 1e-6)]*dim_size)
        # dim = Dimension(dim_size, [dim_regs] * dim_size, [True] * dim_size)
        objective = Objective(lambda sol: function_dict[obj_name](sol.get_x()), dim)  # form up the objective function
        parameter = Parameter(budget=budget, intermediate_result=True, intermediate_freq=100)
        sol = Opt.min(objective, parameter)
        append_all_epoch()
    all_epoch = np.array(get_all_epoch())
    log_address = os.path.join(project_dir, 'ZOOpt_exp/log/low_dim/')
    file_name = os.path.join(log_address, '{}_{}.txt'.format(obj_name, dim_size))
    os.makedirs(log_address, exist_ok=True)
    np.savetxt(file_name, all_epoch)
    print(all_epoch.shape)


# -*- coding: utf-8 -*-56
"""
Created on Fri Feb 24 15:40:57 2023

@author: Gbenga Agunbiade
"""

import numpy as np
from random import seed
from random import random
import scipy.integrate as integrate

###########  MONTE CARLO ####################
def MonteCarlo(f, a, b, n):
    u = np.random.uniform(0, 1, n)  # generate random points uniformly in [0,1]
    arr = f(a+(b-a)*u)
    total = ((b-a)/n)*(arr.sum())
    return total

########### TRAPEZOIDAL RULE #################
def h (a, b, n):
	return (b-a)/float(n)

# Trapezoidal rule function
# TRAPEZOIDAL Numerical integration from a to b
# with n intervals by the Trapezoidal rule

def trap_rule(f, a, b, n):
    total = f(a) + f(b)
    dx = h(a, b, n)
    for k in range(1, n):
        total += 10.0 * f(a + k * dx)
    return dx / 10.0 * total
######### FUNCTION TO INTEGRATE #############

# Function to integrate
def f(x):
    return (np.cos(x)) ** 20 * np.exp(-x / 10.0)
##############################################
print("We are integrating the function cos(x)^5**10*exp(-x/10) in the interval [25,45]:\n")
print("Enter the order of the Quadrature methods, or numerical integral to evaluate: ")
num = int(input())
I_exact = 0.038964609200183953761884221510468
I_MC = MonteCarlo(f, 25.0, 45.0, num)

# Evaluate the integral using the trapezoidal rule
I_trap = trap_rule(f, 25.0, 45.0, num)

# Evaluate the integral using Gaussian quadrature
I_gauss = integrate.fixed_quad(f, 25.0, 45.0, n=num)

print("\nExact:\n", I_exact)
print("Monte Carlo:\n", I_MC)
print("Trapezoidal method:\n", I_trap)
print("Quadrature methods, or numerical integral:\n", I_gauss[0])
print("\nErrors:\n")
print("Iexact-I_MonteCarlo: ", I_exact-I_MC)
print("Iexact-Itrapezoidal: ", I_exact-I_trap)
print("Iexact-Igauss_quad: ", I_exact-I_gauss[0])


from datetime import date
import os
import json

class Gerenciamento:

    # Verificador de arquivos vazios
    def _emptyFile(self, path):
        with open(path, 'r') as file:
            content = file.read()

        if not content:
            return True

    def _migracaoCompanhia(self, path, dado):
        with open(path, "r") as file:
            content = json.load(file)

        hasCompanhia = False

        for item in content["companhias"]:
            if item['companhia'] == dado["companhia"]:
                hasCompanhia = True
                break
            else:
                hasCompanhia = False

        if not hasCompanhia:
            content["companhias"].append(dado)

        with open(path, "w") as file:
            json.dump(content, file)

    def _readDataBase(self, path):
        with open(path, 'r') as file:
            content = json.load(file)

        return content

    def __init__(self, name):
        self.name = name

        # Caminho do Banco de Dados
        self.dbPath = os.path.join("db", "db.json")

        if not os.path.exists(self.dbPath):
            with open(self.dbPath, 'w') as file:
                file.write("")

        emptyFileResponse = self._emptyFile(self.dbPath)

        if emptyFileResponse:
            with open(self.dbPath, 'w') as file:
                 json.dump({
                    "companhias": [],
                    "destinos": []
                 }, file)

        dados = {
            "companhia": self.name,
            "voos": []
        }

        self._migracaoCompanhia(self.dbPath, dados)

        # Variável com o conteúdo do banco de dados
        self.db = self._readDataBase(self.dbPath)

    def cadastroVoo(self, info):

        companhias = self.db

        # Atualização do número do voo de forma automática
        indice = 0

        for companhia in companhias["companhias"]:
            if companhia["companhia"] == self.name:
                quantidadeDeVoos = len(companhia["voos"])
                indice = quantidadeDeVoos

                break

        voo = {}

        try:
            voo = {
                "numeroVoo" : indice + 1,
                "dataVoo" : date(int(info['dataVoo'][2]), int(info['dataVoo'][1]), int(info['dataVoo'][0])).isoformat(),
                "origemVoo" : info['origem'],
                "destinoVoo" : info['destino'],
                "vagasOcupadas" : [],
            }
        except:
            return {"voo": voo, "verification": False}

        # Atualização dos voos na estrutura de dados

        for companhia in companhias["companhias"]:
            if companhia["companhia"] == self.name:

                voosUpdate = companhia
                voosUpdate["voos"].append(voo)
                break

        # Reescreve os voos atualizados no arquivo
        with open(self.dbPath, 'w') as file:
            json.dump(companhias, file)
            return {"voo": voo, "verification": True}

    def cadastroAeroporto(self, info):
        destinos = self.db

        try:
            # Caso não tenha nenhuma destino
            if destinos["destinos"] == []:

                indice = 1
                dados = {
                    "id": indice,
                    "cidade": info["cidade"],
                    "estado": info["estado"]
                }

                destinos["destinos"].append(dados)

                with open(self.dbPath, 'w') as file:
                    json.dump(destinos, file)
                    return {"destino": dados, "verification": True}

            # Verificação para não haver destinos iguais
            hasDestino = False

            for item in destinos["destinos"]:
                if item["cidade"] == info["cidade"]:
                    hasDestino = True
                    break
                else:
                    hasDestino = False

            # Atualização de um novo destino
            if not hasDestino:

                newIndice = int(destinos["destinos"][-1]["id"]) + 1

                dados = {
                    "id": newIndice,
                    "cidade": info["cidade"],
                    "estado": info["estado"]
                }

                destinos["destinos"].append(dados)

                with open(self.dbPath, 'w') as file:
                    json.dump(destinos, file)
                    return {"destino": dados, "verification": True}

        except:
            return {"destino": dados, "verification": False}

    def getDestinos(self):
        destinos = self.db["destinos"]

        return destinos

    def getVoos(self):

        companhias = self.db

        for companhia in companhias["companhias"]:
            if companhia["companhia"] == self.name:
                voos = companhia["voos"]
                break

        return voos

    def cadastrarAssento(self, info):

        db = self.db

        numVoo = info["numVoo"]
        assentoEscolhido = info["assentoEscolhido"]

        for companhia in db["companhias"]:
            if companhia["companhia"] == self.name:

                vagasUpdate = companhia["voos"][numVoo - 1]
                vagasUpdate["vagasOcupadas"].append(assentoEscolhido)

                break

        with open(self.dbPath, "w") as file:
            json.dump(db, file)
            return {"verification": True}

    def getVoosDoDia(self):

        companhias = self.db
        dataAtual = str(date.today())

        hasVoo = False

        print("Data atual: ", dataAtual)
        for companhia in companhias["companhias"]:
            print("")
            print(companhia["companhia"], ":")
            print("")

            for voo in companhia["voos"]:
                if voo["dataVoo"] == dataAtual:
                    hasVoo = True
                    print("ID do Voo: ", voo["numeroVoo"])
                    print("Data:", voo["dataVoo"])
                    print("Rota: {},{} -> {},{}".format(voo["origemVoo"]["cidade"], voo["origemVoo"]["estado"], voo["destinoVoo"]["cidade"], voo["destinoVoo"]["estado"]))
                    print("")
                    print("")

        if not hasVoo:
            print("")
            print("Não há voos hoje!")


#!/usr/bin/env python
from pprint import pprint
from flask import Flask, flash, redirect, render_template, request, url_for
from flask_bootstrap import Bootstrap

from helper.timeline.timeline_builder import TimelineBuilder
from os import environ, path
import os
import time
import pwd
import sys

app = Flask(__name__)
bootstrap = Bootstrap(app)

#prevent caching
@app.after_request
def add_header(r):
    """
    Add headers to both force latest IE rendering engine or Chrome Frame,
    and also to cache the rendered page for 10 minutes.
    """
    r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    r.headers["Pragma"] = "no-cache"
    r.headers["Expires"] = "0"
    r.headers['Cache-Control'] = 'public, max-age=0'
    return r

@app.route('/')
@app.route('/home',methods = ['POST', 'GET'])
def home():
    return render_template('bs_index.html')

@app.route('/Guide')
def guide():
    return render_template('bs_guide.html')

@app.route('/t-menue-2')
def t_2():
    #return render_template('home.html',team = team_1)
    return render_template('test_timeline_fixed_ranges.html')

@app.route('/GTimeline',methods = ['POST', 'GET'])
def SetTimeline():

    print ("in SetTimeLine\n")
    if request.method == 'POST':
        print ("in SetTimeline - POST\n")

        timelineCmd = request.form

        if not 'RadioForBlackoutEventUpdate' in timelineCmd.keys():
            print ("no need to set CalEvent\n")
            set_cal_event = 'off'
        else:
            set_cal_event = timelineCmd['RadioForBlackoutEventUpdate']

        print ("???????????????????????????     DATA PASSED FOR SetTimeline")
        pprint(timelineCmd)

        store_dir = os.path.dirname(os.path.realpath(__file__)) + os.sep + "static/js/timeline"
        result_file = store_dir + os.sep + "timeline.js"
        #header = "timeline  Log Generated on: {}".format(time.ctime(os.path.getctime(result_file)))

        print ("1========================================= before TimelineBuilder\n")
        tlb = TimelineBuilder(store_dir)

        print ("2========================================= before getCachedTimeline\n")
        tlb.getCachedTimeline("timeline")

        tlb.processTimelineOp(timelineCmd['RadioForTimeLineLaneUpdate'],
                              timelineCmd['LaneName'],
                              timelineCmd['Event'],
                              timelineCmd['EventStartDate'],
                              timelineCmd['EventEndDate'],
                              set_cal_event,
                              timelineCmd['BlackoutEvent'],
                              timelineCmd['BlackOutStart'],
                              timelineCmd['BlackOutEnd'])

        print ("3=========================================== FlushTimeLineCacheToFile\n")
        tlb.flushTimelineCacheToFile("timeline")

    return render_template('bs_setTimeline.html',title = 'GTimeline')

if __name__=='__main__':
    app.run(debug=True)


from __future__ import annotations

from types import MappingProxyType
from typing import (
    TYPE_CHECKING,
    Any,
    Mapping,
    Sequence,
    Union,  # noqa: F401
)

import pandas as pd
from anndata import AnnData
from scanpy import logging as logg

from squidpy._constants._constants import ImageFeature
from squidpy._docs import d, inject_docs
from squidpy._utils import Signal, SigQueue, _get_n_cores, parallelize
from squidpy.gr._utils import _save_data
from squidpy.im._container import ImageContainer

__all__ = ["calculate_image_features"]

@d.dedent
@inject_docs(f=ImageFeature)
def calculate_image_features(
    adata: AnnData,
    img: ImageContainer,
    layer: str | None = None,
    library_id: str | Sequence[str] | None = None,
    features: str | Sequence[str] = ImageFeature.SUMMARY.s,
    features_kwargs: Mapping[str, Mapping[str, Any]] = MappingProxyType({}),
    key_added: str = "img_features",
    copy: bool = False,
    n_jobs: int | None = None,
    backend: str = "loky",
    show_progress_bar: bool = True,
    **kwargs: Any,
) -> pd.DataFrame | None:
    """
    Calculate image features for all observations in ``adata``.

    Parameters
    ----------
    %(adata)s
    %(img_container)s
    %(img_layer)s
    %(img_library_id)s
    features
        Features to be calculated. Valid options are:

        - `{f.TEXTURE.s!r}` - summary stats based on repeating patterns
          :meth:`squidpy.im.ImageContainer.features_texture`.
        - `{f.SUMMARY.s!r}` - summary stats of each image channel
          :meth:`squidpy.im.ImageContainer.features_summary`.
        - `{f.COLOR_HIST.s!r}` - counts in bins of image channel's histogram
          :meth:`squidpy.im.ImageContainer.features_histogram`.
        - `{f.SEGMENTATION.s!r}` - stats of a cell segmentation mask
          :meth:`squidpy.im.ImageContainer.features_segmentation`.
        - `{f.CUSTOM.s!r}` - extract features using a custom function
          :meth:`squidpy.im.ImageContainer.features_custom`.

    features_kwargs
        Keyword arguments for the different features that should be generated, such as
        ``{{ {f.TEXTURE.s!r}: {{ ... }}, ... }}``.
    key_added
        Key in :attr:`anndata.AnnData.obsm` where to store the calculated features.
    %(copy)s
    %(parallelize)s
    kwargs
        Keyword arguments for :meth:`squidpy.im.ImageContainer.generate_spot_crops`.

    Returns
    -------
    If ``copy = True``, returns a :class:`pandas.DataFrame` where columns correspond to the calculated features.

    Otherwise, modifies the ``adata`` object with the following key:

        - :attr:`anndata.AnnData.uns` ``['{{key_added}}']`` - the above mentioned dataframe.

    Raises
    ------
    ValueError
        If a feature is not known.
    """
    layer = img._get_layer(layer)
    if isinstance(features, (str, ImageFeature)):
        features = [features]
    features = sorted({ImageFeature(f).s for f in features})

    n_jobs = _get_n_cores(n_jobs)
    start = logg.info(f"Calculating features `{list(features)}` using `{n_jobs}` core(s)")

    res = parallelize(
        _calculate_image_features_helper,
        collection=adata.obs_names,
        extractor=pd.concat,
        n_jobs=n_jobs,
        backend=backend,
        show_progress_bar=show_progress_bar,
    )(adata, img, layer=layer, library_id=library_id, features=features, features_kwargs=features_kwargs, **kwargs)

    if copy:
        logg.info("Finish", time=start)
        return res

    _save_data(adata, attr="obsm", key=key_added, data=res, time=start)

def _calculate_image_features_helper(
    obs_ids: Sequence[str],
    adata: AnnData,
    img: ImageContainer,
    layer: str,
    library_id: str | Sequence[str] | None,
    features: list[ImageFeature],
    features_kwargs: Mapping[str, Any],
    queue: SigQueue | None = None,
    **kwargs: Any,
) -> pd.DataFrame:
    features_list = []
    for crop in img.generate_spot_crops(
        adata, obs_names=obs_ids, library_id=library_id, return_obs=False, as_array=False, **kwargs
    ):
        if TYPE_CHECKING:
            assert isinstance(crop, ImageContainer)
        # load crop in memory to enable faster processing
        crop = crop.compute(layer)

        features_dict = {}
        for feature in features:
            feature = ImageFeature(feature)
            feature_kwargs = features_kwargs.get(feature.s, {})

            if feature == ImageFeature.TEXTURE:
                res = crop.features_texture(layer=layer, **feature_kwargs)
            elif feature == ImageFeature.COLOR_HIST:
                res = crop.features_histogram(layer=layer, **feature_kwargs)
            elif feature == ImageFeature.SUMMARY:
                res = crop.features_summary(layer=layer, **feature_kwargs)
            elif feature == ImageFeature.SEGMENTATION:
                res = crop.features_segmentation(intensity_layer=layer, **feature_kwargs)
            elif feature == ImageFeature.CUSTOM:
                res = crop.features_custom(layer=layer, **feature_kwargs)
            else:
                # should never get here
                raise NotImplementedError(f"Feature `{feature}` is not yet implemented.")

            features_dict.update(res)
        features_list.append(features_dict)

        if queue is not None:
            queue.put(Signal.UPDATE)

    if queue is not None:
        queue.put(Signal.FINISH)

    return pd.DataFrame(features_list, index=list(obs_ids))


from django.urls import path
from product.views import create_product,product_list,product_recieve,product_shipping,product_arrival,product_delivery,product_one

urlpatterns = [
    path('create/', create_product ),
    path('products/', product_list),
    path('recieveproduct/<location>/', product_recieve),
    path('shippingproduct/<location>/', product_shipping),
    path('arrivalproduct/<location>/', product_arrival),
    path('deliveryproduct/productcode/<code>/location/<location>', product_delivery),
    path('oneproduct/<code>/', product_one),

]


import json
import requests

# Ex 12.1
request = "https://api.chucknorris.io/jokes/random"
response = requests.get(request).json()
print("Random Chuck Norris joke:")
print(response["value"])

# Ex 12.2
city = input("Enter city: ")
city = city.capitalize()
key = "################################"
request = "https://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=" + key + "&units=metric"
response = requests.get(request).json()
weather = response["weather"][0]["description"]
temp = response["main"]["temp"]
print(f"Current weather at {city}: {weather}\nTemperature: {temp}")


"""
DYNAMOAPI: GET CURRENT WORKSPACE PATH AND FILE NAME FOR DYNAMO ON ALL HOST VERSIONS
"""
__author__ = 'Brendan cassidy'
__twitter__ = '@brencass86'
__version__ = '1.0.1'
"""
Original code indicated here https://forum.dynamobim.com/t/get-graph-filename/67434/5
This version includes 2 additional outputs for File name with and without file type.
"""
# we need to import the common language runtime to be able to interact with Dynamo

# Importing Reference Modules
# CLR ( Common Language Runtime Module )
import clr
# Adding the DynamoServices.dll module to work with the Dynamo API we need
clr.AddReference('DynamoServices')
from Dynamo.Events import *

# Access to the current Dynamo workspace path(eg location of the opened dynamo file)
currentWorkspacePath = ExecutionEvents.ActiveSession.CurrentWorkspacePath

# Gets the File Name with file type
fileName = currentWorkspacePath.split("\\")[-1]

# Removes the dyn File type from the end of the file name
fileNameWithoutFileType = fileName.replace(".dyn","")

# Outputs the full file path, file name with file type and just file name
OUT = currentWorkspacePath, fileName, fileNameWithoutFileType


from decimal import Decimal

import requests

from cryptoportfolio.interfaces.base import Address

class PoolBitcoinCom(Address):
    decimal_places = 18
    __api_data = None

    def __init__(self, api_key, **kwargs):
        self.api_key = api_key
        super(PoolBitcoinCom, self).__init__(**kwargs)

    def _get_api_data(self):
        if not self.__api_data:
            self.__api_data = requests.get(
                "https://console.pool.bitcoin.com/srv/api/user?apikey=%s" % self.api_key).json()
        return self.__api_data

    def _get_addr_coins_and_tokens_balance(self):
        result = self._get_api_data()
        response = []
        if Decimal(result['bitcoinCashBalance']) != Decimal('0.0'):
            response.append(("BCH", Decimal(result['bitcoinCashBalance'])))
        if Decimal(result['bitcoinBalance']) != Decimal('0.0'):
            response.append(("BTC", Decimal(result['bitcoinCashBalance'])))
        return response


"""Test the accident stats handler class."""

import httpx
import pytest

from tests.static_vars import ACCIDENT_STATS_AFTER_2020, ACCIDENT_STATS_BEFORE_2020, LIFT_DISRUPTIONS

# noinspection PyProtectedMember
from tfl.clients.handlers._accident_stats_handler import AccidentStatsHandler

class TestAccidentStatsHandler:
    """Test the accident stats client class."""

    @pytest.mark.asyncio
    async def test_before_2020(self, httpx_mock) -> None:
        """Test the accident_stats method before 2020."""
        httpx_mock.add_response(
            url="https://api.tfl.gov.uk/AccidentStats/2019",
            json=ACCIDENT_STATS_BEFORE_2020,
            method="GET",
        )
        async with httpx.AsyncClient(base_url="https://api.tfl.gov.uk") as client:
            response = await AccidentStatsHandler(client).get_accident_stats(2019)
        assert response.status_code == 200
        assert response.json() == ACCIDENT_STATS_BEFORE_2020

    @pytest.mark.asyncio
    async def test_after_2020(self, httpx_mock) -> None:
        """Test the accident_stats method after 2020."""
        httpx_mock.add_response(
            url="https://api.tfl.gov.uk/AccidentStats/2020",
            json=ACCIDENT_STATS_AFTER_2020,
            method="GET",
        )
        async with httpx.AsyncClient(base_url="https://api.tfl.gov.uk") as client:
            response = await AccidentStatsHandler(client).get_accident_stats(2020)
        assert response.status_code == 200
        assert response.json() == ACCIDENT_STATS_AFTER_2020


from rest_framework import serializers, status, exceptions
from api.serializer_extender import SerializerExtenderManagerByAddon
from lockable_resource.models import LockableResource
from rqueue.models import Rqueue

# Serializer are helper classes to parse the Model objects to JSON objects,
# so we can return Lockable resources object responses via JSON
class LockableResourceSerializer(serializers.ModelSerializer):
    class Meta:
        model = LockableResource
        fields = "__all__"
        read_only_fields = ["id"]

    # Use this section to add data from addons
    expiry_addon = SerializerExtenderManagerByAddon(
        addon_name="expiry_addon",
        cls_serializer="LockableResourceSerializer",
    )

    def validate(self, attrs):
        """
        Check that the Resource is not Locked
        :param data:
        :return:
        """
        lr_name = attrs.get("name")
        lr_object_pre_save = LockableResource.objects.get(name=lr_name)
        if lr_object_pre_save.is_locked and attrs.get("is_locked"):
            # Important note: raises 406 code status for handling in different services
            raise exceptions.NotAcceptable(
                detail=f"You can not modify a Lockable Resource [{lr_name}] object through the REST API if the resource is locked! "
                "This is prohibited as it might be an attempt locking a resource that is already locked. "
                "Please release first the resource before performing a request that differs from GET. "
            )
        return attrs

class RqueueSerializer(serializers.ModelSerializer):
    class Meta:
        model = Rqueue
        # Here I hardcoded everything, because the ordering is important to display nicer! data is the ugliest display to better it will be last when outputting
        fields = (
            "id",
            "priority",
            "status",
            "time_requested",
            "pending_time",
            "pending_time_descriptive",
            "pended_time_descriptive",
            "description",
            "data",
            "last_beat",
        )


from tkinter import *
from PIL import Image
from PIL import ImageTk
import tkinter.filedialog
import cv2
import os

# def start():
#     global currentImage
#     global w
#     global h
#     global canvas
#     input_images_path = "/Users/tommysarni/design_capstone/frames/vid1"
#     output_images_path = "something"
#     print("started")
#     images_list = [image_name for image_name in os.listdir(input_images_path)]
#     full_paths = []

#     for path in images_list:
#         full_paths.append(os.path.join(input_images_path, path))
#     print(len(full_paths))

#'/Users/tommysarni/design_capstone/frames/vid1/frame00.jpg'
def sort_key(str):
    ending = os.path.basename(os.path.normpath(str))
    ending = ending.split(".")
    ending = ending[0]
    ending = ending.split("frame")
    if len(ending) == 2:
        return int(ending[1])
    else:
        return -1

def reset():
    global workingCopy
    global canvas
    global current
    current = None
    workingCopy = None
    selected = False
    canvas.delete("circle")
    canvas.delete("line")
    canvas.update()

def start(idx = 0):

    global currFrame
    global w, h
    global workingCopy
    global canvas

    input_images_path = "/Users/tommysarni/design_capstone/frames/vid1"
    output_images_path = "something"
    print("started")
    images_list = [image_name for image_name in os.listdir(input_images_path)]

    full_paths = []

    for path in images_list:
        full_paths.append(os.path.join(input_images_path, path))

    full_paths.sort(key=sort_key)

    if len(full_paths) > idx and idx >= 0:
        path = full_paths[idx]
        currFrame = idx
        if len(path) > 0:
            reset()
            # load the image from disk, convert it to grayscale, and detect
            image = cv2.imread(path)
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

            # convert the images to PIL format...
            image = Image.fromarray(image)

            print("image size", image.width, image.height)

            workingCopy = image.copy()

            resizeRatio = min(w / workingCopy.width, h / workingCopy.height)
            print("resize ratio: ", resizeRatio)
            workingCopy = workingCopy.resize((round(workingCopy.size[0]*resizeRatio), round(workingCopy.size[1]*resizeRatio)))

            print("image size", workingCopy.width, workingCopy.height)

            # ...and then to ImageTk format
            workingCopy = ImageTk.PhotoImage(workingCopy)
            canvas.create_image(0,0, image=workingCopy, anchor='nw')
            canvas.bind('<Button-1>', prep)
            updateFrameLabel()

def updateFrameLabel():
    global frameLabel
    frameLabel.config(text=f'Frame: {currFrame}', width=100)

def nxt():
    global currFrame
    start(idx=currFrame+1)

def prev():
    global currFrame
    start(idx=currFrame-1)
    frameLabel.config(text=f'Frame: {currFrame}', width=100)

def select_image():
    #grab reference to the image panels
    print("run")

    global workingCopy

    # open a file chooser dialog and allow the user to select an input
    path = tkinter.filedialog.askopenfilename()
    print(path)

    # ensure a file path was selected
    if len(path) > 0:
		# load the image from disk, convert it to grayscale, and detect
        image = cv2.imread(path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

		# convert the images to PIL format...
        image = Image.fromarray(image)

        print("image size", image.width, image.height)

        global w, h
        global workingCopy
        global canvas

        workingCopy = image.copy()

        resizeRatio = min(w / workingCopy.width, h / workingCopy.height)
        print("resize ratio: ", resizeRatio)
        workingCopy = workingCopy.resize((round(workingCopy.size[0]*resizeRatio), round(workingCopy.size[1]*resizeRatio)))

		# ...and then to ImageTk format
        workingCopy = ImageTk.PhotoImage(workingCopy)
        canvas.create_image(0,0, image=workingCopy, anchor='nw')
        canvas.bind('<Button-1>', prep)

class Contours:

    def __init__(self, name, contour):
        self.name = name
        self.contour = contour

    def __str__(self):
        return f'name: {self.name}\ncontours: {self.contour}\n'

class Contour:

    def __init__(self, name, contours):
        self.name = name
        self.contours = contours

    def __str__(self):
        return f'name: {self.name}\ncontours: {self.contours}\n'

    def addContour(self, c):
        self.contours.append(c)

    def updateContour(self, idx, newPt):
        self.contours[idx] = newPt

    def removeContour(self, idx):
        self.contours.pop(idx)

def create_circle(x, y, r, canvasName): #center coordinates, radius
    x0 = x - r
    y0 = y - r
    x1 = x + r
    y1 = y + r
    return canvasName.create_oval(x0, y0, x1, y1, tag='circle', fill="blue")

def updateUI():
    global current
    global canvas
    global listbox
    if not current == None and not canvas == None:
        draw_smth(current.contours)

        # for c in current.contours:
        #     circ = create_circle(c[0], c[1], 10, canvas)
        #     canvas.tag_raise("circle",'all')

def edit_contour():
    print("editting mode active")
    global editing
    #name for contour group
    global collection
    # frame number added
    global frame
    #popup window for editing
    global popup
    #current image
    global current
    #canvas to draw
    global canvas
    #end result
    global res
    #current frame
    global currFrame
    #last collection label
    global lastCollection

    global listbox

    if not editing:
        editing = True
        popup = tkinter.Tk()
        tkinter.Label(popup,
                text=f'Frame #').grid(row=0)
        tkinter.Label(popup,
                text="Collection").grid(row=1)

        frame = tkinter.Entry(popup)
        collection = tkinter.Entry(popup)
        frame.insert(0, f'{currFrame}')
        if not lastCollection == None:
            collection.insert(0, f'{lastCollection}')

        frame.grid(row=0, column=1)
        collection.grid(row=1, column=1)

        tkinter.Button(popup,
                text='Cancel',
                command=popup.destroy).grid(row=3,
                                            column=0,
                                            sticky=tkinter.W,
                                            pady=4)
        tkinter.Button(popup,
                text='Submit', command=submit).grid(row=3,
                                                            column=1,
                                                            sticky=tkinter.W,
                                                            pady=4)
    else:
        current.addContour(current.contours[0])

        updateUI()
        editing = False
        if res == None:
            res = Contours("vid1", Contour(lastCollection, [current.contours]))
        else:
            res.contour.append(current.contours)

        for c in res.contour.contours:
            print(c.name)
        print("res: ", res)

def submit():
    global current
    global collection
    global frame
    global popup
    global lastCollection
    if not collection.get() == "" and not frame.get() == "":
        lastCollection = collection.get()
        current = Contour(collection.get(), [])
        popup.destroy()

def prep(event):
    global editing
    global current
    if editing and not current == None:
        print(event.x, event.y)
        current.addContour([event.x, event.y])
        # event.widget.config(bg='light blue')
        event.widget.focus_set()  # give keyboard focus to the label
        print(current)
        updateUI()

def get_x_and_y(event):
    global lasx, lasy
    lasx, lasy = event.x, event.y

def draw_smth(contours):
    if len(contours) > 1:
        print(contours)
        canvas.create_line(contours, tag="line")
    # for idx, val in enumerate(contours):
    #     if len(contours) > 1:
    #         print(contours[idx - 1])
    #         print(val)
    #         canvas.create_line((contours[idx - 1][0], contours[idx - 1][1], val[0], val[1]), fill='red', width=2, tag='line')

workingCopy = None
editing = False
res = None
current = None
collection = None
frame = None
popup = None
currentPath = None
currFrame = None
lastCollection = None
lastContours = None

# initialize the window toolkit along with the two image panels
root = Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
canvas = Canvas(root,
           width=w,
           height=h)
canvas.pack(expand=YES, fill=BOTH, side=LEFT)

# sidebar = Frame(root, width=200, bg='white', height=500, relief='sunken', borderwidth=2)
# sidebar.pack(expand=True, fill=BOTH, side=RIGHT)

listbox = Listbox(root)
listbox.pack(side=LEFT, fill=BOTH)
scrollbar = Scrollbar(root)
scrollbar.pack(side = RIGHT, fill = BOTH)

listbox.config(yscrollcommand = scrollbar.set)
scrollbar.config(command = listbox.yview)

begin = Button(canvas, text="Start", command=start)
begin.grid(row=0,column=0)

editContours = Button(canvas, text="edit the contours", command=edit_contour)
editContours.grid(row=0,column=1)

startOver = Button(canvas, text="Reset", command=reset)
startOver.grid(row=0,column=2)

prev = Button(canvas, text="Previous", command=prev)
prev.grid(row=0,column=3)

nxt = Button(canvas, text="Next", command=nxt)
nxt.grid(row=0,column=4)

frameLabel = Label(canvas, text=f'Frame: {currFrame}')
frameLabel.grid(row=0, column=5)
print("test: ", Contours("vid1", Contour("name",[])))

# kick off the GUI
mainloop()


# coding=utf-8
# Author: Winter_pig 2018-06-27

import ccxt
import time
from datetime import datetime
import math

#取消全部委托单
def CancelPendingOrders(exchange,symbol):
    now = datetime.now()
    orders = getOpenOrders(exchange,symbol)
    for order in orders:
        try:
            if ((now - timestamp_datetime(order['timestamp'])).seconds > 10):
                exchange.cancel_order(order['id'], symbol)
            else:
                continue
        except Exception as e:
            print("Cancel Error: {}".format(e))
        else:
            time.sleep(0.5)

#计算下单价格
def GetPrice(exchange,symbol):
    try:
        orderbook = exchange.fetchOrderBook(symbol)
        bid = orderbook['bids'][1][0] if len(orderbook['bids']) > 0 else None
        ask = orderbook['asks'][1][0] if len(orderbook['asks']) > 0 else None
        spread = (orderbook['asks'][0][0]  - orderbook['bids'][0][0])/2 if (bid and ask) else None
        print (exchange.id, 'market price', {'bid': bid, 'ask': ask, 'spread': spread})
        buy_price = bid + spread
        sell_price = ask - spread
        return buy_price, sell_price
    except Exception as e:
        print("GetPrice Error: {}".format(e))
    else:
        return None,None

def GetTickerPrice(exchange,symbol):
    try:
        #orderbook = exchange.fetchOrderBook(symbol)
        #bid = orderbook['bids'][0][0] if len(orderbook['bids']) > 0 else None
        #ask = orderbook['asks'][0][0] if len(orderbook['asks']) > 0 else None
        ticker = exchange.fetch_ticker(symbol)
        bid = ticker['bid']
        ask = ticker['ask']
        spread = (ask  - bid)/2 if (bid and ask) else None
        print (exchange.id, 'market price', {'bid': bid, 'ask': ask, 'spread': spread})
        return bid, ask, spread
    except Exception as e:
        print("GetPrice Error: {}".format(e))
    else:
        return None,None
#timestamp转换成日期
def timestamp_datetime(ts):
     if isinstance(ts, (int, float, str)):
         try:
             ts = int(ts)
         except ValueError:
             raise

         if len(str(ts)) == 13:
             ts = int(ts / 1000)
         if len(str(ts)) != 10:
             raise ValueError
     else:
        raise ValueError()
     return datetime.fromtimestamp(ts)

def getAccount(exchange):
    try:
        account = exchange.fetchBalance()
        return account
    except Exception as e:
        print("getAccount Error: {}".format(e))
    else:
        time.sleep(3)
        return getAccount(exchange)

def getOpenOrders(exchange, symbol):
    try:
        orders = None
        orders = exchange.fetchOpenOrders(symbol)
        return orders
    except Exception as e:
        print("getOpenOrders Error: {}".format(e))
    else:
        time.sleep(3)
        return getOpenOrders(exchange,symbol)

def adjustFloat(v):
    return math.floor(v*100)/100


from django.db import models
from django.conf import settings
from django.utils import timezone
from django.urls import reverse
from django.core.validators import RegexValidator
import string
from datetime import timedelta
import secrets
import abn
import re

from .base import MutableDataRecord

MOBILE_PHONE_REGEX = re.compile(r'^(\+614|04|00614)\d{8}$')
BSB_REGEX = re.compile(r'^\d{3}-?\d{3}$')
BANK_ACCT_REGEX = re.compile(r'^\d{4,20}$')

def validate_abn(value):
    if value and not abn.validate(value):
        return False
    return True

class Person(MutableDataRecord):
    """
    Model representing a tour operator (rider) or other staff member.
    Corresponds 1:1 with Deputy Employees.
    """
    class Meta:
        verbose_name = 'Person'
        verbose_name_plural = 'Riders & Deputy Users'

    MUTABLE_FIELDS = ('first_name', 'last_name', 'active', 'phone', 'email', 'email_verified')
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    display_name = models.CharField(max_length=200, unique=True, null=True, verbose_name='Preferred Name',
        error_messages={
            'unique': 'Display name already taken',
            'blank': 'Display name cannot be blank',
        })
    email = models.EmailField(unique=True, null=True, blank=True, error_messages={
        'unique': 'Email address already in use',
        'blank': 'You must enter an email address',
    })
    email_verified = models.BooleanField(blank=True, default=False)
    phone = models.CharField(max_length=30, unique=True, null=True, blank=True, verbose_name='Contact Phone Number',
        error_messages={
            'unique': 'Phone number already taken',
            'blank': 'You must enter a phone number',
        },
    )

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True,
        blank = True,
        verbose_name = 'Username for login (Optional)',
        help_text = "Allow this person to login directly with a username/password")

    active = models.BooleanField(blank=True)
    abn = models.CharField(max_length=30, blank=True, verbose_name='Contractor ABN',
        validators=[validate_abn])
    bank_bsb = models.CharField(max_length=20, blank=True, verbose_name='Bank account BSB')
    bank_acct = models.CharField(max_length=20, blank=True, verbose_name='Bank account number')
    last_seen = models.DateTimeField(default=timezone.now, null=True, blank=True, verbose_name='Last activity')
    created = models.DateTimeField(default=timezone.now, verbose_name='Date joined')

    # Rider specific data
    RIDER_CLASS_CHOICES = [
        ('00_rider_probationary', 'Probationary Rider (noob)'),
        ('10_rider_standard', 'Standard Rider'),
        ('20_rider_senior', 'Senior Rider'),
        ('30_rider_professional', 'Pro Rider'),
    ]
    rider_class = models.CharField(max_length=30, null=True, blank=True, choices=RIDER_CLASS_CHOICES)
    is_core_rider = models.BooleanField(blank=True, default=False)
    override_pay_rate = models.PositiveIntegerField(null=True, blank=True,
        help_text='Override pay rate for specific rider - LEAVE BLANK unless you are sure!')

    signup_status = models.CharField(max_length=20, choices=(
        ('migrated', 'Migrated account - verification needed'), # migrated -> confirmed
        ('confirmed', 'Signed up - email confirmed'), # confirmed -> complete
        ('complete', 'Signed up - all details completed'),
    ), default='migrated')

    @property
    def name(self):
        fullname = ('%s %s' % (self.first_name, self.last_name)).strip()
        return fullname or self.display_name or (self.user.username if self.user else None) or '(no name)'

    @property
    def has_deputy_account(self):
        return self.source_row_state == 'live' and self.source_row_id is not None

    def __str__(self):
        return '%s (%s)' % (self.name, self.pk)

    def can_login(self):
        return self.active and self.signup_status in ('complete', 'migrated')

    def phone_valid(self):
        if self.has_deputy_account:
            return True
        if self.phone is not None:
            return MOBILE_PHONE_REGEX.fullmatch(self.phone)
        return False

    def abn_valid(self):
        return abn.validate(self.abn) != False

    def bank_details_valid(self):
        return BSB_REGEX.fullmatch(self.bank_bsb) and BANK_ACCT_REGEX.fullmatch(self.bank_acct)

    def profile_complete(self):
        if not self.active or not self.rider_class:
            # don't show profile warnings on non-rider accounts
            return True
        return (
            self.display_name and self.email_verified
            and (self.phone_valid() or self.has_deputy_account) # can't change phone or email once invited to deputy
            and self.abn_valid()
            and self.bank_details_valid()
            and self.signup_status == 'complete'
        )

    def pay_rate(self):
        if not self.rider_class:
            return None
        if self.override_pay_rate:
            return self.override_pay_rate
        from peddleconcept.settings import get_rider_payrate_setting
        return get_rider_payrate_setting().get(self.rider_class)

    def rider_class_label(self):
        for x, y in self.RIDER_CLASS_CHOICES:
            if x == self.rider_class:
                return y

    def bank_details_text(self):
        if self.bank_details_valid():
            return 'Account number ending in %s' % (self.bank_acct[:3])
        else:
            return 'Not provided'

    def to_json(self, in_editor=False):
        data = {
            'id': self.pk,
            'title': self.display_name,
            'phone': self.phone,
        }

        if in_editor:
            data.update({
                'active': self.active,
                'rider_class': self.rider_class,
                'rider_class_label': self.rider_class_label(),
                'is_core_rider': self.is_core_rider,
                'has_deputy': self.has_deputy_account,
            })
        return data

    exists = True # see middleware.py

def get_random_token():
    return secrets.token_urlsafe(42)

class PersonToken(models.Model):
    """ Database-backed URL tokens corresponding to a particular action, ie. for a particular Person object """
    class Meta:
        verbose_name = 'Magic Token (Advanced)'
        verbose_name_plural = 'Magic Tokens (Advanced)'

    TOKEN_ACTION_CHOICES = [
        # Create a generic "signup invitation" URL with a particular random token
        ('rider_invite_generic', 'Rider signup invitation URL'),
        # Existing rider login URLs are converted to this type
        ('rider_login_migrated', 'Migrated rider login URL'),
    ]
    action = models.CharField(max_length=30, choices=TOKEN_ACTION_CHOICES)
    token = models.CharField(max_length=80, default=get_random_token)
    person = models.ForeignKey(Person, on_delete=models.CASCADE, null=True)

    valid_from = models.DateTimeField(auto_now_add=True)
    valid_days = models.PositiveIntegerField(blank=True, default=0,
        verbose_name='Number of days token is valid (0 = forever)')

    def full_url(self):
        return settings.SITE_BASE_URL + self.url

    @property
    def url(self):
        if self.action == 'rider_login_migrated':
            return reverse('token_login_migrate', args=[self.token])
        elif self.action == 'rider_invite_generic':
            return reverse('rider_setup_invite', args=[self.token])

    def is_valid(self):
        if self.valid_days == 0:
            return True
        return self.valid_from + timedelta(days=self.valid_days) > timezone.now()