from math import cos, isclose, radians, sin, sqrt
from typing import Any, Dict, List, Tuple

from pydantic import BaseModel, root_validator

class C(BaseModel):
    """ Complex number as re + i*im """
    re: float # real part
    im: float # imaginary part

    @property
    def mag(self) -> float:
        """ Magnitude """
        return sqrt(self.re**2 + self.im**2)

    @property
    def prob(self) -> float:
        """ Probability of colapsing to this state (= mag**2). """
        return self.mag**2

    def __str__(self) -> str:
        if self.im == 0.0:
            return str(self.re)
        elif self.re == 0.0:
            return f'{self.im}i'
        else:
            return f'({self.re} + {self.im}i)'

    def __add__(self, x: 'C') -> 'C':
        if isinstance(x, C):
            return C(re=self.re+x.re, im=self.im+x.im)
        else:
            raise ValueError('huet addition: {x}')

    def __sub__(self, x: 'C') -> 'C':
        if isinstance(x, C):
            return C(re=self.re-x.re, im=self.im-x.im)
        else:
            raise ValueError('huet addition: {x}')

    def __mul__(self, x: [int, float, 'C']) -> 'C':
        if isinstance(x, C):
            return C(
                re=self.re*x.re - self.im*x.im,
                im=self.re*x.im + self.im*x.re,
            )
        else:
            return C(re=x*self.re, im=x*self.im)

    @property
    def conj(self) -> 'C':
        """ Get conjugate. """
        return C(re=self.re, im=self.im * -1)

class Q(BaseModel):
    """ Qubit as amp0*|0> + amp1*|1>  """
    amp0: C # Amplitude of 0
    amp1: C # Amplitude of 1

    def __str__(self) -> str:
        return f'{self.amp0}*|0> + {self.amp1}*|1>'

    @root_validator()
    def _has_prob_1(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        """ Assert the probability of collapsing to 0 or 1 == 1. """
        prob = values['amp0'].prob + values['amp1'].prob
        if not isclose(prob, 1.0):
            raise ValueError(f'Probability is not 1: {values} {prob}')
        return values

    @property
    def vec(self) -> List[C]:
        """ Qbit to 2-dim vector. """
        return [self.amp0, self.amp1]

# Constants
MS2 = 1/sqrt(2) # Square root of 2 to the minus 1
C0 = C(re=0,im=0) # Complex 0
C1 = C(re=1,im=0) # Complex 1
Q0 = Q(amp0=C1.copy(), amp1=C0.copy()) # |0> aka [1, 0]T
Q1 = Q(amp0=C0.copy(), amp1=C1.copy()) # |1> aka [0, 1]T

def _assert_0_or_1(qubits: List[Q]) -> None:
    for q in qubits:
        if not (q == Q0 or q == Q1):
            raise ValueError(f'Qubit must be |0> or |1>: {q}')

def gen_eye(n: int) -> List[List[float]]:
    """ Make identity matrix. """
    eye = [[C0.copy() for _ in range(n)] for _ in range(n)]
    for i in range(n):
        eye[i][i] = C1.copy()
    return eye

def _round_qubit(q: Q) -> None:
    """ Bring values close to 0 or 1 to 0 or 1. """
    def _round(f: float) -> float:
        if isclose(f, 0, abs_tol=1e-9):
            return 0
        elif isclose(f, 1):
            return 1
        else:
            return f
    q.amp0.re = _round(q.amp0.re)
    q.amp0.im = _round(q.amp0.im)
    q.amp1.re = _round(q.amp1.re)
    q.amp1.im = _round(q.amp1.im)

def _apply_UT(q: Q, ut) -> None:
    """ Apply a 2x2 unitary transformation to qubit q. """
    #print(q)
    amp0 = q.amp0 * ut[0][0] + q.amp1 * ut[0][1]
    amp1 = q.amp0 * ut[1][0] + q.amp1 * ut[1][1]
    q.amp0 = amp0
    q.amp1 = amp1
    _round_qubit(q)
    #print(q)

class SuPos:
    """ Super position """
    def __init__(self, tensor: List[C]) -> None:
        self.reg = tuple(t for t in tensor)

def scale_mat(mat: 'Matrix', s: float) -> 'Matrix':
    """ Scale a matrix by a scalar <s>. """
    for row in mat:
        for j in range(len(row)):
            row[j] *= s
    return mat

def mat_dagger(mat: 'Matrix') -> 'Matrix':
    """ Get hermitian (conjugate) transpose of mat. """
    dagger = []
    for col_ix in range(len(mat[0])):
        new_row = [row[col_ix] for row in mat]
        dagger.append(new_row)
    return dagger

def join_mats(mats: List['Matrix'], axis: str) -> 'Matrix':
    ''' Join matrices horizontally or vertically. '''
    if axis == 'h':
        row_nums = set(len(mat) for mat in mats)
        if len(row_nums) > 1:
            raise ValueError('All matrices must have the same numnber of rows.')

        num_rows = list(row_nums)[0]
        joined = [[] for _ in range(num_rows)]
        for mat in mats:
            for row_ix in range(num_rows):
                joined[row_ix].extend(mat[row_ix])
        return joined
    elif axis == 'v':
        #V join is the same as: dagger --> H join --> dagger.
        daggered = join_mats([mat_dagger(mat) for mat in mats], 'h')
        return mat_dagger(daggered)
    else:
        raise ValueError('Unsupported axis: {axis}')

def tensor_mats(mats: List['Matrix']) -> 'Matrix':
    """ Make a tensor product of matrices. """

def tensor_vecs(vectors: List['Vector']) -> 'Vector':
    """ Make a tensor product of vectors. """
    if len(vectors) < 2:
        return vectors
    elif len(vectors) > 2:
        sub = tensor_vecs(vectors[1:])
        return tensor_vecs([vectors[0], sub])
    else:
        tensor = []
        for a0 in vectors[0]:
            for a1 in vectors[1]:
                tensor.append(a0 * a1)
        return tensor

def circuit(qs: Tuple[Q, Q, Q]) -> Tuple[Q, Q, Q]:
    q0, q1, q2 = qs
    g_HADAMARD(q2)
    g_CNOT(q1, q2)
    g_T_dgr(q2)
    g_CNOT(q0, q2)
    g_T(q2)
    g_CNOT(q1, q2)
    g_T_dgr(q2)
    g_CNOT(q0, q2)
    g_T_dgr(q1)
    g_T(q2)
    g_CNOT(q0, q1)
    g_HADAMARD(q2)
    g_T_dgr(q1)
    g_CNOT(q0, q1)
    g_T(q0)
    g_S(q1)

    return qs

# GATES
def g_NOT(q: Q) -> None:
    """ Reverse the amplitudes. """
    amp0 = q.amp0.copy()
    q.amp0 = q.amp1.copy()
    q.amp1 = amp0

def g_HADAMARD(q: Q) -> None:
    amp0 = (q.amp0 + q.amp1) * MS2
    amp1 = (q.amp0 - q.amp1) * MS2
    q.amp0 = amp0
    q.amp1 = amp1

def g_CNOT(control: Q, target: Q) -> None:
    """ Controlled NOT """
    #_assert_0_or_1([control, target])
    if control == Q1:
        g_NOT(target)

def g_CCNOT(cc: Q, c: Q, t: Q) -> None:
    """ Controlled CNOT """
    #_assert_0_or_1([cc, c, t])
    if cc == Q1:
        g_CNOT(c, t)

def g_SWAP(a: Q, b: Q) -> None:
    _assert_0_or_1([a, b])
    bak = a.copy()
    a.amp0 = b.amp0
    a.amp1 = b.amp1
    b.amp0 = bak.amp0
    b.amp1 = bak.amp1

def g_CSWAP(c: Q, a: Q, b: Q) -> None:
    _assert_0_or_1([c, a, b])
    if c == Q1:
        g_SWAP(a, b)

def g_ROT(q: Q, phi: float) -> None:
    """ Rotate by phi degrees counter-clockwise. """
    rad_phi = radians(phi)
    ut = [
        [cos(rad_phi), -sin(rad_phi)],
        [sin(rad_phi), cos(rad_phi)],
    ]
    _apply_UT(q, ut)

def g_S(q: Q) -> None:
    """ Multiply amp1 by i """
    ut = [
        [1, 0],
        [0, C(re=0, im=1)],
    ]
    _apply_UT(q, ut)

def g_T(q: Q) -> None:
    ut = [
        [1, 0],
        [0, C(re=MS2, im=MS2)],
    ]
    _apply_UT(q, ut)

def g_T_dgr(q: Q) -> None:
    """ T dagger gate """
    ut = [
        [1, 0],
        [0, C(re=MS2, im=-MS2)],
    ]
    _apply_UT(q, ut)

def g_Z(q: Q) -> None:
    """ Multiply amp1 by -1 """
    ut = [
        [1, 0],
        [0, -1],
    ]
    _apply_UT(q, ut)


import math as math
import random as rand
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

def f(x1, x2, x3, x4, x5):
        return math.pow(x1, 7/11.0) + math.pow(x2, 8/11.0) + math.pow(x3, 9/11.0) + math.pow(x4, 10/11.0) + math.sin(x5)

samples = 1000000
results = []
for i in range(samples):
        a = rand.random()
        b = rand.random()
        c = rand.random()

        d = rand.random()
        e_range = math.sqrt(1-d*d)

        e = rand.uniform(0,e_range)

        dice = rand.random()

        if dice < 0.5:
                y = f(a, b, c, d, e)
        else:
                y = f(a, b, c, e, d)
        results.append(y)

area_approx = 0
for number in results:
        area_approx += number

print(area_approx/samples*3.14/4)

sns.distplot(results, hist=False, kde=True,
             kde_kws={'linewidth': 3})
plt.show()


import re
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from ef_crawler.items import EfCrawlerItem

class EvfeSpider(CrawlSpider):
    name = 'evfe'
    allowed_domains = ["gep.or.kr"]
    start_urls = ['http://www.gep.or.kr/domestic-exhibition/exhibitions?pageIndex=1']

    rules = [
            Rule(LinkExtractor(allow=r'/exhibitions\?pageIndex=[1-25]'), callback='parse_item', follow = True)
    ]

    def parse_item(self, response):
        name = response.xpath('//*[@id="print_container"]/form[1]/div[5]/table/tbody/tr/td[2]/a/text()').extract()
        location = response.xpath('//*[@id="print_container"]/form[1]/div[5]/table/tbody/tr/td[4]/text()').extract()
        date = response.xpath('//*[@id="print_container"]/form[1]/div[5]/table/tbody/tr/td[3]/p/text()').extract()

        for item in zip(name, date, location):
            temp = item[2].strip()
            start_day, end_day = temp.split(' ~ ')

            x = start_day.split('-')
            if(int(x[0]) < 2019):
               continue
            scraped_info = {
                'name' : item[0].strip(),
                'location' : item[1].strip(),
                'start_day' : start_day,
                'end_day' : end_day,
            }
            yield scraped_info


import requests
import asyncio
from concurrent.futures import ThreadPoolExecutor
import random
import urllib3
import pdb
import sys
import os

user_agents = [
	'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.3', # Chrome, Windows
	'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36', # Chrome, macOS
	'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36', # Chrome, Linux
	'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/73.0', # Firefox, Windows
	'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/73.0', # Firefox, macOS
	'Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/73.0', # Firefox, Linux
	'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36 Edg/80.0.361.50' # Edge, Windows
	'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15' # Safari, macOS
]

url_list = []
urllib3.disable_warnings()
timeout = 3

async def process_urls():

	with ThreadPoolExecutor(max_workers=10) as executor:
		with requests.Session() as session:

			loop = asyncio.get_event_loop()

			tasks = [
				loop.run_in_executor(
					executor,
					fetch,
					*(session, url) # Allows us to pass in multiple arguments to `fetch`
				)
				for url in url_list
			]

			for response in await asyncio.gather(*tasks):
				pass

def fetch(session, url):

	try:

		response = session.get(url, timeout=timeout, headers={'User-agent' : f'{random.choice(user_agents)}'}, verify=False)

		if response.status_code == 200:

			if response.text != 'null':

				with open(f"{FOLDER_NAME}/{url.split('//')[1].split('.')[0]}", "w", encoding='utf8') as file:
					file.write(response.text)
					print(url)
			else:
				print(f"{url}: 200 OK, NULL response.")

	except Exception as e:
		print(f"Exception! {e}")

def build_list():

	for line in open(sys.argv[1], "r").readlines():
		url_list.append(f"https://{line.rstrip()}.firebaseio.com/.json")

FOLDER_NAME = "firebase_dump"

if len(sys.argv) < 2:
	print(f"Error: Specify a wordlist. \nUsage: \t {sys.argv[0]} <wordlist>")
	sys.exit(0)

if not os.path.isdir(FOLDER_NAME):
	try:
		os.makedirs(FOLDER_NAME)
	except Exception:
		print(f"Error creating folder '{FOLDER_NAME}'.")
		sys.exit(0)

build_list()

# async loop process_urls()
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(process_urls())
loop.run_until_complete(future)


from random import random

import cv2

from config import USE_OPTIMAL_AI

class Paddle:
    def __init__(self, left, top, right, bottom):
        self.left = left
        self.right = right
        self.top = top
        self.bottom = bottom

        self._ai_direction = 0

    def collides_with_ball(self, ball):
        x_collides = (ball.x + 1 == self.left) or (ball.x == self.right)
        y_collides = (ball.y >= self.top) and (ball.y < self.bottom)
        return x_collides and y_collides

    def make_ai_move(self, board, ball):
        follow_ball = ((self.left < ball.x / 2) and (ball.v_x < 0)) \
                      or ((self.left > ball.x / 2) and (ball.v_x > 0))

        if not USE_OPTIMAL_AI and random() < 0.25:
            follow_ball = False

        if follow_ball:
            self.make_move_towards(board, ball.y)
        else:
            if USE_OPTIMAL_AI:
                self.make_move_towards(board, board.height / 2)
            else:
                direction_change = 0

                if random() < 0.5:
                    if self._ai_direction == 0:
                        direction_change = 1 if random() < 0.5 else -1
                    else:
                        direction_change = -self._ai_direction

                self._ai_direction += direction_change

                self.make_move(board, self._ai_direction)

    def make_move_towards(self, board, target_y):
        y_middle = (self.top + self.bottom) / 2

        if target_y > y_middle:
            velocity = 1
        elif target_y < y_middle:
            velocity = -1
        else:
            velocity = 0

        self.make_move(board, velocity)

    def make_move(self, board, y_diff):
        if self.top + y_diff < 0:
            return

        if self.bottom + y_diff > board.height:
            return

        self.top += y_diff
        self.bottom += y_diff

    def draw(self, frame, ratio, x_shift, y_shift):
        top_left = (int(self.left * ratio + x_shift), int(self.top * ratio + y_shift))
        bottom_right = (int(self.right * ratio + x_shift), int(self.bottom * ratio + y_shift))
        cv2.rectangle(frame, top_left, bottom_right, (255, 255, 255), -1)


from shall.ShallEntity import ShallEntity, P, R
from injector import inject
from src.shall.CheckReturnConstraints import CheckReturnConstraints
from src.shall.CheckReturnValue import CheckReturnValue
from src.shall.CheckSideEffects import CheckSideEffects

class Check():
    @inject
    def __init__(self,
                 checkReturnValue:CheckReturnValue[P,R],
                 checkReturnConstraints: CheckReturnConstraints[P,R],
                 checkSideEffects: CheckSideEffects[P,R]
                 ) -> None:
        self.checkReturnValue = checkReturnValue
        self.checkReturnConstraints = checkReturnConstraints
        self.checkSideEffects = checkSideEffects

    def check(self) -> None:
        paramlist = self.parameters[0]
        paramkwargs = self.parameters[1]
        print(self.explanation)
        callResult = self.callable(*paramlist, **paramkwargs)
        self.checkReturnValue.checkReturnValue(callResult)
        self.checkReturnConstraints.checkReturnConstraints( paramlist, paramkwargs)
        self.checkSideEffects.checkSideEffects(paramlist,paramkwargs)


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

try:
    import requests
except ImportError:
    requests = None

from intelmq.lib.bot import Bot

class RestAPIOutputBot(Bot):

    def init(self):
        if requests is None:
            raise ValueError('Could not import requests. Please install it.')

        self.session = requests.Session()
        self.set_request_parameters()
        self.session.proxies.update(self.proxy)
        self.session.headers.update(self.http_header)
        self.session.verify = self.http_verify_cert
        self.session.cert = self.ssl_client_cert

        if self.parameters.auth_token_name and self.parameters.auth_token:
            if self.parameters.auth_type == 'http_header':
                self.session.headers.update(
                    {self.parameters.auth_token_name: self.parameters.auth_token})
            elif self.parameters.auth_type == 'http_basic_auth':
                self.session.auth = self.parameters.auth_token_name, self.parameters.auth_token
        self.session.headers.update({"content-type":
                                     "application/json; charset=utf-8"})
        self.session.keep_alive = False

    def process(self):
        event = self.receive_message()
        if self.parameters.use_json:
            kwargs = {'json': event.to_dict(hierarchical=self.parameters.hierarchical_output)}
        else:
            kwargs = {'data': event.to_dict(hierarchical=self.parameters.hierarchical_output)}

        r = self.session.post(self.parameters.host,
                              timeout=self.http_timeout_sec,
                              **kwargs)
        if not r.ok:
            self.logger.debug("Error during message sending with response body: %r.", r.text)
        r.raise_for_status()
        self.logger.debug('Sent message.')
        self.acknowledge_message()

BOT = RestAPIOutputBot


from typing import Dict

MISTRALAI_MODELS: Dict[str, int] = {
    "mistral-tiny": 32000,
    "mistral-small": 32000,
    "mistral-medium": 32000,
}

def mistralai_modelname_to_contextsize(modelname: str) -> int:
    if modelname not in MISTRALAI_MODELS:
        raise ValueError(
            f"Unknown model: {modelname}. Please provide a valid MistralAI model name."
            "Known models are: " + ", ".join(MISTRALAI_MODELS.keys())
        )

    return MISTRALAI_MODELS[modelname]


import cv2
import numpy as np

#sorting by area

# def get_contour_areas(contours):
#     all_areas = []
#     for cnt in contours:
#         area = cv2.contourArea(cnt)
#         all_areas.append(area)
#     return all_areas

# image = cv2.imread('./../images/shapes.png')
# original_image = image.copy()

# gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

# edged = cv2.Canny(gray,30,200)
# _, contours, _ =   cv2.findContours(edged.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

# print("Contour Areas before sorting")
# print(get_contour_areas(contours))

# sorted_contours = sorted(contours, key=cv2.contourArea, reverse = True)

# print("Contour Areas after sorting")
# print(get_contour_areas(sorted_contours))

# for c in sorted_contours:
#     cv2.drawContours(original_image,[c],-1,(255,0,0),3)
#     cv2.waitKey(0)
#     cv2.imshow('Contours by area',original_image)

# cv2.waitKey(0)
# cv2.destroyAllWindows()
#sorting by position

def x_cord_contour(contours):
    if cv2.contourArea(contours)>10:
        M = cv2.moments(contours)
        return (int(M['m10']/M['m00']))

def label_contour_center(image,c):
    M = cv2.moments(c)
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])
    cv2.circle(image,(cx,cy),10,(0,0,255),-1)
    return image

