# -*- 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 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 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()


'''
In order to solve Dynamic Connectivity problem.
This class represents an implemtation of abstract data type union-find.
Implementation is of quick_union algorithm - Lazy approach

Accept N numbers.
Accept M operations to be performed (union or find)
Operations can be intermixed (Find queries or union operand)

@author: luzC
'''
from src.datatypes.ds_union_find import UF

class QUICK_UNION(UF):

    def union(self, p_obj, q_obj):
        '''
        Connect two objects
        '''
        root_p = self.find_root(p_obj)
        root_q = self.find_root(q_obj)

        self._cc[root_p] = self._cc[root_q]

        print(self._cc)

    def connected(self, p_obj, q_obj):
        '''
        Find out if there is a conexion between 2 given objects
        '''
        return self.find_root(p_obj) == self.find_root(q_obj)

    def find_root(self, obj):
        '''
        Find root
        '''
        if obj not in range(self._n):
            self.error(101, str(obj))
            exit(1)

        # With a while loop
        while(obj != self._cc[obj]):
            obj = self._cc[obj]
        return obj

        # Use recursive method instead of while loop
        #root = self._cc[obj]
        #return root if root == obj else self.find_root(root)

class QUICK_UNION_OPTIMIZED(QUICK_UNION):
    '''
    Optimized by keeping track of tree weight
    '''
    def __init__(self, n):
        super(QUICK_UNION_OPTIMIZED, self).__init__(n)
        self._cc_size = [1]*n

    def union(self, p_obj, q_obj):
        '''
        Connect two objects
        Use the weight of the object trees.
        Place the smaller tree under the larger tree to avoid larger trees
        Need to keep track of tree size
        '''
        root_p = self.find_root(p_obj)
        root_q = self.find_root(q_obj)

        p_size = self._cc_size[root_p]
        q_size = self._cc_size[root_q]

        if p_size < q_size:
            self._cc[root_p] = self._cc[root_q]
            self._cc_size[root_q] += p_size
        else:
            self._cc[root_q] = self._cc[root_p]
            self._cc_size[root_p] += q_size

        print(self._cc)

class QUICK_UNION_OPTIMIZED_PATH_COMPRESSION(QUICK_UNION_OPTIMIZED):
    '''
    Optimized by keeping track of tree weight
    And flattening the tree with path compression
    After finding the root of X, move X under its parent root directly.
    Also move parents of X directly under parent root.
    '''
    def find_root(self, obj):
        '''
        Find root and flatten tree
        '''
        if obj not in range(self._n):
            self.error(101, str(obj))
            exit(1)

        # With a while loop
        while(obj != self._cc[obj]):
            # make grandparent the root
            # other way is to add a second loop to set to root all examined
            #nodes in order to flaten the tree
            self._cc[obj] = self._cc[self._cc[obj]]
            obj = self._cc[obj]
        return obj


# Darren Liang and Stacey Li

def collatz(n):
    steps = 0 # placeholder to count amount of steps
    while n != 1: # keep looping until n equal to 1
        if n % 2 == 0: # divide by 2 if even
            n = n / 2
            print(int(n)) # remove decimals
            steps += 1 # add 1 step
        else: # multiply by 3 and add 1 if odd
            n = (3 * n) + 1
            print(int(n))
            steps += 1
    return "Steps: " + str(steps)

print(collatz(9))
print(collatz(27))


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 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 json
import re
from collections import defaultdict

import opml
import structlog
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.core.paginator import EmptyPage, InvalidPage, Paginator
from django.core.urlresolvers import reverse, reverse_lazy
from django.db import transaction
from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader
from django.template.defaultfilters import slugify
from django.utils.html import format_html
from django.utils.translation import ugettext as _, ungettext
from django.views import generic
from elasticsearch.exceptions import ConflictError, RequestError

from .forms import (ActionForm, CategoryForm, FeedForm, OPMLImportForm,
                    ReadForm, SubscriptionFormSet, UndoReadForm, user_lock)
from .models import Category, UniqueFeed
from .tasks import read_later
from .. import es
from ..decorators import login_required
from ..tasks import enqueue

"""
Each view displays a list of entries, with a level of filtering:
    - home: all entries
    - category: entries in a specific category
    - feed: entries for a specific feed
    - item: a single entry

Entries are paginated.
"""

logger = structlog.get_logger(__name__)

MEDIA_RE = re.compile(
    r'.*<(img|audio|video|iframe|object|embed|script|source)\s+.*',
    re.UNICODE | re.DOTALL)

class Keyboard(generic.TemplateView):
    template_name = 'feeds/keyboard.html'

keyboard = Keyboard.as_view()

def paginate(object_list, page=1, nb_items=25, force_count=None):
    """
    Simple generic paginator for all the ``Entry`` lists
    """
    if force_count is not None:
        def count(x):
            return force_count
        object_list.count = count

    paginator = Paginator(object_list, nb_items)

    try:
        paginated = paginator.page(page)
    except (EmptyPage, InvalidPage):
        paginated = paginator.page(paginator.num_pages)

    return paginated, paginator._count

