import discord,asyncio,DiscordUtils
from discord.ext import commands, tasks
from discord.ext.commands import *
from discord_components import *

music = DiscordUtils.Music()

class Music(Cog):

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

    @command(aliases=["j",])
    async def join(self,ctx):

        if not ctx.voice_client:

            if ctx.author.voice is None:

                await ctx.send("You are not in a Voice Channel yet.")
                return

            elif ctx.guild.me.voice == ctx.author.voice:

                pass

            await ctx.author.voice.channel.connect()

        else:
            try:
                await ctx.author.voice.channel.connect()
            except Exception as e:
                print(e)

    @command(aliases=["l",])
    async def leave(self,ctx):

        if not ctx.voice_client:

            await ctx.send("I\'m not in a Voice Channel yet.")

        else:

            await ctx.voice_client.disconnect()
            """
    @command()
    async def play(self,ctx,*urls):

        url = str(" ".join(urls))

        await ctx.invoke(self.bot.get_command("join"))

        if not ctx.voice_client:
            return

        player = music.get_player(guild_id = ctx.guild.id)

        if not player:
            player = music.create_player(ctx,ffmpeg_error_betterfix = True)

        if not ctx.voice_client.is_playing():
            await player.queue(url,search=True)

            song = await player.play()
            await ctx.send(f"Started Playing {song.name}.")

        else:
            song = await player.queue(url,search=True)
            await ctx.send(f"Added {song.name} to queue.")"""

    @command(aliases=["pl","play"])
    async def playlist(self,ctx,*uri):

        urls = str(" ".join(uri))

        try:
            url = urls.split(",")
        except:
            url = uri

        await ctx.invoke(self.bot.get_command("join"))
        player = music.get_player(guild_id = ctx.guild.id)

        if not ctx.voice_client is None:
            if not player:
                player = music.create_player(ctx,ffmpeg_error_betterfix = True)

            if not ctx.voice_client.is_playing():

                await player.queue(url[0],search=True)
                song = await player.play()
                await ctx.send(f"Started Playing {song.name}.")
                url.pop(0)

            if len(url) > 0:

                for i in url:

                    await player.queue(i,search=True)

            await ctx.send("Added Playlist!")
            await ctx.invoke(self.bot.get_command("queue"))

    @command()
    async def queue(self,ctx):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        embed = discord.Embed(title="Queue", description="Songs in Queue :" , color = discord.Color.random())
        msg = ""
        num = 1
        time = 0
        for i in player.current_queue():
            dur = i.duration
            minutes = dur//60
            seconds = dur%60
            time += dur
            msg += f"{num}. {i.name} {minutes}:{seconds}"
            msg += "\n"
            num += 1
        if len(player.current_queue()) == 0:
            msg = "None"
        minutes = time//60
        seconds = time%60
        embed.add_field(name=msg,value="\u200b")
        embed.set_footer(icon_url=ctx.author.avatar_url,text=f"Total time - {minutes}:{seconds}")
        await ctx.send(embed=embed)

    @command()
    async def resume(self,ctx):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        song = await player.resume()
        await ctx.send(f"Resumed Playing {song.name}")

    @command()
    async def pause(self,ctx):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        song = await player.pause()
        await ctx.send(f"Paused Playing {song.name}")

    @command(aliases=["r",])
    async def remove(self,ctx,num : int):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        num -= 1
        if num == 0:
            return await ctx.invoke(self.bot.get_command("skip"))
        elif num > 0:
            try:
                song = await player.remove_from_queue(num)
                if len(player.current_queue()) == 1:
                    name = song.name
                else:
                    name = song[0].name
                await ctx.send(f"Removed {name} from queue.")
            except IndexError:
                await ctx.send("Invalid number provided. Check the number from queue command.")

    @command(aliases=["s",])
    async def skip(self,ctx):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        song = await player.skip(force=True)
        await ctx.send(f"Skipped {song[0].name}")

    @command()
    async def loop(self,ctx):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        song = await player.toggle_song_loop()

        if song.is_looping:
            await ctx.send(f"{song.name} is now looping.")

        else:
            await ctx.send(f"Stopped looping {song.name}.")

    @command(aliases=["vol",])
    async def volume(self,ctx,num : int = None):

        if not ctx.voice_client:
            return
        player = music.get_player(guild_id = ctx.guild.id)
        if num:
            vol = num/100
            await player.change_volume(vol)
            await ctx.send(f"Volume changed to {num}%")
        else:
            msg = await ctx.send("> Volume :",components=[[Button(style=1,custom_id="0",label="0"),Button(style=1,custom_id="25",label="25"),Button(style=1,custom_id="50",label="50"),Button(style=1,custom_id="75",label="75"),Button(style=1,custom_id="100",label="100"),]])
            def check(res):
                return res.user == ctx.author and res.message.id == msg.id
            self.bot.flag = True
            while self.bot.flag:
                res = await self.bot.wait_for("button_click",check = check)
                vol = int(res.component.custom_id)
                await player.change_volume(vol)
                await res.respond(content="https://cdn.discordapp.com/emojis/803643669323972638.gif?v=1")

    @volume.before_invoke
    async def kk(self,ctx):

        self.bot.flag = False

    @command()
    async def stop(self,ctx):

        if ctx.voice_client is not None:

            try:
                player = music.get_player(guild_id = ctx.guild.id)
                await player.stop()
                await ctx.send("Stopped!")
            except Exception as e:
                print(e)

    @command(aliases=["p",])
    async def player(self,ctx):

        if not ctx.voice_client:

            return

        player = music.get_player(guild_id=ctx.guild.id)
        msg = await ctx.send("> Player :", components=[[Button(style=1,emoji="🔁",custom_id="loop"),Button(style=1,emoji="⏸",custom_id="pause"),Button(style=3,emoji="▶",custom_id="resume"),Button(style=4,emoji="⏹",custom_id="stop"),Button(style=4,emoji="⏭",custom_id="skip")]])

        self.bot.flag = True
        while self.bot.flag:
            def check(res):

                return res.user == ctx.author and res.message.id == msg.id

            res = await self.bot.wait_for("button_click",check=check)
            m1 = await ctx.send("Done.")
            await asyncio.sleep(1)
            await m1.delete()
            await ctx.invoke(self.bot.get_command(res.component.custom_id))

    @player.before_invoke
    async def playe(self,ctx):

        self.bot.flag = False

    @Cog.listener()
    async def on_voice_state_update(self,user,bfr,aftr):

        try:
            if aftr.channel is None:
                voice = discord.utils.get(self.bot.voice_clients,guild = bfr.channel.guild)
                if bfr.channel == voice.channel and len(bfr.channel.members) == 1 and self.bot.user in bfr.channel.members:
                    if not voice.is_connected():
                        return
                    try:
                        player = music.get_player(guild_id=bfr.channel.guild.id)
                        await player.stop()
                    except Exception as e:
                        print(e)
                    await voice.disconnect()

        except AttributeError as e:

            print(e)

    @Cog.listener()
    async def on_command_error(self,ctx,error):

        if isinstance(error,CommandNotFound):
            pass
        else:
            raise(error)

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


import layers
import cv2
import numpy as np
import utils
from PIL import Image
import computationalgraph

def load_images(filenames, IMG_SIZE=50):
    images = []

    for filename in filenames:
        #X shape is [WIDTH, HEIGHT, CHANNELS]
        X = cv2.imread(filename)
        #Resize X to [IMG_SIZE, WIDTH, HEIGHT]
        X = cv2.resize(X, (IMG_SIZE, IMG_SIZE))
        #Transform X to shape [CHANNELS, HEIGHT, WIDTH]
        X = X.transpose(2, 0, 1)
        #X = X[np.newaxis, :, :, :]
        images.append(X)

    return np.stack(images, axis=0)

X = load_images(["billie.png"], IMG_SIZE=50)
print(X.shape)

T = np.array([1,0,0,0,0])
T = T.T

######################################################################################################################
conv = layers.Convolution(kernel_size=3, kernel_channels=3, n_kernels=10, stride=1, same_padding=True)
X  = conv.forward(X)
print("[+] CONVOLVED_shape:", X.shape)
print()

activation = layers.Activation(activation="relu")
X = activation.forward(X)
print("[+] ACTIVATION_shape:", X.shape)
dActivation = activation.backward(np.ones_like(X))
print("dActivation_SHAPE:", dActivation.shape)
print()

maxpool = layers.MaxPooling(window_size=2, window_channels=10, stride=2)
X = maxpool.forward(X)
print("[+] MAXPOOLED_shape:", X.shape)
dMaxpool = maxpool.backward(np.ones_like(X))
print("dMaxpool_SHAPE:", dMaxpool.shape)

N, C, H, W = X.shape

flatten = layers.Flatten((C*H*W, N))
X = flatten.forward(X)
print(X.shape)

I, N = X.shape

fc1 = layers.FullyConnected("fc1", I, 1000, activation="relu")
X = fc1.forward(X)
print(X.shape)

fc2 = layers.FullyConnected("fc2", 1000, 10, activation="softmax")
Y = fc2.forward(X)
print(Y.shape)

cross_entropy = layers.CrossEntropy()
loss = cross_entropy.forward(Y, T)
print(loss)
######################################################################################################################

'''
print()

print("XSHAPE:", X.shape)
print()

N, C, H, W = X.shape

for n in range(N):
    for i in range(C):
        Xi = X[n][i]
        img = Image.fromarray(Xi)
        img = img.convert("LA")
        img_name = "output_example" + str(n) + "_filter" + str(i) + ".png"
        img.save(img_name)
        print("[+] " + img_name + " saved successfully")
'''


# -*- coding: utf-8 -*-
from twisted.internet.protocol import DatagramProtocol
from c2w.main.lossy_transport import LossyTransport
import c2w.main.constants as c2w_constants
import c2w.protocol.constants as constants
from twisted.internet import reactor
from c2w.protocol.message import Message
from c2w.protocol.format_type import FormatType
import logging

logging.basicConfig()
moduleLogger = logging.getLogger('c2w.protocol.udp_chat_client_protocol')