image = cv2.imread('./../images/shapes.png')
original_image = image.copy()

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

edged = cv2.Canny(gray,30,200)
_, contours, _ =   cv2.findContours(edged.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

for(i,c) in enumerate(contours):
    orig = label_contour_center(image,c)

cv2.imshow("Contour Centers",image)
cv2.waitKey(0)

contours_left_to_right = sorted(contours,key=x_cord_contour,reverse=False)

for (i,c) in enumerate(contours_left_to_right):
    cv2.drawContours(original_image,[c],-1,(0,0,255),3)
    M = cv2.moments(c)
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])
    cv2.putText(original_image,str(i+1),(cx,cy),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)
    cv2.imshow('Left to Right Contour',original_image)
    cv2.waitKey(0)
    (x,y,w,h)=cv2.boundingRect(c)

    cropped_contour = original_image[y:y+h,x:x+w]
    image_name = "output_shape_number_"+str(i+1)+ ".jpg"
    print(image_name)
    cv2.imwrite(image_name,cropped_contour)

cv2.waitKey(0)
cv2.destroyAllWindows()


import os.path
import requests
from tqdm import tqdm
from bs4 import BeautifulSoup
from pyld import jsonld
from urllib.parse import unquote

from io import StringIO
import sys

import xml.etree.ElementTree as ET
from music21 import converter, environment

W3C_HAS_SRC = "http://www.w3.org/ns/oa#hasSource"
NANOPUB_URL = "http://digitalduchemin.org:8080/nanopub-server"
LAST_PAGE = 11

# To access emaMXL module from inside tst folder
sys.path.append(os.path.abspath(os.path.join('..', 'emaMXL')))
from emaMXL.emaexp import EmaExp
from emaMXL import emaexp, emaexpfull, slicer

# For suppressing music21 warnings, so the tqdm progress bar is not reprinted upon warnings
class Capturing(list):
    def __enter__(self):
        self._stderr = sys.stderr
        sys.stderr = self._stringio = StringIO()
        return self

    def __exit__(self, *args):
        self.extend(self._stringio.getvalue().splitlines())
        del self._stringio    # free up some memory
        sys.stderr = self._stderr

#
# Scraping functions
#
def scrape_page_nanopubs(page_num, d={}, fails={}):
    """
    Scrapes all nanopubs from the page.
    Saves score xml + selection xml to disk.
    Returns dict[nanopub_num] = (score_name, ema_expression) for reference.
    """
    jsonlds = get_jsonlds(page_num)
    for i in tqdm(range(len(jsonlds))):
        nanopub_num = 1000*(page_num - 1) + i
        try:
            with Capturing() as output:
                score_name, expr_str = scrape_nanopub(nanopub_num, jsonlds[i])
                d[nanopub_num] = (score_name, expr_str)
        except Exception as ex:
            fails[nanopub_num] = ex

    return d, fails

def scrape_nanopub(nanopub_num, jsonld_filename):
    ema_url = ema_url_from_jsonld(jsonld_filename)
    mei_url = unquote(ema_url.split("/")[-4])
    expr_str = "/".join(ema_url.split("/")[-3:])
    score_name = mei_url.split("/")[-1].split(".")[0]
    #
    # Will warn "mei.base: WARNING: Importing <slur> without @startid and @endid is not yet supported."
    #
    # Downloads the MEI score, converts to XML, saves as a file. Use etree to load from file.
    score_path = f"data/scores/{score_name}.xml"
    if not os.path.exists(score_path):
        score = converter.parseURL(mei_url, format='mei')
        score.write("musicxml", fp=score_path)

    # Downloads the MEI selection, converts to XML, saves as a file, and stores etree in the dict.
    selection_path = f"data/selections/nanopub_{nanopub_num}.xml"
    if not os.path.exists(selection_path):
        selection_score = converter.parseURL(ema_url, format='mei')
        selection_score.write("musicxml", fp=selection_path)

    return score_name, expr_str