@login_required
def entries_list(request, page=1, mode=None, category=None, feed=None,
                 starred=False):
    """
    Displays a paginated list of entries.

    ``page``: the page number
    ``mode``: filters the list to display all / unread / starred items
    ``category``: (slug) if set, will filter the entries of this category
    ``feed``: (object_id) if set, will filter the entries of this feed

    Note: only set category OR feed. Not both at the same time.
    """
    page = int(page)
    user = request.user
    es_entries = es.manager.user(request.user).defer(
        'content', 'guid', 'tags', 'read_later_url',
        'author', 'broadcast', 'link', 'starred',
    ).query_aggregate('all_unread', read=False)
    if mode == 'unread':
        es_entries = es_entries.filter(read=False)
    elif mode == 'stars':
        es_entries = es_entries.filter(
            starred=True).query_aggregate('all_starred', starred=True)

    search = request.GET.get('q', '')
    if search:
        es_entries = es_entries.filter(query=search)

    if category is not None:
        category = get_object_or_404(user.categories, slug=category)
        all_url = reverse('feeds:category', args=[category.slug])
        unread_url = reverse('feeds:category', args=[category.slug, "unread"])
        stars_url = reverse('feeds:category', args=[category.slug, "stars"])
        es_entries = es_entries.filter(category=category.pk).query_aggregate(
            'all', category=category.pk).query_aggregate(
                'unread', category=category.pk, read=False)

    if feed is not None:
        feed = get_object_or_404(user.feeds.select_related('category'),
                                 pk=feed)
        all_url = reverse('feeds:feed', args=[feed.pk])
        unread_url = reverse('feeds:feed', args=[feed.pk, "unread"])
        stars_url = reverse('feeds:feed', args=[feed.pk, "stars"])

        category = feed.category
        es_entries = es_entries.filter(feed=feed.pk).query_aggregate(
            'all', feed=feed.pk).query_aggregate(
                'unread', feed=feed.pk, read=False)

    if starred is True:
        es_entries = es_entries.filter(starred=True).query_aggregate(
            'all', starred=True).query_aggregate(
                'unread', starred=True, read=False)
        all_url = reverse('feeds:entries', args=['stars'])
        unread_url = None
        stars_url = None

    if feed is None and category is None and starred is not True:
        all_url = reverse('feeds:entries')
        unread_url = reverse('feeds:entries', args=['unread'])
        stars_url = reverse('feeds:entries', args=['stars'])
        es_entries = es_entries.query_aggregate('all').query_aggregate(
            'unread', read=False)

    if user.oldest_first:
        es_entries = es_entries.order_by('timestamp', 'id')

    if request.method == 'POST':
        if request.POST['action'] in (ReadForm.READ_ALL, ReadForm.READ_PAGE):
            pages_only = request.POST['action'] == ReadForm.READ_PAGE
            form = ReadForm(es_entries, feed, category, user,
                            pages_only=pages_only, data=request.POST)
            if form.is_valid():
                pks = form.save()
                undo_form = loader.render_to_string('feeds/undo_read.html', {
                    'form': UndoReadForm(initial={
                        'pks': json.dumps(pks, separators=(',', ':'))}),
                    'action': request.get_full_path(),
                }, request=request)
                message = ungettext(
                    '1 entry has been marked as read.',
                    '%(value)s entries have been marked as read.',
                    len(pks)) % {'value': len(pks)}
                messages.success(request,
                                 format_html(u"{0} {1}", message, undo_form))

        elif request.POST['action'] == 'undo-read':
            form = UndoReadForm(user, data=request.POST)
            if form.is_valid():
                count = form.save()
                messages.success(
                    request, ungettext(
                        '1 entry has been marked as unread.',
                        '%(value)s entries have been marked as unread.',
                        count) % {'value': count})

        if mode == 'unread':
            return redirect(unread_url)
        elif mode == 'stars':
            return redirect(stars_url)
        else:
            return redirect(all_url)

    try:
        entries = es_entries.fetch(page=page,
                                   per_page=user.entries_per_page,
                                   annotate=user)
    except RequestError as e:
        if 'No mapping found' not in e.error:  # index is empty
            raise
        entries = []
        user._unread_count = unread_count = total_count = 0
    else:
        aggs = entries['aggregations']
        entries = entries['hits']
        unread_count = aggs['entries']['unread']['doc_count']
        total_count = aggs['entries']['all']['doc_count']
        user._unread_count = aggs['entries']['all_unread']['doc_count']
    if mode == 'unread':
        card = unread_count
    elif mode == 'stars':
        card = aggs['entries']['all_starred']['doc_count']
    else:
        card = total_count
    num_pages = card // user.entries_per_page
    if card % user.entries_per_page:
        num_pages += 1
    entries = {
        'object_list': entries,
        'paginator': {
            'num_pages': num_pages,
        },
        'has_previous': page > 1,
        'has_next': page < num_pages,
        'previous_page_number': page - 1,
        'next_page_number': page + 1,
        'number': page,
    }
    request.session['back_url'] = request.get_full_path()

    # base_url is a variable that helps the paginator a lot. The drawback is
    # that the paginator can't use reversed URLs.
    if mode == 'unread':
        base_url = unread_url
    elif mode == 'stars':
        base_url = stars_url
    else:
        base_url = all_url

    context = {
        'category': category,
        'feed': feed,
        'entries': entries,
        'mode': mode,
        'unread_count': unread_count,
        'total_count': total_count,
        'all_url': all_url,
        'unread_url': unread_url,
        'stars_url': stars_url,
        'base_url': base_url,
        'stars': starred,
        'all_unread': aggs['entries']['unread']['doc_count'],
        'entries_template': 'feeds/entries_include.html',
        'search': search,
        'search_form': True,
    }
    if unread_count:
        context['read_all_form'] = ReadForm()
        context['read_page_form'] = ReadForm(pages_only=True, initial={
            'action': ReadForm.READ_PAGE,
            'pages': json.dumps([int(page)]),
        })
        context['action'] = request.get_full_path()
    if (
        len(entries['object_list']) == 0 and
        request.user.feeds.count() == 0
    ):
        context['noob'] = True

    if request.is_ajax():
        template_name = context['entries_template']
    else:
        template_name = 'feeds/entries_list.html'

    return render(request, template_name, context)

