# V7 - Mort des individus et statistiques en temps réel

# Importation des modules nécessaires
import pygame  # Bibliothèque pour la création de jeux-vidéos
import random  # Module pour la génération de nombres aléatoires
import sys  # Module fournissant un accès à certaines variables utilisées ou maintenues par l'interprétateur python
import math # Calculs du cercle à partir du rayon par exemple

# Constantes définissant les paramètres du programme

LARGEUR_ECRAN = 1600  # Largeur de la fenêtre de la simulation
HAUTEUR_ECRAN = 1000  # Hauteur de la fenêtre de la simulation
COULEUR_MUR = (0, 0, 0)  # Couleur des bords de la fenêtre de la simulation (en noir)
COULEUR_FOND = (255, 255, 255)  # Couleur du fond de la fenêtre de la simulation (en blanc)

TAILLE_INDIVIDU = 4  # Taille des individus représentés par des points
NB_INDIVIDUS = 100  # Nombre total d'individus dans la simulation
VITESSE_MAX = 0.1  # Vitesse maximale des individus. Influence la propagation.
TAUX_INFECTIOSITE = 0.3  # La probabilité d'être infecté
TAUX_ASYMPTOMATIQUES = 0.2  # La probabilité d'être asymptomatique et jamais envoyé en quarantaine. Entre 0 et 1.
RAYON_DISTANCIATION = True # Distanciation sociale ou pas (difficile de le faire modulable)
LETALITE = 0.3 # Chances de mourir du virus

# Pour le grand carré
TAILLE_CARRE = 400  # Taille du cadre où les individus évoluent
EMPLACEMENT_CARRE_X = (LARGEUR_ECRAN - TAILLE_CARRE) // 2
EMPLACEMENT_CARRE_Y = (HAUTEUR_ECRAN - TAILLE_CARRE) // 2 - 100
# Conjugués des emplacements (signe inverse)
EMPLACEMENT_CARRE_X_CONJ = (LARGEUR_ECRAN + TAILLE_CARRE) // 2
EMPLACEMENT_CARRE_Y_CONJ = (HAUTEUR_ECRAN + TAILLE_CARRE) // 2 - 100

# Pour le carré de quarantaine - proportionnel au grand carré
TAILLE_QUARANTAINE = TAILLE_CARRE * 0.28  # Taille du cadre de la quarantaine
EMPLACEMENT_QUARANTAINE_X = EMPLACEMENT_CARRE_X + (TAILLE_CARRE * 1.085)
EMPLACEMENT_QUARANTAINE_Y = EMPLACEMENT_CARRE_Y

# Initialisation des modules Pygame manuellement
pygame.display.init()
pygame.font.init()

# Création de la fenêtre
ecran = pygame.display.set_mode((LARGEUR_ECRAN, HAUTEUR_ECRAN))
pygame.display.set_caption("Epydemie")

# Définition de la classe représentant un individu dans la simulation
class Individu:
    def __init__(self, x, y, taille, couleur):
        self.x = x
        self.y = y
        self.taille = taille
        self.couleur = couleur
        # NB_INDIVIDUS AUGMENTE = NB OPÉS AUGMENTE = VITESSE PLUS LENTE = GUERISON PLUS LONGUE mais ça reste correct juste c'est pas beau
        # Vitesse + rapide pour un grand nombre
        self.vitesse_x = (random.uniform(-VITESSE_MAX, VITESSE_MAX) * NB_INDIVIDUS) / 10
        self.vitesse_y = (random.uniform(-VITESSE_MAX, VITESSE_MAX) * NB_INDIVIDUS) / 10
        self.temps_infecte = 0
        # Guérison + courte pour un grand nombre
        self.temps_guerison = random.randint(200000, 600000) * (1/NB_INDIVIDUS)
        self.gueri = False

        self.reperage_quarantaine = random.randint(80000, 200000) * (1/NB_INDIVIDUS)
        self.temps_en_quarantaine = 0
        self.est_en_quarantaine = False

        self.asymptomatique = False
        # Utiliser random.random() pour générer un nombre entre 0 et 1
        if random.random() < TAUX_ASYMPTOMATIQUES:
            self.asymptomatique = True

        self.vie = True

    def dessiner(self):
        pygame.draw.circle(ecran, self.couleur, (int(self.x), int(self.y)), self.taille)

    def placer_en_quarantaine(self):
        if self.couleur == (255, 0, 0) and self.temps_infecte >= self.reperage_quarantaine \
            and self.est_en_quarantaine == False and self.asymptomatique == False:
            self.x = EMPLACEMENT_QUARANTAINE_X + TAILLE_QUARANTAINE / 2
            self.y = EMPLACEMENT_QUARANTAINE_Y + TAILLE_QUARANTAINE / 2
            self.est_en_quarantaine = True

    def gestion_quarantaine(self):
        if self.est_en_quarantaine:
            self.temps_en_quarantaine += 1
            if self.gueri:
                self.est_en_quarantaine = False
                self.temps_en_quarantaine = 0
                # Réapparition aléatoire après guérison dans le grand carré noir
                self.x = random.uniform(EMPLACEMENT_CARRE_X + TAILLE_INDIVIDU, EMPLACEMENT_CARRE_X_CONJ - TAILLE_INDIVIDU)
                self.y = random.uniform(EMPLACEMENT_CARRE_Y + TAILLE_INDIVIDU, EMPLACEMENT_CARRE_Y_CONJ - TAILLE_INDIVIDU)

    def bouger(self):
        self.x += self.vitesse_x
        self.y += self.vitesse_y

    def rebondir_sur_murs(self):
        # Vérifier si l'individu atteint les bords du cadre et les fait rebondir en conséquence
        if not self.est_en_quarantaine:
            if self.x - self.taille < EMPLACEMENT_CARRE_X:
                self.x = EMPLACEMENT_CARRE_X + self.taille
                self.vitesse_x = -self.vitesse_x
            elif self.x + self.taille > EMPLACEMENT_CARRE_X_CONJ:
                self.x = EMPLACEMENT_CARRE_X_CONJ - self.taille
                self.vitesse_x = -self.vitesse_x

            if self.y - self.taille < EMPLACEMENT_CARRE_Y:
                self.y = EMPLACEMENT_CARRE_Y + self.taille
                self.vitesse_y = -self.vitesse_y
            elif self.y + self.taille > EMPLACEMENT_CARRE_Y_CONJ:
                self.y = EMPLACEMENT_CARRE_Y_CONJ - self.taille
                self.vitesse_y = -self.vitesse_y
        else:
            self.rebondir_sur_murs_quarantaine()

    def rebondir_sur_murs_quarantaine(self):
        # Vérifier si l'individu atteint les bords du cadre de la quarantaine et les fait rebondir en conséquence
        if self.x - self.taille < EMPLACEMENT_QUARANTAINE_X or self.x + self.taille > EMPLACEMENT_QUARANTAINE_X + TAILLE_QUARANTAINE:
            self.vitesse_x = -self.vitesse_x
        if self.y - self.taille < EMPLACEMENT_QUARANTAINE_Y or self.y + self.taille > EMPLACEMENT_QUARANTAINE_Y + TAILLE_QUARANTAINE:
            self.vitesse_y = -self.vitesse_y

    def detecter_collision(self, autre_individu):
        # Calculer la distance entre deux individus et tester s'ils entrent en collision
        distance = ((self.x - autre_individu.x) ** 2 + (self.y - autre_individu.y) ** 2) ** 0.5
        return distance <= self.taille + autre_individu.taille

    def infecter(self):
        self.couleur = (255, 0, 0)  # Couleur d'un individu qui est infecté (en rouge)
        self.gueri = False

    def progresser_guerison(self):
        global nb_morts
        # Vérifier quand l'individu infecté pourra être guéri
        if self.couleur == (255, 0, 0):  # Si l'individu est infecté
            self.temps_infecte += 1
            if self.temps_infecte >= self.temps_guerison:
                # Utiliser random.random() pour générer un nombre entre 0 et 1
                if random.random() < LETALITE:
                    self.vie = False  # L'individu décède
                    nb_morts += 1
                else:
                    self.couleur = (0, 255, 0)  # Couleur de l'individu guéri (en vert)
                    self.temps_infecte = 0
                    self.gueri = True

    def appliquer_distanciation(self, autres_individus):
        for autre in autres_individus:
            if autre != self:
                distance = ((self.x - autre.x) ** 2 + (self.y - autre.y) ** 2) ** 0.5
                if distance < 10:
                    angle = random.uniform(0, 2 * math.pi)
                    deplacement_x = 10 * math.cos(angle)
                    deplacement_y = 10 * math.sin(angle)
                    self.x += deplacement_x
                    self.y += deplacement_y

# Création d'une liste d'individus pour la simulation
individus = [Individu(
    random.randint(EMPLACEMENT_CARRE_X + TAILLE_INDIVIDU, EMPLACEMENT_CARRE_X_CONJ - TAILLE_INDIVIDU),
    random.randint(EMPLACEMENT_CARRE_Y + TAILLE_INDIVIDU, EMPLACEMENT_CARRE_Y_CONJ - TAILLE_INDIVIDU),
    TAILLE_INDIVIDU,
    (255, 0, 0)  # Couleur pour le premier individu (en rouge)
)] + [Individu(
    random.randint(EMPLACEMENT_CARRE_X + TAILLE_INDIVIDU, EMPLACEMENT_CARRE_X_CONJ - TAILLE_INDIVIDU),
    random.randint(EMPLACEMENT_CARRE_Y + TAILLE_INDIVIDU, EMPLACEMENT_CARRE_Y_CONJ - TAILLE_INDIVIDU),
    TAILLE_INDIVIDU,
    (0, 0, 255)  # Couleur pour les autres individus (en bleu)
) for i in range(NB_INDIVIDUS - 1)]

# Liste des couples d'individus en collision
collisions_en_cours = []

# Compteur des individus morts
nb_morts = 0

# Initialisation des listes pour les statistiques
# On met la ligne des bleus de base à 160 pour que ça fasse pas vide au début
historique_bleus = [160 for i in range(LARGEUR_ECRAN)]
historique_rouges = [0 for i in range(LARGEUR_ECRAN)]
historique_verts = [0 for i in range(LARGEUR_ECRAN)]
historique_morts = [0 for i in range(LARGEUR_ECRAN)]