#
# Evaluation functions
#
def evaluate_ema2_page(page_num):
    jsonlds = get_jsonlds(page_num)
    for i in range(len(jsonlds)):
        nanopub_num = 1000 * (page_num - 1) + i
        ema_url = ema_url_from_jsonld(jsonlds[i])
        mei_url = unquote(ema_url.split("/")[-4])
        expr_str = "/".join(ema_url.split("/")[-3:])
        score_name = mei_url.split("/")[-1].split(".")[0]

        try:
            evaluate_ema2(score_name, expr_str, f"nanopub_{nanopub_num}")
        except Exception as ex:
            print(f"Exception for nanopub_{nanopub_num}: {ex}")

def evaluate_ema2(score_name, expr_str, truth_filename, print_fail_elem=False):
    # TODO: Maybe try downloading if we can't find it
    score_path = f"data/scores/{score_name}.xml"
    selection_path = f"data/selections/{truth_filename}.xml"
    if not os.path.exists(score_path):
        print(f"Skipping {truth_filename}; score not found.")
        return
    if not os.path.exists(selection_path):
        print(f"Skipping {truth_filename}; selection not found.")
        return

    print(f"Evaluating {truth_filename}")
    ema2_tree = slicer.slice_score_path(score_path, expr_str)
    omas_tree = ET.parse(selection_path)
    diff_test(ema2_tree.getroot(), omas_tree.getroot(), print_fail_elem)
    # For debugging
    ema2_tree.write("data/selection_temp.xml")
    return ema2_tree, omas_tree

# Suggested usage: Open Python console, run this function,
# then compare the content of selection_temp.xml and selections/nanopub_X.xml.
def evaluate_ema2_by_num(nanopub_num, print_fail_elem=False):
    """ Evaluates a single nanopub. """
    page_num = 1 + nanopub_num // 1000
    jsonlds = get_jsonlds(page_num)
    score_name, expr_str = scrape_nanopub(nanopub_num, jsonlds[nanopub_num % 1000])
    return evaluate_ema2(score_name, expr_str, f"nanopub_{nanopub_num}", print_fail_elem)
# List of failing nanopubs (but are okay to ignore)
# Selection on digital du chemin is incorrect (usually minor errors):
# 22, 31, 35, 63, 67, 70, 74, 106
# bad music21 conversion / malformed score:
# 40, 85

def diff_test(elem1: ET.Element, elem2: ET.Element, print_fail_elem):
    """ A simple recursive function that checks if the structure and tags of these two trees are generally the same. """
    if len(elem1) == len(elem2) and elem1.tag == elem2.tag:
        # print(f"Matched {root1.tag}: {len(root1)} children.")
        # TODO: Is it wise to sort? The nanopubs might have elements out of order
        #  (or maybe music21 conversion jumbled them up)
        # Leaving staves unsorted (by id) seems okay
        elem1 = sorted(list(elem1), key=lambda x: (x.tag, x.get('id', None) if x.tag != 'part' else None))
        elem2 = sorted(list(elem2), key=lambda x: (x.tag, x.get('id', None) if x.tag != 'part' else None))
        for i in range(len(elem1)):
            diff_test(elem1[i], elem2[i], print_fail_elem)
    else:
        print(f"Mismatch at {elem1.tag}, {elem1.attrib}: {len(elem1)} children vs. {elem2.tag}, {elem2.attrib}: {len(elem2)} children.")
        if print_fail_elem:
            print_elems_recursive(elem1)
            print_elems_recursive(elem2)

#
# Utility functions for tst and scraper
#
def get_jsonlds(page_num):
    """ Fetches a list of .jsonld file URLs on the specified page. """
    r = requests.get(f"{NANOPUB_URL}/nanopubs.html?page={page_num}")
    soup = BeautifulSoup(r.text, 'html.parser')
    results = soup.findAll("a", text="jsonld", attrs={"type": "application/ld+json"})
    file_names = [x.attrs["href"] for x in results]
    return file_names

def ema_url_from_jsonld(jsonld_filename):
    """ Takes a .jsonld filename and extracts the full EMA request URL. """
    nanopub = jsonld.load_document(f"{NANOPUB_URL}/{jsonld_filename}")
    for graph in nanopub["document"]:
        for item in graph["@graph"]:
            if W3C_HAS_SRC in item:
                return item[W3C_HAS_SRC][0]['@id']
    return None

def ema_exps_from_page(page_num):
    """ Constructs an EmaExp for every nanopub on the page. """
    file_names = get_jsonlds(page_num)
    ema_exps = []
    for file_name in file_names:
        ema_url = ema_url_from_jsonld(file_name)
        ema_exps.append(EmaExp(*ema_url.split("/")[:-3]))
    return ema_exps

def print_elems_recursive(elem, i=0):
    print(" "*i, elem)
    for child in elem:
        print_elems_recursive(child, i+4)

environment.set('autoDownload', 'allow')

if __name__ == '__main__' and len(sys.argv) == 2 and sys.argv[1] == "scrape":
    print(os.getcwd())
    if os.path.basename(os.getcwd()) == 'emaMXL':
        os.chdir('tst')

    if os.path.basename(os.getcwd()) != 'tst':
        print("\"scraper.py scrape\" should be run from within the emaMXL root folder or emaMXL/tst.")
        exit()

    if not os.path.exists("data"):
        os.mkdir('data')
        os.mkdir('data/selections')
        os.mkdir('data/scores')
    for p in range(1, LAST_PAGE+1):
        scrape_page_nanopubs(p)


import random
import pygame
from pygame.locals import *
from Hangman.Person import Person
from Hangman.Button import Button

black = (0, 0, 0)
background_color = (161, 241, 255)
LETTERCLICKED = USEREVENT + 1
PLAY = USEREVENT + 2

class GameInstance:
    hidden_word = ""
    displayed_word = ""
    category = ""
    buttons = []
    words = {}
    playing = False
    incorrect_guesses = 0
    correct_guesses = 0

    def __init__(self, w, h):
        self.screen_width = w
        self.screen_height = h
        self.screen = pygame.display.set_mode((w, h))
        self.person = Person()
        self.font = 'LexendDeca-Regular.ttf'
        self.form_word_dict()

    def form_word_dict(self):
        file = open('words.txt', 'r')

        for line in file:
            if line:
                temp_arr = line.split(", ")
                self.words[temp_arr[0]] = temp_arr[1]

        file.close()

    def generate_word(self):
        self.hidden_word = random.choice(list(self.words.keys()))
        self.category = self.words[self.hidden_word]
        self.displayed_word = '_ ' * len(self.hidden_word)

    def generate_keyboard(self):
        buttons = []
        w = 20
        h = 20
        x_margin = 50
        y_margin = 30
        for i in range(97, 110):
            x = (i - 97) * (2 * w) + x_margin
            y = y_margin
            button = Button(LETTERCLICKED, chr(i), w, h, x, y)
            buttons.append(button)
        for j in range(110, 123):
            x = (j - 110) * (2 * w) + x_margin
            y = 2 * h + y_margin
            button = Button(LETTERCLICKED, chr(j), w, h, x, y)
            buttons.append(button)
        self.buttons = buttons

    def is_button_clicked(self):
        for but in self.buttons:
            if but.clicked():
                self.buttons.remove(but)

    def is_won(self):
        if self.displayed_word.replace(" ", "") == self.hidden_word and self.correct_guesses != 0:
            self.playing = False
            return True
        return False

    def is_lost(self):
        if self.incorrect_guesses == 6:
            self.playing = False
            return True
        return False

    def play(self):
        self.reset()
        self.playing = True

    def is_playing(self):
        return self.playing

    def update(self, guess):

            found = False
            for x in range(0, len(self.hidden_word)):
                if self.hidden_word[x] == guess.action:
                    l_displayed_word = list(self.displayed_word)
                    l_displayed_word[x*2] = guess.action
                    new = ''
                    for i in l_displayed_word:
                        new += i
                    self.displayed_word = new
                    found = True
            if found:
                self.correct_guesses += 1
            else:
                self.incorrect_guesses += 1
                self.person.hang(self.incorrect_guesses)

    def reset(self):
        self.buttons = []
        self.generate_keyboard()
        self.hidden_word = ""
        self.displayed_word = ""
        self.category = ""
        self.generate_word()
        self.incorrect_guesses = 0
        self.correct_guesses = 0
        pygame.event.clear()

    def draw_basics(self):

        self.screen.fill(background_color)
        self.screen.blit(self.person.image, self.person.rect)
        for but in self.buttons:
            self.screen.blit(but.surf, but.rect)
            self.screen.blit(but.surf2, but.rect2)

    def play_screen(self):
        self.draw_basics()

        word_font = pygame.font.Font(self.font, 20)
        guess_word_text = word_font.render(self.displayed_word, True, black)
        word_rect = guess_word_text.get_rect()
        word_rect.center = (self.person.rect.right + 50, self.person.rect.center[1])
        category_text = word_font.render(self.category, True, black)
        category_rect = category_text.get_rect()
        category_rect.center = (word_rect.center[0], word_rect.top - 20)

        self.screen.blit(category_text, category_rect)
        self.screen.blit(guess_word_text, word_rect)

    def option_screen(self, state):
        self.buttons = []
        width = 60
        height = 40
        play_but = Button(PLAY, 'Play', width, height, self.screen_width/4, self.screen_height/5 * 4)
        quit_but = Button(QUIT, 'Exit', width, height, self.screen_width/4 * 3, self.screen_height/5 * 4)
        self.buttons.append(play_but)
        self.buttons.append(quit_but)
        self.draw_basics()
        if state == 'won':
            s = 'You won this round!'
        elif state == 'lost':
            s = 'Uh Oh... He died.'
        elif state == 'start':
            s = 'Hang that Man!'
        else:
            s = 'Something went wrong'
        message1_font = pygame.font.Font(self.font, 40)
        message1 = message1_font.render(s, True, black)
        message1_rect = message1.get_rect()
        message1_rect.center = (self.screen_width/2, height + 20)
        self.screen.blit(message1, message1_rect)
        if state != 'start':
            message2_font = pygame.font.Font(self.font, 20)
            message2 = message2_font.render('The answer was ' + self.hidden_word, True, black)
            message2_rect = message2.get_rect()
            message2_rect.center = (self.person.rect.right + 30, self.person.rect.center[1])
            self.screen.blit(message2, message2_rect)


from datetime import datetime

from django.shortcuts import get_object_or_404
from django.utils.datetime_safe import datetime as d_datetime

from rest_framework import viewsets, permissions, response, status, filters, pagination
from rest_framework_simplejwt.views import TokenObtainPairView

from .models import Subject, Topic, SubTopic, Department, Bookmark, WatchHistory
from .serializer import SerializedSubjects, SerializedSubTopic, WatchHistorySerializer