class c2wUdpChatClientProtocol(DatagramProtocol):

    def __init__(self, serverAddress, serverPort, clientProxy, lossPr):
        """
        :param serverAddress: The IP address (or the name) of the c2w server,
            given by the user.
        :param serverPort: The port number used by the c2w server,
            given by the user.
        :param clientProxy: The clientProxy, which the protocol must use
            to interact with the Graphical User Interface.

        Class implementing the UDP version of the client protocol.

        .. note::
            You must write the implementation of this class.

        Each instance must have at least the following attributes:

        .. attribute:: serverAddress

            The IP address of the c2w server.

        .. attribute:: serverPort

            The port number of the c2w server.

        .. attribute:: clientProxy

            The clientProxy, which the protocol must use
            to interact with the Graphical User Interface.

        .. attribute:: lossPr

            The packet loss probability for outgoing packets.  Do
            not modify this value!  (It is used by startProtocol.)

        .. note::
            You must add attributes and methods to this class in order
            to have a working and complete implementation of the c2w
            protocol.
        """

        #: The IP address of the c2w server.
        self.serverAddress = serverAddress
        #: The port number of the c2w server.
        self.serverPort = serverPort
        #: The clientProxy, which the protocol must use
        #: to interact with the Graphical User Interface.
        self.clientProxy = clientProxy
        self.lossPr = lossPr

        self.format = FormatType()

        # Dictionary of Type Message
        self.waitingMessages = {}

        # Emission counter
        self.emissionCounter = 0
        # Received counter
        self.receivedCounter = 0
        # Message number in the header of the messages
        self.numMessage = 0

        # Users list
        self.usersConnected = {}
        self.room = None
        self.movies = []

        self.mainRoom = True
        self.firstLogin = True
        self.userName = None

    def startProtocol(self):
        """
        DO NOT MODIFY THE FIRST TWO LINES OF THIS METHOD!!

        If in doubt, do not add anything to this method.  Just ignore it.
        It is used to randomly drop outgoing packets if the -l
        command line option is used.
        """
        self.transport = LossyTransport(self.transport, self.lossPr)
        DatagramProtocol.transport = self.transport

    def sendLoginRequestOIE(self, userName):
        """
        :param string userName: The user name that the user has typed.

        The client proxy calls this function when the user clicks on
        the login button.
        """
        moduleLogger.debug('loginRequest called with username=%s', userName)
        self.userName = userName
        pack = self.format.msg_connexion(self.numMessage, userName)

        self.sendPackage(pack, 1)

    def sendChatMessageOIE(self, message):
        """
        :param message: The text of the chat message.
        :type message: string

        Called by the client proxy  when the user has decided to send
        a chat message

        .. note::
           This is the only function handling chat messages, irrespective
           of the room where the user is.  Therefore it is up to the
           c2wChatClientProctocol or to the server to make sure that this
           message is handled properly, i.e., it is shown only by the
           client(s) who are in the same room.
        """
        self.numMessage += 1
        pack = self.format.msg_chat(self.numMessage, self.userName, message)
        self.sendPackage(pack, 9)

    def sendJoinRoomRequestOIE(self, roomName):
        """
        :param roomName: The room name (or movie title.)

        Called by the client proxy  when the user
        has clicked on the watch button or the leave button,
        indicating that she/he wants to change room.

        .. warning:
            The controller sets roomName to
            c2w.main.constants.ROOM_IDS.MAIN_ROOM when the user
            wants to go back to the main room.
        """

        self.numMessage += 1
        if roomName == c2w_constants.ROOM_IDS.MAIN_ROOM:
            message = self.format.msg_quitter_salon(self.numMessage)
            self.sendPackage(message, 4)

        else:
            message = self.format.msg_selection_film(self.numMessage, roomName)
            self.sendPackage(message, 3)
            self.room = roomName

    def sendLeaveSystemRequestOIE(self):
        """
        Called by the client proxy  when the user
        has clicked on the leave button in the main room.
        """
        self.numMessage += 1
        message = self.format.msg_quitter_app(self.numMessage)
        self.sendPackage(message, 2)

    def datagramReceived(self, datagram, host_port):
        """
        :param string datagram: the payload of the UDP packet.
        :param host_port: a touple containing the source IP address and port.

        Called **by Twisted** when the client has received a UDP
        packet.
        """

        [longueur, num_sequence, type, message] = self.format.datagram_received(datagram)

        # If the client receives a different type than 0 -> Always send the ACK
        if type != 0:
            pack = self.format.msg_acquittemen(num_sequence)
            self.transport.write(pack, host_port)

        if type == 0:
            if num_sequence == self.emissionCounter:
                # Set the message as sended
                self.waitingMessages[num_sequence].sended = True
                self.emissionCounter += 1

                # Format Type 2 : Quitter Application
                if self.waitingMessages[self.numMessage].type == 2:
                    self.clientProxy.leaveSystemOKONE()

                # Format 3: Selection du Film
                if self.waitingMessages[self.numMessage].type == 3:
                    self.clientProxy.joinRoomOKONE()
                    self.mainRoom = False

                # Format 4 : Quitter salon Film
                if self.waitingMessages[self.numMessage].type == 4:
                    self.clientProxy.joinRoomOKONE()
                    self.mainRoom = True

                # Delete message if it was sent
                del self.waitingMessages[num_sequence]
                if bool(self.waitingMessages):
                    self.controlPackages(self.emissionCounter)

        if num_sequence == self.receivedCounter and type != 0:
            self.receivedCounter += 1
            # Format Type 7 : Acceptation connexion
            if type == 7:
                self.room = c2w_constants.ROOM_IDS.MAIN_ROOM
                self.usersConnected[host_port] = []

            # Type 5: liste des films
            if type == 5:
                self.movies = self.format.get_movie_list(message)

            # Type 6: liste Utilisateurs
            if type == 6:
                self.usersConnected[host_port] = self.format.get_user_list(message)
                # I have the movies and users!

                if self.mainRoom:  # The user is in the main room
                    self.clientProxy.setUserListONE([])
                    if not self.firstLogin:
                        self.clientProxy.setUserListONE(self.usersConnected[host_port])
                    else:
                        self.clientProxy.initCompleteONE(self.usersConnected[host_port], self.movies)
                        self.firstLogin = False

                else:  # The user is in the movie room
                    self.clientProxy.setUserListONE([])
                    for user in self.usersConnected[host_port]:
                        self.clientProxy.userUpdateReceivedONE(user[0], self.room)

            # Format Type 8 : Refus de connexion
            if type == 8:
                self.clientProxy.connectionRejectedONE("Un utilisateur avec ce nom existe déjà")

            # Format 9 : Chat
            if type == 9:
                self.clientProxy.chatMessageReceivedONE(message[0], message[1])

    def sendPackage(self, pack, type):
        message = Message(pack, type)
        self.waitingMessages[self.numMessage] = message

        self.controlPackages(self.numMessage)

    def controlPackages(self, num_sequence):
        if num_sequence == self.emissionCounter:
            # Send the message
            self.transport.write(self.waitingMessages[num_sequence].data, (self.serverAddress, self.serverPort))
            # Increase emission counter
            self.waitingMessages[num_sequence].attempsCounter += 1
            # Reemission message
            reactor.callLater(1, self.resendPackage, num_sequence)

    def resendPackage(self, num_sequence):
        if num_sequence in self.waitingMessages:
            message = self.waitingMessages[num_sequence]
            # If the message is set as not sended
            if message.sended is False:
                # If attemps counter <= 7
                if message.attempsCounter <= constants.MAX_ATTEMPS_RESEND:
                    self.transport.write(message.data, (self.serverAddress, self.serverPort))
                    # Increase attemps counter
                    message.attempsCounter += 1

                    # Call this method again
                    reactor.callLater(1, self.resendPackage, num_sequence)
                else:
                    self.clientProxy.connectionRejectedONE("Connection rejected")
                    self.clientProxy.applicationQuit()


import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
train = pd.read_csv("training.csv")
train = train.drop(['url'], axis=1)

x_train = train.iloc[:, 0:-1]
y_train = train.iloc[:, -1]

clf = RandomForestClassifier(n_estimators=100, random_state=0)
clf.fit(x_train, y_train)

test = pd.read_csv("testing.csv")
test = test.drop(['url'], axis=1)

x_test = test.iloc[:, 0:-1]
y_test = test.iloc[:, -1]
y_pred = clf.predict(x_test)

print("Number of test data points:", len(y_pred))
print("Accuracy: ",accuracy_score(y_test, y_pred))
print("Precision: ",precision_score(y_test, y_pred, pos_label='phishing'))
print("Recall: ",recall_score(y_test, y_pred, pos_label='phishing'))
print("F1 Score: ",f1_score(y_test, y_pred, pos_label='phishing'))


import re

from django.utils.text import compress_string
from django.utils.cache import patch_vary_headers

from django import http

try:
    import levelhub.settings as settings

    XS_SHARING_ALLOWED_ORIGINS = settings.XS_SHARING_ALLOWED_ORIGINS
    XS_SHARING_ALLOWED_METHODS = settings.XS_SHARING_ALLOWED_METHODS
except:
    XS_SHARING_ALLOWED_ORIGINS = '*'
    XS_SHARING_ALLOWED_METHODS = ['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE']