# Boucle principale de la simulation
while True:
    # Quitter sans problèmes en fermant la fenêtre
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    # Dessiner le fond blanc
    ecran.fill(COULEUR_FOND)

    # Dessiner le cadre noir
    pygame.draw.rect(ecran, COULEUR_MUR, pygame.Rect(EMPLACEMENT_CARRE_X, EMPLACEMENT_CARRE_Y, TAILLE_CARRE, TAILLE_CARRE), 2)

    # Dessiner le cadre de la quarantaine
    pygame.draw.rect(ecran, COULEUR_MUR, pygame.Rect(EMPLACEMENT_QUARANTAINE_X, EMPLACEMENT_QUARANTAINE_Y, TAILLE_QUARANTAINE, TAILLE_QUARANTAINE), 2)

    # Filtrer les individus en vie
    individus = [ind for ind in individus if ind.vie]

    # Appliquer la distanciation sociale si c'est demandé
    if RAYON_DISTANCIATION:
        for individu in individus:
            if individu.est_en_quarantaine == False:
                individu.appliquer_distanciation(individus)

    # Déplacer et faire rebondir les individus dans le cadre
    for individu in individus:
        individu.progresser_guerison()
        individu.placer_en_quarantaine()
        individu.gestion_quarantaine()
        individu.bouger()
        individu.rebondir_sur_murs()
        individu.dessiner()

    # Vérifier les collisions en cours
    collisions_en_cours = [(i, j) for (i, j) in collisions_en_cours if i.detecter_collision(j)]

    # Tester les collisions et mettre à jour les couleurs
    ind_no_quarantaine = [ind for ind in individus if ind.est_en_quarantaine == False]
    for i in range(len(ind_no_quarantaine)):
        for j in range(i + 1, len(ind_no_quarantaine)):
            if (ind_no_quarantaine[i], ind_no_quarantaine[j]) not in collisions_en_cours and ind_no_quarantaine[i].detecter_collision(ind_no_quarantaine[j]):
                collisions_en_cours.append((ind_no_quarantaine[i], ind_no_quarantaine[j]))
                # L'un des deux est rouge
                if ind_no_quarantaine[i].couleur == (255, 0, 0) or ind_no_quarantaine[j].couleur == (255, 0, 0):
                    # Utiliser random.random() pour générer un nombre entre 0 et 1
                    if random.random() < TAUX_INFECTIOSITE:
                        ind_no_quarantaine[i].infecter(), ind_no_quarantaine[j].infecter()  # Rouges tous les deux

    # Compteurs pour les statistiques
    nb_bleus = sum(1 for ind in individus if ind.couleur == (0, 0, 255))
    nb_rouges = sum(1 for ind in individus if ind.couleur == (255, 0, 0))
    nb_verts = sum(1 for ind in individus if ind.couleur == (0, 255, 0))
    # nb_morts initialisé plus tôt comme c'est linéaire

    # Afficher les statistiques en temps réel
    font = pygame.font.Font(None, 36)
    text_bleus = font.render(f"Non exposés : {nb_bleus}", True, (0, 0, 255))
    text_rouges = font.render(f"Infectés : {nb_rouges}", True, (255, 0, 0))
    text_verts = font.render(f"Guéris : {nb_verts}", True, (0, 255, 0))
    text_morts = font.render(f"Morts : {nb_morts}", True, (169, 169, 169))
    ecran.blit(text_bleus, (10, 10))
    ecran.blit(text_rouges, (10, 50))
    ecran.blit(text_verts, (10, 90))
    ecran.blit(text_morts, (10, 130))

    # Ajouter les valeurs actuelles à l'historique
    historique_bleus.append(nb_bleus)
    historique_rouges.append(nb_rouges)
    historique_verts.append(nb_verts)
    historique_morts.append(nb_morts)

    # Coefficienter avec 160 pour garder un affichage stable peu importe NB_INDIVIDUS
    historique_bleus[-1] *= (160 / NB_INDIVIDUS)
    historique_rouges[-1] *= (160 / NB_INDIVIDUS)
    historique_verts[-1] *= (160 / NB_INDIVIDUS)
    historique_morts[-1] *= (160 / NB_INDIVIDUS)

    historique_bleus = historique_bleus[-LARGEUR_ECRAN:]
    historique_rouges = historique_rouges[-LARGEUR_ECRAN:]
    historique_verts = historique_verts[-LARGEUR_ECRAN:]
    historique_morts = historique_morts[-LARGEUR_ECRAN:]

    # Dessiner les courbes statistiques en temps réel avec des points
    for i in range(len(historique_bleus)):
        x = i

        y_bleus = (HAUTEUR_ECRAN - historique_bleus[i] - 50)
        y_rouges = (HAUTEUR_ECRAN - historique_rouges[i] - 50)
        y_verts = (HAUTEUR_ECRAN - historique_verts[i] - 50)
        y_morts = (HAUTEUR_ECRAN - historique_morts[i] - 50)

        pygame.draw.circle(ecran, (0, 0, 255), (x, y_bleus), 2)  # Point bleu
        pygame.draw.circle(ecran, (255, 0, 0), (x, y_rouges), 2)  # Point rouge
        pygame.draw.circle(ecran, (0, 255, 0), (x, y_verts), 2)   # Point vert
        pygame.draw.circle(ecran, (169, 169, 169), (x, y_morts), 2)  # Point gris

    # Indications pour les valeurs des courbes
    text_100p = font.render("100%", True, (0, 0, 0))
    text_0p = font.render("0%", True, (0, 0, 0))
    ecran.blit(text_100p, (10, HAUTEUR_ECRAN - 250))
    ecran.blit(text_0p, (10, HAUTEUR_ECRAN - 35))

    # Mettre à jour l'affichage
    pygame.display.flip()


import paho.mqtt.client as mqtt
import time
import _thread
import os
from datetime import datetime

# will be closed at another thread (.close())
# 3rd argument indicates no. of lines to buffer
# set to 1 so the buffer will flush in this case
log_file = open("on_off.log", "a+", 1)
log_sche = open("schedule.log", "a+", 1)

def chg_str(value):
    if value < 10:
	    return "0" + str(value)
    else:
        return str(value)

def get_time_str():
    t = datetime.now()
    time_str = "[" + str(t.year)[2:4] + "-" + chg_str(t.month) + "-" + chg_str(t.day) + "] "
    time_str = time_str + chg_str(t.hour) + ":" + chg_str(t.minute) + ":" + chg_str(t.second) + " ~ "
    return time_str

def on_message(client, userdata, message):
    msg = str(message.payload.decode("utf-8"))

    if "control" in message.topic:
        log_file.write(get_time_str() + msg + "\n")

    elif "schedule" in message.topic:
        log_sche.write(msg+"\n")

def publish(lol):
    while 1:
        line = input("Please enter the message to publish : ")
        if line == "":
            print("No input, program will end now ...")
            client.loop_stop()  # stop the loop
            client.unsubscribe("uscclab/#")
            client.disconnect()
            log_file.close()
            os._exit(1)
            break
        else:
            client.publish(topic, line)
            time.sleep(0.5)

broker_address = input("Enter the broker ip(leave blank for default): ")
if broker_address == "":
    broker_address = "140.116.82.42" # default

client = mqtt.Client("Server Client")
client.username_pw_set("weblogin", "wtf123")
client.on_message = on_message # attach function to callback
client.connect(broker_address) # connect to broker

client.loop_start() # start the loop
client.subscribe("uscclab/#")

# start a new thread to pending user input and publish
_thread.start_new_thread(publish, ("lol",))  # format: start_new_thread(function_name ,("args","second args"))

while 1:
    pass


import discord
from discord.ext.commands import slash_command
from discord.ext import commands
from discord.ext.commands import Cog

import os
import regex as re
from dotenv import load_dotenv
import requests
import numpy as np
import pandas as pd

import cohere
from qdrant_client import QdrantClient
from qdrant_client import models
from qdrant_client.http import models as rest
from qdrant_client.models import Filter

load_dotenv()  # load all the variables from the env file

CHAT_HISTORY_PATH = '/content/drive/MyDrive/career/projects/hackathons/lablab-cohere-qdrant-hackathon/discord-chat-history.csv'
BASE_MESSAGE_URL = "https://discord.com/channels/{guild_id}/{channel_id}/{message_id}"
QDRANT_CLOUD_HOST = "19531f2c-0717-4706-ac90-bd8dd1a6b0cc.us-east-1-0.aws.cloud.qdrant.io"
QDRANT_COLLECTION_NAME = 'discord'

co = cohere.Client(os.getenv('COHERE_API_KEY'))
qdrant_client = QdrantClient(
    host=QDRANT_CLOUD_HOST,
    prefer_grpc=False,
    api_key=os.getenv('QDRANT_API_KEY'),
)
discord_client = discord.Client()
bot = discord.Bot()

def embed_text(text: list, model='multilingual-22-12'):
    """Generate text embeddings."""
    if type(text) is str:
        text = [text]
    embeddings = co.embed(text, model=model)
    vectors = [list(map(float, vector)) for vector in embeddings.embeddings]
    return vectors

@bot.event
async def on_ready():
    print(f"{bot.user} is ready and online!")

# Define a search filter for author
ignore_author = "Fetcher"
author_filter = Filter(**{"must_not": [{"key": "author", "match": {"value": "Fetcher"}},
                                       {"key": "author", "match": {"value": "Findio"}},
                                       {"key": "author", "match": {"value": "Chatter"}},
                                       ],
                       "must": [{ "key": "word_count", "range": { "gte": 3 }}]
                       })

@bot.slash_command(name="fetch", description="Search for messages by embedding")
async def fetch(ctx, query: str, k_max=5):
    min_words = 20
    vectors = embed_text(query)
    for vector in vectors:
        response = qdrant_client.search(
            collection_name=QDRANT_COLLECTION_NAME,
            query_vector=vector,
            query_filter=author_filter,
            limit=k_max,
        )
    results = [record.payload for record in response]

    # def get_plain(content: str):
    #     plain = re.sub(r'\n', ' \n', content)
    #     plain = re.sub(r'(>.*\n|```(.|\n)*```|`?|\n)', '', plain.lower().strip())
    #     return plain

    if len(results) > 0:
        output = []
        # result_str = f'Search query: "{query}":\nSearch results:\n'
        # for result in results:
            # TODO: summarize by thread not single messages
            # if len(result['content'].split()) >= min_words:
            #     summary = co.summarize(
            #         text=result['content'],
            #         model='summarize-xlarge',
            #         length='medium',
            #         extractiveness='low',
            #         temperature=0.3,
            #         additional_command="to remember a conversation"
            #     ).summary
            # else:
            #     summary = result['content']

            # result_message = result['content']
            # if len(result_message) > 100:
            #     result_message = result_message[:100] + '...'

            # result_str += f"""
            # * {result['author']} wrote [{result['created_at'][:16]}]:
            # [{result_message}]({result['jump_url']})
            # {result['guild_id']}/{result['channel_id']}/{result['msg_id']}
            # """

        embed=discord.Embed(color=0x1eff00)
        for result in results:
            embed.add_field(name=f"{result['author']} at {result['created_at'][:16]}\n{result['channel_id']}.{result['msg_id']}",
                            value=f"[{result['content'][:200]}...]({result['jump_url']})",
                            inline=False)
        embed.set_footer(text="Use `/discuss` to message user on this topic.")

        # await ctx.respond(content=result_str)
        await ctx.respond(f':wave: Your search results for "{query}"', embed=embed)
    else:
        await ctx.respond("No matching messages found.")

@bot.slash_command(name="revise", description="Revise sentence for clarity")
async def revise(ctx, sentence: str):
    """Use generate API to revise sentence."""

    prompt = f"Give me a better version of the following sentence that is more concise and clear, in a polite, fun, yet professional tone: {sentence}"
    response = co.generate(model='command-xlarge-beta',
                        prompt = prompt,
                        max_tokens=90,
                        temperature=0.5,
                        )
    revised = response.generations[0].text
    await bot.wait_until_ready()
    if revised:
        embed=discord.Embed(color=0x1eff00)
        embed.add_field(name="Original", value=sentence, inline=False)
        embed.add_field(name="Revised", value=revised, inline=False)
        await ctx.respond(":wave: Here you go.", embed=embed)
        # await ctx.respond(content=f"__Old__:\n{sentence}\n__Revised__: {revised}")
    else:
        await ctx.respond(content="No revision available.")

@bot.slash_command(name="discuss", description="Start a conversation on a topic.")
async def start_convo(ctx: discord.ApplicationContext, user, id: str):
    try:
        channel_id, msg_id = id.split('.')
        try:
            # Get the message
            msg = await ctx.fetch_message(int(msg_id))
        except:
            # Try to get the thread's parent channel
            msg = await ctx.fetch_message(int(channel_id))

        def get_plain_thread(content: str):
            plain = re.sub(r'\n', ' \n', content)
            plain = re.sub(r'(>.*\n|```(.|\n)*```|`?|\n)', '', plain.lower().strip())
            return plain

        plain_thread = get_plain_thread(msg.content) + ' '
        thread_summary = ''
        if msg.flags.has_thread:
            async for m in msg.thread.history(limit=100, oldest_first=True):
                formatted_content = m.content
                plain_thread += get_plain_thread(formatted_content) + ' '
        else:
            pass

        thread_summary = co.summarize(
            text=plain_thread,
            model='summarize-xlarge',
            length='medium',
            extractiveness='low',
            temperature=0.3,
            additional_command="to remember a conversation"
        ).summary

        embed=discord.Embed(color=0x1eff00)
        embed.add_field(name=f"Original message thread", value=f"[{msg.content[:200]}...]({msg.jump_url})", inline=False)
        embed.add_field(name=f"TL;DR", value=thread_summary, inline=False)
        await ctx.respond(f':wave: {user}, <@{ctx.author.id}> wants to chat with you about below.', embed=embed)
    except:
        await ctx.respond("No message found.")