class SuccessMixin(object):
    success_message = None

    def get_success_message(self):
        return self.success_message

    def form_valid(self, form):
        response = super().form_valid(form)
        msg = self.get_success_message()
        if msg is not None:
            messages.success(self.request, msg)
        return response

class CategoryMixin(SuccessMixin):
    form_class = CategoryForm
    success_url = reverse_lazy('feeds:manage')

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def get_object(self):
        return get_object_or_404(self.request.user.categories,
                                 slug=self.kwargs['slug'])

class AddCategory(CategoryMixin, generic.CreateView):
    template_name = 'feeds/category_form.html'

add_category = login_required(AddCategory.as_view())

class EditCategory(CategoryMixin, generic.UpdateView):
    template_name = 'feeds/edit_category.html'

    def get_success_message(self):
        return _('%(category)s has been successfully '
                 'updated') % {'category': self.object}

edit_category = login_required(EditCategory.as_view())

class DeleteCategory(CategoryMixin, generic.DeleteView):
    success_url = reverse_lazy('feeds:manage')

    @transaction.atomic
    def delete(self, request, *args, **kwargs):
        self.object = self.get_object()
        pk = self.object.pk
        name = self.object.name
        self.object.delete()
        request.user.delete_category_entries(pk)
        messages.success(
            self.request,
            _('%(category)s has been successfully deleted') % {
                'category': name})
        success_url = self.get_success_url()
        return redirect(success_url)

    def get_context_data(self, **kwargs):
        entry_count = es.client.count(
            index=es.user_alias(self.request.user.pk),
            doc_type='entries',
            body={
                'query': {
                    'filtered': {
                        'filter': {'term': {'category': self.object.pk}},
                    },
                },
            },
        )['count']
        kwargs.update({
            'entry_count': entry_count,
            'feed_count': self.object.feeds.count(),
        })
        return super().get_context_data(**kwargs)

delete_category = login_required(DeleteCategory.as_view())

class FeedMixin(SuccessMixin):
    form_class = FeedForm
    success_url = reverse_lazy('feeds:manage')

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def get_object(self):
        return get_object_or_404(self.request.user.feeds,
                                 pk=self.kwargs['feed'])

class AddFeed(FeedMixin, generic.CreateView):
    template_name = 'feeds/feed_form.html'

    def get_success_message(self):
        return _('%(feed)s has been successfully '
                 'added') % {'feed': self.object.name}

    def get_initial(self):
        initial = super().get_initial()
        if 'feed' in self.request.GET:
            initial['url'] = self.request.GET['feed']
        if 'name' in self.request.GET:
            initial['name'] = self.request.GET['name']
        return initial

add_feed = login_required(AddFeed.as_view())

class EditFeed(FeedMixin, generic.UpdateView):
    template_name = 'feeds/edit_feed.html'

    def get_success_message(self):
        return _('%(feed)s has been successfully '
                 'updated') % {'feed': self.object.name}

edit_feed = login_required(EditFeed.as_view())

class DeleteFeed(FeedMixin, generic.DeleteView):
    def get_context_data(self, **kwargs):
        entry_count = es.client.count(
            index=es.user_alias(self.request.user.pk),
            doc_type='entries',
            body={
                'query': {
                    'filtered': {
                        'filter': {'term': {'feed': self.object.pk}},
                    },
                },
            },
        )['count']
        kwargs['entry_count'] = entry_count
        return super().get_context_data(**kwargs)

    @transaction.atomic
    def delete(self, request, *args, **kwargs):
        self.object = self.get_object()
        pk = self.object.pk
        name = self.object.name
        self.object.delete()
        request.user.delete_feed_entries(pk)
        messages.success(
            request,
            _('%(feed)s has been successfully deleted') % {
                'feed': name})
        success_url = self.get_success_url()
        return redirect(success_url)

delete_feed = login_required(DeleteFeed.as_view())