class DashboardView(viewsets.ViewSet):
	permission_classes = [permissions.IsAuthenticated]

	def list(self, request):
		bookmark = Bookmark.objects.filter(user=request.user)

		my_subjects = 0
		completed_subjects = 0
		bookmarks = bookmark[0].topics.count() if bookmark.count() else 0
		questions_completed = 0
		activities = request.user.accountactivity_set.values()[:5]
		watch_list = request.user.watchhistory_set.values('id', 'subtopic__name', 'subtopic__slug')[:5]

		data = dict(
			my_subjects=my_subjects,
			completed_subjects=completed_subjects,
			bookmarks=bookmarks,
			questions_completed=questions_completed,
			watch_list=watch_list,
			activities=activities
		)

		return response.Response(data)

class SubjectsView(viewsets.ModelViewSet):
	permission_classes = [permissions.AllowAny]
	serializer_class = SerializedSubjects
	queryset = Subject.objects.all()
	filter_backends = [filters.SearchFilter]
	search_fields = ['department__slug']
	pagination_class = pagination.LimitOffsetPagination

	def retrieve(self, request, pk):

		queryset = get_object_or_404(Subject, slug=pk)
		serializer = SerializedSubjects(queryset).data

		"""
		Get three related subjects
		"""
		related_subjects_queryset = Subject.objects.filter(department=queryset.department).exclude(id=queryset.id)[:3]
		related_subject_serializer = SerializedSubjects(related_subjects_queryset, many=True)
		serializer['related_subjects'] = related_subject_serializer.data

		user_bookmarks = []
		user_watch_history = []

		if request.user.is_authenticated:
			bookmark_query = Bookmark.objects.filter(user=request.user)
			watchlist_query = request.user.watchhistory_set.all().only('id')

			if bookmark_query:
				user_bookmarks = [x[0] for x in bookmark_query[0].topics.values_list('id')]
			if watchlist_query:
				user_watch_history = [x.subtopic.id for x in watchlist_query]

		serializer['topics'] = tuple(
			{
				**topic,
				'sub_topics': tuple(
					dict(
						id=subtopic.id,
						name=subtopic.name,
						slug=subtopic.slug,
						ordering=subtopic.ordering,
						lock=subtopic.lock,
						bookmarked=subtopic.id in user_bookmarks,
						watched=subtopic.id in user_watch_history,
					) for subtopic in
					SubTopic.objects.filter(topic__name=topic["name"]).order_by('ordering')
				)
			} for topic in
			queryset.topic_set.values("id", "name", "ordering").order_by('ordering')
		)

		return response.Response(serializer, status=status.HTTP_200_OK)

	def update(self, request):
		return response.Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

	def destroy(self, request, *args, **kwargs):
		return response.Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)

class DepartmentView(viewsets.ViewSet):
	permission_classes = [permissions.AllowAny]

	def list(self, request):
		queryset = Department.objects.values("id", "name", "slug")
		return response.Response(queryset, status=status.HTTP_200_OK)

class SubTopicView(viewsets.ViewSet):
	permission_classes = [permissions.IsAuthenticated]

	def retrieve(self, request, pk):
		data = get_object_or_404(SubTopic, slug=pk)

		if request.user.subscriptionplan.subscription_status in ['free-trial', 'paid']:
			if datetime.now().timetuple() <= request.user.subscriptionplan.expiry_date.timetuple():
				WatchHistory.objects.get_or_create(user=request.user, subtopic=data)
				serializer = SerializedSubTopic(data)
				return response.Response(serializer.data)
			return response.Response({'msg': "Current Subscription has Expired"}, status=status.HTTP_401_UNAUTHORIZED)

		return response.Response({'msg': "Subscribe to watch video"}, status=status.HTTP_401_UNAUTHORIZED)

class BookmarkView(viewsets.ViewSet):
	permission_classes = [permissions.IsAuthenticated]

	def list(self, request):
		data = get_object_or_404(Bookmark, user=request.user)
		data = data.topics.all()
		data = [
			dict(
				id=subtopic.pk, subject=subtopic.topic.subject.name, subject_slug=subtopic.topic.subject.slug,
				subtopic=subtopic.name, completed='40%', tumbnail=subtopic.topic_thumbnail.url,
				slug=subtopic.slug,
			)
			for subtopic in data
		]

		return response.Response(data)

	def create(self, request):
		subtopic = get_object_or_404(SubTopic, pk=request.data['pk'])
		Bookmark.add_bookmark(request.user, subtopic)

		return response.Response(status=status.HTTP_201_CREATED)

	def destroy(self, request, pk):
		subtopic = get_object_or_404(SubTopic, pk=pk)
		Bookmark.remove_bookmark(request.user, subtopic)

		return response.Response(status=status.HTTP_200_OK)

class WatchHistoryView(viewsets.ModelViewSet):
	permission_classes = [permissions.IsAuthenticated]
	queryset = WatchHistory.objects.all()
	serializer_class = WatchHistorySerializer
	pagination_class = pagination.LimitOffsetPagination

	def get_queryset(self):
		queryset = WatchHistory.objects.filter(user=self.request.user)
		return queryset


import re

from django.shortcuts import render
from apps.front.models import Document
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from pure_pagination import PageNotAnInteger, Paginator
from django.http import HttpResponse
from django.db.models import Q, F
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

from apps.utils.pyecharts_restful import JsonResponse
import db_tools.data.show_data as s_data

import json
from rest_framework.views import APIView
from pyecharts.charts import Bar, Line, Pie, WordCloud, Graph
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
from collections import Counter
from apps.utils import handle_memcache

# Create your views here.

def index(request):
    return render(request, 'front/index.html')

def search(request):
    search_cat_id = request.GET.get('searchtype') # 获取前端查询类型参数
    words = request.GET.get('words') # 获取前端查询关键词参数
    page = request.GET.get('page', 1)  # 获取页数

    # 根据查询条件和关键词内容，在数据库查找相关的内容
    if search_cat_id == 'title':
        if words:
            documents = Document.objects.filter(title__contains=words).all()
        else:
            documents = Document.objects.all()
    elif search_cat_id == 'author':
        if words:
            documents = Document.objects.filter(author__contains=words).all()
        else:
            documents = Document.objects.all()
    elif search_cat_id == 'source':
        if words:
            documents = Document.objects.filter(acticle_source__contains=words).all()
        else:
            documents = Document.objects.all()
    elif search_cat_id == 'keywords':
        if words:
            documents = Document.objects.filter(key_words__contains=words).all()
        else:
            documents = Document.objects.all()
    elif search_cat_id == 'summary':
        if words:
            documents = Document.objects.filter(summary__contains=words).all()
        else:
            documents = Document.objects.all()
    else:
        documents = Document.objects.all()

    # 搜索结果可视化核心代码
    author_list = []
    source_list = []
    year_list = []
    orginize_list = []
    key_words = []
    for document in documents:
        author_list += hander_author(document.author)
        source_list.append(document.acticle_source.split(",")[0])
        year_list.append(get_year(document.acticle_source.split(",")[1]))
        orginize_list.append(document.author_location.split(",")[0])
        key_words += handle_words(document.key_words)
    orginize_dict = Counter(orginize_list)
    author_dict = Counter(reversed(author_list))
    source_dict = Counter(source_list)
    year_dict = Counter(reversed(year_list))
    words_dict = Counter(key_words)

    words_list = sorted(words_dict.items(),key=lambda item:item[1])
    print(words_list)

    new_year = sorted(year_dict.items(),key=lambda item: item[0])
    new_year_name = []
    new_year_nums = []
    for item in new_year:
        new_year_name.append(item[0])
        new_year_nums.append(item[1])
    # memcache 存储词云数据
    handle_memcache.set_key("words",words_list)

    # memcached 存储作者信息
    handle_memcache.set_key("author_name",list(author_dict.keys())[:20])
    handle_memcache.set_key("author_nums",list(author_dict.values())[:20])

    # memcached 存储期刊信息
    handle_memcache.set_key("qikan_name",list(source_dict.keys())[:20])
    handle_memcache.set_key("qikan_nums",list(source_dict.values())[:20])

    # memcached 存储年份信息
    handle_memcache.set_key("year_name",new_year_name)
    handle_memcache.set_key("year_nums",new_year_nums)

    # memcached 存储机构信息
    handle_memcache.set_key("org_name",list(orginize_dict.keys()))
    handle_memcache.set_key("org_nums",list(orginize_dict.values()))

    p = Paginator(documents, 10, request=request)
    s_documents = p.page(page)
    # 查询内容返回前端模板，前端可以通过{{ documents }} 的方式获取数据
    context = {
        'documents': s_documents,
    }
    # 返回模板文件与数据
    return render(request, 'front/search.html', context=context)

def get_year(value):
    if re.search("\d+",value):
        return re.search("\d+",value).group()
    return ""

def handle_words(value):
    return value.split(",")

def hander_author(value):
    return [i.strip() for i in value.split(",")]

def document_list(request):
    all_documents = Document.objects.all()
    page = request.GET.get('page', 1)

    p = Paginator(all_documents, 20, request=request)
    documents = p.page(page)
    context = {
        'documents': documents,

    }
    return render(request, 'front/list.html', context=context)

#  可视化图表作者柱状图参数配置
def author_bar() -> Bar:
    x = handle_memcache.get_value("author_name")
    y = handle_memcache.get_value("author_nums")
    c = (
        Bar()
            .add_xaxis(x)
            .add_yaxis("作者", y)
            .set_global_opts(
            title_opts=opts.TitleOpts(title="作者数量", subtitle="相关文章数量"), # 设置标题
            xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)), # 横轴设置字体倾斜45°，可显示全部作者名称
        )
            .dump_options_with_quotes() # 返回Json 格式的数据，前端解析调用
    )
    return c

def orginize_bar() -> Bar:
    o_x = handle_memcache.get_value("org_name")
    o_y = handle_memcache.get_value("org_nums")
    c = (
        Bar()
            .add_xaxis(o_x)
            .add_yaxis("机构", o_y, category_gap="60%")
            .set_series_opts(
            itemstyle_opts={
                "normal": {
                    "color": JsCode(
                        """new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                    offset: 0,
                    color: 'rgba(0, 122, 255, 1)'
                }, {
                    offset: 1,
                    color: 'rgba(0, 77, 167, 1)'
                }], false)"""
                    ),
                    "barBorderRadius": [30, 30, 30, 30],
                    "shadowColor": "rgb(0, 160, 221)",
                }
            }
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title="机构"),
            xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
        )
            .dump_options_with_quotes()
    )
    return c

def year_line():
    x = handle_memcache.get_value("year_name")
    y = handle_memcache.get_value("year_nums")

    line2 = (
        Line()
            .set_global_opts(
            tooltip_opts=opts.TooltipOpts(is_show=False),
            xaxis_opts=opts.AxisOpts(type_="category"),
            yaxis_opts=opts.AxisOpts(
                type_="value",
                axistick_opts=opts.AxisTickOpts(is_show=True),
                splitline_opts=opts.SplitLineOpts(is_show=True),
            ),
        )
            .add_xaxis(xaxis_data=x)
            .add_yaxis(
            series_name="",
            y_axis=y,
            symbol="emptyCircle",
            is_symbol_show=True,
            label_opts=opts.LabelOpts(is_show=False),
        )
            # 设置 boundary_gap 的时候一定要放在最后一个配置项里, 不然会被覆盖
            .dump_options_with_quotes()
    )
    return line2