@bot.slash_command(name="getthread", description="Summarize a thread or message.")
async def get_thread(ctx: discord.ApplicationContext, id):
    try:
        channel_id, msg_id = id.split('.')
        try:
            # Get the message
            msg = await ctx.fetch_message(int(msg_id))
        except:
            # Try to get the thread's parent channel
            msg = await ctx.fetch_message(int(channel_id))

        def get_plain_thread(content: str):
            plain = re.sub(r'\n', ' \n', content)
            plain = re.sub(r'(>.*\n|```(.|\n)*```|`?|\n)', '', plain.lower().strip())
            return plain

        plain_thread = get_plain_thread(msg.content) + ' '
        if msg.flags.has_thread:
            async for m in msg.thread.history(limit=100, oldest_first=True):
                formatted_content = m.content
                plain_thread += get_plain_thread(formatted_content) + ' '
        await ctx.respond(plain_thread)
    except:
        await ctx.respond("No message found.")

@bot.slash_command(name="keyword_search", description="Search for messages containing a keyword")
async def search_messages(ctx: commands.Context, keyword: str):
    channel = ctx.channel
    messages = []
    async for message in channel.history(limit=100):
        if keyword in message.content:
            messages.append(f"{message.content}\nURL: {message.jump_url}")

    if messages:
        messages_str = "\n".join(messages)

        # 將訊息分割成多個部分，每個部分不超過 1000 字元
        message_parts = [messages_str[i:i+1000] for i in range(0, len(messages_str), 1000)]
        for part in message_parts:
            await ctx.send(f"Matching messages:\n{part}")
    else:
        await ctx.send(f"No messages found containing '{keyword}'")

@bot.slash_command(name="savehistory", description="Save chat history")
async def fetch(ctx: discord.ApplicationContext):

    def is_command(msg):
        """Checking if the message is a command call"""
        if len(msg.content) == 0:
            return False
        elif msg.content.split()[0] == '_scan':
            return True
        else:
            return False

    data = []
    async for msg in ctx.channel.history(limit=10000, oldest_first=True):
        # if msg.author != ctx.user:
        # if not is_command(msg):
        # Get root message
        data.append({'content': msg.content,
                    'created_at': msg.created_at,
                    'author': msg.author.name,
                    'jump_url': msg.jump_url,
                    'author_id': msg.author.id,
                    'msg_id': msg.id,
                    'channel_id': msg.channel.id,
                    'guild_id': msg.guild.id,
                    })
        # Get thread messages (if any)
        if msg.flags.has_thread:
            async for thread_msg in msg.thread.history(limit=100, oldest_first=True):
                data.append({'content': thread_msg.content,
                            'created_at': thread_msg.created_at,
                            'author': thread_msg.author.name,
                            'jump_url': thread_msg.jump_url,
                            'author_id': thread_msg.author.id,
                            'msg_id': thread_msg.id,
                            'channel_id': thread_msg.channel.id,
                            'guild_id': thread_msg.guild.id,
                            })
            # if len(data) == limit:
            #     break

    data = pd.DataFrame(data)
    data.to_csv(CHAT_HISTORY_PATH)
    await ctx.respond("Chat history saved!")
    print(f'Chat history saved to {CHAT_HISTORY_PATH}')

bot.run(os.getenv('DISCORD_TOKEN'))


import math
import ConfigReader
import pickle
import collections
import Preprocessor
import logging
import time

__author__ = 'gabriel'

class TfIdf:
    def __init__(self):
        pass

    def generate_model(self, inverted_list):
        self.inverted_list = inverted_list
        self.n_terms = len(inverted_list)
        self.n_docs = len({j for i in inverted_list.values() for j in i})

        self.document_frequency = dict()
        self.term_document_frequency = dict()
        self.document_max_term_frequency = dict()

        begin_time = time.perf_counter()
        for term in inverted_list:
            counter = collections.Counter(inverted_list[term])

            # number of times a term appears on different documents
            self.document_frequency[term] = len(counter.keys())
            self.term_document_frequency[term] = counter
            for doc_id in counter:
                if doc_id not in self.document_max_term_frequency or \
                self.document_max_term_frequency[doc_id] < counter[doc_id]:
                    self.document_max_term_frequency[doc_id] = counter[doc_id]

        end_time = time.perf_counter()
        elapsed_time = end_time - begin_time
        logging.info("Model generation performance: " + str(elapsed_time/self.n_terms) + " terms per seconds")

    def weight(self, term, doc_id):
        if term not in self.document_frequency:
            return 0.0

        tf = self.term_document_frequency[term][doc_id]
        max_tf = self.document_max_term_frequency[doc_id]
        df = self.document_frequency[term]
        tf_idf = tf/max_tf * math.log10(self.n_docs/df)
        return tf_idf

    def query_vector(self, query):
        terms = Preprocessor.preprocessor_tokenizer(query)

        counter = collections.Counter(terms)
        query_vector = dict()
        query_vector_magnitude = 0
        for term in terms:
            if term not in self.document_frequency:
                continue

            max_tf = counter.most_common(1)[0][1] # it returns an list of item + frequency
            tf = counter[term]
            df = self.document_frequency[term]
            val = (0.5 + 0.5*tf/max_tf)*math.log10(self.n_terms/df)
            query_vector[term] = val

            query_vector_magnitude += val*val

        # normalizing step
        query_vector_magnitude = math.sqrt(query_vector_magnitude)
        for term in query_vector:
            query_vector[term] /= query_vector_magnitude

        return query_vector

    def retrieve(self, query):
        query_vec = self.query_vector(query)

        candidates = set()
        for term in query_vec.keys():
            candidates.update(self.inverted_list[term])

        docs_similarity = dict()
        for doc_id in candidates:
            doc_sim = 0
            doc_magnitude = 0

            for query_term in query_vec:
                doc_component = self.weight(query_term, doc_id)
                doc_magnitude += doc_component*doc_component

                # dot product
                doc_sim += doc_component * query_vec[query_term]

            # normalizing step
            doc_magnitude = math.sqrt(doc_magnitude)
            docs_similarity[doc_id] = doc_sim/doc_magnitude
        return docs_similarity

class Indexer():
    def __init__(self, weight_function = TfIdf()):
        self.weight_function = weight_function

    def read_inv_list(self, inv_list_file):
        inv_list = dict()
        with open(inv_list_file) as file:
            for l in file.readlines():
                temp = l.split(';')
                term = temp[0]
                list = temp[1]
                inv_list[term] = eval(list)
        return inv_list

    def do_index(self, cfg_file="index.cfg"):
        logging.info("Execution begin")

        cfg = ConfigReader.read_cfg(cfg_file)
        logging.info("Configuration file read")

        inv_list_file = cfg['LEIA'][0]
        model_file = cfg['ESCREVA'][0]

        inv_list = self.read_inv_list(inv_list_file)
        logging.info("Inverted list read: " + str(len(inv_list)) + " terms")

        self.weight_function.generate_model(inv_list)
        logging.info("Model generated")

        with open(model_file, 'wb') as pick_file:
            pickle.dump(self.weight_function, pick_file)
        logging.info("Model saved")

        logging.info("Execution ended")

if __name__ == "__main__":
    logging.basicConfig(filename='log/indexer.log', level=logging.INFO, format='%(asctime)s\t%(levelname)s\t%(message)s')
    index = Indexer()
    index.do_index()


#!/usr/bin/python
# coding: utf-8
# -*- coding: utf-8 -*-
"""Hash matching of ed2k hashes"""

from xlrd3 import open_workbook
from xlwt3 import Workbook
import hashlib
from binascii import hexlify
from functools import reduce
from os import listdir,path,walk
from os.path import isfile,abspath,isdir,join,getsize
#f = open("matches.txt",'w')
def cmpHashes(outputfile,hashesDict,metfile):
    """compare hashes of met xls file and file ed2key hashes"""
    wb = open_workbook(metfile)

    s=wb.sheets()[0]
    sheet = wb.sheet_by_index(0)         #input sheet

    book = Workbook()

    sheet1=book.add_sheet('Found')
    sheet2=book.add_sheet("NOT FOUND")

    #print ("number of roews",s.nrows)
    hashCalcprog=[]
    filesize=[]
    knowndotMedHashes=[]
    lastpostedUTC=[]
    lastsharedUTC=[]
    requestsAccepted=[]
    bytesUploaded=[]

    for i in range(sheet.nrows):#read hashes of met xls file
        #also includes labels
        knowndotMedHashes.append(sheet.cell_value(i,17).lower())
        filesize.append(sheet.cell_value(i,2))
        lastpostedUTC.append(sheet.cell_value(i,5))
        lastsharedUTC.append(sheet.cell_value(i,6))
        requestsAccepted.append(sheet.cell_value(i,8))
        bytesUploaded.append(sheet.cell_value(i,9))
    hash_indexes={}
    #hash_indexes=[knowndotMed.index(hash)
    i=0
    k=0
   # print (knowndotMedHashes)
    sheet1.write(k,0,'filename' )
    sheet1.write(k,2,filesize[k])
    sheet1.write(k,3,lastpostedUTC[k])
    sheet1.write(k,4,lastsharedUTC[k])
    sheet1.write(k,5,requestsAccepted[k])
    sheet1.write(k,1,'hash')

    for hash in  hashesDict.keys():

        try:

            index=knowndotMedHashes.index(hash)#retrieve index of matched hash
            hash_indexes[index]=hashesDict[hash]
            sheet1.write(k+1,0,hashesDict[hash] )
            sheet1.write(k+1,2,filesize[index])
            sheet1.write(k+1,3,lastpostedUTC[index])
            sheet1.write(k+1,4,lastsharedUTC[index])
            sheet1.write(k+1,5,requestsAccepted[index])
            sheet1.write(k+1,1,hash)
            k+=1
        except ValueError:

            notFoundfile=hashesDict[hash]
            sheet2.write(i+1,0,hashesDict[hash] )
            sheet2.write(i+1,1,hash)

            i+=1
            continue

    i=0

    book.save(outputfile)
#print (hash_indexes)
#f.write(str(hash_indexes))
#f.close()

def hash_file(file_path):
    """ Returns the ed2k hash of a given file. """
    sys.stdout.write("Finding hash for %s ...\n" %file_path.encode("utf8"))
    md4 = hashlib.new('md4').copy

    def gen(f):
        while True:
            x = f.read(9728000)
            if x: yield x
            else: return

    def md4_hash(data):
        m = md4()
        m.update(data)
        return m

    with open(file_path, 'rb') as f:
        a = gen(f)
        hashes = [md4_hash(data).digest() for data in a]# Building up a list of md4 hashes associated with 9500KB blocks
      #  print(type(hashes[0]),type(a))
        if len(hashes) == 1:
            #print (type(hashes[0]),hashes[0])
            hash=hexlify(hashes[0])
            return str(hash)[1:].replace('\'','')  if str(hash)[0]=='b' else str(hash).replace('\'','')
        else: return str(md4_hash(reduce(lambda a,d: a + d, hashes)).hexdigest())#function, items [, initial])

def genfile(inputfolder):

    for dirpath,dirnames,filenames in  walk(inputfolder):
          #sys.stdout.write("Retrieving hashes in %d ...\n" %len(dirnames) )
          for file in filenames:

            yield file,dirpath