@login_required
def item(request, entry_id):
    entry = es.entry(request.user, entry_id)
    if not entry.read:
        try:
            entry.update(read=True)
        except ConflictError:
            # Double click // two operations at a time. Entry has already
            # been marked as read.
            pass
    back_url = request.session.get('back_url',
                                   default=entry.feed.get_absolute_url())

    # Depending on the list used to access to this page, we try to find in an
    # intelligent way which is the previous and the next item in the list.

    # This way the user has nice 'previous' and 'next' buttons that are
    # dynamically changed
    mode = None
    bits = back_url.split('/')
    # FIXME: The kw thing currently doesn't work with paginated content.
    kw = {'user': request.user}

    if bits[1] == 'unread':
        # only unread
        kw['read'] = False
        mode = 'unread'

    elif bits[1] == 'stars':
        mode = 'stars'
        kw['starred'] = True

    elif bits[1] == 'feed':
        # Entries in self.feed
        kw = {'feed': entry.feed}

    elif bits[1] == 'category':
        # Entries in self.feed.category
        category_slug = bits[2]
        category = Category.objects.get(slug=category_slug, user=request.user)
        kw = {'feed__category': category}

    if len(bits) > 3:
        if bits[3] == 'unread':
            kw['read'] = False
            mode = 'unread'
        elif bits[3] == 'stars':
            kw['starred'] = True

    # The previous is actually the next by date, and vice versa
    es_entries = es.manager.user(request.user).exclude(id=entry.pk)
    if 'feed' in kw:
        es_entries = es_entries.filter(feed=kw['feed'].pk)
    if 'read' in kw:
        es_entries = es_entries.filter(read=kw['read'])
    if 'feed__category' in kw:
        es_entries = es_entries.filter(category=kw['feed__category'].pk)
    if 'starred' in kw:
        es_entries = es_entries.filter(starred=kw['starred'])
    previous = es_entries.filter(timestamp__gte=entry.date).order_by(
        'timestamp', 'id').fetch(per_page=1)
    previous = previous['hits'][0] if previous['hits'] else None
    if previous is not None:
        if previous.date == entry.date:
            previous = es_entries.filter(
                timestamp__gte=entry.date).filter(
                id__gt=entry.pk
            ).order_by('timestamp', 'id').fetch(per_page=1)
            previous = previous['hits'][0] if previous['hits'] else None
        if previous is not None:
            previous = previous.get_absolute_url()
    next = es_entries.filter(timestamp__lte=entry.date).order_by(
        '-timestamp', '-id').fetch(per_page=1)
    next = next['hits'][0] if next['hits'] else None
    if next is not None:
        if next.date == entry.date:
            next = es_entries.filter(
                timestamp__lte=entry.date).filter(
                id__lt=entry.pk
            ).order_by('-timestamp', '-id').fetch(per_page=1)
            next = next['hits'][0] if next['hits'] else None
        if next is not None:
            next = next.get_absolute_url()

    if request.user.oldest_first:
        previous, next = next, previous

    # if there is an image in the entry, don't show it. We need user
    # intervention to display the image.
    has_media = media_safe = False
    if MEDIA_RE.match(entry.subtitle):
        has_media = True

    if request.method == 'POST':
        form = ActionForm(data=request.POST)
        if form.is_valid():
            action = form.cleaned_data['action']
            if action == 'images':
                if 'never' in request.POST:
                    entry.feed.img_safe = False
                    entry.feed.save(update_fields=['img_safe'])
                elif 'once' in request.POST:
                    media_safe = True
                elif 'always' in request.POST:
                    entry.feed.img_safe = True
                    entry.feed.save(update_fields=['img_safe'])
            elif action == 'unread':
                entry.update(read=False, refresh=True)
                return redirect(back_url)
            elif action == 'read_later':
                enqueue(read_later, args=[request.user.pk, entry.pk],
                        timeout=20, queue='high')
                messages.success(
                    request,
                    _('Article successfully added to your reading list'),
                )
            elif action in ['star', 'unstar']:
                entry.update(starred=action == 'star', refresh=True)

    context = {
        'category': entry.feed.category,
        'back_url': back_url,
        'mode': mode,
        'previous': previous,
        'next': next,
        'has_media': has_media,
        'media_safe': media_safe,
        'object': entry,
    }
    return render(request, 'feeds/entry_detail.html', context)

def truncate(value, length):
    if len(value) > length - 3:
        value = value[:length - 3] + '...'
    return value

def save_outline(user, category, outline, existing):
    count = 0
    try:
        opml_tag = outline._tree.getroot().tag == 'opml'
    except AttributeError:
        opml_tag = False
    if (
        not hasattr(outline, 'xmlUrl') and
        hasattr(outline, 'title') and
        outline._outlines
    ):
        if opml_tag:
            cat = None
            created = False
        else:
            slug = slugify(outline.title)
            if not slug:
                slug = 'unknown'
            title = truncate(outline.title, 1023)
            slug = slug[:50]
            cat, created = user.categories.get_or_create(
                slug=slug, defaults={'name': title},
            )
        for entry in outline._outlines:
            count += save_outline(user, cat, entry, existing)
        if created and cat.feeds.count() == 0:
            cat.delete()

    for entry in outline:
        count += save_outline(user, category, entry, existing)

    if (hasattr(outline, 'xmlUrl')):
        if outline.xmlUrl not in existing:
            existing.add(outline.xmlUrl)
            title = getattr(outline, 'title',
                            getattr(outline, 'text', _('No title')))
            title = truncate(title, 1023)
            user.feeds.create(category=category, url=outline.xmlUrl,
                              name=title)
            count += 1
    return count