def xueke_pie():
    data1 = handle_memcache.get_value("qikan_name")
    data2 = handle_memcache.get_value("qikan_nums")
    c = (
        Pie()
            .add(
            "",
            [
                list(z)
                for z in zip(
                data1,
                data2,
            )
            ],
            center=["40%", "50%"],
        )
            .set_global_opts(
            title_opts=opts.TitleOpts(title="期刊占比"),
            legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"),
        )
            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
            .dump_options_with_quotes()
    )
    return c

def qikan_bar() -> Bar:
    x = handle_memcache.get_value("qikan_name")
    y = handle_memcache.get_value("qikan_nums")
    c = (
        Bar()
            .add_xaxis(x)
            .add_yaxis("期刊", y)
            .reversal_axis()
            .set_series_opts(label_opts=opts.LabelOpts(position="right"))
            .set_global_opts(title_opts=opts.TitleOpts(title="期刊数量展示"))
            .dump_options_with_quotes()
    )
    return c

def cat_pie():
    data1 = s_data.cat
    data2 = s_data.cat_nums
    c = (
        Pie()
            .add(
            "",
            [list(z) for z in zip(data1, data2)],
            radius=["40%", "55%"],
            label_opts=opts.LabelOpts(
                position="outside",
                formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c}  {per|{d}%}  ",
                background_color="#eee",
                border_color="#aaa",
                border_width=1,
                border_radius=4,
                rich={
                    "a": {"color": "#999", "lineHeight": 22, "align": "center"},
                    "abg": {
                        "backgroundColor": "#e3e3e3",
                        "width": "100%",
                        "align": "right",
                        "height": 22,
                        "borderRadius": [4, 4, 0, 0],
                    },
                    "hr": {
                        "borderColor": "#aaa",
                        "width": "100%",
                        "borderWidth": 0.5,
                        "height": 0,
                    },
                    "b": {"fontSize": 16, "lineHeight": 33},
                    "per": {
                        "color": "#eee",
                        "backgroundColor": "#334455",
                        "padding": [2, 4],
                        "borderRadius": 2,
                    },
                },
            ),
        )
            .set_global_opts(title_opts=opts.TitleOpts(title="资源类型展示"))
            .dump_options_with_quotes()
    )
    return c

def wordshow():
    words_list = handle_memcache.get_value('words')[::-1][1:50]
    c = (
        WordCloud()
            .add(series_name="热点分析", data_pair=words_list, word_size_range=[6, 66],shape="star")
            .set_global_opts(
            title_opts=opts.TitleOpts(
                title="热点分析", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
            ),
            tooltip_opts=opts.TooltipOpts(is_show=True),
        )
            .dump_options_with_quotes()
    )
    return c

def relation():
    nodes = [
        {"name": "邢蓓蓓", "symbolSize": 10},
        {"name": "林剑", "symbolSize": 20},
        {"name": "武敬平", "symbolSize": 30},
        {"name": "陶锋", "symbolSize": 40},
        {"name": "宋振峰", "symbolSize": 50},
        {"name": "胡伟", "symbolSize": 40},
        {"name": "吴小龙", "symbolSize": 30},
        {"name": "喻小勇", "symbolSize": 20},
    ]
    links = []
    for i in nodes:
        for j in nodes:
            links.append({"source": i.get("name"), "target": j.get("name")})
    c = (
        Graph()
            .add("", nodes, links, repulsion=8000)
            .set_global_opts(title_opts=opts.TitleOpts(title="关系图"))
            .dump_options_with_quotes()
    )
    return c

# 作者柱状图类视图函数，继承DRF的APIView ，返回Json格式的数据
class AuthorChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(author_bar()))

class OrginiseChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(orginize_bar()))

class YearChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(year_line()))

class XuekeChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(xueke_pie()))

class QikanChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(qikan_bar()))

class CatChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(cat_pie()))

class WordChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(wordshow()))

class RelationChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(relation()))

@method_decorator([login_required(login_url='/user/login/'),],name='dispatch') # 类视图的装饰器使用方法，同样需要登录才能执行
class ShowView(APIView):
    def get(self, request, *args, **kwargs):

        # 返回可视化模板文件，使用utf-8编码，可以正常显示中文
        return HttpResponse(content=open("./templates/front/show.html", encoding="utf-8").read())

@login_required(login_url='/user/login/')  # 添加装饰器，此视图函数需要登录之后才能执行
def upper_search(request):
    page = request.GET.get('page',1)
    searchtype1 = request.GET.get('searchtype1') # 获取搜索类型参数1

    upper_words1 = request.GET.get('upper_words1') # 获取前端查询条件第一个关键词
    searchtype_logic = request.GET.get('searchtype_logic') # 获取前端逻辑类型“与”，“或”
    searchtype2 = request.GET.get('searchtype2')  # 获取搜索类型参数2
    upper_words2 = request.GET.get('upper_words2')# 获取前端查询条件第二个关键词
    #
    # print(searchtype1)
    # print(upper_words1)
    # print(searchtype2)
    # print(upper_words2)

    if upper_words1 and upper_words2:
        # 如果前端查询逻辑关系是 “与” ，执行下面的操作
        if searchtype_logic == 'and':

            # 判断关键词的类型，执行相应的数据库查询操作
            if searchtype1 == 'author' and searchtype2 == 'title':
                documents = Document.objects.filter(author__icontains=upper_words1, title__icontains=upper_words2).all()
            elif searchtype1 == 'author' and searchtype2 == 'keywords':
                documents = Document.objects.filter(author__icontains=upper_words1,
                                                    key_words__icontains=upper_words2).all()
            elif searchtype1 == 'author' and searchtype2 == 'summary':
                documents = Document.objects.filter(author__icontains=upper_words1,
                                                    summary__icontains=upper_words2).all()
            elif searchtype1 == 'title' and searchtype2 == 'keywords':
                documents = Document.objects.filter(title__icontains=upper_words1,
                                                    key_words__icontains=upper_words2).all()
            elif searchtype1 == 'keywords' and searchtype2 == 'summary':
                documents = Document.objects.filter(key_words__icontains=upper_words1,
                                                    summary__icontains=upper_words2).all()
            elif searchtype1 == 'title' and searchtype2 == 'summary':
                documents = Document.objects.filter(key_words__icontains=upper_words1,
                                                    summary__icontains=upper_words2).all()
            elif searchtype1 == 'author' and searchtype2 == 'author':
                documents = Document.objects.filter(author__icontains=[upper_words1,upper_words2]).all()
            else:
                documents = Document.objects.all()

        # 如果前端查询逻辑关系是 “或” ，执行下面的操作
        else:
            print('or')
            if searchtype1 == 'author' and searchtype2 == 'title':
                documents = Document.objects.filter(
                    Q(author__icontains=upper_words1) | Q(title__icontains=upper_words2)).all()
            elif searchtype1 == 'author' and searchtype2 == 'keywords':
                documents = Document.objects.filter(
                    Q(author__icontains=upper_words1) | Q(key_words__icontains=upper_words2)).all()
            elif searchtype1 == 'author' and searchtype2 == 'summary':
                documents = Document.objects.filter(
                    Q(author__icontains=upper_words1) | Q(summary__icontains=upper_words2)).all()
            elif searchtype1 == 'title' and searchtype2 == 'keywords':
                documents = Document.objects.filter(
                    Q(title__icontains=upper_words1) | Q(key_words__icontains=upper_words2)).all()
            elif searchtype1 == 'keywords' and searchtype2 == 'summary':
                documents = Document.objects.filter(
                    Q(key_words__icontains=upper_words1) | Q(summary__icontains=upper_words2)).all()
            elif searchtype1 == 'keywords' and searchtype2 == 'author':
                documents = Document.objects.filter(
                    Q(key_words__icontains=upper_words1) | Q(author__icontains=upper_words2)).all()
            elif searchtype1 == 'title' and searchtype2 == 'summary':
                documents = Document.objects.filter(
                    Q(title__icontains=upper_words1) | Q(summary__icontains=upper_words2)).all()
            elif searchtype1 == 'title' and searchtype2 == 'author':
                documents = Document.objects.filter(
                    Q(title__icontains=upper_words1) | Q(author__icontains=upper_words2)).all()
            elif searchtype1 == 'author' and searchtype2 == 'author':
                print("两个作者")
                documents = Document.objects.filter(
                    Q(author__icontains=upper_words1) | Q(author__icontains=upper_words2)).all()
            else:
                documents = Document.objects.all()
        # 搜索结果可视化核心代码
        # 搜索结果可视化核心代码
        author_list = []
        source_list = []
        year_list = []
        orginize_list = []
        key_words = []
        for document in documents:
            author_list += hander_author(document.author)
            source_list.append(document.acticle_source.split(",")[0])
            year_list.append(get_year(document.acticle_source.split(",")[1]))
            orginize_list.append(document.author_location.split(",")[0])
            key_words += handle_words(document.key_words)
        orginize_dict = Counter(orginize_list)
        author_dict = Counter(reversed(author_list))
        source_dict = Counter(source_list)
        year_dict = Counter(reversed(year_list))
        words_dict = Counter(key_words)

        words_list = sorted(words_dict.items(), key=lambda item: item[1])

        new_year = sorted(year_dict.items(), key=lambda item: item[0])
        new_year_name = []
        new_year_nums = []
        for item in new_year:
            new_year_name.append(item[0])
            new_year_nums.append(item[1])
        # memcache 存储词云数据
        handle_memcache.set_key("words", words_list)

        # memcached 存储作者信息
        handle_memcache.set_key("author_name", list(author_dict.keys())[:20])
        handle_memcache.set_key("author_nums", list(author_dict.values())[:20])

        # memcached 存储期刊信息
        handle_memcache.set_key("qikan_name", list(source_dict.keys())[:20])
        handle_memcache.set_key("qikan_nums", list(source_dict.values())[:20])

        # memcached 存储年份信息
        handle_memcache.set_key("year_name", new_year_name)
        handle_memcache.set_key("year_nums", new_year_nums)

        # memcached 存储机构信息
        handle_memcache.set_key("org_name", list(orginize_dict.keys()))
        handle_memcache.set_key("org_nums", list(orginize_dict.values()))

        p = Paginator(documents, 8, request=request)
        s_documents = p.page(page)

        context = {
            'documents': s_documents,
        }
        return render(request, 'front/search.html', context=context)

    else:
        documents = Document.objects.all()
        # 搜索结果可视化核心代码
        author_list = []
        source_list = []
        year_list = []
        orginize_list = []
        key_words = []
        for document in documents:
            author_list += hander_author(document.author)
            source_list.append(document.acticle_source.split(",")[0])
            year_list.append(get_year(document.acticle_source.split(",")[1]))
            orginize_list.append(document.author_location.split(",")[0])
            key_words += handle_words(document.key_words)
        orginize_dict = Counter(orginize_list)
        author_dict = Counter(reversed(author_list))
        source_dict = Counter(source_list)
        year_dict = Counter(reversed(year_list))
        words_dict = Counter(key_words)

        words_list = sorted(words_dict.items(), key=lambda item: item[1])
        print(words_list)

        new_year = sorted(year_dict.items(), key=lambda item: item[0])
        new_year_name = []
        new_year_nums = []
        for item in new_year:
            new_year_name.append(item[0])
            new_year_nums.append(item[1])
        # memcache 存储词云数据
        handle_memcache.set_key("words", words_list)

        # memcached 存储作者信息
        handle_memcache.set_key("author_name", list(author_dict.keys())[:20])
        handle_memcache.set_key("author_nums", list(author_dict.values())[:20])

        # memcached 存储期刊信息
        handle_memcache.set_key("qikan_name", list(source_dict.keys())[:20])
        handle_memcache.set_key("qikan_nums", list(source_dict.values())[:20])

        # memcached 存储年份信息
        handle_memcache.set_key("year_name", new_year_name)
        handle_memcache.set_key("year_nums", new_year_nums)

        # memcached 存储机构信息
        handle_memcache.set_key("org_name", list(orginize_dict.keys()))
        handle_memcache.set_key("org_nums", list(orginize_dict.values()))

        p = Paginator(documents, 8, request=request)
        s_documents = p.page(page)

        context = {
            'documents': s_documents,
        }
        return render(request, 'front/search.html', context=context)