if __name__ == '__main__':
    import sys
    if len(sys.argv) == 4:

        inputfolder = abspath(sys.argv[1])
        metfile=abspath(sys.argv[2])
        outputfile= abspath(sys.argv[3])
      #  print("i",inputfolder, outputfile)
        files=[]
        hashes=[]
       # hashes=list(map(lambda file:hash_file(join(inputfolder, file)),filter(lambda file:isfile(join(inputfolder,file)),listdir(inputfolder))))
        for file,dirpath in genfile(inputfolder):
       #   sys.stdout.write("Retrieving hashes in %s ...\n" %dirpath)
          if getsize(dirpath+"\\"+file)!=0:
            files.append(dirpath+"\\"+file)
            hashes.append(hash_file(join(dirpath, file)))
       # files=list(filter(lambda file: isfile(join(inputfolder, file)),listdir(inputfolder)))
            sys.stdout.write("Retrieving hashes in %s ...\n" %inputfolder)

            hashesDict=dict(zip(hashes, files))
            sys.stdout.write("Comparing hashes ...\n")
            cmpHashes(outputfile,hashesDict,metfile)
          else:
            sys.stdout.write("Zero size file %s ...\n" %file)

    else:
        sys.stderr.write("Usage : python %s inputfolder metfile outputfile\n" % sys.argv[0])
        raise SystemExit(1)


import sys
import statistics
import logging
from string import Template
import re

class StatBuilder:
    all_counter = 0
    err_counter = 0
    all_time_sum = 0.0
    data = {}
    re_url = re.compile(
        r"^/((?:\w|\d)+[a-zA-Z0-9-._~:?#\[\]@!$&'()*+,;=]*\/*)+(?:\?\S+)*$")

    def __init__(self, max_records: int, err_threshold_perc: int, logger: logging.Logger):
        self.err_threshold_perc = err_threshold_perc
        self.max_records = max_records
        self.logger = logger

    def process_logfile(self, logfile: str) -> None:
        import mimetypes
        import gzip

        self.logger.info('processing file: {}'.format(logfile))
        (_, file_encoding) = mimetypes.guess_type(logfile)
        fd = gzip.open(logfile, 'rt') if file_encoding == 'gzip' else open(
            logfile, 'r')

        for (url, duration) in StatBuilder.__log_line_provider(fd):
            self.__add_data(url, duration)

        self.logger.info('in file {} found {} records'.format(
            logfile, self.all_counter))
        err_perc = self.err_counter / self.all_counter * 100
        if err_perc > self.err_threshold_perc:
            self.logger.error(
                'error threshold {}%% exceeded - got {}%%. giving up, dude..'.format(self.err_threshold_perc, err_perc))
            return

        self.__calculate_stats()

    def create_report(self, to_file: str):
        try:
            fd = open('report.html', 'r')
            t = Template(fd.read())

            s = t.safe_substitute(table_json=self.__get_data())
            fd = open(to_file, 'w')
            fd.write(s)
            self.logger.info('created report file: {}'.format(to_file))
        except:
            self.logger.exception(
                'error occured while creating report: {}'.format(sys.exc_info()[1]))

    def __log_line_provider(fd):
        '''
        generator providing line-by-line from log file
        '''
        for i in fd:
            arr = StatBuilder.__clean_str(i).split(' ')
            url = arr[6]
            req_time = arr[-1]
            yield (url, req_time)

    def __clean_str(_str: str) -> str:
        norm_str = re.sub(r'\s{2,}', ' ', _str)
        return re.sub(r'("|\[|\]|\n)', '', norm_str)

    def __add_data(self, url: str, duration: str):
        self.logger.debug(
            'processing url \'{}\' with duration {}'.format(url, duration))
        try:
            if not self.re_url.match(url):
                raise SyntaxError
            dur = float(duration)
            self.all_time_sum += dur
            if not url in self.data:
                self.data[url] = {
                    'count': 0,
                    'durations': [],
                }
            self.data[url]['count'] += 1
            self.data[url]['durations'].append(dur)
        except ValueError:
            self.logger.warn("duration '{}' is not valid".format(duration))
            self.err_counter += 1
        except SyntaxError:
            self.logger.warn("url '{}' is not valid".format(url))
            self.err_counter += 1
        self.all_counter += 1

    def __calculate_stats(self):
        for key, val in self.data.items():
            count = val['count']
            durations = val['durations']
            val['count_perc'] = count / self.all_counter * 100
            val['time_sum'] = sum(durations)
            val['time_perc'] = val['time_sum'] / self.all_time_sum * 100
            val['time_avg'] = val['time_sum'] / count
            val['time_max'] = max(durations)
            val['time_med'] = statistics.median(durations)
            val['url'] = key

    def __get_data(self) -> list:
        sorted_list = sorted(list(self.data.values()),
                             key=lambda i: i['time_sum'], reverse=True)
        return sorted_list[:self.max_records]

{'mimetypes': 'mimetypes', 'gzip': 'gzip'}.__log_line_provider

{'mimetypes': 'mimetypes', 'gzip': 'gzip'}.__clean_str


from bokeh.models import HoverTool
from bokeh.models.glyphs import VBar
from bokeh.plotting import figure
from bokeh.charts import Histogram, Bar,Donut, HeatMap, TimeSeries
from bokeh.embed import components
from bokeh.models.sources import ColumnDataSource
from bokeh.palettes import Spectral11
from bokeh.themes import Theme
from bokeh.io import curdoc
import pandas as pd
import numpy as np
from flask import Flask, render_template

app = Flask(__name__)

bokehtheme = Theme(json={
'attrs' : {
    'Figure' : {
        'background_fill_color': '#2F2F2F',
        'border_fill_color': '#2F2F2F',
        'outline_line_color': '#444444',
    },
    'Grid': {
        'grid_line_dash': [6, 4],
        'grid_line_alpha': .3,
    },
    'Title': {
        'text_color': 'white'
    }
}})

df = pd.read_csv('data/testapp.csv')
df.date = pd.to_datetime(df.date, )

dfbig = pd.read_json('data/messy_with_countries.json')
dfbig.date = pd.to_datetime(dfbig.date)

dffi = pd.read_json('data/dffi.json')

mask = dfbig['teams'].isin(['Other', 'Unaffiliated'])
df2 = dfbig[~mask]
# @app.route("/")
# def index():
#     return render_template('index.html')

#
# @app.route("/dashboard/")
# def graphme():
#     plot = create_histogram(df['Age_at_win'].dropna())
#     q = bydate(dfbig,'Prize_USD','date')
#     plot2 = create_bigbar(q, 'date','Prize_USD','Earnings By Year')
#
#     p = nlargest(dfbig, 'CountryName','Prize_USD',10)
#     plot3 = create_donut(p, 'CountryName','Prize_USD',
#                             'Earnings by Top 10 Countries')
#
#     r = nlargest(df2, 'teams','Prize_USD',5)
#     plot4 = create_bar_chart(r, 'teams','Prize_USD',
#                             'Earnings by Top 5 Teams')
#
#     script, div = components(plot2)
#     script2, div2 = components(plot)
#     script3, div3 = components(plot3)
#     script4, div4 = components(plot4)
#
#     plot = figure()
#     # plot.circle([1,2], [3,4])
#     # script2, div2 = components(plot)
#     return render_template("index.html", the_div=div, the_script=script,
#                             the_div2=div2, the_script2=script2,
#                             the_div3=div3, the_script3=script3,
#                             the_div4=div4, the_script4=script4)

@app.route("/")
def graph1():
    plot = create_histogram2(df['Age_at_win'].dropna())
    q = bydate(dfbig,'Prize_USD','date')
    plot2 = create_bar_chart2(q, 'date','Prize_USD','Earnings By Year')

    p = nlargest(dfbig, 'CountryName','Prize_USD',10)
    plot3 = create_donut2(p, 'CountryName','Prize_USD',
                            'Earnings by Top 10 Countries')

    r = nlargest(df2, 'teams','Prize_USD',5)
    plot4 = create_bar_chart2(r, 'teams','Prize_USD',
                            'Earnings by Top 5 Teams')
    plot5 = create_bar_chart3(dffi,'Feature','Importance',
                            'Feature Importance - Random Forests')

    script, div = components(plot2)
    script2, div2 = components(plot)
    script3, div3 = components(plot3)
    script4, div4 = components(plot4)
    script5, div5 = components(plot5)

    plot = figure()
    # plot.circle([1,2], [3,4])
    # script2, div2 = components(plot)
    return render_template("longpage.html", the_div=div, the_script=script,
                            the_div2=div2, the_script2=script2,
                            the_div3=div3, the_script3=script3,
                            the_div4=div4, the_script4=script4,
                            the_div5=div5, the_script5=script5)

def nlargest(df, col1, col2, n):
    x = df.groupby(df[col1])[col2].apply(lambda i: i.sum())
    tn = x.nlargest(n)
    df2 = pd.DataFrame({'year': tn.index, col2: tn})
    return df2

def bydate(df, col, date):
    x = df.groupby(df.date.dt.year)[col].apply(lambda i: i.sum())
    df2 = pd.DataFrame({'year': x.index, col: x})
    return df2

def create_bar_chart(df,col1, col2, title):
    TOOLS = [HoverTool(tooltips=[(str(col1),'$x'),(str(col2),'@y{1.11}')])]
    plot = Bar(df, col1, values=col2, title=title, tools=TOOLS,
                color=Spectral11[1], ylabel="Total Earnings (in USD)",
                legend=False, plot_width=300, plot_height=300)
    return plot

def create_bar_chart2(df,col1, col2, title):
    TOOLS = [HoverTool(tooltips=[(str(col1),'$x'),(str(col2),'@y{1.11}')])]
    plot = Bar(df, col1, values=col2, title=title, tools=TOOLS,
                color=Spectral11[1], ylabel="Total Earnings (in USD)",
                legend=False, plot_width=400, plot_height=400)
    return plot

def create_bar_chart3(df,col1, col2, title):
    TOOLS = [HoverTool(tooltips=[(str(col1),'$x'),(str(col2),'@y{1.1111}')])]
    plot = Bar(df, col1, values=col2,
               legend=False, title=title, tools=TOOLS,
               color=Spectral11[2], plot_width=400, plot_height=400)
    return plot

def create_bigbar(df,col1, col2, title):
    TOOLS = [HoverTool(tooltips=[(str(col1),'$x'),(str(col2),'@y{1.11}')])]
    plot = Bar(df, label=col1, values=col2, tools=TOOLS,
                color=Spectral11[2], ylabel="Total Earnings (in USD)",
                 legend=False, title=title, sizing_mode='stretch_both')
    return plot

def create_donut(df,col1, col2, title):
    plot = Donut(df, label=col1, values=col2, color=Spectral11,
                 title=title, plot_width=300, plot_height=300)
    return plot

def create_donut2(df,col1, col2, title):
    plot = Donut(df, label=col1, values=col2, color=Spectral11,
                 title=title, plot_width=400, plot_height=400)
    return plot

def create_histogram(data):
    TOOLS = [HoverTool(tooltips=[('Age:','$x{int}'),('total','@y')])]
    plot = Histogram(data, title='Age:', legend='bottom_right',
                    ylabel="Number of Tournaments",
                    tools=TOOLS, plot_width=300, plot_height=300)
    return plot

def create_histogram2(data):
    TOOLS = [HoverTool(tooltips=[('Age:','$x{int}'),('total','@y')])]
    plot = Histogram(data, title='Age:', legend='bottom_right',
                    ylabel="Number of Tournaments",
                    tools=TOOLS, plot_width=400, plot_height=400)
    return plot

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080, debug=True)


import os

import spacy
from datasets import load_from_disk, load_metric