class XsSharing(object):
    """
        This middleware allows cross-domain XHR using the html5 postMessage API.

        Access-Control-Allow-Origin: http://foo.example
        Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
    """

    def process_request(self, request):

        if 'HTTP_ORIGIN' in request.META:
            origin = request.META['HTTP_ORIGIN']
        elif 'HTTP_X_CLIENT_IP' in request.META:
            origin = request.META['HTTP_X_CLIENT_IP']
        else:
            origin = request.META['HTTP_HOST']

        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = http.HttpResponse()
            response['Access-Control-Allow-Origin'] = origin  # XS_SHARING_ALLOWED_ORIGINS
            response['Access-Control-Allow-Methods'] = ",".join(XS_SHARING_ALLOWED_METHODS)
            response['Access-Control-Allow-Credentials'] = 'true'
            if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.META:
                response['Access-Control-Allow-Headers'] = request.META['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
            response['Access-Control-Max-Age'] = '0'

            return response

        return None

    def process_response(self, request, response):

        # Avoid unnecessary work
        if response.has_header('Access-Control-Allow-Origin'):
            return response

        if 'HTTP_ORIGIN' in request.META:
            origin = request.META['HTTP_ORIGIN']
        elif 'HTTP_X_CLIENT_IP' in request.META:
            origin = request.META['HTTP_X_CLIENT_IP']
        else:
            origin = request.META['HTTP_HOST']

        response['Access-Control-Allow-Origin'] = origin  # XS_SHARING_ALLOWED_ORIGINS
        response['Access-Control-Allow-Methods'] = ",".join(XS_SHARING_ALLOWED_METHODS)
        response['Access-Control-Allow-Credentials'] = 'true'
        if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.META:
            response['Access-Control-Allow-Headers'] = request.META['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
        response['Access-Control-Max-Age'] = '0'

        return response


import httphelper
import requests
import quandl, pandas as pd

quandl_partialurl = 'https://www.quandl.com/api/v3/datasets/WIKI/{}/data.json?start_date={}&api_key={}'
quandl_fullurl = 'https://www.quandl.com/api/v3/datasets/WIKI/{}/data.json?&api_key={}'

def load_historicdata(symbol):
    url = quandl_fullurl.format(symbol, quandl.ApiConfig.api_key)
    return __process_request(url)

def load_partialhistoricdata(symbol, startdate):
    url = quandl_partialurl.format(symbol, startdate.strftime('%Y-%m-%d'), quandl.ApiConfig.api_key)
    # print(url)
    return __process_request(url)

def __process_request(url):

    #jsn = requests.get(url).json()
    jsn = httphelper.get_httprequest(url).json()

    data = jsn['dataset_data']['data']
    cln = jsn['dataset_data']['column_names']
    df = pd.DataFrame(data = data, columns = cln)
    df.set_index('Date', inplace=True)
    df.index = df.index.astype('M')
    df = df.sort_index()

    return df


from flask import Blueprint, request, current_app
from libs.awsservice import *
from libs.awsclient import awsTempToken
from libs.awss3service import *
from libs.awssupport import awssupport
from libs.defResponse import success, nonauthorization
from models.Company import CompanyControl
from models.AwsTokenRecord import AwsRecordControl
from views.auth import auth
from datetime import datetime
from uuid import uuid4
import mimetypes
import os

makeImage = Blueprint("makeImage", __name__)

import boto3

@makeImage.route("/make_image", methods = ["POST"])
@auth.login_required
def image():
    if not request.json or not request.json.get("CompanyId") or not request.json.get("service_list") or not request.json.get("StartTime") or not request.json.get("EndTime") or not request.json.get("Unit") or not request.json.get("Region"):
        return success(20002, msg="缺少必要参数")
    service_list = request.json.get("service_list")

    aksk = CompanyControl().getAwsSecret(request.json.get("CompanyId"))
    if not aksk:
        return success(20007, msg="客户id不正确")

    dict_result = {}
    startTime = datetime.strptime(request.json.get("StartTime"), '%Y, %m, %d')
    endTime = datetime.strptime(request.json.get("EndTime"), '%Y, %m, %d')
    dict_result['Unit'] = request.json.get("Unit")
    P = []
    MetricName = ''
    for i in service_list:
        if not i.get("Namespace") or not i.get("Dimensions") or not i.get("ServiceType") or not i.get("Statistics") or not i.get("MetricName"):
            return success(20003, msg="缺少必要参数")
        service_dict = {}
        service_dict['serviceType'] = i.get("ServiceType")
        MetricName = i.get("MetricName")
        dict_result['type'] = MetricName
        # s3_client = boto3.client('s3', aws_access_key_id=aksk[0],
        #                          aws_secret_access_key=aksk[1],
        #                          region_name=request.json.get("Region"))
        # s3_client.download_file('bositool.file', '1.PNG', 'test.png')
        client = boto3.client('cloudwatch', aws_access_key_id=aksk[0],
                              aws_secret_access_key=aksk[1],
                              region_name=request.json.get("Region"))

        response = client.get_metric_statistics(
            Namespace=i.get("Namespace"),
            MetricName=i.get("MetricName"),
            Dimensions=i.get("Dimensions"),
            StartTime=startTime,
            EndTime=endTime,
            Period=int((endTime - startTime).total_seconds()),
            # Period=i.json.get("Period"),
            Statistics=i.get("Statistics"),
            Unit=request.json.get("Unit")
            # Unit='Percent'
        )
        p = {}
        j = response['Datapoints'][0]
        a = 1
        for en in i.get("Statistics"):
            k = j[en]
            p['k'+str(a)] = en
            p['v'+str(a)] = k
            a += 1
        service_dict['p'] = p
        P.append(service_dict)
    dict_result['P'] = P

    '''
     {
        'type':'cpu',
        'Unit':'Percent',
        'P': [
            {
                'serviceType':'ec2',
                'p': {
                    'k1': 'max',
                    'k2': 'avg',
                    'v1': '95',
                    'v2': '90'
                }
            }, {
                'serviceType':'rds',
                'p': {
                    'k1': 'max',
                    'k2': 'avg',
                    'v1': '94',
                    'v2': '91'
                }
            }, {
                'serviceType':'redis',
                'p': {
                    'k1': 'max',
                    'k2': 'avg',
                    'v1': '93',
                    'v2': '90'
                }
            }
        ]
     }
    '''
    print(111)
    print(dict_result)
    print(111)
    file_path = make_image(dict_result)

    s3_client = boto3.client('s3', aws_access_key_id=aksk[0],
                              aws_secret_access_key=aksk[1],
                              region_name=request.json.get("Region"))
    CompanyName = CompanyControl().getCompanyName(request.json.get("CompanyId"))
    dir = CompanyName + '/' + request.json.get("Region") + '/' + request.json.get("StartTime") + '-' + request.json.get("EndTime") + '/' + MetricName
    s3_client.upload_file(str(file_path), 'bositool.file', dir + '/test.png')
    return success(20000, msg="更新成功")

@makeImage.route("/list_image", methods=["POST"])
@auth.login_required
def list_image():
    if not request.json or not request.json.get("CompanyId") or not request.json.get("Region"):
        return success(20002, msg="缺少必要参数")
    aksk = CompanyControl().getAwsSecret(request.json.get("CompanyId"))
    if not aksk:
        return success(20007, msg="客户id不正确")
    s3_client = boto3.client('s3', aws_access_key_id=aksk[0],
                              aws_secret_access_key=aksk[1])
    CompanyName = CompanyControl().getCompanyName(request.json.get("CompanyId"))
    response = s3_client.list_objects(
        Bucket='bositool.file',
        Marker=CompanyName
    )
    k = []
    for i in response['Contents']:
        d = {}
        key = i['Key']
        if not key.startswith(CompanyName):
            continue
        # k.append(key)
        d['key'] = key
        d['url'] = 'https://s3.{}.amazonaws.com.cn/{}/{}'.format(request.json.get("Region"), 'bositool.file', key)
        k.append(d)
    return {
        "image": k
    }

from unittest import mock
from os.path import *

def get_chrome_driver():
    from selenium import webdriver
    options = webdriver.ChromeOptions()
    options.add_argument("headless")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-dev-shm-usage')
    return webdriver.Chrome(options=options)

from snapshot_selenium import snapshot as driver
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot

def make_image(data):
    print("make in")
    metric = data["type"]
    unit = data['Unit']
    name_list = []
    for i in data["P"]:
        name_list.append(i["serviceType"])

    png = png_bar_chart(metric, unit, name_list, data)
    with mock.patch('snapshot_selenium.snapshot.get_chrome_driver', get_chrome_driver):
        make_snapshot(driver, png.render(), "{}.png".format(metric), 2, 2, True)
    file_path = os.path.abspath("/app") + "/{}.png".format(metric)
    print(file_path)
    return file_path

def png_bar_chart(metric, unit, x_name, data):
    bar = Bar(init_opts=opts.InitOpts(theme="white", bg_color="#c4ccd3"))
    bar.add_xaxis(x_name)

    k_list = []
    v_list = []
    for j in range(int((len(data['P'][0]['p'].keys()) / 2))):
        key = 'k' + str(j + 1)
        k_list.append(key)
        val = 'v' + str(j + 1)
        v_list.append(val)

    V = []
    a = 0
    for _ in range(len(v_list)):
        v = []
        for k in data['P']:
            v.append(k['p'][v_list[a]])
        V.append(v)
        a += 1
    print(V)

    a = 0
    for i in k_list:
        bar.add_yaxis(data['P'][0]['p'][i], V[a])
        a += 1

    bar.reversal_axis()
    bar.set_series_opts(label_opts=opts.LabelOpts(position="right"))
    bar.set_global_opts(title_opts=opts.TitleOpts(title="{}".format(metric),
                                                  pos_right="40%",
                                                  pos_top="15"),
                        legend_opts=opts.LegendOpts(pos_top="20",
                                                    pos_right="20",
                                                    orient="vertical"),
                        xaxis_opts=opts.AxisOpts(name="{}".format(unit)),
                        yaxis_opts=opts.AxisOpts(name="服务类型"))
    return bar


''' This is used to plot the results from the pitch detector.
	To change which sound file you're looking at, modify the 'testing' variable.
	To change which note you're looking at, modify the 'ii' variable.
	To change if you're looking at a single note or the entire melody,
		modify the 'sung_note' variable, and 'timestamps', and axarr[0].scatter
'''

#import pitch detectors:
from helpers import *
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
np.set_printoptions(threshold='nan')

hopSize = 128 #units: samples
frameSize = 2048 #units: samples
sr = 44100 #sample rate: 44100 samples per second
guessUnvoiced = True # read the algorithm's reference for more details
run_predominant_melody = PitchMelodia(guessUnvoiced=guessUnvoiced,
                                      frameSize=frameSize,
                                      hopSize=hopSize)
methods = ['yinfft']

indir = '/Users/asdfang/Desktop/YEAR3/17SPRING/399EECSindependentstudy/HarmonizeMe/PitchOnsetTrackerTests'

''' MODIFY testing AND ii BASED ON WHAT TEST AND WHICH LABEL YOU'RE LOOKING AT: '''
testing = 'Male_1a'
ii = 0 #looking at the ii-th label, starting from 0

sound_file = testing + '.wav'
label_file = testing + '_Labels.txt'

sound_path = indir + '/' + testing + '/' + sound_file
label_path = indir + '/' + testing + '/' + label_file

sound_path = './totest/original.wav'
label_path = './totest/original_Labels.txt'

#testing from specific file
# sound_path = 'tests/1a/original.wav'
# label_path = 'tests/1a/original_Labels.txt'

#loading full sound file into a mono array of dtype=numpy.float32
audio_array, dummy_var = librosa.core.load(sound_path, sr=sr)

# test_onsets = aubio_onsets(audio_array)
# for ii in range(0, len(test_onsets)):
# 	test_onsets[ii] = test_onsets[ii]/44100.0
# print test_onsets

#parsing text file
full_labels = open(label_path)
lines = full_labels.readlines()
label_info = [] #parsed file
for l in lines:
	label_info.append(l.strip().split('\t')) #split with spaces as separation; strip() takes care of the \t's
#label_info[x] holds the xth label; elements are strings
#label[x][0] holds the start time, label[x][1] holds the end time, label[x][2] holds the info for the xth label

#parsing ground truths
ground_truth_onsets_seconds = []
ground_truth_onsets_samps = []
lines = []
with open(label_path) as input:
    lines = zip(*(line.strip().split('\t') for line in input))

for midi, onset in zip(lines[2], lines[0]):
	ground_truth_onsets_seconds.append(float(onset))
# convert onsets to samples
for onset in ground_truth_onsets_seconds:
	ground_truth_onsets_samps.append(int(numpy.around(onset*sr)))

#start and end in terms of seconds
s_time = float(label_info[ii][0])
e_time = float(label_info[ii][1])
#start and end in terms of samples
start = int(np.rint(s_time * float(sr)))
end = int(np.rint(e_time * float(sr)))
lbl = label_info[ii][2]

#making midi arrays
ground_truth_midis = []
for l in label_info:
	if l[2].strip() == "SIL":
		ground_truth_midis.append(90.0)
	else:
		ground_truth_midis.append(float(l[2]))

''' MODIFY THIS BASED ON ISOLATED NOTE VS. FULL MELODY: '''
# ISOLATED NOTE:
# sung_note = audio_array[start:end]

#FULL MELODY:
sung_note = audio_array
s_time = 0.0
e_time = librosa.get_duration(audio_array, sr=sr)

#feeding it into the pitch detector; first pad
#pad with zeros to make it divisible by hopSize
# audio_length = sung_note.size
# num_padded_zeros = 128 - (audio_length % 128)
# sung_note = np.concatenate([sung_note, np.zeros(num_padded_zeros, dtype=np.float32)])
detector_result_midi_verbose = aubio_pitches(audio_array)
detector_result_midis = verbose_to_detected_midi(detector_result_midi_verbose, ground_truth_onsets_samps, hopSize)

'''
matplot time!
'''
''' MODIFY THIS BASED ON ISOLATED NOTE VS. FULL MELODY: '''
dur = librosa.get_duration(sung_note, sr=sr)
# if full melody:
timestamps = np.linspace(s_time, e_time, len(detector_result_midi_verbose))
#if sliced note:
# num_times = len(detector_result_midi_verbose[int(np.around(start/hopSize)):int(np.around(end/hopSize))])
# timestamps = np.linspace(s_time, e_time, num_times) #+1 because of padding

#plotting
f, axarr = plt.subplots(2, figsize=(15, 9))
green_patch = mpatches.Patch(color='green', label='Ground Truth Onsets')
black_patch = mpatches.Patch(color='black', label='Ground Truth Pitch')
red_patch = mpatches.Patch(color='red', label='Pitch Detector Result')
axarr[0].legend(handles=[green_patch, black_patch, red_patch])
''' MODIFY THIS BASED ON ISOLATED NOTE VS. FULL MELODY: '''
#full melody:
axarr[0].scatter(timestamps, detector_result_midi_verbose)
#spliced note:
# axarr[0].scatter(timestamps, detector_result_midi_verbose[int(np.around(start/hopSize)):int(np.around(end/hopSize))])
axarr[0].set_title('Pitch Detector')
axarr[0].set_ylabel('MIDI Note Number')
axarr[0].set_xlabel('Time (s)')
xmin = s_time
xmax = e_time
ymin = 50.0
ymax = 80.0
axarr[0].axis([xmin, xmax, ymin, ymax]) #xmin, xmax, ymin, ymax
axarr[0].vlines(ground_truth_onsets_seconds, ymin, ymax, colors='green')

''' MODIFY THIS BASED ON ISOLATED NOTE VS. FULL MELODY: '''
#if visualizing one note
'''
if label_info[ii][2].strip() == 'SIL':
	axarr[0].text((e_time-s_time)/2.5, (ymax-ymin)*0.75, "SIL", color='black')
else:
	axarr[0].hlines(ground_truth_midis[ii], s_time, e_time, color='black')
	axarr[0].text(s_time+(e_time-s_time)/2.0, ground_truth_midis[ii]+5, str(ground_truth_midis[ii]), color='black')
	axarr[0].hlines(detector_result_midis[ii], s_time, e_time, color='red')
	axarr[0].text(s_time+(e_time-s_time)/2.0, detector_result_midis[ii]-5, str(round(float(detector_result_midis[ii]), 1)), color='red')
'''

#if visualizing full melody
for ii in range(0, len(ground_truth_midis)):
	if label_info[ii][2].strip() == 'SIL':
		continue
	s = float(label_info[ii][0])
	e = float(label_info[ii][1])
	axarr[0].hlines(ground_truth_midis[ii], s, e, colors='black')
	axarr[0].text(s+(e-s)/3.5, ground_truth_midis[ii]+5, str(ground_truth_midis[ii]), color='black')
	axarr[0].hlines(detector_result_midis[ii], s, e, colors='red')
	axarr[0].text(s+(e-s)/3.5, detector_result_midis[ii]-5, str(round(float(detector_result_midis[ii]), 1)), color='red')

f.subplots_adjust(hspace=0.5)
plt.show()


from django.shortcuts import render, redirect, get_object_or_404
from django.views import View

from .cart_module import Cart
from .models import Order, OrderItem, DiscountCode
from product.models import Product

class CartDetailView(View):
    def get(self, request):
        cart = Cart(request)
        return render(request, "order/cart.html", {'cart':cart})

class CartAddView(View):
    def post(self, request, pk):
        product = get_object_or_404(Product, id=pk)
        size, color, quantity, price, discount_price = request.POST.get('size', '-'), \
            request.POST.get('color', '-'), request.POST.get('quantity'), \
            request.POST.get('price'), request.POST.get('discount_price')
        cart = Cart(request)
        cart.add(product, size, color, quantity, price, discount_price)
        return redirect('order:cart-detail')

class CartDeleteView(View):
    def get(self, request, id):
        cart = Cart(request)
        cart.delete(id)
        return redirect('order:cart-detail')

class OrderDetailView(View):
    def get(self, request, pk):
        order = get_object_or_404(Order, id=pk)
        return render(request, 'order/order-detail.html', {'order':order})

class OrderAddView(View):
    def get(self, request):
        cart = Cart(request)
        order = Order.objects.create(user=request.user, total_price=cart.total())
        for item in cart:
            OrderItem.objects.create(order=order, product=item['product'], size=item['size'], \
                color=item['color'], quantity=item['quantity'], price=item['price'])
        return redirect('order:order-detail', order.id)

class ApplyDiscountView(View):
    def post(self, request, pk):
        code = request.POST.get('discount_code')
        order = get_object_or_404(Order, id=pk)
        discount_code = get_object_or_404(DiscountCode, name=code)
        if discount_code.quantity == 0:
            return redirect('order:order-detail', order.id)
        order.total_price -= order.total_price*discount_code.discount/100
        order.save()
        discount_code.quantity -= 1
        discount_code.save()
        return redirect('order:order-detail', order.id)


# Jane Street: June 2020
# Twenty Four Seven

# The grid is incomplete. Place numbers in some of the empty cells below so that in total the grid
# contains one 1, two 2’s, etc., up to seven 7’s. Furthermore, each row and column must contain
# exactly 4 numbers which sum to 20. Finally, the numbered cells must form a connected region*,
# but every 2-by-2 subsquare in the completed grid must contain at least one empty cell.

# The answer to this puzzle is the product of the areas of the connected groups of empty squares in the completed grid.

from z3 import *
from functools import reduce
import time

import constraints
import helper

tfs_array = (
    (0, 4, 0, 0, 0, 0, 0),
    (0, 0, 6, 3, 0, 0, 6),
    (0, 0, 0, 0, 0, 5, 5),
    (0, 0, 0, 4, 0, 0, 0),
    (4, 7, 0, 0, 0, 0, 0),
    (2, 0, 0, 7, 4, 0, 0),
    (0, 0, 0, 0, 0, 1, 0),
)

def one_to_seven(grid, c):
    s_grid_size = 7

    c.add(constraints.findNNs(grid,s_grid_size))

def row_col_four_twenty(grid, c):
    constraints.sum_of_rows(grid, c, 20)
    constraints.count_in_each_r_and_c(grid, c, 4)

s = Solver()

X = [[Int("x_%s_%s" % (i + 1, j + 1)) for j in range(7)] for i in range(7)]

one_to_seven(X, s)
row_col_four_twenty(X, s)

constraints.check_n_by_n_subgrid_empty_space(X, s, 2, 1)
constraints.check_within_range(X, s, 0, 7)

tfs_array_constr = [
    If(tfs_array[i][j] == 0, True, X[i][j] == tfs_array[i][j])
    for i in range(7)
    for j in range(7)
]

s.add(tfs_array_constr)

def calculate_answer(grid):
   print("Final Answer : ")
   print(reduce((lambda x,y: x*y), helper.count_region(grid, count_zero=True)))
   print("Execution Complete!!")

# enforce_cell_neighbours(X, s)
stats_to_print = ["decisions", "solve-eqs-steps",
                  "time", "num allocs", "memory"]
start_time = time.time_ns()
while True:
    if s.check() == sat:
        print("------------------------")
        # print(s.statistics().keys())
        m = s.model()
        print("stats for this run")
        stats = s.statistics()
        for stat in stats_to_print:
            if stat in stats.keys():
                print(stat, stats.get_key_value(stat))

        r = [[m.evaluate(X[i][j]).as_long() for j in range(7)] for i in range(7)]
        if len(helper.count_region(r, count_zero=False))==1:
            print("found solution")
            print_matrix(r)
            calculate_answer(r)
            break
        else:
            print("rerun")
            new_c = Not(And([X[i][j] == r[i][j]
                        for i in range(7) for j in range(7)]))
            s.add(new_c)

    else:
        print("failed to solve")
        break

end_time = time.time_ns()

print("elapsed time:", end_time-start_time)


import tensorflow as tf
import kerastuner as kt
import os
import cv2
import random
import time
import numpy as np
import pickle
import h5py
import keras
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Activation, Flatten, MaxPooling2D, Dropout

DATADIR = "faces"
IMG_SIZE = 128
CATEGORIES = ["Akif", "Ali", "Ela", "Fatih", "Furkan"]
num_classes = 5

def create_training_data ():
    training_data = []
    for category in CATEGORIES:
        path = os.path.join (DATADIR, category)
        class_num = CATEGORIES.index (category)
        for img in os.listdir (path):
            try:
                img_array = cv2.imread (os.path.join (path, img), cv2.IMREAD_GRAYSCALE)
                new_array = cv2.resize (img_array, (IMG_SIZE, IMG_SIZE))
                training_data.append ([new_array, class_num])
            except Exception as e:
                print (e)
                pass
    random.shuffle (training_data)
    return training_data

training_data = create_training_data ()
[training_data, test_data] = train_test_split (training_data)
X = []
y = []

for features, label in training_data:
    X.append (features)
    y.append (label)
X_test = []
y_test = []
for features, label in test_data:
    X_test.append (features)
    y_test.append (label)
X = np.array (X).reshape (-1, IMG_SIZE, IMG_SIZE, 1)
X_test = np.array (X_test).reshape (-1, IMG_SIZE, IMG_SIZE, 1)
y = np.array (y)
y_test = np.array (y_test)

def build_model(hp):
    model=Sequential()
    input_kernel=hp.Choice('input_kernel',[3,5,11])
    input_activation= hp.Choice('input_activation',['softmax','softplus','softsign','relu','tanh','sigmoid','hard_sigmoid','linear'])
    input_units=hp.Choice('input_units',[20,32,64,128,256,384,512])
    input_stride=hp.Choice('input_stride',[1,2,3,4])
    #input_padding=hp.Choice('input_padding',['same','valid'])
    model.add(Conv2D(input_units,(input_kernel,input_kernel),strides=(input_stride,input_stride),padding='same',input_shape=(IMG_SIZE,IMG_SIZE,1),activation=input_activation))

    for i in range(hp.Int("Conv_Layer_Groups",min_value=1,max_value=2)):
        for j in range(hp.Int(f'Conv_Layer_Group_{i}_Layers',min_value=1,max_value=4)):
            conv_units=hp.Choice(f'Conv_Group_{i}_Layer_{j}_units',[20,32,64,128,256,384,512])
            conv_kernel=hp.Choice(f'Conv_Group_{i}_Layer_{j}_kernel',[3,5,11])
            conv_activation= hp.Choice(f'Conv_Group_{i}_Layer_{j}_activation',['softmax','softplus','softsign','relu','tanh','sigmoid','hard_sigmoid','linear'])
            conv_stride=hp.Choice(f'Conv_Group_{i}_Layer_{j}_stride',[1,2,3,4])
            model.add(Conv2D(conv_units,kernel_size=(conv_kernel,conv_kernel),strides=(conv_stride,conv_stride),activation=conv_activation,padding='same'))

        model.add(MaxPooling2D(pool_size=(2,2)))

    model.add(Flatten())

    for a in range(hp.Int('Dense_Layers',min_value=1,max_value=2)):
        dense_units=hp.Choice(f'Dense_Layer_{a}_units',[512,1024,2048,4096])
        dense_activation=hp.Choice(f'Dense_Layer_{a}_activation',['softmax','softplus','softsign','relu','tanh','sigmoid','hard_sigmoid','linear'])
        model.add(Dense(units=dense_units,activation=dense_activation))
        drop_rate= hp.Choice(f'Dense_Layer_{a}_dropout_droprate',  [ 0.05, 0.1, 0.15, 0.2,0.25, 0.3, 0.35, 0.40, 0.45, 0.50])
        model.add(Dropout(drop_rate))

    model.add(Dense(5))
    model.add(Activation('softmax'))

    loss='sparse_categorical_crossentropy'

    model.compile(optimizer=tf.keras.optimizers.Adam(hp.Float('learning_rate', 1e-4, 1e-2, sampling='log')),loss='sparse_categorical_crossentropy',metrics=['accuracy'])
    print(model.summary())
    return model

LOG_DIR = f"{int (time.time ())}"
tuner=kt.RandomSearch
tuner = kt.RandomSearch(
    build_model,
    objective='val_acc',
    max_trials=2,
    executions_per_trial=1,
    directory=LOG_DIR)

tuner.search(x=X,
             y=y,
             verbose=2, # just slapping this here bc jupyter notebook. The console out was getting messy.
             epochs=1,
             batch_size=64,
             validation_data=(X_test,y_test))

print (tuner.get_best_hyperparameters () [0].values)
print (tuner.results_summary ())
print (tuner.get_best_models () [0].summary ())
model=tuner.get_best_models()[0]
tf.keras.models.save_model(model,'mymodel.h5')
new_model=tf.keras.models.load_model('mymodel.h5')


#!/usr/bin/env python
"""
# License: GNU Affero General Public License v3 or later
# A copy of GNU AGPL v3 should have been included in this software package in LICENSE.txt.

File containing definition of the NCBI class and containing functions useful for handling NCBI taxonomy databases
"""

import gzip
import logging
import os
import string
import sys

from typing import Dict, Set, Tuple
from itertools import chain

import pandas as pd

from tqdm import tqdm

from autometa.common.utilities import file_length
from autometa.common.exceptions import DatabaseOutOfSyncError
from autometa.config.utilities import DEFAULT_CONFIG
from autometa.taxonomy.database import TaxonomyDatabase

logger = logging.getLogger(__name__)

NCBI_DIR = DEFAULT_CONFIG.get("databases", "ncbi")
# For cases where autometa has not been configured, attempt to find ncbi directory via source
NCBI_DIR = NCBI_DIR if not "None" in NCBI_DIR else NCBI_DIR.replace("None", ".")

class NCBI(TaxonomyDatabase):
    """Taxonomy utilities for NCBI databases."""

    def __init__(self, dbdir, verbose=False):
        """
        Instantiates the NCBI class

        Parameters
        ----------

        dbdir : str
            Path to the database directory

        verbose : bool, optional
            log progress to terminal, by default False

        """
        self.dbdir = dbdir
        self.verbose = verbose
        self.disable = not self.verbose
        self.names_fpath = os.path.join(self.dbdir, "names.dmp")
        self.nodes_fpath = os.path.join(self.dbdir, "nodes.dmp")
        self.merged_fpath = os.path.join(self.dbdir, "merged.dmp")
        self.delnodes_fpath = os.path.join(self.dbdir, "delnodes.dmp")
        # Set prot.accession2taxid filepath
        self.accession2taxid_fpath = os.path.join(self.dbdir, "prot.accession2taxid")
        acc2taxid_gz = ".".join([self.accession2taxid_fpath, "gz"])
        if not os.path.exists(self.accession2taxid_fpath) and os.path.exists(
            acc2taxid_gz
        ):
            self.accession2taxid_fpath = acc2taxid_gz
        # Set prot.accession2taxid.FULL.gz filepath
        self.accession2taxidfull_fpath = os.path.join(
            self.dbdir, "prot.accession2taxid.FULL"
        )
        acc2taxid_gz = ".".join([self.accession2taxidfull_fpath, "gz"])
        if not os.path.exists(self.accession2taxidfull_fpath) and os.path.exists(
            acc2taxid_gz
        ):
            self.accession2taxidfull_fpath = acc2taxid_gz
        # Set dead_prot.accession2taxid filepath
        self.dead_accession2taxid_fpath = os.path.join(
            self.dbdir, "dead_prot.accession2taxid"
        )
        acc2taxid_gz = ".".join([self.dead_accession2taxid_fpath, "gz"])
        if not os.path.exists(self.dead_accession2taxid_fpath) and os.path.exists(
            acc2taxid_gz
        ):
            self.dead_accession2taxid_fpath = acc2taxid_gz
        # Check formatting for nr database
        self.nr_fpath = os.path.join(self.dbdir, "nr.gz")
        nr_bname = os.path.splitext(os.path.basename(self.nr_fpath))[0]
        nr_dmnd_fname = ".".join([nr_bname, "dmnd"])
        nr_dmnd_fpath = os.path.join(self.dbdir, nr_dmnd_fname)
        if os.path.exists(nr_dmnd_fpath):
            self.nr_fpath = nr_dmnd_fpath
        if "dmnd" not in os.path.basename(self.nr_fpath):
            # This check should probably be in the dependencies/databases file...
            logger.warning(
                f"DatabaseWarning: {self.nr_fpath} needs to be formatted for diamond!"
            )
        # Setup data structures from nodes.dmp, names.dmp and merged.dmp
        self.nodes = self.parse_nodes()
        self.names = self.parse_names()
        self.merged = self.parse_merged()
        self.delnodes = self.parse_delnodes()

    def __repr__(self):
        """
        Operator overloading to return the string representation of the class object

        Returns
        -------
        str
            String representation of the class object
        """
        return str(self)

    def __str__(self):
        """
        Operator overloading to return the directory path of the class object

        Returns
        -------
        str
            Directory path of the class object
        """
        # Perhaps should place summary here of files that do or do not exist?
        return self.dbdir

    def parse_names(self) -> Dict[int, str]:
        """
        Parses through names.dmp database and loads taxids with scientific names

        Returns
        -------
        dict
            {taxid:name, ...}
        """
        if self.verbose:
            logger.debug(f"Processing names from {self.names_fpath}")
        names = {}
        fh = open(self.names_fpath)
        for line in tqdm(fh, disable=self.disable, desc="parsing names", leave=False):
            taxid, name, __, classification = line.strip("\t|\n").split("\t|\t")[:4]
            taxid = int(taxid)
            name = name.lower()
            # Only add scientific name entries
            if classification == "scientific name":
                names.update({taxid: name})
        fh.close()
        if self.verbose:
            logger.debug("names loaded")
        return names

    def parse_nodes(self) -> Dict[int, str]:
        """
        Parse the `nodes.dmp` database to be used later by :func:`autometa.taxonomy.ncbi.NCBI.parent`, :func:`autometa.taxonomy.ncbi.NCBI.rank`
        Note: This is performed when a new NCBI class instance is constructed

        Returns
        -------
        dict
            {child_taxid:{'parent':parent_taxid,'rank':rank}, ...}
        """
        if self.verbose:
            logger.debug(f"Processing nodes from {self.nodes_fpath}")
        fh = open(self.nodes_fpath)
        __ = fh.readline()  # root line
        nodes = {1: {"parent": 1, "rank": "root"}}
        for line in tqdm(fh, disable=self.disable, desc="parsing nodes", leave=False):
            child, parent, rank = line.split("\t|\t")[:3]
            parent, child = [int(node) for node in [parent, child]]
            rank = rank.lower()
            nodes.update({child: {"parent": parent, "rank": rank}})
        fh.close()
        if self.verbose:
            logger.debug("nodes loaded")
        return nodes

    def parse_merged(self) -> Dict[int, int]:
        """
        Parse the merged.dmp database
        Note: This is performed when a new NCBI class instance is constructed

        Returns
        -------
        dict
            {old_taxid: new_taxid, ...}
        """
        if self.verbose:
            logger.debug(f"Processing nodes from {self.merged_fpath}")
        fh = open(self.merged_fpath)
        merged = {}
        for line in tqdm(fh, disable=self.disable, desc="parsing merged", leave=False):
            old_taxid, new_taxid = [
                int(taxid) for taxid in line.strip("\t|\n").split("\t|\t")
            ]
            merged.update({old_taxid: new_taxid})
        fh.close()
        if self.verbose:
            logger.debug("merged loaded")
        return merged

    def parse_delnodes(self) -> Set[int]:
        """
        Parse the delnodes.dmp database
        Note: This is performed when a new NCBI class instance is constructed

        Returns
        -------
        set
            {taxid, ...}
        """
        if self.verbose:
            logger.debug(f"Processing delnodes from {self.delnodes_fpath}")
        fh = open(self.delnodes_fpath)
        delnodes = set()
        for line in tqdm(
            fh, disable=self.disable, desc="parsing delnodes", leave=False
        ):
            del_taxid = int(line.strip("\t|\n"))
            delnodes.add(del_taxid)
        fh.close()
        if self.verbose:
            logger.debug("delnodes loaded")
        return delnodes

    def convert_taxid_dtype(self, taxid: int) -> int:
        """
        1. Converts the given `taxid` to an integer and checks whether it is positive.
        2. Checks whether `taxid` is present in both nodes.dmp and names.dmp.
        3a. If (2) is false, will check for corresponding `taxid` in merged.dmp and convert to this then redo (2).
        3b. If (2) is true, will return converted taxid.
        4. If (3a) is false will look for `taxid` in delnodes.dmp. If present will convert to root (taxid=1)

        Parameters
        ----------
        taxid : int
            identifier for a taxon in NCBI taxonomy databases - nodes.dmp, names.dmp or merged.dmp

        Returns
        -------
        int
            `taxid` if the `taxid` is a positive integer and present in either nodes.dmp or names.dmp or
            taxid recovered from merged.dmp

        Raises
        ------
        ValueError
            Provided `taxid` is not a positive integer
        DatabaseOutOfSyncError
            NCBI databases nodes.dmp, names.dmp and merged.dmp are out of sync with each other
        """
        #  Step 1 Converts the given `taxid` to an integer and checks whether it is positive.
        # Checking taxid instance format
        # This checks if an integer has been added as str, eg. "562"
        if isinstance(taxid, str):
            invalid_chars = set(string.punctuation + string.ascii_letters)
            invalid_chars.discard(".")
            if set(taxid).intersection(invalid_chars) or taxid.count(".") > 1:
                raise ValueError(f"taxid contains invalid character(s)! Given: {taxid}")
            taxid = float(taxid)
        # a boolean check is needed as they will evaluate silently to 0 or 1 when cast as ints. FALSE=0, TRUE=1
        # float(taxid).is_integer() checks if it is something like 12.0 vs. 12.9
        # is_integer only takes float as input else raises error, thus isinstance( ,float) is used before it to make sure a float is being passed
        if isinstance(taxid, bool) or (
            isinstance(taxid, float) and not taxid.is_integer()
        ):
            raise ValueError(f"taxid must be an integer! Given: {taxid}")
        taxid = int(taxid)
        if taxid <= 0:
            raise ValueError(f"Taxid must be a positive integer! Given: {taxid}")
        # Checking databases
        #  Step 2: Check whether taxid is present in both nodes.dmp and names.dmp.
        if taxid not in self.names and taxid not in self.nodes:
            # Step 3a. Check for corresponding taxid in merged.dmp
            if taxid not in self.merged:
                # Step 4: look for taxid in delnodes.dmp. If present will convert to root (taxid=1)
                if taxid in self.delnodes:
                    # Assign deleted taxid to root...
                    if self.verbose:
                        logger.debug(
                            f"Found {taxid} in delnodes.dmp, converting to root (taxid=1)"
                        )
                    taxid = 1
                else:
                    err_message = f"Databases out of sync. {taxid} not in found in nodes.dmp, names.dmp, merged.dmp or delnodes.dmp"
                    raise DatabaseOutOfSyncError(err_message)
            else:
                # Step 3b. convert taxid from merged.
                if self.verbose:
                    logger.debug(
                        f"Converted {taxid} to {self.merged[taxid]} from merged.dmp"
                    )
                taxid = self.merged[taxid]
                if taxid not in self.names and taxid not in self.nodes:
                    # NOTE: Do not check delnodes.dmp here, as at this point it appears the databases are indeed out of sync.
                    # i.e. The taxid should either be in merged.dmp or in delnodes.dmp if not in nodes.dmp or names.dmp
                    err_message = f"Databases out of sync. Merged taxid ({taxid}) not found in nodes.dmp or names.dmp!"
                    raise DatabaseOutOfSyncError(err_message)
        return taxid

    def search_prot_accessions(
        self,
        accessions: set,
        sseqids_to_taxids: Dict[str, int] = None,
        db: str = "live",
    ) -> Dict[str, int]:
        """Search prot.accession2taxid.gz and dead_prot.accession2taxid.gz

        Parameters
        ----------
        accessions : set
            Set of subject sequence ids retrieved from diamond blastp search (sseqids)

        sseqids_to_taxids : Dict[str, int], optional
            Dictionary containing sseqids converted to taxids

        db : str, optional
            selection of one of the prot accession to taxid databases from NCBI. Choices are live, dead, full

            * live: prot.accession2taxid.gz
            * full: prot.accession2taxid.FULL.gz
            * dead: dead_prot.accession2taxid.gz

        Returns
        -------
        Dict[str, int]
            Dictionary containing sseqids converted to taxids
        """
        if not sseqids_to_taxids:
            sseqids_to_taxids = {}
        if not isinstance(db, str):
            raise ValueError(f"db must be a string! Type Given: {type(db)}")
        db = db.lower()
        choices = {
            "live": self.accession2taxid_fpath,
            "dead": self.dead_accession2taxid_fpath,
            "full": self.accession2taxidfull_fpath,
        }
        if db not in choices:
            raise ValueError(f"db must be one of live, full or dead. Given: {db}")
        fpath = choices.get(db)

        # Revert to accession2taxid if FULL is not present
        if db == "full" and (not os.path.exists(fpath) or not os.path.getsize(fpath)):
            logger.warn(
                "prot.accession2taxid.FULL.gz was not found. Reverting to prot.accession2taxid.gz"
            )
            logger.warn(
                "To achieve greater resolution of your metagenome taxonomy, considering downloading the prot.accession2taxid.FULL.gz database file"
            )
            fpath = choices.get("live")
            db = "live"

        if not os.path.exists(fpath) or not os.path.getsize(fpath):
            raise FileNotFoundError(fpath)

        # "rt" open the database in text mode instead of binary to be handled like a text file
        fh = gzip.open(fpath, "rt") if fpath.endswith(".gz") else open(fpath)
        filename = os.path.basename(fpath)
        # skip the header line
        __ = fh.readline()
        logger.debug(
            f"Searching for {len(accessions):,} accessions in {filename}. This may take a while..."
        )
        n_lines = file_length(fpath, approximate=True) if self.verbose else None
        desc = f"Parsing {filename}"
        converted_sseqid_count = 0
        for line in tqdm(
            fh, disable=self.disable, desc=desc, total=n_lines, leave=False
        ):
            if db == "full":
                # FULL format is accession.version\ttaxid\n
                acc_num = None  # Just in case
                acc_ver, taxid = line.strip().split("\t")
            else:
                # dead and live formats are accession\taccession.version\ttaxid\tgi\n
                acc_num, acc_ver, taxid, _ = line.strip().split("\t")

            taxid = int(taxid)
            if acc_ver in accessions:
                sseqids_to_taxids[acc_ver] = taxid
                converted_sseqid_count += 1

            # So prog will not have to search through the accessions set
            if db == "full":
                continue

            # Search for base accession if using live or dead accession2taxid databases
            if acc_num in accessions:
                sseqids_to_taxids[acc_num] = taxid
                converted_sseqid_count += 1

        fh.close()
        logger.debug(f"sseqids converted from {filename}: {converted_sseqid_count:,}")
        return sseqids_to_taxids

    def convert_accessions_to_taxids(
        self, accessions: set
    ) -> Tuple[Dict[str, Set[int]], pd.DataFrame]:
        # We first get all unique accessions that were retrieved from the blast output
        recovered_accessions = set(
            chain.from_iterable(
                [qseqid_sseqids for qseqid_sseqids in accessions.values()]
            )
        )
        # Check for sseqid in dead_prot.accession2taxid.gz in case an old db was used.
        # Any accessions not found in live prot.accession2taxid db *may* be here.
        # This *attempts* to prevent accessions from being assigned root (root taxid=1)
        try:
            sseqids_to_taxids = self.search_prot_accessions(
                accessions=recovered_accessions,
                db="dead",
                sseqids_to_taxids=None,
            )
            dead_sseqids_found = set(sseqids_to_taxids.keys())
        except FileNotFoundError as db_fpath:
            logger.warn(f"Skipping taxid conversion from {db_fpath}")
            sseqids_to_taxids = None
            dead_sseqids_found = set()

        # Now build the mapping from sseqid to taxid from the full/live accession2taxid dbs
        # Possibly overwriting any merged accessions to live accessions
        sseqids_to_taxids = self.search_prot_accessions(
            accessions=recovered_accessions,
            db="full",
            sseqids_to_taxids=sseqids_to_taxids,
        )

        # Remove accessions: Ignore any accessions already found
        live_sseqids_found = set(sseqids_to_taxids.keys())
        live_sseqids_found -= dead_sseqids_found
        recovered_accessions -= live_sseqids_found
        if recovered_accessions:
            logger.warn(
                f"accessions without corresponding taxid: {len(recovered_accessions):,}"
            )
        root_taxid = 1
        taxids = {}
        sseqid_not_found = pd.NA
        sseqid_to_taxid_df = pd.DataFrame(
            [
                {
                    "qseqid": qseqid,
                    "sseqid": sseqid,
                    "raw_taxid": sseqids_to_taxids.get(sseqid, sseqid_not_found),
                }
                for qseqid, qseqid_sseqids in accessions.items()
                for sseqid in qseqid_sseqids
            ]
        )
        # Update taxids if they are old.
        sseqid_to_taxid_df["merged_taxid"] = sseqid_to_taxid_df.raw_taxid.map(
            lambda tid: self.merged.get(tid, tid)
        )
        # If we still have missing taxids, we will set the sseqid value to the root taxid
        # fill missing taxids with root_taxid
        sseqid_to_taxid_df["cleaned_taxid"] = sseqid_to_taxid_df.merged_taxid.fillna(
            root_taxid
        )
        root_taxid = 1
        for qseqid, qseqid_sseqids in accessions.items():
            # NOTE: we only want to retrieve the set of unique taxids (not a list) for LCA query
            qseqid_taxids = {
                sseqids_to_taxids.get(sseqid, root_taxid) for sseqid in qseqid_sseqids
            }
            taxids[qseqid] = qseqid_taxids
        return taxids, sseqid_to_taxid_df

if __name__ == "__main__":
    print("file containing Autometa NCBI utilities class")
    import sys

    sys.exit(1)


import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

file_path_csv = '../data/data.csv'
data = pd.read_csv(file_path_csv)

data.head()

# Devices Used
plt.figure(figsize=(10, 6))
sns.countplot(x='DEVICE_TYPE_W63', data=data)
plt.title('Distribution of Devices Used')
plt.ylabel('Count')
plt.xlabel('Type of Device')
plt.xticks(ticks=[0, 1, 2], labels=['Desktop', 'Mobile Phone', 'Tablet'])
plt.show()

# Age Category
plt.figure(figsize=(10, 6))
sns.countplot(x='F_AGECAT', data=data)
plt.title('Distribution by Age')
plt.ylabel('Count')
plt.xlabel('Age Category')
plt.show()

# Education Level
plt.figure(figsize=(10, 6))
sns.countplot(x='F_EDUCCAT', data=data)
plt.title('Distribution by Level of Education')
plt.ylabel('Count')
plt.xlabel('Level of Education')
plt.show()

# Correlation Matrix
subset_columns = [
    'DEVICE_TYPE_W63',
    'LANG_W63_W63',
    'SNSUSE_W63',
    'VIDEOGAME_W63',
    'F_AGECAT',
    'F_EDUCCAT',
    'F_INCOME',
    'SMARTPHONE_W63',
    'F_SEX'
]

correlation_data = data[subset_columns]
correlation_matrix = correlation_data.corr()

plt.figure(figsize=(12, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.title('Correlation Matrix')
plt.show()


from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models

class Task(models.Model):
    text = models.CharField(max_length=160)
    deadline = models.DateField()
    progress = models.IntegerField(
        default=0,
        validators=[
            MinValueValidator(0),
            MaxValueValidator(100)
        ]
    )


import sys,argparse,codecs

from tfner.configfromfile import ModelConfig
from tfner.core import build_model

#----------------------------------------------------------------------
# main function
def main(argv):
    # parse command-line arguments
    parser=argparse.ArgumentParser(description="build a NN model for NER")
    # optional arguments
    #parser.add_argument("--arg",type=int,default=42,help="description")
    # positional arguments
    parser.add_argument("config_file",help="configuration file indicating the parameters for the training")

    param=parser.parse_args()

    # do main
    cfg=ModelConfig(param.config_file)
    build_model(cfg)

if __name__ == "__main__":
    main(sys.argv[1:])


import cv2
def collage(imag):
    vi=cv2.VideoCapture("C:\\Users\\anand\\Videos\\cheeta.mp4")
    fps=int(vi.get(cv2.CAP_PROP_FPS))
    w=int(vi.get(cv2.CAP_PROP_FRAME_WIDTH))
    h=int(vi.get(cv2.CAP_PROP_FRAME_HEIGHT))
    op=cv2.VideoWriter("C:\\Users\\anand\\Videos\\cheeta.avi",cv2.VideoWriter_fourcc('X','V','I','D'),fps,(w,h))
    while True:
        success,frame=vi.read()
        if success:
            frame[0:270,1180:1280]=imag
            frame=cv2.copyMakeBorder(frame,10,10,10,10,cv2.BORDER_CONSTANT,value=[255,0,0])
            cv2.imshow("Video",frame)
            op.write(frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        else:
            break
    vi.release()
    op.release()
    cv2.destroyAllWindows()

liberty=cv2.imread("C:\\Users\\anand\\Pictures\\Liberty.jpg",1)
statue=liberty[50:320,180:280]
collage(statue)


# Problem 24
# ==========
#
#
#    A permutation is an ordered arrangement of objects. For example, 3124 is
#    one possible permutation of the digits 1, 2, 3 and 4. If all of the
#    permutations are listed numerically or alphabetically, we call it
#    lexicographic order. The lexicographic permutations of 0, 1 and 2 are:
#
#                        012   021   102   120   201   210
#
#    What is the millionth lexicographic permutation of the digits 0, 1, 2, 3,
#    4, 5, 6, 7, 8 and 9?
import itertools as it

gen = it.permutations(range(0, 10))

count = 0
for i in gen:
   count += 1
   if count == 1000000:
      print(i)

#       Congratulations, the answer you gave to problem 24 is correct.
#
# You are the 80878th person to have solved this problem.
#
# Return to Problems page.


from flask import Flask, render_template, request
from main import get_candlestick_data, save_to_csv, get_market_caps

import plotly.express as px
import pandas as pd
import plotly.graph_objects as go

app = Flask(__name__)

SYMBOLS = [
    "ADAUSDT",
    "DOGEUSDT",
    "TRXUSDT",
    "MATICUSDT",
    "SOLUSDT",
    "LTCUSDT",
    "DOTUSDT",
    "BUSDDAI",
    "AVAXUSDT",
    "SHIBUSDT",
]

@app.route("/candlestick")
def candlestick():
    symbol = request.args.get("symbol", default="BTCUSDT")
    interval = request.args.get("interval", default="1m")

    candlestick_data = get_candlestick_data(symbol, interval)
    save_to_csv(candlestick_data, symbol, interval)

    df = pd.read_csv(f"{symbol}-{interval}.csv")

    candlestick_df = go.Figure(
        data=[
            go.Candlestick(
                x=df["Open time"],
                open=df["Open"],
                high=df["High"],
                low=df["Low"],
                close=df["Close"],
            )
        ]
    )
    candlestick_json = candlestick_df.to_json()

    return render_template(
        "candlestick.html",
        candlestick=candlestick_json,
        symbol=symbol,
        interval=interval,
    )

@app.route("/piechart")
def piechart():
    market_caps = get_market_caps(SYMBOLS)
    df_market_caps = pd.DataFrame(
        {"Symbol": SYMBOLS, "Market Cap": market_caps}
    )

    pie = px.pie(df_market_caps, values="Market Cap", names="Symbol")
    pie_json = pie.to_json()

    return render_template("piechart.html", pie=pie_json)

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


from http.client import responses
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from scipy.stats import chi2_contingency
from sklearn.preprocessing import LabelEncoder

import matplotlib as plt
import seaborn as sns

url="http://data.insideairbnb.com/singapore/sg/singapore/2021-10-28/visualisations/listings.csv"
data =pd.read_csv(url)

new_data=data.copy()

# x1: reviews_per_month  --> mean_rpm: 0.65
mean_rpm="{:.2f}".format((data.iloc[:,-5]).mean(skipna=True))
(new_data.iloc[:,-5]).fillna(value=mean_rpm,inplace=True)

# x2: availability_365   --> mean_nor: 239.63
mean_nor="{:.2f}".format((data.iloc[:,-3]).mean(skipna=True))
(new_data.iloc[:,-3]).fillna(value=mean_nor,inplace=True)

with open ("/Users/faritorab/Desktop/newlisting.csv" , 'w') as f:
    new_data.to_csv(f)

# print(new_data.head())
#        id                                              name  host_id host_name  ... calculated_host_listings_count availability_365  number_of_reviews_ltm  license
# 0   50646                   Pleasant Room along Bukit Timah   227796   Sujatha  ...                              1              365                      0      NaN
# 1   71609               Ensuite Room (Room 1 & 2) near EXPO   367042   Belinda  ...                              4              365                      0      NaN
# 2   71896                   B&B  Room 1 near Airport & EXPO   367042   Belinda  ...                              4              365                      0      NaN
# 3   71903                        Room 2-near Airport & EXPO   367042   Belinda  ...                              4              365                      0      NaN
# 4  275343  Conveniently located City Room!(1,2,3,4,5,6,7,8)  1439258     Joyce  ...                             50              343                      0      NaN

# [5 rows x 18 columns]

X=new_data[["reviews_per_month","availability_365"]]
y=new_data["price"]

print("X: \n",X)
# X:
#       reviews_per_month  availability_365
# 0                 0.21               365
# 1                 0.27               365
# 2                 0.32               365
# 3                 0.64               365
# 4                 0.19               343
# ...                ...               ...
# 4118              0.65               362
# 4119              0.65               365
# 4120              0.65               358
# 4121              0.65               364
# 4122              0.65               358
print("y:\n",y)
# y:
#  0        80
# 1       177
# 2        81
# 3        81
# 4        52
#        ...
# 4118    123
# 4119     88
# 4120     58
# 4121    276
# 4122    480

regr = LinearRegression()
regr.fit(X, y)

print('b0: \t', regr.intercept_)
# b0: 174.4405622545075

print('slope: \t', regr.coef_)
# slope: [-6.76081324  0.0507245 ]

print('R^2: \t', regr.score(X, y))
# R^2: 0.0006654739313914915

response = regr.predict(X)
print('predicted response:', response, sep='\n')
# predicted response:
# [191.5352338  191.129585   190.79154434 ... 188.20540448 188.50975147
#  188.20540448]

#------------------------------------------------------------------------------------------------------------------------------------

contingency_table = pd.crosstab(
    new_data['neighbourhood_group'],
    new_data['room_type'],
    margins = True
)

print(contingency_table)
# room_type            Entire home/apt  Hotel room  Private room  Shared room   All
# neighbourhood_group
# Central Region                  1547         179          1448          132  3306
# East Region                       54           3           201            6   264
# North Region                      13           0           100            6   119
# North-East Region                 33           0           106            4   143
# West Region                      122           0           158           11   291
# All                             1769         182          2013          159  4123

# print(stats.chi2_contingency(crosstab))

# neighbourhood_group = new_data["neighbourhood_group"]
# # l=LabelEncoder()
# # neighbourhood_group=l.fit_transform(neighbourhood_group)

# room_type=new_data["room_type"]
# # l=LabelEncoder()
# # room_type=l.fit_transform(room_type)

x_squared, p, dof, expected = chi2_contingency(contingency_table)

print(x_squared,"\n", p,"\n", dof,"\n",expected )


import imutils
import shutil
import numpy as np
import copy
import glob
import cv2
import os
import re

PIC_NAMES = [
    #'alien',
    'alienmonster',
    #'avocado',
    'beamingfacewithsmilingeyes',
    #'baguettebread',
    'butterfly',
    'banana',
    'babychick',
    'balloon',
    'books',
    'bird',
    #'cat',
    'cactus',
    'carrot',
    #'clapperboard',
    'dragon',
    #'dog',
    #'duck',
    'eyes',
    'fox',
    'fire',
    'fish',
    'frog',
    #'flagpoland',
    'ghost',
    'growingheart',
    'gemstone',
    #'hamburger',
    'honeybee',
    'lizard',
    'octopus',
    'okhandlightskintone',
    'parrot',
    'panda',
    'penguin',
    'pizza',
    'purpleheart',
    'rainbow',
    #'radioactive',
    #'rabbit',
    #'rabbitface',
    'recyclingsymbol',
    'rooster',
    #'rocket',
    #'smilingfacewithsmilingeyes',
    #'shark',
    'shield',
]

PAL_DIR = os.path.join('backend', 'palette')
DEST_DIR = os.path.join('static', 'emotes')
stack = None
SIZE = 40

for family in os.listdir(PAL_DIR):
    path = os.path.join(PAL_DIR, family)
    count = 0
    if os.path.isdir(path):
        "CHECK FAMILY Loop LEVEL"
        destination = os.path.join(DEST_DIR, family)
        os.makedirs(destination, exist_ok=True)

        for fil in os.listdir(path):
            name = os.path.basename(fil)[:-4]
            src = os.path.join(path, fil)
            dst = os.path.join(destination, fil)

            if name in PIC_NAMES:
                shutil.copyfile(src, dst)
                count += 1

        all_pics = copy.copy(PIC_NAMES)
        preview = None
        for name in PIC_NAMES:
            "Check pictures in order from list"
            fil = f"{name}.png"

            img_array = cv2.imread(os.path.join(destination, fil), cv2.IMREAD_UNCHANGED)
            try:
                img_array = cv2.cvtColor(img_array, cv2.COLOR_BGR2BGRA)
                img_array = cv2.resize(img_array, (SIZE,SIZE))
                all_pics.pop(all_pics.index(name))
            except Exception:
                img_array = np.zeros((SIZE,SIZE,4), dtype=np.uint8)
                #img_array = cv2.cvtColor(img_array, cv2.COLOR_BGR2BGRA)

            if preview is not None:
                #print(preview.shape, img_array.shape)
                preview = np.concatenate([preview, img_array], axis=1)
            else:
                preview = img_array

        "Save preview image is exists"
        if preview is not None:
            cv2.imwrite(os.path.join(DEST_DIR, f"{family}.png"), preview)
            if stack is not None:
                stack = np.concatenate([stack, preview], axis=0)
            else:
                stack = preview

        print()
        print(f"{path}")
        print(f"missing:\n{all_pics}")

if stack is not None:
    cv2.imwrite(os.path.join(DEST_DIR, f"STACK.png"), stack)


import json
from urllib.parse import urlparse
from stark.codecs import BaseCodec
from stark.codecs.jsonschema import JSONSchemaEncoder
from stark.schema import (
    SchemaDefinitions,
    JSONSchema,
    String,
    Choice,
    Object,
    Any,
    Reference,
    Array,
    Boolean,
    is_schema
)
from stark.compat import dict_type
from stark.document import Document

SchemaRef = Object(
    properties={"$ref": String(pattern="^#/components/schemas/")}
)

RequestBodyRef = Object(
    properties={"$ref": String(pattern="^#/components/requestBodies/")}
)

ResponseRef = Object(
    properties={"$ref": String(pattern="^#/components/responses/")}
)

openapi_definitions = SchemaDefinitions()

OpenAPI = Object(
    title="OpenAPI",
    properties={
        "openapi": String(),
        "info": Reference("Info", definitions=openapi_definitions),
        "servers": Array(items=Reference("Server", definitions=openapi_definitions)),
        "paths": Reference("Paths", definitions=openapi_definitions),
        "components": Reference("Components", definitions=openapi_definitions),
        "security": Array(items=Reference("SecurityRequirement", definitions=openapi_definitions)),
        "tags": Array(items=Reference("Tag", definitions=openapi_definitions)),
        "externalDocs": Reference("ExternalDocumentation", definitions=openapi_definitions),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["openapi", "info", "paths"]
)

openapi_definitions["JSONSchema"] = JSONSchema

openapi_definitions["Info"] = Object(
    properties={
        "title": String(allow_blank=True),
        "description": String(format="textarea", allow_blank=True),
        "termsOfService": String(format="url", allow_blank=True),
        "contact": Reference("Contact", definitions=openapi_definitions),
        "license": Reference("License", definitions=openapi_definitions),
        "version": String(allow_blank=True),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["title", "version"]
)

openapi_definitions["Contact"] = Object(
    properties={
        "name": String(),
        "url": String(format="url"),
        "email": String(format="email"),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["License"] = Object(
    properties={
        "name": String(),
        "url": String(format="url"),
    },
    required=["name"],
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Server"] = Object(
    properties={
        "url": String(allow_blank=True),
        "description": String(format="textarea"),
        "variables": Object(additional_properties=Reference("ServerVariable", definitions=openapi_definitions)),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["url"]
)

openapi_definitions["ServerVariable"] = Object(
    properties={
        "enum": Array(items=String()),
        "default": String(),
        "description": String(format="textarea"),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["default"]
)

openapi_definitions["Paths"] = Object(
    pattern_properties={
        "^/": Reference("Path", definitions=openapi_definitions),
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Path"] = Object(
    properties={
        "summary": String(),
        "description": String(format="textarea"),
        "get": Reference("Operation", definitions=openapi_definitions),
        "put": Reference("Operation", definitions=openapi_definitions),
        "post": Reference("Operation", definitions=openapi_definitions),
        "delete": Reference("Operation", definitions=openapi_definitions),
        "options": Reference("Operation", definitions=openapi_definitions),
        "head": Reference("Operation", definitions=openapi_definitions),
        "patch": Reference("Operation", definitions=openapi_definitions),
        "trace": Reference("Operation", definitions=openapi_definitions),
        "servers": Array(items=Reference("Server", definitions=openapi_definitions)),
        "parameters": Array(items=Reference("Parameter", definitions=openapi_definitions))  # TODO: | ReferenceObject
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Operation"] = Object(
    properties={
        "tags": Array(items=String()),
        "summary": String(),
        "description": String(format="textarea"),
        "externalDocs": Reference("ExternalDocumentation", definitions=openapi_definitions),
        "operationId": String(),
        "parameters": Array(items=Reference("Parameter", definitions=openapi_definitions)),
        # TODO: | ReferenceObject
        "requestBody": RequestBodyRef | Reference("RequestBody", definitions=openapi_definitions),
        # TODO: RequestBody | ReferenceObject
        "responses": Reference("Responses", definitions=openapi_definitions),
        # TODO: "callbacks"
        "deprecated": Boolean(),
        "security": Array(Reference("SecurityRequirement", definitions=openapi_definitions)),
        "servers": Array(items=Reference("Server", definitions=openapi_definitions)),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["ExternalDocumentation"] = Object(
    properties={
        "description": String(format="textarea"),
        "url": String(format="url"),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["url"]
)

openapi_definitions["Parameter"] = Object(
    properties={
        "name": String(),
        "in": Choice(choices=["query", "header", "path", "cookie"]),
        "description": String(format="textarea"),
        "required": Boolean(),
        "deprecated": Boolean(),
        "allowEmptyValue": Boolean(),
        "style": String(),
        "schema": Reference("JSONSchema", definitions=openapi_definitions) | SchemaRef,
        "example": Any(),
        # TODO: Other fields
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["name", "in"]
)

openapi_definitions["RequestBody"] = Object(
    properties={
        "description": String(),
        "content": Object(additional_properties=Reference("MediaType", definitions=openapi_definitions)),
        "required": Boolean(),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Responses"] = Object(
    properties={
        "default": Reference("Response", definitions=openapi_definitions) | ResponseRef,
    },
    pattern_properties={
        "^([1-5][0-9][0-9]|[1-5]XX)$": Reference("Response", definitions=openapi_definitions) | ResponseRef,
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Response"] = Object(
    properties={
        "description": String(),
        "content": Object(additional_properties=Reference("MediaType", definitions=openapi_definitions)),
        "headers": Object(additional_properties=Reference("Header", definitions=openapi_definitions)),
        # TODO: Header | ReferenceObject
        # TODO: links
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["MediaType"] = Object(
    properties={
        "schema": Reference("JSONSchema", definitions=openapi_definitions) | SchemaRef,
        "example": Any(),
        # TODO "examples", "encoding"
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Header"] = Object(
    properties={
        "description": String(format="textarea"),
        "required": Boolean(),
        "deprecated": Boolean(),
        "allowEmptyValue": Boolean(),
        "style": String(),
        "schema": Reference("JSONSchema", definitions=openapi_definitions) | SchemaRef,
        "example": Any(),
        # TODO: Other fields
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False
)

openapi_definitions["Components"] = Object(
    properties={
        "schemas": Object(additional_properties=Reference("JSONSchema", definitions=openapi_definitions)),
        "responses": Object(additional_properties=Reference("Response", definitions=openapi_definitions)),
        "parameters": Object(additional_properties=Reference("Parameter", definitions=openapi_definitions)),
        "requestBodies": Object(additional_properties=Reference("RequestBody", definitions=openapi_definitions)),
        "securitySchemes": Object(additional_properties=Reference("SecurityScheme", definitions=openapi_definitions)),
        # TODO: Other fields
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
)

openapi_definitions["Tag"] = Object(
    properties={
        "name": String(),
        "description": String(format="textarea"),
        "externalDocs": Reference("ExternalDocumentation", definitions=openapi_definitions),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["name"]
)

openapi_definitions["SecurityRequirement"] = Object(
    additional_properties=Array(items=String()),
)

openapi_definitions["SecurityScheme"] = Object(
    properties={
        "type": Choice(choices=["apiKey", "http", "oauth2", "openIdConnect"]),
        "description": String(format="textarea"),
        "name": String(),
        "in": Choice(choices=["query", "header", "cookie"]),
        "scheme": String(),
        "bearerFormat": String(),
        "flows": Any(),  # TODO: OAuthFlows
        "openIdConnectUrl": String(),
    },
    pattern_properties={
        "^x-": Any(),
    },
    additional_properties=False,
    required=["type"]
)

METHODS = [
    "get", "put", "post", "delete", "options", "head", "patch", "trace"
]

class OpenAPICodec(BaseCodec):
    media_type = "application/vnd.oai.openapi"
    format = "openapi"

    def encode(self, document, **options):
        if not isinstance(document, Document):
            error = "Document instance expected."
            raise TypeError(error)

        definitions = {}
        codec = JSONSchemaEncoder(
            definitions,
            definition_base="components/schemas"
        )
        paths = self.get_paths(document, codec=codec)
        data = self.validate_document(document, definitions, paths)
        kwargs = {
            "ensure_ascii": False,
            "indent": 4,
            "separators": (",", ": ")
        }
        return json.dumps(data, **kwargs).encode("utf-8")

    @staticmethod
    def validate_document(document, definitions, paths):
        openapi = OpenAPI.validate({
            "openapi": "3.0.0",
            "info": {
                "version": document.version,
                "title": document.title,
                "description": document.description
            },
            "servers": [{
                "url": document.url
            }],
            "paths": paths
        })

        if definitions:
            openapi["components"] = {"schemas": dict(definitions)}

        if not document.url:
            openapi.pop("servers")

        return openapi

    def get_paths(self, document, codec):
        paths = dict_type()

        for link, name, sections in document.walk_links():
            path = urlparse(link.url).path
            operation_id = link.name
            method = link.method.lower()

            if path not in paths:
                paths[path] = {}
            paths[path][method] = self.get_operation(link, operation_id, codec)

        return paths

    def get_operation(self, link, operation_id, codec):
        operation = {
            "operationId": operation_id
        }
        if link.title:
            operation["summary"] = link.title
        if link.description:
            operation["description"] = link.description
        tags = link.tags if link.tags else []
        if tags:
            operation["tags"] = tags
        if link.path_fields or link.query_fields:
            operation["parameters"] = [
                self.get_parameter(field, codec) for field in
                link.path_fields + link.query_fields
            ]
        if link.body_field:
            schema = link.body_field.schema
            if schema is None:
                content_info = {}
            else:
                content_info = {
                    "schema": codec.encode(Reference(to=schema))
                }
            operation["requestBody"] = {
                "content": {
                    link.encoding: content_info
                }
            }
        if link.response is not None:
            schema = link.response.schema
            if is_schema(schema):
                schema = Reference(to=schema)
            response = {
                "description": "",
            }
            if schema is not None:
                response["content"] = {
                    link.response.encoding: {
                        "schema": codec.encode(schema)
                    }
                }
            operation["responses"] = {
                str(link.response.status_code): response
            }
        return operation

    @staticmethod
    def get_parameter(field, codec):
        parameter = {
            "name": field.name,
            "in": field.location
        }
        if field.required:
            parameter["required"] = True
        if field.description:
            parameter["description"] = field.description
        if field.schema:
            parameter["schema"] = codec.encode(field.schema)
        return parameter