def test(request):
    upper_words1 = request.GET.get('upper_words1')
    upper_words2 = request.GET.get('upper_words2')

    documents = Document.objects.filter(Q(title__contains=upper_words1) | Q(key_words__contains=upper_words2)).all()

    for d in documents:
        print(d.title)
        print(d.key_words)

    context = {
        "documents":documents
    }
    return render(request,'front/search.html',context=context)


from django.urls import path
from . import views
from django.views.decorators.csrf import csrf_exempt
# from django.contrib.auth.views import login, logout

urlpatterns = [

    path('api/accounts', views.AccountList.as_view(), name='account_list'), # api/contacts will be routed to the ContactList view for handling
    path('api/accounts/<int:pk>', views.AccountDetail.as_view(), name='account_detail'), # api/contacts will be routed to the ContactDetail view for handling

    # api/users will be routed to the UserAccountList for handling
    path('api/useraccount', views.UserAccountList.as_view(), name='useraccount_list'),

    #api/users/:id will be routed to the UserAccountDetails for handling
    path('api/useraccount/<int:pk>', views.UserAccountDetail.as_view(), name='useraccount_detail'),

    #api/users/login will be routed to check_login for handling
    path('api/useraccount/login', csrf_exempt(views.check_login), name='check_login')

]


from discord.ext import commands
import discord
import asyncio
import mysql.connector
from BD.connect_bd import connectBD

def findid(message):
    message = message.replace("<","")
    message = message.replace("@","")
    message = message.replace("!","")
    message = message.replace(">","")
    message = message.replace("&","")
    return int(message)

def Getting_big_str(*arg1):
    message = ""
    for i in range(len(arg1[0])):
        message += str(arg1[0][i]) + " "
    return message