def test(args):
    """This function will test a given model on the test set of the prepared
    dataset.

    According to https://arxiv.org/pdf/2010.12421.pdf, for the task of Sentiment
    analysis, we need to use macro-averaged Recall metric to compare models.

    For the sake of completeness, this function also compute accuracy, precision,
    and F-1 score.

    Args:
        args (argparse.Namespace): CLI arguments.
    """
    # Load our model
    print("Loading model...")
    sentiment_model = spacy.load(os.path.join(args.model, "model-best"))

    # Load our dataset
    print("Loading dataset...")
    dataset = load_from_disk(args.dataset)

    # Create the metrics
    accuracy = load_metric("accuracy")
    precision = load_metric("precision")
    recall = load_metric("recall")
    f1 = load_metric("f1")

    print("Evaluating test set...")
    for i, tweet in enumerate(dataset["test"]):
        if not args.full and i > 100:
            # The test set is quite big (12k samples), it takes some time
            # So unless the user asked for full test set evaluation, just run
            # on the first 100 samples
            break

        # Predict using our trained model
        pred = sentiment_model(tweet["text"])

        # Spacy format -> int (0, 1, 2)
        sentiments = [pred.cats["negative"], pred.cats["neutral"], pred.cats["positive"]]
        pred_label = max(range(len(sentiments)), key=lambda i: sentiments[i])

        # Metrics
        accuracy.add(prediction=pred_label, reference=tweet["label"])
        precision.add(prediction=pred_label, reference=tweet["label"])
        recall.add(prediction=pred_label, reference=tweet["label"])
        f1.add(prediction=pred_label, reference=tweet["label"])

    # Display metrics to user
    print(f"\nAccuracy : {accuracy.compute()['accuracy']:.4f}")
    print(f"Precision : {precision.compute(average='macro')['precision']:.4f}")
    print(f">> Recall : {recall.compute(average='macro')['recall']:.4f}")
    print(f"F1-score : {f1.compute(average='macro')['f1']:.4f}")


from brownie import AdvancedCollectible, network
from scripts.helpful_scripts import get_breed
from metadata.sample_metadata import metadata_template
from pathlib import Path
import requests, json, os

breed_to_image_uri = {
    "PUG": "https://ipfs.io/ipfs/QmSsYRx3LpDAb1GZQm7zZ1AuHZjfbPkD6J7s9r41xu1mf8?filename=pug.png",
    "SHIBA_INU": "https://ipfs.io/ipfs/QmYx6GsYAKnNzZ9A6NvEKV9nf1VaDzJrqDR23Y8YSkebLU?filename=shiba-inu.png",
    "ST_BERNARD": "https://ipfs.io/ipfs/QmUPjADFGEKmfohdTaNcWhp7VGk26h5jXDA7v3VtTnTLcW?filename=st-bernard.png",
}

def main():
    # get most recent deployment
    advanced_collectible = AdvancedCollectible[-1]
    # get the number of tokens that have been created
    number_of_advanced_collectibles = advanced_collectible.tokenCounter()
    print(f"You have created {number_of_advanced_collectibles} collectibles")
    # loop through all the tokens and get metadata
    for token_id in range(number_of_advanced_collectibles):
        breed = get_breed(advanced_collectible.tokenIdToBreed(token_id))
        # metadata file for each token
        metadata_file_name = (f"./metadata/{network.show_active()}/{token_id}-{breed}.json")
        collectible_metadata = metadata_template
        if Path(metadata_file_name).exists():
            print(f"{metadata_file_name} already exists! Delete it to overwrite!")
        else:
            print(f"Creating Metadata file: {metadata_file_name}")
            collectible_metadata["name"] = breed
            collectible_metadata["description"] = f"An adorable {breed} pup"
            # need to get the image_uri
            image_path = "./img/" + breed.lower().replace("_","-") + ".png"

            image_uri = None
            # upload image to ipfs
            if os.getenv("UPLOAD_IPFS") == "true":
                image_uri = upload_to_ipfs(image_path)

            # we're setting image_uri to image_uri if image_uri isn't none
            image_uri = image_uri if image_uri else breed_to_image_uri[breed]

            collectible_metadata["image"] = image_uri
            # dump the collectible_metadata for the current nft to its own file
            with open(metadata_file_name, "w") as file:
                json.dump(collectible_metadata, file)
            if os.getenv("UPLOAD_IPFS") == "true":
                # upload metadata file to ipfs
                upload_to_ipfs(metadata_file_name)

def upload_to_ipfs(filepath):
    # going to the path of the file. rb means open file in binary with name fp
    with Path(filepath).open("rb") as fp:
        # read binary and store
        image_binary = fp.read()
        # upolad to ipfs
        ipfs_url = "http://127.0.0.1:5001"
        endpoint = "/api/v0/add"
        response = requests.post(ipfs_url + endpoint, files={"file":image_binary})
        ipfs_hash = response.json()["Hash"]
        # "./img/0-PUG.png" -> "PUG.png"
        filename = filepath.split("/")[-1:][0]
        image_uri = f"https://ipfs.io/ipfs/{ipfs_hash}?filename={filename}"
        print(image_uri)
        return image_uri


import json
import os

from flask import Blueprint, request, current_app, make_response

from primerserver2.web.config import load

bp = Blueprint('db', __name__)
@bp.route('/dbselect')
def dbselect():
    web_config = load()
    dbs_in_select = {}
    for (template, meta) in web_config['templates'].items():
        (desc, group, ids) = (meta['description'], meta['group'], meta['IDs'])
        if group not in dbs_in_select:
            dbs_in_select[group] = {}
        if template not in dbs_in_select[group]:
            dbs_in_select[group][template] = {}
        dbs_in_select[group][template]['desc'] = desc
        dbs_in_select[group][template]['IDs'] = ids
    return json.dumps(dbs_in_select, indent=4)

@bp.route('/dbinfo')
def dbinfo():
    web_config = load()
    return json.dumps(web_config['templates'], indent=4)

@bp.route('/dbdownload/<template>/')
def dbdownload(template):
    web_config = load()
    db_dir = web_config['templates_directory']
    result = os.popen(f'cut -f 1,2 {db_dir}/{template}.fai').read()
    response = make_response(result)
    response.headers["Content-Disposition"] = f"attachment; filename={template}.fai"
    response.headers["Content-type"] = "application/octet-stream"
    return response


import os
import shutil

import torch
import fire
import gin
import json
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pickle as pkl

from loguru import logger

from env_search.device import DEVICE
from env_search.warehouse.emulation_model.emulation_model import WarehouseEmulationModel
from env_search.analysis.utils import load_archive_gen, load_experiment, load_metrics
from env_search.utils import kiva_env_str2number, flip_tiles
from env_search.mpl_styles.utils import mpl_style_file
from env_search.analysis.visualize_env import visualize_kiva
from env_search.analysis.tile_usage import get_figsize_qd, plot_tile_usage

def main(
    logdir: str,
    gen: int = None,
    offline_logdir_data: str = None,
    w_mode: bool = True,
):
    logdir = load_experiment(logdir)
    reload_pth = logdir.pfile("reload_em.pth")
    reload_pkl = logdir.pfile("reload_em.pkl")

    # Read in master seed
    with open(logdir.pfile("seed"), "r") as f:
        seed = int(f.readline())

    # Load trained model
    model = WarehouseEmulationModel(seed=seed + 420)
    model.load(reload_pkl, reload_pth, map_location="cpu")

    breakpoint()

    # The model is trained offline, need to read test map from logdir that
    # contains the training data.
    if offline_logdir_data:
        reload_em_pkl = os.path.join(offline_logdir_data, "reload_em.pkl")
        with open(reload_em_pkl, "rb") as f:
            data = pkl.load(f)
            dataset = data["dataset"]
        env_unrepaired = dataset.levels[0]
        env_repaired = dataset.repaired_maps[0]
        occupancy = dataset.occupancys[0]
        true_obj = dataset.objectives[0]
        true_measure1, true_measure2 = dataset.measures[0]

        if w_mode:
            env_repaired = flip_tiles(
                env_repaired,
                'r',
                'w',
            )

    else:
        # Load one of the training maps from the archive
        gen = load_metrics(logdir).total_itrs if gen is None else gen
        df = pd.read_pickle(logdir.file(f"archive/archive_{gen}.pkl"))

        global_opt = df["objective"].idxmax()
        env_unrepaired = df.iloc[global_opt]["metadata"]["warehouse_metadata"][
            "map_int_unrepaired"]
        env_repaired = df.iloc[global_opt]["metadata"]["warehouse_metadata"][
            "map_int"]
        occupancy = df.iloc[global_opt]["metadata"]["warehouse_metadata"][
            "tile_usage"]
        occupancy = np.mean(occupancy, axis=0)

        # Process the map
        # Maps in archive contains 'w' while maps in dataset are already
        # processed
        if w_mode:
            env_unrepaired = flip_tiles(
                env_unrepaired,
                'w',
                'r',
            )

        # Get real value
        true_obj = df.iloc[global_opt]["objective"]
        true_measure1 = df.iloc[global_opt]["behavior_0"]
        true_measure2 = df.iloc[global_opt]["behavior_1"]

    env_unrepaired = env_unrepaired[np.newaxis, ...]

    # Compute the repaired map and tile usage map
    with torch.no_grad():
        pred_repaired_map, pred_occupancy = \
            model.pre_network.int_to_logits(
                torch.as_tensor(env_unrepaired, device=DEVICE))
        pred_occupancy = torch.softmax(torch.flatten(pred_occupancy), dim=0)
        pred_occupancy = torch.reshape(pred_occupancy, occupancy.shape)
    pred_repaired_map = pred_repaired_map.numpy()
    pred_repaired_map = np.argmax(pred_repaired_map, axis=1)[0]
    if w_mode:
        pred_repaired_map = flip_tiles(
            pred_repaired_map,
            'r',
            'w',
        )

    # Create plot
    grid_kws = {"height_ratios": (0.475, 0.475, 0.05)}
    pred_fig, (ax_pred_map, ax_pred_tile_use,
          ax_pred_tile_use_cbar) = plt.subplots(3,
                                           1,
                                           figsize=get_figsize_qd(),
                                           gridspec_kw=grid_kws)
    fig, (ax_map, ax_tile_use,
        ax_tile_use_cbar) = plt.subplots(3,
                                        1,
                                        figsize=get_figsize_qd(),
                                        gridspec_kw=grid_kws)
    # Plot and save to disk
    validate_mdl_dir = logdir.dir("validate_mdl")
    if os.path.exists(validate_mdl_dir):
        shutil.rmtree(validate_mdl_dir)
    os.mkdir(validate_mdl_dir)

    # Plot unrepaired map
    visualize_kiva(
        env_unrepaired[0],
        filenames = ["unrepaired.png"],
        store_dir = validate_mdl_dir,
    )

    # Plot ground-truth repaired map with pred tile usage
    visualize_kiva(
        env_repaired,
        ax=ax_map,
    )
    plot_tile_usage(
        occupancy,
        occupancy.shape[0],
        occupancy.shape[1],
        fig,
        ax_tile_use,
        ax_tile_use_cbar,
        logdir,
        filenames=[
            f"validate_mdl/tile_usage.png",
        ],
        dpi=300,
    )

    # Plot pred repaired map with pred tile usage
    visualize_kiva(
        pred_repaired_map,
        ax=ax_pred_map,
    )
    plot_tile_usage(
        pred_occupancy,
        pred_occupancy.shape[0],
        pred_occupancy.shape[1],
        pred_fig,
        ax_pred_tile_use,
        ax_pred_tile_use_cbar,
        logdir,
        filenames=[
            f"validate_mdl/pred_tile_usage.png",
        ],
        dpi=300,
    )

    # Compute the final obj and measures
    obj, measures = model.predict(env_unrepaired)
    print(f"Predicted obj: {obj[0]}")
    print(f"Predicted measures: [{measures[0][0]}, {measures[0][1]}]")

    print(f"True obj: {true_obj}")
    print(f"True measures: [{true_measure1}, {true_measure2}]")

if __name__ == '__main__':
    fire.Fire(main)


"""
    This file contains the in-memory cacheing implementation for the weather api
"""

import datetime
from typing import Optional, Tuple

__cache = {}
lifetime_in_hours = 1.0

def get_weather(
    city: str, state: Optional[str], country: Optional[str], units: Optional[str]
):
    """_summary_: This is the Weather route of the api
    units (optional): The units to get the weather in. Default is metric
    """
    # Get the response from the async function
    key = __create_key(city, state, country, units)
    data: dict = __cache.get(key)
    # What happens if there is not data
    if not data:
        # Return none
        return None

    # Get the last time the same key was used
    last = data["time"]
    # Check if the same request was made less than an hour ago
    dt = datetime.datetime.now() - last

    if dt / datetime.timedelta(minutes=60) < lifetime_in_hours:
        # Remove the data
        return data["value"]

    del __cache[key]
    return None