@login_required
@transaction.atomic
def import_feeds(request):
    """Import feeds from an OPML source"""
    if request.method == 'POST':
        form = OPMLImportForm(request.POST, request.FILES)
        if form.is_valid():
            # get the list of existing feeds
            existing_feeds = set(request.user.feeds.values_list('url',
                                                                flat=True))

            entries = opml.parse(request.FILES['file'])
            try:
                with user_lock('opml_import', request.user.pk, timeout=30):
                    imported = save_outline(request.user, None, entries,
                                            existing_feeds)
            except ValidationError:
                logger.info("prevented duplicate import", request=request)
            else:
                message = " ".join([ungettext(
                    u'%s feed has been imported.',
                    u'%s feeds have been imported.',
                    imported) % imported,
                    _('New content will appear in a moment when you refresh '
                      'the page.')
                ])
                messages.success(request, message)
                return redirect('feeds:entries')

    else:
        form = OPMLImportForm()

    context = {
        'form': form,
    }
    return render(request, 'feeds/import_feeds.html', context)

@login_required
def dashboard(request, mode=None):
    categories = request.user.categories.values()
    feeds = request.user.feeds.all()

    for cat in categories:
        cat['unread_count'] = 0

    feed_to_cat = {feed.pk: feed.category_id for feed in feeds}

    category_feeds = defaultdict(list)
    category_counts = defaultdict(int)

    counts = es.counts(request.user, feed_to_cat.keys(), stars=mode == 'stars')
    _all = 0
    for feed in feeds:
        feed.unread_count = counts[str(feed.pk)][str(feed.pk)]['doc_count']
        _all += feed.unread_count
        if feed.category_id is None:
            continue
        category_feeds[feed.category_id].append(feed)
        category_counts[feed.category_id] += feed.unread_count

    for c in categories:
        c['unread_count'] = category_counts[c['id']]
        c['feeds'] = {'all': category_feeds[c['id']]}

    uncategorized = [feed for feed in feeds if feed.category_id is None]
    for feed in uncategorized:
        feed.unread_count = counts[str(feed.pk)][str(feed.pk)]['doc_count']

    if mode == 'unread':
        categories = [c for c in categories if c['unread_count']]

        for c in categories:
            c['feeds'] = {'all': [feed for feed in c['feeds']['all']
                                  if feed.unread_count]}
        uncategorized = [feed for feed in uncategorized
                         if feed.unread_count]
    total = len(uncategorized) + sum(
        (len(c['feeds']['all']) for c in categories)
    )

    has_orphans = bool(len(uncategorized))

    if has_orphans:
        categories = [
            {'feeds': {'all': uncategorized}}
        ] + list(categories)

    col_size = total // 3
    col_1 = None
    col_2 = None
    done = len(uncategorized)
    for index, cat in enumerate(categories[has_orphans:]):
        if col_1 is None and done > col_size:
            col_1 = index + 1
        if col_2 is None and done > 2 * col_size:
            col_2 = index + 1
        done += len(cat['feeds']['all'])

    context = {
        'categories': categories,
        'breaks': [col_1, col_2],
        'mode': mode,
    }
    return render(request, 'feeds/dashboard.html', context)

class Subscribe(generic.FormView):
    form_class = SubscriptionFormSet
    template_name = 'feeds/subscribe.html'

    def get_initial(self):
        urls = [l for l in self.request.GET.get('feeds', '').split(',') if l]
        self.feed_count = len(urls)

        self.existing = self.request.user.feeds.filter(url__in=urls)

        existing_urls = set([e.url for e in self.existing])

        new_urls = [url for url in urls if url not in existing_urls]
        name_prefill = {}
        if new_urls:
            uniques = UniqueFeed.objects.filter(
                url__in=new_urls)
            for unique in uniques:
                name_prefill[unique.url] = unique.job_details.get('title')

        return [{
            'name': name_prefill.get(url),
            'url': url,
            'subscribe': True,
        } for url in new_urls]

    def get_form(self, form_class=None):
        formset = super().get_form(form_class)
        cats = [['', '-----']] + [
            (str(c.pk), c.name) for c in self.request.user.categories.all()
        ]
        for form in formset:
            form.fields['category'].choices = cats
            form.user = self.request.user
        return formset

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['site_url'] = self.request.GET.get('url')
        return ctx

    def form_valid(self, formset):
        created = 0
        for form in formset:
            if form.cleaned_data['subscribe']:
                if form.cleaned_data['category']:
                    category = self.request.user.categories.get(
                        pk=form.cleaned_data['category'],
                    )
                else:
                    category = None
                self.request.user.feeds.create(
                    name=form.cleaned_data['name'],
                    url=form.cleaned_data['url'],
                    category=category,
                )
                created += 1
        if created == 1:
            message = _('1 feed has been added')
        else:
            message = _('%s feeds have been added') % created
        messages.success(self.request, message)
        return redirect(reverse('feeds:entries'))

subscribe = login_required(Subscribe.as_view())

class ManageFeeds(generic.TemplateView):
    template_name = 'feeds/manage_feeds.html'

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        feeds = self.request.user.feeds.select_related('category').order_by(
            'category__name', 'category__id', 'name',
        ).extra(select={
            'muted': """
                select muted from feeds_uniquefeed
                where feeds_uniquefeed.url = feeds_feed.url
            """,
            'error': """
                select muted_reason from feeds_uniquefeed
                where feeds_uniquefeed.url = feeds_feed.url
            """,
        })

        ctx['feeds'] = feeds
        return ctx