class Users(commands.Cog):
    @commands.command()
    async def stats(self,ctx,arg1=None):
        if ctx.message.guild == None:
            await ctx.send("Простите но хозяйн не позволяет мне общеться с незнакомцами вне гильдии :(")
            return 0

        await ctx.message.delete()
        try:
            if not arg1:
                member = ctx.author
            else:
                member = ctx.guild.get_member(findid(arg1))

            mybd = connectBD()
            bdcursor = mybd.cursor()

            bdcursor.execute("SELECT balance,box,chat_message,voice_online,couple,instagram,AboutMe FROM Users WHERE id = {}".format(member.id))
            listinfo = bdcursor.fetchall()

            mybd.commit()

            if not listinfo:
                return 0

            embed=discord.Embed(color=0xff8080)
            embed.set_author(name = "Статистика,{}".format(member.name), icon_url = member.avatar_url)
            embed.set_thumbnail(url = member.avatar_url)
           # embed.add_field(name="Имя:", value="```{}```".format(member.name), inline=False)
            embed.add_field(name="💰 Баланс:", value="```{}🍭```".format(listinfo[0][0]), inline=True)
            embed.add_field(name="🎁 Коробок:", value="```{}```".format(listinfo[0][1]), inline=True)
            embed.add_field(name="✉ Сообщений:", value="```{} ```".format(listinfo[0][2]), inline=True)
            embed.add_field(name="⏲ Голосовой онлайн:", value="```{} ч```".format(int(listinfo[0][3]) // 60), inline=True)
            if listinfo[0][4] == "Одинок":
                embed.add_field(name="💙 Пара:", value="```{} ```".format(listinfo[0][4]), inline=True)
            else:
                mayer = ctx.guild.get_member(findid(listinfo[0][4]))
                embed.add_field(name="💙 Пара:", value="```{} ```".format(mayer), inline=True)
            embed.add_field(name="💻 Instagram", value="```{} ```".format(listinfo[0][5]), inline=True)
            embed.add_field(name="💁 О себе:", value="```{} ```".format(listinfo[0][6]), inline=False)
            embed.set_footer(text="Вызвал {}".format(ctx.author))
            await ctx.send(embed=embed)
        except ValueError:
            ErrorMessage =  await ctx.channel.send("Бип-Буп, что-то пошло не так!")
            await asyncio.sleep(5)
            await ErrorMessage.delete()

    @commands.command()
    async def status(self,ctx,*arg1):
        if ctx.message.guild == None:
            await ctx.send("Простите но хозяйн не позволяет мне общеться с незнакомцами вне гильдии :(")
            return 0

        await ctx.message.delete()
        if not arg1:
            helpmessage = await ctx.channel.send("Привет <@{}>, я вижу что у тебя проблемы с командой status! Я тебе помогу:"
                                    "```/status [Текст]```\n".format(ctx.author.id))
            await asyncio.sleep(5)
            await helpmessage.delete()
            return 0
        message = Getting_big_str(arg1)
        if len(message) > 50:
            helpmessage = await ctx.channel.send("Привет,{} твоя характеристика больше чем 50 символов. Попытайся уложиться именно в 50")
            await asyncio.sleep(5)
            await helpmessage.delete()
            return 0

        try:
            mybd = connectBD()
            bdcursor = mybd.cursor()

            bdcursor.execute("UPDATE Users set AboutMe = \"{}\" WHERE id = {}".format(message,ctx.author.id))

            mybd.commit()
        except ValueError:
            ErrorMessage =  await ctx.channel.send("Бип-Буп, что-то пошло не так!")
            await asyncio.sleep(5)
            await ErrorMessage.delete()

    @commands.command()
    async def instagram(self,ctx,arg1= None):
        if ctx.message.guild == None:
            await ctx.send("Простите но хозяйн не позволяет мне общеться с незнакомцами вне гильдии :(")
            return 0

        await ctx.message.delete()
        if not arg1:
            helpmessage = await ctx.channel.send("Привет <@{}>, я вижу что у тебя проблемы с командой instagram! Я тебе помогу:"
                                    "```/instagram [Ссылка]```\n".format(ctx.author.id))
            await asyncio.sleep(5)
            await helpmessage.delete()
            return 0
        if len(arg1) > 50:
            helpmessage = await ctx.channel.send("Привет,{} твоя ссылка больше чем 50 символов. Попытайся уложиться именно в 50")
            await asyncio.sleep(5)
            await helpmessage.delete()
            return 0

        try:
            mybd = connectBD()
            bdcursor = mybd.cursor()

            bdcursor.execute("UPDATE Users set instagram = '{}' WHERE id = {}".format(arg1,ctx.author.id))

            mybd.commit()
        except ValueError:
            ErrorMessage =  await ctx.channel.send("Бип-Буп, что-то пошло не так!")
            await asyncio.sleep(5)
            await ErrorMessage.delete()

    @commands.command()
    async def avatar(self,ctx,arg1= None):
        if ctx.message.guild == None:
            await ctx.send("Простите но хозяйн не позволяет мне общеться с незнакомцами вне гильдии :(")
            return 0

        try:
            if arg1:
                member = ctx.guild.get_member(findid(arg1))
            else:
                member = ctx.guild.get_member(ctx.author.id)
            embed = discord.Embed(title = 'Avatar: {}'.format(member),color = 53380)
            embed.set_image(url = member.avatar_url)
            await ctx.send(embed = embed)
        except ValueError:
            ErrorMessage =  await ctx.channel.send("Бип-Буп, что-то пошло не так!")
            await asyncio.sleep(5)
            await ErrorMessage.delete()

    @commands.command()
    async def shop(self,ctx):
        if ctx.message.guild == None:
            await ctx.send("Простите но хозяйн не позволяет мне общеться с незнакомцами вне гильдии :(")
            return 0

        await ctx.message.delete()
        embed=discord.Embed(title="Магазин ролей.", description="Ниже вы представлены роли который можно будет купить за 🍭\nЦена за данные роли 10.000🍭",color=0x8080ff)
        embed.add_field(name = "Столб №1:" ,value="1) <@&{}>  .\n"
                                "2) <@&{}> .\n"
                                "3) <@&{}> .\n"
                                "4) <@&{}> .\n"
                                "5) <@&{}> .\n"
                                "6) <@&{}> .\n"
                                "7) <@&{}> .\n"
                                "8) <@&{}> .".format(658962593091944459,658962591628132362,658962583100850177,658962580554907669,658962595021193256,658962578822922252,658962576234905600,658962601711239178), inline=False)
        embed.add_field(name = "Столб №2: " ,value="9) <@&{}> .\n"
                                "10) <@&{}> .\n"
                                "11) <@&{}> .\n"
                                "12) <@&{}> .\n"
                                "13) <@&{}> .\n"
                                "14) <@&{}> .\n"
                                "15) <@&{}> .\n"
                                "16) <@&{}> .".format(658962599127547915,658962596917018655,658962573764591616,658962570446635011,658962551303831564,658962548346978306,658962545494982666,658962249284714497), inline=False)
        embed.set_footer(text="Чтоб купить роль используйте команду /buy [Номер]")
        await ctx.send(embed=embed)

    @commands.command()
    async def buy(self,ctx,arg1=None):
        if ctx.message.guild == None:
            await ctx.send("Простите но хозяйн не позволяет мне общеться с незнакомцами вне гильдии :(")
            return 0

        await ctx.message.delete()
        if not arg1:
            helpmessage = await ctx.channel.send("Привет <@{}>, я вижу что у тебя проблемы с командой instagram! Я тебе помогу:"
                                    "```/instagram [Ссылка]```\n".format(ctx.author.id))
            await asyncio.sleep(5)
            await helpmessage.delete()
            return 0

        myBD = connectBD()
        bdcursor = myBD.cursor()

        try:
            listrole = (658962593091944459,658962591628132362,658962583100850177,658962580554907669,658962595021193256,658962578822922252,658962576234905600,658962601711239178,658962599127547915,658962596917018655,658962573764591616,658962570446635011,658962551303831564,658962548346978306,658962545494982666,658962249284714497)
            role = ctx.guild.get_role(listrole[int(arg1) - 1])

            bdcursor.execute("SELECT balance FROM Users WHERE id = {}".format(ctx.author.id))
            select = bdcursor.fetchall()
            balance = int(select[0][0])

            if balance < 10000:
                helpmessage = await ctx.channel.send("Привет <@{}>, я вижу что у тебя не хватает 🍭 чтоб купить роль.Приходи когда соберешь.".format(ctx.author.id))
                await asyncio.sleep(5)
                await helpmessage.delete()
                myBD.commit()
                return 0

            sql = "INSERT INTO Roles VALUES(%s,%s,%s)"
            val = (ctx.author.id,ctx.author.name,role.id)
            bdcursor.execute(sql,val)

            bdcursor.execute("UPDATE Users set balance = {} WHERE id = {}".format(balance-10000,ctx.author.id))

            await ctx.author.add_roles(role)

        except ValueError:
            ErrorMessage =  await ctx.channel.send("Бип-Буп, что-то пошло не так!")
            await asyncio.sleep(5)
            await ErrorMessage.delete()

        myBD.commit()

    @commands.command()
    async def stats_bot(self,ctx):
        await ctx.message.delete()

        bot1 = ctx.guild.get_member(234395307759108106)
        bot2 = ctx.guild.get_member(235088799074484224)
        bot3 = ctx.guild.get_member(184405311681986560)

        if not bot1.voice:
            infobot1 = "Свободный"
        else:
            infobot1 = "Занят"

        if not bot2.voice:
            infobot2 = "Свободный"
        else:
            infobot2 = "Занят"

        if not bot3.voice:
            infobot3 = "Свободный"
        else:
            infobot3 = "Занят"

        embed=discord.Embed(title="Информация о музыкальных ботов!", description="Ниже вы можете посмотреть статистику ботов и так-же их тег.\n", color=0xff8040)
        embed.add_field(name="Статистика:", value="```Music №1: {} || Тег:  -  \nMusic №2: {} || Тег:  !  \nMusic №3: {} || Тег:  ;;  ```".format(infobot1,infobot2,infobot3), inline=True)
        embed.set_footer(text="Вызвал {}".format(ctx.author.name))
        await ctx.send(embed=embed)


import cv2
import A1_function1
import time
import numpy
import A1_total_process

ori = cv2.imread("shapes.png", cv2.IMREAD_GRAYSCALE)
h, w = ori.shape
sub = numpy.zeros((h, w), dtype='uint8')
## print kernel!!!!!!!!!!!
print("------get_gaussian_filter_1d(5,1)(vertical)------")
print(A1_function1.get_gaussian_filter_1d(5,1))
print("-----get_gaussian_filter_1d(5,1)(horizontal)-----")
print((A1_function1.get_gaussian_filter_1d(5,1)).T)
print("-----------get_gaussian_filter_2d(5,1)-----------")
print(A1_function1.get_gaussian_filter_2d(5,1))

## gaussian filter!!!!!!
filtering_list = ['shapes.png', 'lenna.png']
time_start = time.clock()
A1_total_process.image_filtering_process(filtering_list)

## computational time, kernel (5,1)
print("-------------Computational Time(5,1)-------------")
kernel1d = A1_function1.get_gaussian_filter_1d(5, 1)
time_start = time.clock()
ori1 = A1_function1.cross_correlation_1d(ori, kernel1d)
img = A1_function1.cross_correlation_1d(ori1, kernel1d.T)
time_elapsed = (time.clock() - time_start)
print("1D filtering time :", end=' ')
print(time_elapsed)

time_start = time.clock()
kernel2d = A1_function1.get_gaussian_filter_2d(5, 1)
time_start = time.clock()
img2 = A1_function1.cross_correlation_2d(ori, kernel2d)
time_elapsed = (time.clock() - time_start)
print("2D filtering time :", end=' ')
print(time_elapsed)

sub = (numpy.abs(img2-img)).astype('uint8')
print("sum of difference :", end=' ')
print(numpy.sum(sub))
cv2.imshow("difference map", sub)

cv2.waitKey(0)
cv2.destroyAllWindows()

image filtering and edge detection/A1_image_filtering.py


from dataclasses import dataclass, field
from typing import Optional
from nova.beleg_request import BelegRequest

__NAMESPACE__ = "http://nova.voev.ch/services/v14/vertrieb"

@dataclass
class ErstelleBelege:
    """Request-Element für den 4.

    Klang
    """
    class Meta:
        name = "erstelleBelege"
        namespace = "http://nova.voev.ch/services/v14/vertrieb"

    beleg_request: Optional[BelegRequest] = field(
        default=None,
        metadata={
            "name": "belegRequest",
            "type": "Element",
            "required": True,
        }
    )


import requests
import re
from uuid import uuid4
from lxml import html

class ClientSideException(Exception):
    pass

class ServerSideException(Exception):
    pass

class MetacriticPS4HtmlParser:
    def __init__(self):
        self._url = "https://www.metacritic.com/game/playstation-4"
        self._top_games = {}

    @property
    def top_ps4_games(self):
        return self._top_games

    def parse(self):
        html_string = self._get_website_content()
        top_games_list = self._get_parsed_html_string(html_string)
        self._parse_top_games_list(top_games_list)

    def _get_website_content(self):
        headers = {
            "x-instart-request-id": str(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0",  # noqa
        }
        response = requests.get(self._url, headers=headers)
        if not response.ok:
            self._handle_http_error_and_reraise(response)
        return response.content

    def _get_parsed_html_string(self, response_content):
        tree = html.fromstring(response_content)
        top_games_table_content = tree.xpath(
            "//div[contains(@class, 'browse_list_wrapper')]//table//tr/td//text()"
        )
        return [
            elem.strip()
            for elem in top_games_table_content
            if self._non_empty_string(elem)
        ]

    def _non_empty_string(self, string):
        return not re.search(r"^[\n\t\s]*$", string)

    def _parse_top_games_list(self, top_games_list):
        for i in range(0, len(top_games_list), 10):
            current_game = top_games_list[i:i + 10]
            name = current_game[2]
            self._top_games[name] = {
                "metascore": current_game[0],
                "rank": current_game[1][:-1],  # remove the . at the end (1. -> 1)
                "name": current_game[2],
                "release_date": current_game[4],
                "summary": current_game[5],
                "user_score": current_game[9],
            }

    def _handle_http_error_and_reraise(self, response):
        if 400 <= response.status_code < 500:
            raise ClientSideException(response.text)
        if response.status_code >= 500:
            raise ServerSideException(response.text)


import torch
import glob
#import DAN module from model.py
from model import DAN
#import FastCountVectorizer
from fastCountVectorizer import FastCountVectorizer
#import IMDBDataset from datasets/imdbDataset.py
from datasets.imdbDataset import ImdbDataset

#import torch Dataset
from torch.utils.data import Dataset, DataLoader

import random

tokenizer = FastCountVectorizer('../data/fast_countvectorizer/top_million_ngrams.txt')

config = {
    'embed_dimension': 1000,
    'intermediate_dimension': 1000
}

model = DAN(
    num_embeddings=tokenizer.size()+1,
    embed_dimension=config['embed_dimension'],
    intermediate_dimension=config['intermediate_dimension']
)

#load the model from the checkpoint
old_state_dict = torch.load('model_best.pth.tar', map_location='cpu')['state_dict']
#rename all the keys in the state_dict to not contain "module."
new_state_dict = {}
for key in old_state_dict:
    new_state_dict[key.replace('module.', '')] = old_state_dict[key]
model.load_state_dict(new_state_dict)

#load the dataset
test_files = glob.glob("../data/imdb/test/*/*.txt")
#randomly sample 100 files from the test set
test_files = random.sample(test_files, 2000)
dataset = ImdbDataset(test_files, tokenizer)

#get the dataloader
dataloader = torch.utils.data.DataLoader(dataset, batch_size=4, shuffle=False)

model.eval()
num_correct, total = 0,0

#add zeros until a has length 1000
def pad_with_zeros(a):
    return a + [0] * (1000 - len(a))
def prepare_text(s):
    return torch.LongTensor([pad_with_zeros(tokenizer.tokenize(s))])

#iterate through each batch
for batch_idx, (data, target) in enumerate(dataloader):
    #load the batch
    #data, target = data.to(torch.device('cuda')), target.to(torch.device('cuda'))
    #make predictions
    output = model(data)
    #check if the prediction is correct
    _, predicted = torch.max(output.data, 1)

    _, target_value = torch.max(target, 1)
    #increment the number of correct predictions and the total number of predictions
    num_correct += (predicted == target_value).sum().item()
    total += target.size(0)

#print the accuracy
print("Accuracy: %.2f %%" % (100 * num_correct / total))


from aiogram import types
from telegram_bot_pagination import InlineKeyboardPaginator

def get_pagination_buttons(
    page_count: int, current_page: int, data_pattern: str, cls=InlineKeyboardPaginator
):
    paginator = cls(page_count, current_page=current_page, data_pattern=data_pattern)
    pagination_buttons = [
        types.InlineKeyboardButton(text=button["text"], callback_data=button["callback_data"])
        for button in paginator.keyboard
    ]

    return pagination_buttons


from django.urls import path
from . import views

# this like app.use() in express
urlpatterns = [
    path('', views.Home.as_view(), name="home"),
    path('folios/', views.FolioList.as_view(), name="folios"),
    path('folios/new/', views.FolioCreate.as_view(), name="new_folio"),
    path('folios/<int:pk>/', views.FolioDetail.as_view(), name="folio_detail"),
    path('folios/<int:pk>/update', views.FolioUpdate.as_view(), name="folio_update"),
    path('folios/<int:pk>/delete', views.FolioDelete.as_view(), name="folio_delete"),
    path('folios/<int:pk>/new/', views.QuartetCreate.as_view(), name="new_quartet"),
    path('folios/<int:folio_pk>/<int:pk>', views.QuartetDetail.as_view(), name="quartet_detail"),
    path('folios/<int:folio_pk>/<int:pk>/update', views.QuartetUpdate.as_view(), name="quartet_update"),
    path('folios/<int:folio_pk>/<int:pk>/delete', views.QuartetDelete.as_view(), name="quartet_delete"),
    path('folios/<int:folio_pk>/<int:pk>/new_text_entry/', views.TextEntryCreate.as_view(), name="new_text_entry"),
    path('folios/<int:folio_pk>/<int:pk>/new_image_entry/', views.ImageEntryCreate.as_view(), name="new_image_entry"),
    path('folios/<int:folio_pk>/<int:pk>/new_embed_entry/', views.EmbedEntryCreate.as_view(), name="new_embed_entry"),
    path('folios/<int:folio_pk>/<int:pk>/new_video_entry/', views.VideoEntryCreate.as_view(), name="new_video_entry"),
    path('folios/<int:folio_pk>/<int:quartet_pk>/<int:pk>/delete/', views.EntryDelete.as_view(), name="entry_delete"),
    path('accounts/signup/', views.Signup.as_view(), name="signup")
]


import os
import cv2
import time
import glob
import argparse
import datetime
import numpy as np
from tqdm import tqdm
import logzero
from logzero import logger as log
from pprint import pprint
from ipdb import set_trace as pause
from pathlib import Path, PosixPath

from request_api import SoftFPN
from video import FileVideoStream
from profiler import Profiler
from utils import checkfolder, convert_det_dict, crop_im, plot_one_box, decode_ratio

label_list = ["person", "head_shoulder", "face"]
label_list2 = ['bank_staff', 'cleaner', 'money_staff', 'person', 'security_staff']
label_list3 = ['bank_staff_vest', 'cleaner', 'money_staff', 'person', 'security_staff', 'bank_staff_shirt',
               'bank_staff_coat', 'security_staff_black']

color_list = [(0, 255, 0), (255, 0, 0), (0, 0, 255)]
color_list2 = [(169, 169, 169), (0, 255, 255), (0, 128, 128), (130, 0, 75), (203, 192, 255)]
color_list3 = [(169, 169, 169), (0, 255, 255), (0, 128, 128), (130, 0, 75), (203, 192, 255), (0, 165, 255),
               (235, 206, 135), (90, 90, 90)]
color_dict3 = {k: v for k, v in zip(label_list3, color_list3)}

def creat_log_dir(cfg):
	prefix = time.strftime('%Y-%m%d-%H%M-%S', time.localtime(time.time()))
	log_dir = Path(cfg.log_dir) / prefix
	checkfolder(log_dir)
	log_path = str(log_dir / "track_log.txt")
	logzero.logfile(log_path, maxBytes=1e6, backupCount=3)
	cfg.log_dir = log_dir

	log.info('\n=================New Log=================\n')
	log.info(cfg)
	pprint(cfg)
	log.info('\n=================New Log=================\n')

class MOT:
	def __init__(self, cfg, debug=False):
		self.cfg = cfg
		self.det_model = SoftFPN(detect_type='bank_person_hs')
		self.cls_model = SoftFPN(detect_type='mob2staff8')

		if cfg.track_type == "person":
			self.feat_model = SoftFPN('person_feature')
		elif cfg.track_type == "head_shoulder":
			self.feat_model = SoftFPN('hs_feature')
		else:
			raise TypeError(f" wrong track type : {cfg.track_type}, please check")

	def step(self, frames, frame_id, video_name):
		with Profiler('detect'):
			det_datas = self.det_model(frames)

			dec_dict_list = []
			for det_data in det_datas:
				det_dict = convert_det_dict(det_data)
				dec_dict_list.append(det_dict)

		for index, det_dict in enumerate(dec_dict_list):
			if self.cfg.track_type in det_dict.keys():
				# 裁剪目标小图，提取深度特征
				tlbrs = det_dict[cfg.track_type]["tlbrs"]
				# tlbrs = decode_ratio(tlbrs, frame.shape[0], frame.shape[1])
				ims = [crop_im(frames[index], tlbr) for tlbr in tlbrs]

				# this is used to crop detect small img
				# if self.cfg.save_img:
				# 	for i, img in enumerate(ims):
				# 		img_name = "{}_({}_{}).jpg".format(video_name[:-4], frame_id, i)
				# 		save_img_path = cfg.log_dir / "img" / img_name
				# 		dir_path = save_img_path.parent
				# 		if not dir_path.exists():
				# 			dir_path.mkdir(parents=True)
				# 		cv2.imwrite(str(save_img_path), img)

				with Profiler('mob2staff'):
					labels = []
					scores = []
					for i in range(0, len(ims), 16):
						if (len(ims) - i) < 16:
							label_dict = self.cls_model(ims[i:])[0]
						else:
							label_dict = self.cls_model(ims[i:i + 16])[0]
						labels += label_dict["class"]["label"]
						scores += label_dict["class"]["score"]

				# 存小图
				if self.cfg.save_img:
					for i, label in enumerate(labels):
						img_name = "{}_({}_{}).jpg".format(video_name.split(".")[0], frame_id-(16-index), i)
						save_img_path = cfg.log_dir / "img" / f"{label_list3.index(label)}-{label}" / img_name
						dir_path = save_img_path.parent
						if not dir_path.exists():
							dir_path.mkdir(parents=True)
						cv2.imwrite(str(save_img_path), ims[i])

				# 绘制检测框信息
				if self.cfg.save_video:
					for i, (tlbr, label, score) in enumerate(zip(tlbrs, labels, scores)):
						text = label + " " + score[:4]
						# text = label+ " " + str(round(score,2))
						plot_one_box(frames[index], tlbr, text, color=color_dict3[label])

			else:
				print("Frame {} no detections".format(frame_id-(16-index)))

		return frames

	@staticmethod
	def print_timing_info():
		log.debug('=================Timing Stats=================')
		log.debug(f"{'detect:':<37}{Profiler.get_avg_millis('detect'):>6.3f} ms")
		log.debug(f"{'mob2staff:':<37}{Profiler.get_avg_millis('mob2staff'):>6.3f} ms")

def demo(cfg, video_path):
	video_name = os.path.basename(video_path)
	outputFile = str(cfg.log_dir / f"demo_{video_name}")
	width, height = 1280, 720
	if cfg.save_video:
		fourcc = cv2.VideoWriter_fourcc(*'mp4v')  ## MJPG MP4V
		output = cv2.VideoWriter(outputFile, fourcc, 5, (width, height))
	fvs = FileVideoStream(video_path).start()
	mot = MOT(cfg)

	frame_id = 0
	frame_count = 0
	frames = []
	while fvs.running():
		if ((frame_id % (cfg.skip_frame)) != 0) or (frame_id < 0):
			# frame = fvs.read()
			frame_id += 1
			continue
		frame = fvs.read()
		if frame is None:
			break
		frames.append(frame)
		frame_count += 1
		frame_id += 1
		if frame_count % 16 == 0:
			log.info(f'\n=================New Frame {frame_count}=================\n')
			frames = mot.step(frames, frame_count, video_name)
			mot.print_timing_info()

			if cfg.save_video:
				for frame in frames:
					frame = cv2.resize(frame, (width, height))
					output.write(frame)
			if cfg.show_predict_video:
				for frame in frames:
					cv2.imshow('test', frame)
					key = cv2.waitKey(1) & 0xFF
					if key == ord('s'):  # suspend 按s键会暂停
						cv2.waitKey(0)
					if key == ord('c'):  # continue 按c键不动的话，视频会持续运行
						continue
					if key == ord('q'):  # quit
						exit()
			frames = []
	cv2.destroyAllWindows()
	fvs.stop()

def traversal_videos(cfg):
	creat_log_dir(cfg)
	# videos in folder
	video_list = sorted(glob.glob(os.path.join(cfg.video_path, "*.mp4")))[6:]
	video_list = ["/mnt/shy/农行POC/abc_data/第九批1119/cut/C57_3_1101_ 0920_ 0940_001523--001537.mp4"]
	for i, video_path in enumerate(video_list):
		log.info(f"{i} / {len(video_list) - 1}")
		log.info(f"====> {video_path}")
		demo(cfg, video_path)

# folders in folder
# folders = sorted(os.listdir(cfg.video_path))
# video_list = []
# for folder in folders:
# 	current_folder = os.path.join(cfg.video_path, folder)
# 	video_list += glob.glob(os.path.join(current_folder, "*.mp4"))
# for i, video_path in enumerate(video_list):
# 	print(f"{i} / {len(video_list) - 1}")
# 	print(f"====> {video_path}")
# 	demo(cfg, video_path)

def parse_args():
	parser = argparse.ArgumentParser(description="MOT")
	# parser.add_argument(
	# 	"--yml", default="./configs/track.yml")
	parser.add_argument("--save_video", default=True)
	parser.add_argument("--save_img", default=False)
	parser.add_argument("--show_predict_video", default=False)
	parser.add_argument(
		"--video_path",
		# default="/mnt/shy/track/test_yze/cut/guimian_05.mp4"
		# default="/mnt/shy/农行POC/abc_data/第五批0926/cut_video/C26_2_0923_1000_1020_000000--000200.mp4"
		default="/mnt/shy/农行POC/abc_data/第九批1119/cut/"

		# default="/mnt/shy/track/test_yze/guimian.mp4"
	)
	# person  head_shoulder  face
	parser.add_argument(
		"--track_type",
		# default="head_shoulder"
		default="person"
		# default="bank_person_hs"
	)
	parser.add_argument(
		"--skip_frame", default=20, type=int)
	# argument = parser.add_argument("--feature_weight", default=0.9, type=float)
	parser.add_argument(
		"--log_dir",
		# default="/mnt/shy/track/test_yze/logs/"
		default="/mnt2/sjh/农行data/第九批1119/"
	)

	return parser.parse_args()

if __name__ == "__main__":
	cfg = parse_args()
	traversal_videos(cfg)


import h5py
import numpy as np
import sys
import os
import json
from datetime import datetime, date
from tqdm import tqdm

def progress(count, total, status='', info=""):
    bar_len = 100
    filled_len = int(round(bar_len * count / float(total)))

    percents = round(100.0 * count / float(total), 1)
    bar = 'O' * filled_len + '.' * (bar_len - filled_len)

    _ = "{0} [{1}] {2}%".format(info, bar, percents)
    print(_, end='\r')

def json_from_file(fnm):
    r = None
    with open(fnm) as json_file:
        r = json.load(json_file)
    return r

def load_ground_stations(fnm):
    return json_from_file(fnm)

def load_omi_data(fnm, data_field):
    with h5py.File(fnm) as f:
        # Read dataset.
        dset = f[data_field]
        data = dset[:]
        # Handle fill value.
        data[data == dset.fillvalue] = np.nan
        data = np.ma.masked_where(np.isnan(data), data)
        return data

def read_station_data(station_id, date, type=["NO2"], time="13:00"):
    try:
        r = {}
        fnm = "{0}/{1}/{2}.json".format(STATION_FOLDER, station_id, date)
        station_data = json_from_file(fnm)
        for d in station_data["data"]["tabularData"]["bodyContent"]:
            if d["from date"][-5:] == time:
                for t in type:
                    r[t] = d[t]
                break
        return r
    except Exception as ex:
        return None

########################################################################################################################
OMI_DATA_FOLDER = "data/OMI"
GROUND_STATIONS = "data/Indian_station_list_OMIxy.json"
DATA_FIELD_NAME = "HDFEOS/GRIDS/ColumnAmountNO2/Data Fields/ColumnAmountNO2"
STATION_FOLDER = "data/cpcb"
PROCESSED_DATA = "data/processed_data-17-22.json"

ground_stations = load_ground_stations(GROUND_STATIONS)
ground_measure_item = ["NO2"]
ground_measure_time = "13:00"

stations_data = {}
fnm = None
omi_file_count = len(os.listdir(OMI_DATA_FOLDER))
current_count = 0

for file in os.listdir(OMI_DATA_FOLDER):
    if file.endswith(".he5"):
        fnm = os.path.join(OMI_DATA_FOLDER, file)
        omi_data = load_omi_data(fnm, DATA_FIELD_NAME)  # NO2
        # OMI-Aura_ L3-OMNO2d_ 2021m0311_ v003-2021m0421t134756.he5
        fnm_list = fnm.split("_")
        yr, mm, dd = fnm_list[2][:4], fnm_list[2][5:7], fnm_list[2][7:9]
        omi_time = fnm_list[3][-10:][:6]

        for station in ground_stations:
            if station["station_id"] not in stations_data:
                stations_data[station["station_id"]] = station.copy()

            st = stations_data[station["station_id"]]
            ground_data = read_station_data(station["station_id"],
                                            "{0}-{1}-{2}".format(dd, mm, yr),
                                            ground_measure_item,
                                            ground_measure_time)
            if "date" in st:
                st["date"].append("{0}/{1}/{2}".format(yr, mm, dd))
                st["OMI_NO2"].append(str(omi_data[station["OMI_y"]][station["OMI_x"]]))
                # st["time"].append(omi_time)
                for item in ground_measure_item:
                    if ground_data:
                        st[item].append(ground_data[item])
                    else:
                        st[item].append(None)
            else:
                st["date"] = ["{0}/{1}/{2}".format(yr, mm, dd)]
                st["OMI_NO2"] = [str(omi_data[station["OMI_y"]][station["OMI_x"]])]
                # st["time"] = [omi_time]
                for item in ground_measure_item:
                    if ground_data:
                        st[item] = [ground_data[item]]
                    else:
                        st[item] = [None]
        # stations_data[st["station_id"]] = st
        current_count += 1
        progress(current_count, omi_file_count, "", "{0}/{1}/{2}".format(mm, dd, yr))
        # if current_count > 10:
        #     break

if stations_data:
    with open(PROCESSED_DATA, "w") as json_file:
        json_file.write(json.dumps(stations_data))