def set_weather(city: str, state: str, country: str, units: str, value: dict):
    key = __create_key(city, state, country, units)
    data = {"time": datetime.datetime.now(), "value": value}
    __cache[key] = data
    __clean_out_of_date()

def __create_key(city: str, state: str, country: str, units: str):
    if not city or not country or not units:
        raise Exception("City, State, Country, and Units are required")
    # state can be optional
    if not state:
        state = ""

    return (
        city.strip().lower(),
        state.strip().lower(),
        country.strip().lower(),
        units.strip().lower(),
    )

def __clean_out_of_date():
    for key, data in list(__cache.items()):
        dt = datetime.datetime.now() - data.get("time")
        if dt / datetime.timedelta(minutes=60) > lifetime_in_hours:
            del __cache[key]


import os,sys
import argparse

parser = argparse.ArgumentParser(description="Deduplicate reads for hypervariable genes")
parser.add_argument("-1", "--read1", type=str, required=True, help="Path to the fastq file 1")
parser.add_argument("-2", "--read2", type=str, required=True, help="Path to the fastq file 2")
parser.add_argument("-c","--conda_directory",type=str, required=True,help="Path to the conda 3 environment")
parser.add_argument("-t","--num_threads",type=str, required=False,help="number of threads")
parser.add_argument("-o","--output_folder",type=str, required=True,help="The name of the output folder")
args = vars(parser.parse_args())
condaDir = args['conda_directory']
read1 = args['read1']
read2 = args['read2']
outputFolder = args['output_folder']
if not args['num_threads']:
	threads = 1
else:
	threads = args['num_threads']

hvg = ['RL12','RL13','RL5A','RL6','UL11','UL120','UL139','UL146','UL1','UL20','UL73','UL74','UL9','UL55','UL75','UL100']
os.system("mkdir -p ./"+outputFolder+"/reads")
os.system("mkdir -p ./"+outputFolder+"/scaffolds")
outfile = open("./"+outputFolder+"/deduplicationStats.txt","w")
outfile.write("Gene\tOriginal_Mapped_Reads\tDeduplicate_Mapped_Reads\n")

for gene in hvg:
	print("Indexing reference for gene %s" %gene)
	os.system(condaDir+"/bin/bowtie2-build -q ./elongedCDS/"+gene+"_elongedCDS.fasta reference > null 2>&1")
	print("Aligning reads to reference....")
	os.system(condaDir+"/bin/bowtie2 --very-sensitive-local -1 "+read1+" -2 "+read2+" -x reference -S alignment.sam -p "+threads+ " > null 2>&1")
	print("Coverting sam to bam....")
	os.system(condaDir+"/bin/samtools view -h -bS alignment.sam > alignment.bam")
	print("Collecting first mapped reads....")
	os.system(condaDir+"/bin/samtools view -h -b -F 4 -f 8 alignment.bam > firstMapped.bam")
	print("Collecting second mapped reads....")
	os.system(condaDir+"/bin/samtools view -h -b -F 8 -f 4 alignment.bam > secondMapped.bam")
	print("Collecting both mapped reads....")
	os.system(condaDir+"/bin/samtools view -h -b -F12 alignment.bam > bothMapped.bam")
	print("Merging alignments....")
	os.system(condaDir+"/bin/samtools merge -f merged.bam firstMapped.bam secondMapped.bam bothMapped.bam")
	print("Calculating number of original reads....")
	os.system(condaDir+"/bin/samtools view merged.bam | wc -l >readCount")
	infile = open("readCount")
	beforeDedupReads = int(infile.readline().rstrip())
	infile.close()
	print("Picard add groups....")
	os.system(condaDir+"/bin/picard AddOrReplaceReadGroups I=merged.bam O=rg_added_sorted.bam SO=coordinate RGID=id RGLB=library RGPL=Ilumina RGPU=machine RGSM=Consensus >null 2>&1")
	print("Picard mark duplicates....")
	os.system(condaDir+"/bin/picard MarkDuplicates I=rg_added_sorted.bam O=dedupped.bam  CREATE_INDEX=true VALIDATION_STRINGENCY=SILENT M=output.metrics >null 2>&1")
	print("Discarding reads with duplicates....")
	os.system(condaDir+"/bin/samtools view -h -b -F 1024 dedupped.bam > alignment_removedDup.bam")
	print("Calculating number of deduplicated reads....")
	os.system(condaDir+"/bin/samtools view alignment_removedDup.bam | wc -l >readCount")
	infile = open("readCount")
	afterDedupReads = int(infile.readline().rstrip())
	infile.close()
	outfile.write(gene+"\t"+str(beforeDedupReads)+"\t"+str(afterDedupReads)+"\n")
	print("Extracting reads....")
	os.system(condaDir+"/bin/bam2fastq  -o read#.fq alignment_removedDup.bam")

	print("Performing denovo using spades")
	os.system(condaDir+"/bin/spades.py -1 read_1.fq -2 read_2.fq --cov-cutoff auto --careful -o outputSpades -t "+threads+" >null 2>&1")

	os.system("mv read_1.fq ./"+outputFolder+"/reads/"+gene+"_dedup_1.fastq")
	os.system("mv read_2.fq ./"+outputFolder+"/reads/"+gene+"_dedup_2.fastq")
	if os.path.isfile("./outputSpades/scaffolds.fasta") == True:
		os.system("mv ./outputSpades/scaffolds.fasta ./"+outputFolder+"/scaffolds/"+gene+"_scaffolds.fasta")

	os.system("rm -rf all_* alignment* null merged.bam firstMapped.bam readCount secondMapped.bam bothMapped.bam reference* outputSpades output.metrics dedupped.bai dedupped.bam rg_added_sorted.bam")

os.system("cat ./"+outputFolder+"/reads/*dedup_1.fastq > ./"+outputFolder+"/reads/all_1.fastq")
os.system("cat ./"+outputFolder+"/reads/*dedup_2.fastq > ./"+outputFolder+"/reads/all_2.fastq")
outfile.close()


import h5py
import numpy
import numpy as np

# this is the imputed SNP matrix provided by the 1001G project
f = h5py.File('1001_SNP_MATRIX/imputed_snps_binary.hdf5', 'r')

# this is the list of SNPs after filters
# (genotyping rate 0.2 and
# pruning/MAF settings = --indep-pairwise 100 10 0.1 --maf 0.05)
listofsnps = np.genfromtxt('1001G_MAF0.05.prune.in', dtype="str")

# Get all SNP positions for all chromosomes
positions = f['positions'][:]
snps = f['snps'][:]
print(positions.shape)

# Array of tuples with start/stop indices for each chromosome
chr_regions = f['positions'].attrs['chr_regions']

# Initialize arrays to hold indices and positions
chrs = [1, 2, 3, 4, 5]
indices = []
positions_chr = []
positions_all = []
genotypes = []
position = []
ix = []

# The positions in the h5py files are NOT associated with chromosome number
# so we need to retrieve the indices to delimit the 5 chromosomes
for i in chrs:
    indices.append(chr_regions[i-1])

# Convert positions to chr:position format so we can find the intersection
# with the pruned list
count = 0
for i in chrs:
    positions_chr = [str(i)+":"+str(position)
                     for position in
                     positions[indices[i-1][0]:indices[i-1][1]]]
    if count == 0:
        positions_all = positions_chr
    else:
        positions_all = np.append(positions_all, positions_chr)
    count += 1

ix = numpy.where(numpy.isin(positions_all, listofsnps))

# Save genotype of selected snps
ix = np.array(ix, dtype=int)
count = 0

for i in ix:
    if count == 0:
        genotypes = snps[i]
    else:
        genotypes = np.vstack((genotypes, snps[i]))
    count += 1

# Save SNP names (final number of variables =
# intersection between provided list of snps and the snps in the h5 matrix)
count = 0
for i in ix:
    if count == 0:
        position = positions_all[i]
    else:
        position = np.vstack((position, positions_all[i]))
    count += 1

# Save final genotype matrix
np.savetxt("1001G_gen.csv", np.transpose(genotypes), delimiter=',', fmt="%s")

# Save final SNP ids
np.savetxt("1001G_snpids.csv", np.transpose(position), delimiter=',', fmt="%s")


from datetime import date, timedelta, datetime
import argparse
import os
import getpass
import sys

# Variables needed:
url = 'https://www.ncei.noaa.gov/data/sea-surface-temperature-optimum-interpolation/v2.1/access/avhrr/'
FILE = 'oisst-avhrr-v02r01.'
FILETYPE = '.nc'
PRELIM = '_preliminary.nc'
PATH_BASE = '/g/data/ia39/aus-ref-clim-data-nci/oisst/data/tmp/'
PATH_OUT = '/g/data/ia39/aus-ref-clim-data-nci/oisst/data/yearly/'