manage = login_required(ManageFeeds.as_view())


# Reference
# https://www.youtube.com/watch?v=LuLCLgMElus&list=PLgUwDviBIf0rPG3Ictpu74YWBQ1CaBkm2&index=9

class Solution:
    def nextPermutation(self, num: List[int]) -> None:
        """
        Do not return anything, modify num in-place instead.
        """
        index = len(num)-1
        for i in range(len(num)-1, -1, -1):
            if len(num) == 1:
                break
            else:
                if(num[i] > num[i-1]):
                    index = i-1
                    break
        if index >= 0:
            for i in range(len(num)-1, index-1, -1):
                if len(num) == 1:
                    break
                if(num[index] < num[i]):
                    temp = num[index]
                    num[index] = num[i]
                    num[i] = temp
                    for i in range(1, ((len(num)-index)//2 if (len(num)-index) % 2 == 0 else (len(num)-index)//2 + 1)):
                        temp = num[i+index]
                        num[i+index] = num[len(num)-i]
                        num[len(num)-i] = temp
                    break
        else:
            for i in range(len(num)//2):
                temp = num[i]
                num[i] = num[len(num)-i-1]
                num[len(num)-i-1] = temp

01 Array/31. Next Permutation/01 Solution.py


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')

]


class Node:
    """Дерево, листья которого могут менять статус всех своих предков на открытый"""
    def __init__(self, id=None, title=None, parent=None, slug=None):
        self.id = id
        self.title = title
        self.parent = parent
        self.slug = slug
        self.children = []
        self.status = 'close'

    def __add__(self, other):
        self.children.append(other)
        return self

    def change_status(self, selected):
        if self.slug == selected:
            self.status = 'open'
            if self.parent != 0:
                self.parent.change_status(self.parent.slug)
        else:
            if self.children is not None:
                for ch in self.children:
                    ch.change_status(selected)
        return self


import os.path
import argparse

ARG_E_IGNORE = "ignore"
ARG_E_IGNORE_SKIP = "ignoreSkip"
ARG_E_WARN = "warn"
ARG_E_EXIT = "exit"
ARG_E_EXIT_SILENT = "exitSilent"

def main():
	parser = argparse.ArgumentParser(description = "Resolve relative file paths to absolute file path.")

	parser.add_argument("file",
	                    type = str,
	                    help = "file to get path of",
	                    nargs = "+")

	parser.add_argument("-e",
	                    type = str,
	                    choices = [ARG_E_IGNORE, ARG_E_IGNORE_SKIP, ARG_E_WARN, ARG_E_EXIT, ARG_E_EXIT_SILENT],
	                    default = ARG_E_WARN)

	#read and check user suplied arguments
	parser = parser.parse_args()

	for fname in parser.file:
	    #get real path
	    rpath = os.path.realpath(fname)
	    #check that file exists
	    fileExists = os.path.isfile(rpath) or os.path.isdir(rpath)

	    if fileExists:
	        print(rpath)
	    else:
	        if parser.e == ARG_E_IGNORE_SKIP:
	            continue
	        elif parser.e == ARG_E_IGNORE:
	            print(rpath)
	        elif parser.e == ARG_E_EXIT_SILENT:
	            exit()
	        elif parser.e == ARG_E_WARN or parser.e == ARG_E_EXIT:
	            print(fname + " does not exist!")
	            if parser.e == ARG_E_WARN:
	                print(rpath)
	            elif parser.e == ARG_E_EXIT:
	                exit()

if __name__ == '__main__':
	main()


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 qqbot import QQBotSlot as qqbotslot,RunBot
from qqbot import qqbotsched as qqbotsched
from qqbot import _bot as bot
bot.Login(['-q', '1234'])
import time
@qqbotsched(hour='23',minute='01')
def mytask(bot):
    gl=bot.List('group','大逗比(~_~;)')
    if gl is not None:
        for group in gl:
            bot.SendTo(group,'请交日报')
def onQQMessage(bot,contact,member,content):
    if content.startswith("日报"):
        """
        打包我们的日志文件
        """
        bot.SendTo(contact,'日报已经收到')

if __name__=='__main__':
    RunBot()
    bot.lit('buddy')


import tensorflow as tf
import os
from utils.reprocessing import generator_enqueue
from utils.reprocessing import PAD_ID,GO_ID, EOS_ID, UNK_ID

class Variational_autoencoder_Seq2Seq(object):

    def __init__(self, layers_size=100, VAE_layers_size=100, learning_rate=0.01,
                 vocab_size=1000,
                 init_embedding=None, embedding_size=100,
                 lr_decay=0.9, scope='seq2seq', max_grad_norm=5, queue_capacity=1000,
                 max_length=50, min_length=3, num_samples=1024,
                 type_model='Train', tracking='tracking', dtype=tf.float32):
        self.layers_size = layers_size
        self.learning_rate = learning_rate
        self.VAE_layers_size = VAE_layers_size
        self.vocab_size = vocab_size
        self.max_length = max_length
        self.lr_decay = lr_decay
        self.scope = scope
        self.embedding_size = embedding_size
        self.min_length = min_length
        self.max_grad_norm = max_grad_norm
        self.init_embedding = init_embedding
        self.tracking = tracking
        self.num_samples = num_samples
        self.dtype = dtype
        self.type_model = type_model
        self.graph = None

    def _cell(self, num_units, keep_prob=1.):
        cell = tf.contrib.rnn.BasicLSTMCell(num_units)
        return cell

    def _clip_gradients(self, grads_and_vars, embedding_norm = 0.1):
        """In addition to standard gradient clipping, also clips embedding
        gradients to a specified value."""
        clipped_gradients = []
        variables = []
        for gradient, variable in grads_and_vars:
            if "embedding" in variable.name:
                tmp = tf.clip_by_norm(
                    gradient.values, embedding_norm)
                gradient = tf.IndexedSlices(tmp, gradient.indices, gradient.dense_shape)
            clipped_gradients.append(gradient)
            variables.append(variable)
        return list(zip(clipped_gradients, variables))

    def _optimizer(self, loss):
        """Create the optimizer node of the graph."""
        self.lr_var = tf.Variable(self.learning_rate, trainable=False)
        tvars = tf.trainable_variables()
        grads, _ = tf.clip_by_global_norm(tf.gradients(loss, tvars),
                                          self.max_grad_norm)
#         grads_and_vars = self._clip_gradients(list(zip(grads, tvars)))
        grads_and_vars = zip(grads, tvars)

        optimizer = tf.train.AdamOptimizer(
            learning_rate=self.lr_var, epsilon=1e-08)
        _train_op = optimizer.apply_gradients(
            grads_and_vars, global_step=self.global_step)
        return _train_op

    def _sample_posterior(self, x):
        x = tf.concat(x, axis=-1)
        latent_dim = self.VAE_layers_size
        with tf.variable_scope('variantional_autoencoder'):
            #             epsilon = tf.constant(1e-8)
            self.z_mu = tf.layers.dense(
                inputs=x, units=latent_dim, name='z_mu')
            self.z_var = tf.layers.dense(inputs=x, units=latent_dim, activation=tf.nn.softplus,
                                         bias_initializer=tf.constant_initializer(
                                             -2.5),
                                         name='z_log_sigma') + 1e-8

            epsilon = tf.random_normal(shape=tf.shape(self.z_mu))
            z = self.z_mu + tf.sqrt(self.z_var) * epsilon

        self.variable_summaries(z)
        concat = tf.layers.dense(
            inputs=z, units=2 * self.layers_size, name='project_state')
        state = tf.contrib.rnn.LSTMStateTuple(*tf.split(concat, 2, 1))

        kl_div = -0.5 * tf.reduce_sum(1.0 + tf.log(self.z_var) - tf.square(self.z_mu) - self.z_var,
                                      axis=1)
        self.kl_div = tf.reduce_mean(kl_div)

        tf.summary.scalar('KL_divergence_loss', self.kl_div)

        return state

    def _encoder(self, inputs):
        encoder_cell = self._cell(self.layers_size)
        encoder_outputs, encoder_state = tf.nn.dynamic_rnn(
            encoder_cell, inputs, dtype=self.dtype)

        return encoder_outputs, encoder_state

    def _decoder(self, inputs, state, is_train):
        decoder_cell = self._cell(self.layers_size, self.keep_prob)
        with tf.variable_scope('decoder'):
            self.sequence_length = tf.cast(
                tf.reduce_sum(self.weight, axis=1), tf.int32)

            train_helper = tf.contrib.seq2seq.TrainingHelper(
                inputs, self.sequence_length)
            inference_helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(
                self.embedding,
                tf.fill(
                    [self.batch_size], GO_ID),
                tf.constant(EOS_ID))

            project_layer = layers_core.Dense(self.embedding.get_shape()[
                                              0], name='output_project')
            def _create_decoder(helper):
                return tf.contrib.seq2seq.BasicDecoder(
                    cell=decoder_cell,
                    helper=helper,
                    initial_state=state,
                    output_layer=project_layer)  # initial state of decoder
            train_decoder = _create_decoder(train_helper)
            inference_decoder = _create_decoder(inference_helper)

        return tf.cond(is_train,
                       lambda: tf.contrib.seq2seq.dynamic_decode(
                           train_decoder, maximum_iterations=self.max_length),
                       lambda: tf.contrib.seq2seq.dynamic_decode(inference_decoder, maximum_iterations=self.max_length))

    def variable_summaries(self, var):
        """Attach a lot of summaries to a Tensor (for TensorBoard visualization)."""
        with tf.name_scope('summaries'):
            mean = tf.reduce_mean(var)
            tf.summary.scalar('mean', mean)
        with tf.name_scope('stddev'):
            stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
            tf.summary.scalar('stddev', stddev)
            tf.summary.scalar('max', tf.reduce_max(var))
            tf.summary.scalar('min', tf.reduce_min(var))
            tf.summary.histogram('histogram', var)

    def annealing_schedule(self, t, pivot):
        return tf.nn.sigmoid((t - pivot) / pivot * 10)

    def build_model(self, data_inputs, validate_inputs=None):
        with tf.Graph().as_default() as self.graph:
            # Placeholder
            self.global_step = tf.Variable(0, trainable=False)
            self.batch_size = tf.placeholder(
                tf.int32, shape=(), name='batch_size')
            self.annealing_pivot = tf.placeholder(
                tf.float32, shape=(), name='annealing_pivot')
            self.keep_prob = tf.placeholder(
                tf.float32, shape=(), name='keep_prob')
            self.is_train = tf.placeholder(tf.bool, shape=(), name='is_train')
            self.word_keeping = tf.placeholder(
                dtype=tf.float32, shape=(), name='word_keeping')
            self.l2_epsilon = tf.placeholder(
                dtype=tf.float32, shape=(), name='l2_epsilon')

            self.scale_kl_div = tf.placeholder(
                dtype=tf.float32, shape=(), name='scale_kl_div')

            self.coord = tf.train.Coordinator()
            self.generator_enqueue = generator_enqueue(
                self.coord, data_inputs, validate_inputs)
            encode_queue, decode_queue, weight_queue = self.generator_enqueue.get_queue(
                self.batch_size)

            self.encode_input = tf.placeholder_with_default(
                encode_queue, shape=[None, None], name='encode_input')
            self.decode_input = tf.placeholder_with_default(
                decode_queue, shape=[None, None], name='decode_input')
            self.weight = tf.placeholder_with_default(
                weight_queue, shape=[None, None], name='weigth')

            ###EMBEDDING###
            if self.init_embedding is not None:
                self.embedding = tf.get_variable("embedding",
                                                 initializer=self.init_embedding,
                                                 trainable=True)
            else:
                self.embedding = tf.get_variable("embedding",
                                                 [self.vocab_size, self.embedding_size])

            emb_encode = tf.nn.embedding_lookup(
                self.embedding, self.encode_input)

            # Word dropout

            random_tensor = self.word_keeping + \
                tf.random_uniform(shape=tf.shape(self.decode_input))
            binary_tensor = tf.floor(random_tensor)
            dropped_decode = tf.where(tf.greater(binary_tensor, 0),
                                      self.decode_input, tf.fill(tf.shape(self.decode_input), UNK_ID))
            emb_decode = tf.nn.embedding_lookup(self.embedding, dropped_decode)
            ###

            ###ENCODER###
            encoder_outputs, encoder_state = self._encoder(emb_encode)
            ###

            ###SAMPLING###
            sample = self._sample_posterior(encoder_state)
            ###

            ###DECODER###
            self.outputs, final_state, final_sequence_length = self._decoder(
                emb_decode, sample, self.is_train)
            ###

            # BUILD LOSS
            _logits = self.outputs.rnn_output

            tf.summary.histogram('output', self.outputs.sample_id)
            paddings = [[0, 0], [0, self.max_length -
                                 tf.shape(_logits)[1]], [0, 0]]
            logits = tf.pad(_logits, paddings, "CONSTANT")

            _target = self.decode_input[:, 1:]  # remove the start_token
            paddings = [[0, 0], [0, self.max_length - tf.shape(_target)[1]]]
            target = tf.pad(_target, paddings, "CONSTANT")

            paddings = [
                [0, 0], [0, self.max_length - tf.shape(self.weight)[1]]]
            padded_weight = tf.pad(self.weight, paddings, "CONSTANT")

            self.reconstruct_loss = tf.contrib.seq2seq.sequence_loss(
                logits, target, padded_weight)

            tf.summary.scalar('reconstruct_loss', self.reconstruct_loss)

            annealing_weight = self.annealing_schedule(
                tf.cast(self.global_step, tf.float32), self.annealing_pivot)
            # TOTAL LOSS
            self.total_loss = self.reconstruct_loss + annealing_weight * self.kl_div
            tf.summary.scalar('total_loss', self.total_loss)

            self.op = self._optimizer(self.total_loss)

            self.merged = tf.summary.merge_all()
            self.train_writer = tf.summary.FileWriter(self.tracking)
            self.init = tf.global_variables_initializer()
            self.saver = tf.train.Saver()
        return self

    def save(self, sess, model_dir=""):
        self.saver.save(sess, os.path.join(
            model_dir, 'dynamic_attention_decoder'), global_step=self.global_step)

    def load(self, sess, model_dir=""):
        ckpt = tf.train.get_checkpoint_state(model_dir)
        if ckpt and ckpt.model_checkpoint_path:
            print('success')
            self.saver.restore(sess, ckpt.model_checkpoint_path)
        else:
            print('fail')

    def validate(self, sess, inputs, batch_size=1, feed_dict={}):
        losses = 0
        for i in range(len(inputs) // batch_size):
            def pad(x):
                max_len = len(max(x, key=len))
                x = map(lambda y: (max_len - len(x)) * [0], x)
                return x
            batch_inputs = inputs[i * batch_size: (i + 1) * batch_size]
            weight_input = map(lambda x: [1.] * len(x), batch_inputs)
            decode_input = map(lambda x: [GO_ID] + x + [EOS_ID], batch_inputs)
            feed_dict[self.encode_input] = pad(batch_inputs)
            feed_dict[self.decode_input] = pad(decode_input)
            feed_dict[self.weight] = pad(weight_input)

            loss, = sess.run([self.total_loss], feed_dict=feed_dict)
            losses += loss
        return losses

    def train(self, sess):
        thread = threading.Thread(target=self.generator_enqueue.run, args=(
            sess, self.max_length, self.min_length))
        thread.daemon = True
        thread.start()
        self.coord.register_thread(thread)

    def stop_train(self, sess):
        self.coord.request_stop()


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)