def parse_input():
    ''' Parse input arguments '''
    parser = argparse.ArgumentParser(description='''Concatonate daily OISST netcdf files into yearly.
             Usage: python3 oisst_concat.py -y <year>
             Also rechunks yearly files and saves the info to its history attr.''', formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('-y','--year', type=int, help='year to process',
                        required=True)
    return vars(parser.parse_args())

def daterange(start_date, end_date):
    '''Creates a list of the dates in the specified year'''
    for n in range(int((end_date - start_date).days)):
        yield start_date + timedelta(n)

def rm_prelim(year, YMD, YM):
    '''Removes preliminary files if the proper files exist.'''
    dir_year=str(year)
    YMD_file = str(YMD)
    YM_file = str(YM)

    path_file = PATH_BASE+dir_year+'/'+FILE+YMD_file+FILETYPE
    path_prelim = PATH_BASE+dir_year+'/'+FILE+YMD_file+PRELIM
    isExist = os.path.exists(path_file)
    isExist_prelim = os.path.exists(path_prelim)

    if ((isExist == True) and (isExist_prelim == True)):
        os.remove(path_prelim)
    else:
        pass

def bash_cdo(year):
    '''Using subprocess to run cdo to conatenate daily files into yearly.
    And ncks to rechunk the yearly file.'''
    dir_year=str(year)

    IN_FILE = PATH_BASE+dir_year+'/'+FILE+dir_year+'*.nc'
    TMP_FILE = PATH_OUT+'oisst-avhrr-v02r01_'+dir_year+'_tmp.nc'
    OUT_FILE = PATH_OUT+'oisst-avhrr-v02r01_'+dir_year+'.nc'

    # Check to see if final file exists
    # Delete it if it does, ncks doesn't seem to like it already exisitng.
    isExist = os.path.exists(OUT_FILE)
    if isExist == True:
        os.remove(OUT_FILE)
    else:
        pass

    # Concatenate the daily files into one yearly file:
    cmd_cat = 'cdo --no_history -O -L --sortname --no_warnings -f nc4 -z zip_5 cat'+' '+IN_FILE+' '+TMP_FILE
    os.system(cmd_cat)
    print('Concatonate done!')

    # Rechunk the yearly file:
    cmd_chun = 'ncks --cnk_dmn time,366 --cnk_dmn lat,720 --cnk_dmn lon,720'+' '+TMP_FILE+' '+OUT_FILE
    os.system(cmd_chun)
    os.remove(TMP_FILE)
    print('Re-chunking done!')

    # Add what has been done to the history:
    hist = 'downloaded original files from'+' '+url+'. Using cdo to concatenate files: '+cmd_cat+' '+'and nco to modify chunks: '+cmd_chun
    cmd_ncatted = 'ncatted -O -a history,global,o,c,\'{0}\' %s'.format(hist)%(OUT_FILE)
    print(cmd_ncatted)
    os.system(cmd_ncatted)
    print('History added to'+OUT_FILE)

def main():
    '''Main function to combine everything together.'''

    inputs=parse_input()
    year = inputs["year"]

    start_date = date(year, 1, 1)
    if year == date.today().year:
        end_date = date(year, date.today().month, date.today().day)
    else:
        end_date = date(year+1, 1, 1)

    # Loop through all the dates and download the required files:
    for single_date in daterange(start_date, end_date):
        YMD = single_date.strftime("%Y%m%d")
        YM = single_date.strftime("%Y%m")

        # Remove any redundant prelim file
        rm_prelim(year, YMD, YM)

    dt = str(date.today())
    usr = str(getpass.getuser())
    print('-------------------------------------------------------------------------')

    # Run the conatenate & rechunking:
    bash_cdo(year)

    # Info for logging:
    now = datetime.now()
    current_time = str(now.strftime("%H:%M:%S"))
    print(dt+' '+current_time+': the'+' '+str(year)+' daily data was concatenated into one file by'+' '+usr)
    print('-------------------------------------------------------------------------')

# Run the script.
if __name__ == "__main__":
    # Logs all python output to file:
    with open("concat_log.txt", 'a') as f:
        sys.stdout = f
        # Run the script
        main()

    f.close()


from django.contrib import admin
from api.models import Account,School

class AccountAdmin(admin.ModelAdmin):
    list_display = ['account_id','username','firstname','lastname','email','is_verified','is_deleted']
    search_fields = ['username','firstname','lastname']
    list_filter = ['is_verified','is_deleted']

# class SchoolAdmin(admin.ModelAdmin):
#     list_display = ['school_id','owner_id','name','address']

admin.site.register(Account,AccountAdmin)
# admin.site.register(School,SchoolAdmin)


def run():
    import numpy as np
    from scipy import ndimage
    import pandas as pd
    from scipy.io import wavfile
    from scipy.signal import spectrogram
    import pickle
    import time
    import os
#
#     FILE_NAMEs= ['/Users/alexwang/Downloads/pred_kegl-1.wav',
#                  '/Users/alexwang/Downloads/silencedintervals.wav']
    curr_dir = os.getcwd()
    path_parent = os.path.dirname(curr_dir)
    data_dir = path_parent + '/data'
    FILE_NAMEs= [data_dir + '/audio/pred_kegl-1.wav',
                 data_dir + '/audio/silencedintervals.wav']

    MODEL_DIR=data_dir + '/processed/1911_k1.pkl'

    output_dir=curr_dir #specify output dir if you want

    def db(S):
        return 10 * np.log10(S)

    def pred_pop(filename,OUTPUT_DIR=''):

        SHRINK_RATIO=0.4
        hop = 5

        model=pickle.load(open(MODEL_DIR,'rb'))

        fs,wav = wavfile.read(filename)
        nn=fs*20
        j=0
        n = 0
        startlist = []
        endlist = []
        label = []
        tm = []

        while j+nn<len(wav):
            twav = wav[j:j+nn]
            f,t,Sxx = spectrogram(twav,fs=fs,window='hann',nperseg=1024,nfft=2048,noverlap=512)
            S=db(Sxx)
            S=ndimage.zoom(S,SHRINK_RATIO)
            S-=S.min()
            S/=S.max()
            S=S.reshape((1,S.shape[0],S.shape[1],1))

            model_output = model.predict(S,verbose=0).argmax(axis=1) # make prediction here

            tm.append(j/fs)
            label.append(model_output)
            if model_output == 1:
                if not startlist:
                    startlist.append(j)
                    endlist.append(j+nn)
                    n+=1
                elif j<=endlist[-1]:
                    endlist.pop()
                    endlist.append(j+nn)
                else:
                    n+=1
                    startlist.append(j)
                    endlist.append(j+nn)
            j+=hop*fs

        # save model prediction
        df = pd.DataFrame({'starttime':tm,'prediction':label})
        outname=f'{OUTPUT_DIR}/pred.csv' if OUTPUT_DIR else 'pred.csv'
        df.to_csv(outname) # change filepath and name here

        #save start and end time of problematic pieces
        startlist = np.array(startlist)/fs
        endlist = np.array(endlist)/fs
        df2 = pd.DataFrame({'start':startlist,'end':endlist})
        outname=f'{OUTPUT_DIR}/timeidx.csv' if OUTPUT_DIR else 'timeidx.csv'
        df2.to_csv(outname) #change filepath and name here

    def ma(inv, n) :
        tmp = np.cumsum(inv, dtype=float)
        tmp[n:] = tmp[n:] - tmp[:-n]
        return tmp[n - 1:] / n

    def find_silence(filename,dur = 6,OUTPUT_DIR=''): #default 6 sec
        fs,wav = wavfile.read(filename)
        wav2 = np.array(abs(wav))
        wav2[wav2<=0.03]=0
        wav2[wav2>0.03]=1
        N=dur*fs
        wav3 = ma(wav2,N)
        label = np.where(wav3<10**-3,1,0)
        label2 = np.diff(label)
        idx = np.round(np.where(label2==1)[0]/fs,1)
        idx2 = np.round(np.where(label2==-1)[0]/fs,1)+dur
        df =pd.DataFrame({'start':idx,'end':idx2})
        outname=f'{OUTPUT_DIR}/silenceidx.csv' if OUTPUT_DIR else 'silenceidx.csv'
        df.to_csv(outname)

    st = time.time()
    find_silence(FILE_NAMEs[1],dur=6,OUTPUT_DIR=output_dir)
    et = time.time()
    dt = et-st
    #np.savetxt('testtime.csv',dt)
    st = time.time()
    pred_pop(FILE_NAMEs[0], OUTPUT_DIR=output_dir)
    et = time.time()
    dt2 = et-st
    #np.savetxt('testtime.csv',[dt,dt2])

run()


from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

app = Flask(__name__)

line_bot_api = LineBotApi('SEj0ATQYEE8AwGHW+f8iIX95OTz/Pw9v+H0UdgU+vGdyUjpOFiVT4kQIqOKtejxYFtEc4C5idZSkM7Rru1rui0GlN3sAMx+IAV6Wn33NsZ2Tm8CfU6LebxylXvyHIBcTv1JwbeefU6JJu4CuBYMRogdB04t89/1O/w1cDnyilFU=')
handler = WebhookHandler('59efc3ed8602bc77ce971ad68561a377')

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))

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


"""
    @Author <UNK>
    @Splitter 王振琦
    @Date <UNK>
    @Describe 微信
"""

import requests
import scrapy
from scrapy import Selector

from monitor import logger

class Weixin:
    name = "微信"

    def __init__(self):
        pass

    def get_request_from_keyword(self, headers, search_url, keyword, *args, **kwargs):
        params = (
            ('type', '2'),
            ('ie', 'utf8'),
            ('s_from', 'hotnews'),
        )
        cookies = {
            'ABTEST': '0|1632473526|v1',
            'IPLOC': 'CN3702',
            'SUID': 'E246A7779F22A40A00000000614D91B6',
            'weixinIndexVisited': '1',
            'SUV': '0055E9D278E0DD08614D91B8D4FC3378',
            'SNUID': 'EF4DAC7B0B0EC1B4D0E11FC90C8E1258',
            'JSESSIONID': 'aaac23-7Kzbz26rEoqhUx',
        }
        try:
            for page in range(16):
                url = search_url.substitute(keyword=keyword, page=page)
                response = requests.get(url, headers=headers, params=params, cookies=cookies, timeout=10)
                html = Selector(text=response.text)
                results = html.xpath("//div[@class='txt-box']//a//@href").extract()
                for res in results:
                    url = 'https://weixin.sogou.com/' + res
                    meta = {
                        "url": url,
                        "name": "baidu",
                        "platform": "weixin",
                        "keyword": keyword,
                        "callback": "parse_page"
                    }
                    yield scrapy.Request(url=url, meta=meta, dont_filter=False)
        except Exception as e:
            logger.exception(f"E 西陆军事检索{e}")
            yield None

if __name__ == '__main__':
    search_url = 'https://weixin.sogou.com/weixin?query={}&s_from=hotnews&type=2&page={}&ie=utf8'
    headers = {
        'Connection': 'keep-alive',
        'Cache-Control': 'max-age=0',
        'sec-ch-ua': '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
        'sec-ch-ua-mobile': '?0',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'Sec-Fetch-Site': 'same-origin',
        'Sec-Fetch-Mode': 'navigate',
        'Sec-Fetch-User': '?1',
        'Sec-Fetch-Dest': 'document',
        'Accept-Language': 'zh,en-GB;q=0.9,en-US;q=0.8,en;q=0.7',
    }
    weixin = Weixin()
    for a in weixin.get_request_from_keyword(headers=headers, search_url=search_url, keyword=""):
        print(a)


# coding: utf-8

from flask import Flask
import os

app = Flask(__name__)

@app.route("/")
def index():
  return "cf-sample-python index page"

if __name__ == "__main__":
  port = 8888
  if os.environ.has_key("PORT"):
    port = int(os.environ['PORT'])

  app.run(host="0.0.0.0", port=port, debug=True)


from scipy import integrate
from numpy import sqrt
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(0,1.2,num=100)
y1,y2=x**2,sqrt(x)
plt.plot(x,y1,'r',x,y2,lw=3)

ax = plt.gca()
ax.spines['right'].set_color('blue')
ax.spines['top'].set_color('red')
ax.spines['left'].set_color('yellow')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.xaxis.set_visible('True')
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
plt.title('Surface integral of closed Area')

plt.fill_between(x, y1, y2,where=y2>=y1, facecolor='y', interpolate=False)
plt.text(0.6, 0.2,r'$y_1=x^2$',fontsize=20)
plt.text(0.05, 0.65,r'$y_2=\sqrt{x}$',fontsize=20,)
plt.axis([-0.2, 1.2, -0.2, 1.2])
plt.grid(True)
plt.annotate('Area D', xy=(0.3,0.42),fontsize=20)

plt.ylim(-0.2,1.4)
plt.xlim(-0.2,1.4)
plt.yticks([i*0.2 for i in np.arange(1,8)],[r'0.2', r'$0.4$', r'$0.6$', r'$0.8$', r'$1.0$', r'$1.2$', r'$1.4$'],fontsize=10,)
plt.show()

s1,abser1 = integrate.quad(lambda x:sqrt(x)-x**2,0,1)
print("Area of D is %.10f" %s1)
s2,abser2 = integrate.dblquad(lambda x,y: 1,0,1,lambda x :x**2,lambda x:sqrt(x))
print("Area of D is %.10f" %s2)


import http.client
import json
from json.decoder import JSONDecodeError
from calendar import monthrange
from random import randint
from threading import Thread

class BirdAPI:
	def __init__(self, region, n, gameinfo=None):
		if gameinfo:
			self.load_total = len(gameinfo["Checklists"])
			self.region = gameinfo["Region"]
			self.checklist_codes = gameinfo["Checklists"]
		else:
			self.load_total = n
			self.region = region
			self.checklist_codes = []

		self.conn = http.client.HTTPSConnection("api.ebird.org")
		self.payload = ''
		self.headers = {
			'X-eBirdApiToken': '6c8plv8d6h6b'
		}
		self.i = 0
		self.checklists = []
		self.locs = []
		self.tax = {}
		self.curr_checklist = None
		self.min_species = 10
		self.begin_thread()

	def begin_thread(self):
		"""Begin a new thread that fetches until we have the desired number of checklists"""
		Thread(target=self.fetch_until_stop).start()

	def fetch_until_stop(self):
		"""Fetch checklists until we have the desired number."""
		n_fail = 0
		while n_fail < 10 and len(self.checklists) < self.load_total:
			y = randint(2000, 2022)
			m = randint(1, 12)
			d = randint(1, monthrange(y, m)[1])
			checklists = self.checklist_codes if len(self.checklist_codes) >= self.load_total \
							else self.getchecklists(self.region, y, m, d)
			for c in checklists:
				if type(c) == str:
					clist = self.lookup(f"/v2/product/checklist/view/{c}")
				else:
					clist = self.lookup(f"/v2/product/checklist/view/{c['subID']}")
				if len(clist["obs"]) >= self.min_species and self.percent_X(clist["obs"]) < 0.5:
					if clist not in self.checklists and self.process_checklist(clist):
						self.checklists.append(clist)
						if c not in self.checklist_codes:
							self.checklist_codes.append(c['subID'])
						break
				if len(self.checklists) == self.load_total:
					break
			n_fail += 1
		if n_fail >= 10:
			print(f"Unable to find checklist in region {self.region} with species list of at least {self.min_species}!")
			assert n_fail < 10

	def percent_X(self, obs):
		X = 0
		for sp in obs:
			if str(sp["howManyStr"]) == "X":
				X += 1
		return X / len(obs)

	def process_checklist(self, checklist):
		self.locs.append(self.hotspotloc(checklist))
		if self.locs[-1] is None:
			self.locs.pop()
			return False
		for sp in checklist["obs"]:
			if sp["speciesCode"] not in self.tax:
				self.tax[sp["speciesCode"]] = self.taxonomy(sp["speciesCode"])
		return True

	def get_checklist(self):
		if len(self.checklists) <= self.i:
			print("Loading checklists... please wait.")
		while len(self.checklists) <= self.i:
			pass
		curr_checklist = self.checklists[self.i]
		return curr_checklist["obsDt"] + " https://ebird.org/checklist/" + curr_checklist["subId"] + "\n" + self.specieslist(curr_checklist)

	def get_location(self):
		self.i += 1
		return self.locs[self.i-1]

	# def new_checklist(self):
	# 	for _ in range(10):
	# 		y = randint(2000, 2022)
	# 		m = randint(1, 12)
	# 		d = randint(1, monthrange(y, m)[1])
	# 		self.curr_checklist = self.filterspecies(self.getchecklists(self.region, y, m, d), self.min_species)
	# 		print(self.curr_checklist)
	# 		if self.curr_checklist:
	# 			return
	# 	# print(self.curr_checklist)
	# 	print(f"Unable to find checklist in region {self.region} with species list of at least {self.min_species}!")
	# 	assert self.curr_checklist

	# Below are lookup tools

	def lookup(self, url):
		try:
			self.conn.request("GET", url, self.payload, self.headers)
			res = self.conn.getresponse()
		except http.client.RemoteDisconnected:
			self.conn = http.client.HTTPSConnection("api.ebird.org")
			return self.lookup(url)
		data = res.read()
		try:
			return json.loads(data.decode('utf-8'))
		except JSONDecodeError:
			return data.decode('utf-8')

	def taxonomy(self, spcode):
		return self.lookup(f"/v2/ref/taxonomy/ebird?species={spcode}").split(",")[15]

	def getchecklists(self, region, y, m, d):
		query = f"/v2/product/lists/{region}/{y}/{m}/{d}?maxResults=200"
		return self.lookup(query)

	def specieslist(self, clist):
		out = ""
		for sp in clist["obs"]:
			out += str(sp["howManyStr"]) + " " + self.tax[sp["speciesCode"]]
			if "comments" in sp:
				out += ": " + str(sp["comments"]) + "\n"
			else:
				out += "\n"
		return out

	def hotspotloc(self, checklist):
		hotspot = self.lookup(f"/v2/ref/hotspot/info/{checklist['locId']}")
		if not hotspot:
			return None
		return hotspot["latitude"], hotspot["longitude"], hotspot["hierarchicalName"]


import logging

from Server.ProtocolDefenitions import FILE_PORT
from Server.Server import Server

logger = logging.getLogger(__name__)

def read_port():
    logger.debug(f"Reading from '{FILE_PORT}'...")
    with open(FILE_PORT) as file:
        res = int(file.readline())
        logger.debug("OK")
        return res

if __name__ == '__main__':
    port = read_port()
    server = Server(port)
    server.start()


import requests
from rest_framework import serializers

# import json
# BASE_DIR="http://127.0.0.1:8000/"  #where it will go
# END_POINT="updates/"

# def get_list():
#     r=requests.get(BASE_DIR + END_POINT)
#     data=r.json()
#     print(data["content"])
#     print(r.status_code)
#     # for i in data:
#     #     print(i["content"])

#     return data

# get_list()
# # print(get_list())

# def create_update():
#     dict={
#         "user":1,
#         "content":"asdad",}
#     r=requests.post(BASE_DIR + END_POINT,data=dict)
#     print(r.json())
# create_update()

class StatusSerializers(serializers.ModelSerializer):
    email=serializers.EmailField()

    def validate_email(self,value):
        if len(value) >10:
            raise serializers.ValidationError("more than 10 words")

        return value

StatusSerializers()
data={"email":"asdssssssss"}
asdasd=StatusSerializers(data=data)

if asdasd.is_valid():
    print("true")
else:
    print("False")


# -*- coding: utf-8 -*-
# @Author  : Junru_Lu
# @File    : CNN_SentenceSimilarity_Module.py
# @Software: PyCharm
# @Environment : Python 3.6+

# 基础包
import tensorflow as tf
import math
import jieba
import os
import numpy as np
from gensim.models import keyedvectors

# 编码相关包
import importlib, sys
importlib.reload(sys)

'''
本配置文件用于测试句子相似度判断的CNN模型
'''

# ------------------预加载------------------ #

cur_dir = os.path.dirname(os.path.abspath(__file__)) or os.getcwd()  # 当前项目路径

# jieba分词的词典包括：基础词典+动态添加的项目核心词+动态添加的领域相关词
# 项目核心词表
all_keywords = set(list(open(cur_dir + '/basic_data_file/keywords.txt', 'r').read().strip().split('\n')))
for keyword in all_keywords:
    jieba.add_word(keyword, freq=None, tag=None)
# 领域相关词：推荐来源之一，搜狗细胞词库
# 附：搜狗细胞词库解析代码https://github.com/LuJunru/SMPCUP2017_ELP/blob/master/Sougou_dic_trans.py
field_words = set(list(open(cur_dir + '/basic_data_file/fieldwords.txt', 'r').read().strip().split('\n')))
for field_word in field_words:
    jieba.add_word(field_word, freq=None, tag=None)

# 基于10G中文维基训练的60维词向量
word_vectors = keyedvectors.KeyedVectors.load(cur_dir + '/Word Embedding/Word60.model')  # 加载预先训练好的词向量

# CNN相关参数
MAX_LENTH = 16  # 训练时保留的词的最大数量, 必须为4的倍数
OUT_SIZE1 = int(MAX_LENTH / 4)  # MAX_LENTH / 4 = 10
OUT_SIZE2 = int(MAX_LENTH / 2)  # MAX_LENTH / 2 = 20
CLASS_TYPE = 2
path = cur_dir + '/pre_trained_models/CNN_' + str(MAX_LENTH)
saverpath = path + '/CNN_' + str(MAX_LENTH) + '.ckpt'

# ------------------基础函数------------------ #

def sen_vector_gen(title_words):  # 生成句子的向量
    sen_vector = np.zeros(60, dtype=float)
    length = 0
    for word in title_words:
        try:
            sen_vector += word_vectors[word]
            length += 1
        except:
            try:  # 若当前词没有对应向量，尝试能否进一步切词获得向量(总比直接跳过好)
                for w in jieba.lcut(word):
                    sen_vector += word_vectors[w]
                    length += 1
            except:
                pass
    if length != 0:
        sen_vector = sen_vector / length  # 用词的词向量的平均值来表示句子向量
    return [sen_vector]

def get_vec_cosine(vec1, vec2):  # 计算两个向量的相似度
    tmp = np.vdot(vec1, vec1) * np.vdot(vec2, vec2)
    if tmp == 0.0:
        return 0.0
    return np.vdot(vec1, vec2) / math.sqrt(tmp)

def s1_s2_simipics(s1_list, s2_list, max_lenth):  # 生成feature map
    k = 0
    simi = []
    while k < max_lenth:
        try:
            sen_k = sen_vector_gen(s1_list[k])
            j = 0
            while j < max_lenth:
                try:
                    sen_j = sen_vector_gen(s2_list[j])
                    simi_pic = get_vec_cosine(sen_k, sen_j)
                except:
                    simi_pic = 0.0
                simi.append(simi_pic)
                j += 1
        except:
            simi_pic = 0.0
            simi.append(simi_pic)
        k += 1
    while len(simi) < MAX_LENTH**2:
        simi.append(0.0)
    return simi

# ------------------CNN------------------ #

def weight_variable(shape, var_name):  # 定义初始权重
    # 形状为shape的随机变量
    initial = tf.truncated_normal(shape, stddev=0.1, name=var_name)
    return tf.Variable(initial)

def bias_variable(shape, var_name):  # 定义初始偏置值
    initial = tf.constant(0.1, shape=shape, name=var_name)
    return tf.Variable(initial)

def conv2d(x, W):
    # stride[1,x_movement,y_movement,1]
    # padding=same:不够的地方补0；padding=valid:会缩小
    # 2维卷积层,卷积步长为(x=1,y=1)
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2x2(x):
    # maxpooling
    # ksize表示核函数大小
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

# CNN网络结构
keep_prob = tf.placeholder(tf.float32)
# None表示无论多少行例子都可以
xs = tf.placeholder(tf.float32, [MAX_LENTH ** 2], 'x_input')
# -1表示feature map个数,1表示Channel个数
x_image = tf.reshape(xs, [-1, MAX_LENTH, MAX_LENTH, 1])

# 第一层卷积+pooling
# 核函数大小patch=2*2;通道数，即特征数为1所以in_size=1;新特征的厚度为OUT_SIZE1
W_conv1 = weight_variable([5, 5, 1, OUT_SIZE1], 'w1')
b_conv1 = bias_variable([OUT_SIZE1], 'b1')
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

# 第二层卷积+pooling
# 核函数大小patch=2*2;in_size=4;新特征的厚度为OUT_SIZE2
W_conv2 = weight_variable([5, 5, OUT_SIZE1, OUT_SIZE2], 'w2')
b_conv2 = bias_variable([OUT_SIZE2], 'b2')
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

# 第一层全连接层func1 layer
W_fc1 = weight_variable([OUT_SIZE1 * OUT_SIZE1 * OUT_SIZE2, MAX_LENTH], 'wf1')
b_fc1 = bias_variable([MAX_LENTH], 'bf1')
h_pool2_flat = tf.reshape(h_pool2, [-1, OUT_SIZE1 * OUT_SIZE1 * OUT_SIZE2])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# 第二层全连接层func2 layer
W_fc2 = weight_variable([MAX_LENTH, CLASS_TYPE], 'wf2')
b_fc2 = bias_variable([CLASS_TYPE], 'bf2')
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

# ------------------主函数------------------ #

if __name__ == '__main__':

    while True:

        s1 = input("请输入句子1：")
        s2 = input("请输入句子2：")

        with tf.Session() as sess:
            saver = tf.train.Saver()
            saver.restore(sess, saverpath)
            prediction_result = sess.run(prediction, feed_dict={xs: s1_s2_simipics(jieba.lcut(s1), jieba.lcut(s2), MAX_LENTH), keep_prob: 1.0})

        print(prediction_result.tolist()[0][-1])


from django.urls import path
# We also need to define subordinate URLS in our app's urls.py file which will point to specific functions in our views moduke.
# To do this, we need to import the views.py module.
from . import functionviews
# We need at least four URLS, one for each part of the CRUD cycle.
# We can optionally include two URLS which serve the purpose of reading data, one for listing all musicians in the database and one for displaying the data of one musician in detail.

# The detail, edit, and delete URLs need to pass the primary key of the musician in the URL.
# We can do this using the code <int:pk> inside of a path.

urlpatterns = [
    path('', functionviews.index, name='home'), # /musicians
    path('<int:pk>', functionviews.detail, name='detail'), # /musicians/1
    path('add', functionviews.add, name='add'), # /musicians/add
    path('edit/<int:pk>', functionviews.edit, name='edit'), # /musicians/edit/2
    path('delete/<int:pk>', functionviews.delete, name='delete'), # /musicians/delete/3
]