#!/usr/bin/python3
"""
This module creates the Rectangle class which inherits from the base class.
"""
from models.base import Base

class Rectangle(Base):
    """
    This class is the rectangle class which inherits
    from the base class and which the Square class also
    inherits from
    """
    def __init__(self, width, height, x=0, y=0, id=None):
        super().__init__(id)
        self.width = width
        self.height = height
        self.x = x
        self.y = y

    @property
    def width(self):
        return self.__width

    @width.setter
    def width(self, value):
        if not isinstance(value, int):
            raise TypeError("width must be an integer")
        if value <= 0:
            raise ValueError("width must be > 0")
        self.__width = value

    @property
    def height(self):
        return self.__height

    @height.setter
    def height(self, value):
        if not isinstance(value, int):
            raise TypeError("height must be an integer")
        if value <= 0:
            raise ValueError("height must be > 0")
        self.__height = value

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, value):
        if not isinstance(value, int):
            raise TypeError("x must be an integer")
        if value < 0:
            raise ValueError("x must be >= 0")
        self.__x = value

    @property
    def y(self):
        return self.__y

    @y.setter
    def y(self, value):
        if not isinstance(value, int):
            raise TypeError("y must be an integer")
        if value < 0:
            raise ValueError("y must be >= 0")
        self.__y = value

    def area(self):
        """Calculate and return the area of the rectangle."""
        return self.__width * self.__height

    def display(self):
        """Print a representation of the rectangle with '#' characters."""
        for _ in range(self.__y):
            print()
        for _ in range(self.__height):
            print(" " * self.__x + "#" * self.__width)

    def __str__(self):
        """Return a string representation of the rectangle."""
        return f"[Rectangle] ({self.id}) {self.__x}/{self.__y} - \
            {self.__width}/{self.__height}"

    def to_dictionary(self):
        """Return a dictionary representation of the rectangle."""
        return {
            "id": self.id,
            "width": self.width,
            "height": self.height,
            "x": self.x,
            "y": self.y
        }


import re
from rpython.translator import exceptiontransform
from rpython.rtyper.annlowlevel import llhelper
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.tool.sourcetools import func_with_new_name
from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib.objectmodel import specialize
from pypy.interpreter.error import OperationError
from pypy.module._hpy_universal import llapi

class APISet(object):

    def __init__(self, cts, is_debug, prefix=r'^_?HPy_?', force_c_name=False):
        self.cts = cts
        self.is_debug = is_debug
        self.prefix = re.compile(prefix)
        self.force_c_name = force_c_name
        self.all_functions = []
        self.frozen = False

    def _freeze_(self):
        self.all_functions = unrolling_iterable(self.all_functions)
        self.frozen = True
        return True

    def parse_signature(self, cdecl, error_value):
        d = self.cts.parse_func(cdecl)
        ARGS = d.get_llargs(self.cts)
        RESULT = d.get_llresult(self.cts)
        FUNC = lltype.Ptr(lltype.FuncType(ARGS, RESULT))
        return d.name, FUNC, self.get_ll_errval(d, FUNC, error_value)

    def get_ll_errval(self, d, FUNC, error_value):
        c_result_t = d.tp.result.get_c_name() # a string such as "HPy" or "void"
        if error_value is None:
            # automatically determine the error value from the return type
            if c_result_t == 'HPy':
                return 0
            elif c_result_t == 'void':
                return None
            elif isinstance(FUNC.TO.RESULT, lltype.Ptr):
                return lltype.nullptr(FUNC.TO.RESULT.TO)
            else:
                raise Exception(
                    "API function %s: you must explicitly specify an error_value "
                    "for functions returning %s" % (d.name, c_result_t))
        elif error_value == 'CANNOT_FAIL':
            # we need to specify an error_value anyway, let's just use the
            # exceptiontransform default
            return exceptiontransform.default_error_value(FUNC.TO.RESULT)
        else:
            assert c_result_t != 'HPy' # sanity check
            if lltype.typeOf(error_value) != FUNC.TO.RESULT:
                raise Exception(
                    "API function %s: the specified error_value has the "
                    "wrong lltype: expected %s, got %s" % (d.name, FUNC.TO.RESULT,
                                                           lltype.typeOf(error_value)))
            return error_value

    def func(self, cdecl, cpyext=False, func_name=None, error_value=None):
        """
        Declare an HPy API function.

        If the function is marked as cpyext=True, it will be included in the
        translation only if pypy.objspace.hpy_cpyext_API==True (the
        default). This is useful to exclude cpyext in test_ztranslation

        If func_name is given, the decorated function will be automatically
        renamed. Useful for automatically generated code, for example in
        interp_number.py

        error_value specifies the C value to return in case the function
        raises an RPython exception. The default behavior tries to be smart
        enough to work in the most common and standardized cases, but without
        guessing in case of doubts.  In particular, there is no default
        error_value for "int" functions, because CPython's behavior is not
        consistent.

        error_value can be:

            - None (the default): automatically determine the error value. It
              works only for the following return types:
                  * HPy: 0
                  * void: None
                  * pointers: NULL

            - 'CANNOT_FAIL': special string to specify that this function is
              not supposed to fail.

            - a specific value: in this case, the lltype must exactly match
              what is specified for the function type.
        """
        if self.frozen:
            raise RuntimeError(
                'Too late to call @api.func(), the API object has already been frozen. '
                'If you are calling @api.func() to decorate module-level functions, '
                'you might solve this by making sure that the module is imported '
                'earlier')
        def decorate(fn):
            from pypy.module._hpy_universal.state import State
            name, ll_functype, ll_errval = self.parse_signature(cdecl, error_value)
            if name != fn.__name__:
                raise ValueError(
                    'The name of the function and the signature do not match: '
                    '%s != %s' % (name, fn.__name__))
            #
            if func_name is not None:
                fn = func_with_new_name(fn, func_name)
            #
            # attach various helpers to fn, so you can access things like
            # HPyNumber_Add.get_llhelper(), HPyNumber_Add.basename, etc.

            # get_llhelper
            @specialize.memo()
            def make_wrapper(space):
                def wrapper(*args):
                    state = space.fromcache(State)
                    handles = state.get_handle_manager(self.is_debug)
                    try:
                        return fn(space, handles, *args)
                    except OperationError as e:
                        state.set_exception(e)
                        return ll_errval
                wrapper.__name__ = 'ctx_%s' % fn.__name__
                if self.force_c_name:
                    wrapper.c_name = fn.__name__
                return wrapper
            def get_llhelper(space):
                return llhelper(ll_functype, make_wrapper(space))
            get_llhelper.__name__ = 'get_llhelper_%s' % fn.__name__
            fn.get_llhelper = get_llhelper

            # basename
            fn.basename = self.prefix.sub(r'', fn.__name__)

            fn.cpyext = cpyext
            # record it into the API
            self.all_functions.append(fn)
            return fn
        return decorate

    @staticmethod
    def int(x):
        """
        Helper method to convert an RPython Signed into a C int
        """
        return rffi.cast(rffi.INT_real, x)

    @staticmethod
    def cast(typename, x):
        """
        Helper method to convert an RPython value into the correct C return
        type.
        """
        lltype = llapi.cts.gettype(typename)
        return rffi.cast(lltype, x)

    @staticmethod
    def ccharp2text(space, ptr):
        """
        Convert a C const char* into a W_UnicodeObject
        """
        s = rffi.constcharp2str(ptr)
        return space.newtext(s)

API = APISet(llapi.cts, is_debug=False)
DEBUG = APISet(llapi.cts, is_debug=True)


from pdf2image import convert_from_path
import os
from PIL import Image
import logging
import concurrent.futures

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def convert_pdf_to_image(pdf_path, output_folder, output_size=(1920, 2560)): # attention
    # Check if the file is a PDF (case-insensitive)
    if pdf_path.lower().endswith('.pdf'):
        try:
            # Convert the first page of the PDF to an image
            images = convert_from_path(pdf_path, first_page=1, last_page=1)

            # Save the image
            for i, image in enumerate(images):
                # Create the output file path
                base_name = os.path.basename(pdf_path)
                name_without_ext = os.path.splitext(base_name)[0]
                image_path = os.path.join(output_folder, f"{name_without_ext}.jpg")

                # Resize the image
                image.thumbnail(output_size, Image.LANCZOS)

                # Save the image
                image.save(image_path, 'JPEG')

            logger.info(f'Successfully converted {pdf_path} to image and saved at {image_path}')

        except Exception as e:
            logger.error(f'Failed to convert {pdf_path} to image: {e}')

def parallel_convert_pdf_to_image(pdf_folder, output_folder, output_size=(1920, 2560)): # attention
    # Create 'images' directory if it does not exist
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # Get all PDF files in the folder
    pdf_files = [os.path.join(pdf_folder, filename) for filename in os.listdir(pdf_folder) if filename.lower().endswith('.pdf')]

    # Use a ThreadPoolExecutor to parallelize the conversion process
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.map(convert_pdf_to_image, pdf_files, [output_folder]*len(pdf_files), [output_size]*len(pdf_files))

# Usage
parallel_convert_pdf_to_image('./pdfs_1077', './images_1920_2560') # attention

# 1280, 1600
# 1440, 1920
# 1920, 2560

# 1080, 1440
# 1140, 1520
# 1260, 1680
# 1320, 1760
# 1380, 1840
# 1500, 2000
# 1560, 2080
# 1620, 2160
# 1680, 2240
# 1740, 2320
# 1800, 2400
# 1860, 2480


# This Recommender class is based on repo https://github.com/bhaskatripathi/pdfGPT
# Which is the main source of inspiration for this project.

import os
import tensorflow_hub as hub
import numpy as np
from utils import pdf_to_chunks, translate_text
from RecursiveSummarizer import RecursiveSummarizer
from OpenAIManager import OpenAIManager

class Recommender:
    def __init__(self, openAI_key):
        embeddings_qa_encoder = hub.load('https://tfhub.dev/google/universal-sentence-encoder/3')
        self.embeddings_q_encoder  = embeddings_qa_encoder.signatures['question_encoder']
        self.embeddings_a_encoder  = embeddings_qa_encoder.signatures['response_encoder']

        self.open_ai_manager = OpenAIManager(openAI_key)
        self.recursive_summarizer = RecursiveSummarizer(openAI_key)

    def get_answer_embeddings(self, chunks, batch=1000):
        embeddings = []
        for i in range(0, len(chunks), batch):
            chunks_batch = chunks[i:(i+batch)]
            emb_batch = self.embeddings_a_encoder(chunks_batch)
            embeddings.append(emb_batch)
        embeddings = np.vstack(embeddings)
        return embeddings

    def save_embeddings_for_chunks(self, chunks, batch=1000, n_neighbors=5):
        self.chunks = chunks
        self.embeddings = self.get_answer_embeddings(chunks, batch=batch)
        n_neighbors = min(n_neighbors, len(self.embeddings))
        self.nn = NearestNeighbors(n_neighbors=n_neighbors)
        self.nn.fit(self.embeddings)

    def search(self, text):
        inp_emb = self.embeddings_q_encoder([text])
        neighbors = self.nn.kneighbors(inp_emb, return_distance=False)[0]
        return [self.chunks[i] for i in neighbors]

    def load(self, path):
      pdf_file = os.path.basename(path)
      embeddings_file = f"{pdf_file}.npy"

      if os.path.isfile(embeddings_file):
          embeddings = np.load(embeddings_file)
          self.embeddings = embeddings
          return "Embeddings loaded from file"

      chunks = pdf_to_chunks(path, self.recursive_summarizer)
      self.save_embeddings_for_chunks(chunks)
      np.save(embeddings_file, self.embeddings)
      return 'Corpus Loaded.'

    def question_answer(self, file, question):
        if file == None:
            return '[ERROR]: PDF is empty. Provide one.'

        old_file_name = file.name
        file_name = file.name
        file_name = file_name[:-12] + file_name[-4:]
        os.rename(old_file_name, file_name)
        self.load(file_name)

        if question.strip() == '':
            return '[ERROR]: Question field is empty'

        return self.generate_answer(question)

    def get_additional_answers(self, prompt):
        prompt_for_additional_questions = (
            prompt
            + "Instructions: You are given a query and a set of search results. "
            + "It must be enough to compose a comprehensive answer to the query without any "
            + "additional knowledge using search results. Your goal is to provide 1 to 5 additional questions "
            + "to be answered in order to make search results full enough to compose answer to query. " +
            + "Feel free to ask about language syntax, additional conditions, theory, ask for examples, etc. " +
            + "If you provide additional questions make them short and concise. Start each question with \"Q:\"."
        )
        answer = self.open_ai_manager.get_answer(prompt_for_additional_questions)
        if ('Q:' not in answer):
            return ''
        additional_questions = answer.split('Q:')[1:]
        prompt += "\nAdditional Help Questions:\n"
        for additional_question in additional_questions:
            topn_chunks = self.search(additional_question)
            top_chunk   = topn_chunks[0]
            prompt += f"Q: {additional_question}\nA: {top_chunk}\n\n"
        return prompt

    def generate_answer(self, question):
        question = translate_text(question)
        topn_chunks = self.search(question)
        prompt = ""
        prompt += 'search results:\n\n'
        for c in topn_chunks:
            prompt += c + '\n\n'

        prompt = self.get_additional_answers(prompt + f"Query: {question}\n")

        prompt += "Instructions: Compose a comprehensive reply to the query using the search results given. "\
                  "Cite each reference using [Page Number] notation (every result has number). "\
                  "Citation should be done at the end of each sentence. If the search results mention multiple subjects "\
                  "with the same name, create separate answers for each.  Make sure the answer is correct and don't output false. "\
                  "Ignore results which has nothing to do with the question. Only answer what is asked. "\
                  "Provide additional explanations or examples if asked by user. "\
                  "The answer should be short and concise. Answer step-by-step. \n\nQuery: {question}\nAnswer: "

        print(prompt)

        answer = self.open_ai_manager.get_answer(prompt)
        return answer


import json as js

item = {
	"name" : "Johntavious",
	"age" : "22",
	"classes" : ["Junior Design", "Algorithms", "Prob/Stat", "Comp Sys Arch"],
	"Institution" : "Georgia Tech",
	"players_rank" : {
			1 : "Kyrie",
			2 : "Lebron",
			3 : "PG-13",
			4 : "Kobe"
		}
}
# source = open('data.json', 'r')
# json_obj = js.load(source)

with open("data.json", "w") as f:
	js.dump(item, f, indent=4);

# print(json_obj["name"])
# players = json_obj["players_rank"] #returns a map

# print(players);


import pyautogui
import time
import random

# time.sleep(5)
# pyautogui.press("down")
def uparrow():
    time.sleep(5)
    pyautogui.press("up")

def downarrow():
    time.sleep(5)
    pyautogui.press("Down")

def like():
    time.sleep(5)
    # pyautogui.press("l")
    start = pyautogui.locateCenterOnScreen('liked.png')#If the file is not a png file it will not work
    # print(start)
    if start:
        print("already Liked")
    else:
        print("Bot liked")
        pyautogui.press("l")

# like()
commentlist = ["🏆🏆🏆", "king 👑", "Drop it 🔥" ,
                "Wow " , "Dope" , "💪💪" ,"👍👍","Fireeee" , "My man👑" ,
                "❤❤❤" ,"Hell yeah" , "Lets goooooo ❤🔥❤🔥" ,
                "Wooo" , "Dope af" , "crazy af 💞",
                "won my heard", "Bro drop this asap",
                "Sad for those who havnt yet discovered this music",
                "Sin the best", "God level", "💪💪" , "🙏🙏🙏", "Weeeew 🙂" ,
                "Greateeee", "Real Barz" ,"Rap Gold", "This is some real ..." ,
                "Holly Molly"]

def writeComment():
    int  = random.randint(0,len(commentlist)-1)
    # print(int,":" ,commentlist[int])
    comment = commentlist[int]
    time.sleep(4)
    commentarea = pyautogui.locateCenterOnScreen("realcomment.png")
    pyautogui.moveTo(commentarea)
    print(commentarea)

    time.sleep(1)
    pyautogui.leftClick()
    time.sleep(1)
    pyautogui.typewrite(comment)
    pyautogui.press("enter")
    print("entered")

    # to get out of the comment section.

# change over here
# we can fetch the video count somehow. and store it in totalVideos Variable.
totalVideos = 53
def mainup():
    counter =0
    Up =True
    while Up:
        counter +=1
        if counter<totalVideos:
            uparrow()
        else:
            print("No More Up")
            up = False
            maindown()

def maindown():
    counter =0
    Down =True
    while Down:
        counter +=1
        like()
        # writeComment()
        # time.sleep(1)
        # pyautogui.press("tab")
        if counter<totalVideos:
            downarrow()
        else:
            print("No More down")
            mainup()
            Down = False

maindown()


""" Implements discriminative loss for autoencoder. """
import torch
import torch.nn as nn

class DRAELossAutograd(nn.Module):

    def __init__(self, lamb, size_average=True):
        super(DRAELossAutograd, self).__init__()
        self.lamb = lamb
        self.size_average = size_average  # for compatibility, not used

    def forward(self, inputs, targets):
        err = inputs.sub(targets).pow(2).view(inputs.size(0), -1).sum(dim=1, keepdim=False)
        err_sorted, _ = torch.sort(err)
        total_scatter = err.sub(err.mean()).pow(2).sum()
        regul = 1e6
        obj = None
        for i in range(inputs.size(0)-1):
            err_in = err_sorted[:i+1]
            err_out = err_sorted[i+1:]
            within_scatter = err_in.sub(err_in.mean()).pow(2).sum() + \
                             err_out.sub(err_out.mean()).pow(2).sum()
            h = within_scatter.div(total_scatter)
            if h < regul:
                regul = h
                obj = err_in.mean()

        return obj + self.lamb * regul


# -*- coding: utf-8 -*-
# Author:tomorrow505

import tkinter as tk
from tkinter import Label, Entry, Button, StringVar, messagebox, LEFT
from tkinter.filedialog import askdirectory
import os
import json
from utils import commen_component

CONFIG_DL_PATH = './conf/config_dl.json'

class ConfigDlPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        self.config_dl = self.controller.config_dl

        self.label_1 = Label(self, text="**多个目录均衡硬盘容量，缓存用于存储少量临时文件**", fg='red', font=("Helvetica", 12))
        self.label_2 = Label(self, text="学习资源：", font=("Helvetica", 10))
        self.label_3 = Label(self, text="影视娱乐：", font=("Helvetica", 10))
        self.label_4 = Label(self, text="动画动漫：", font=("Helvetica", 10))
        self.label_5 = Label(self, text="其他资源：", font=("Helvetica", 10))
        self.label_6 = Label(self, text="缓存目录：", font=("Helvetica", 10))

        self.var_2 = StringVar()
        self.var_3 = StringVar()
        self.var_4 = StringVar()
        self.var_5 = StringVar()
        self.var_6 = StringVar()

        self.entry_2 = Entry(self, textvariable=self.var_2, width=70, borderwidth=3, font=('Helvetica', '14'))
        self.entry_3 = Entry(self, textvariable=self.var_3, width=70, borderwidth=3, font=('Helvetica', '14'))
        self.entry_4 = Entry(self, textvariable=self.var_4, width=70, borderwidth=3, font=('Helvetica', '14'))
        self.entry_5 = Entry(self, textvariable=self.var_5, width=70, borderwidth=3, font=('Helvetica', '14'))
        self.entry_6 = Entry(self, textvariable=self.var_6, width=70, borderwidth=3, font=('Helvetica', '14'))

        self.button_2 = Button(self, text="...", command=self.select_folder_study)
        self.button_3 = Button(self, text="...", command=self.select_folder_movie)
        self.button_4 = Button(self, text="...", command=self.select_folder_carton)
        self.button_5 = Button(self, text="...", command=self.select_folder_others)
        self.button_6 = Button(self, text="...", command=self.select_folder_cache)

        self.frame = tk.LabelFrame(self, text='更多配置', height=200, width=200)

        self.bool_check_rss = tk.IntVar()
        self.bool_check_anony = tk.IntVar()
        self.bool_check_server = tk.IntVar()

        self.check_rss = tk.Checkbutton(self.frame, text='是否开启RSS（默认关闭）', variable=self.bool_check_rss,
                                        command=self.check_rss, anchor=tk.W)
        self.check_anony = tk.Checkbutton(self.frame, text='是否关闭匿名（默认匿名）', variable=self.bool_check_anony,
                                          command=self.check_anony, anchor=tk.W)
        self.check_server = tk.Checkbutton(self.frame, text='是否开启服务器（默认关闭）', variable=self.bool_check_server,
                                           command=self.check_server, anchor=tk.W)

        self.var_port = tk.StringVar()
        self.label_port = tk.Label(self.frame, text='端口：', anchor=tk.W)
        self.ertry_port = tk.Entry(self.frame, textvariable=self.var_port)

        self.var_ip = tk.StringVar()
        self.label_ip = tk.Label(self.frame, text='主机地址：', anchor=tk.W)
        self.ertry_ip = tk.Entry(self.frame, textvariable=self.var_ip)

        self.var_refresh_time = tk.StringVar()
        self.label_refresh_time = tk.Label(self.frame, text='间隔：', anchor=tk.W)
        self.ertry_refresh_time = tk.Entry(self.frame, textvariable=self.var_refresh_time)

        self.button_submit = Button(self, text="确定", command=self.submit_configur_dl)
        self.button_reset = Button(self, text="重置", command=self.cancel)

        self.create_page()

    def create_page(self):
        self.label_1.pack(side="top", fill="x", pady=15)

        self.label_2.place(x=0, y=48, width=160, height=30)
        self.entry_2.place(x=125, y=48, width=520, height=30)
        self.button_2.place(x=660, y=46, width=20, height=30)

        self.label_3.place(x=0, y=88, width=160, height=30)
        self.entry_3.place(x=125, y=88, width=520, height=30)
        self.button_3.place(x=660, y=86, width=20, height=30)

        self.label_4.place(x=0, y=128, width=160, height=30)
        self.entry_4.place(x=125, y=128, width=520, height=30)
        self.button_4.place(x=660, y=126, width=20, height=30)

        self.label_5.place(x=0, y=168, width=160, height=30)
        self.entry_5.place(x=125, y=168, width=520, height=30)
        self.button_5.place(x=660, y=166, width=20, height=30)

        self.label_6.place(x=0, y=208, width=160, height=30)
        self.entry_6.place(x=125, y=208, width=520, height=30)
        self.button_6.place(x=660, y=206, width=20, height=30)

        self.button_submit.place(x=280, y=420, width=70, height=30)
        self.button_reset.place(x=420, y=420, width=70, height=30)

        self.frame.place(x=50, y=266, width=630, height=120)

        self.check_anony.place(x=40, y=55, width=180, height=30)
        self.check_rss.place(x=270, y=55, width=180, height=30)
        self.check_server.place(x=40, y=20, width=180, height=30)

        self.label_ip.place(x=270, y=20, width=60, height=30)
        self.ertry_ip.place(x=330, y=22, width=120, height=25)
        self.label_port.place(x=470, y=20, width=60, height=30)
        self.ertry_port.place(x=510, y=22, width=50, height=25)

        self.label_refresh_time.place(x=470, y=55, width=60, height=30)
        self.ertry_refresh_time.place(x=510, y=57, width=50, height=25)

        self.var_2.set(self.config_dl['study_path'])
        self.var_3.set(self.config_dl['movie_path'])
        self.var_4.set(self.config_dl['carton_path'])
        self.var_5.set(self.config_dl['others_path'])
        self.var_6.set(self.config_dl['cache_path'])

        self.var_ip.set(self.config_dl['server_ip'])
        self.var_port.set(self.config_dl['server_port'])
        self.var_refresh_time.set(self.config_dl['refresh_time'])

        self.bool_check_rss.set(self.config_dl['rss_open'])
        self.bool_check_server.set(self.config_dl['server_open'])
        self.bool_check_anony.set(self.config_dl['anony_close'])

        if not self.bool_check_server.get():
            self.ertry_port.config(state='readonly')
            self.ertry_ip.config(state='readonly')
        if not self.bool_check_rss.get():
            self.ertry_refresh_time.config(state='readonly')

    def select_folder_study(self):
        path_ = askdirectory()
        self.var_2.set(path_)

    def select_folder_movie(self):
        path_ = askdirectory()
        self.var_3.set(path_)

    def select_folder_carton(self):
        path_ = askdirectory()
        self.var_4.set(path_)

    def select_folder_others(self):
        path_ = askdirectory()
        self.var_5.set(path_)

    def select_folder_cache(self):
        path_ = askdirectory()
        self.var_6.set(path_)

    def submit_configur_dl(self):
        study_path = self.var_2.get()
        movie_path = self.var_3.get()
        carton_path = self.var_4.get()
        others_path = self.var_5.get()
        cache_path = self.var_6.get()

        img_path = cache_path + '/imgs'

        folder = os.path.exists(img_path)
        if not folder:
            os.makedirs(img_path)

        port = self.var_port.get()
        ip = self.var_ip.get()

        self.config_dl['study_path'] = study_path
        self.config_dl['movie_path'] = movie_path
        self.config_dl['carton_path'] = carton_path
        self.config_dl['others_path'] = others_path
        self.config_dl['img_path'] = img_path
        self.config_dl['cache_path'] = cache_path
        self.config_dl['rss_open'] = self.bool_check_rss.get()
        old_refresh_time =  self.config_dl['refresh_time']
        self.config_dl['refresh_time'] = self.var_refresh_time.get()
        self.config_dl['server_open'] = self.bool_check_server.get()
        self.config_dl['anony_close'] = self.bool_check_anony.get()
        self.config_dl['server_port'] = port
        self.config_dl['server_ip'] = ip

        with open(CONFIG_DL_PATH, 'w') as f:
            json.dump(self.config_dl, f)

        self.controller.config_dl = commen_component.load_config_dl()
        self.controller.frames['AutoUploadPage'].config_dl = commen_component.load_config_dl()
        self.controller.frames['HandUploadPage'].config_dl = commen_component.load_config_dl()
        self.controller.check_remote_server()
        result = self.controller.frames['AutoUploadPage'].check_rss_mode()

        if int(old_refresh_time) != int(self.config_dl['refresh_time']) and result == 'opened_already':
            self.controller.frames['AutoUploadPage'].reopen_rss()
        # messagebox.showinfo('提示', '配置完成！')

    def cancel(self):
        self.var_2.set('')
        self.var_3.set('')
        self.var_4.set('')
        self.var_5.set('')
        self.var_6.set('')
        if self.bool_check_anony.get() == 1:
            self.bool_check_anony.set(0)
        if self.bool_check_server.get() == 1:
            self.bool_check_server.set(0)
        if self.bool_check_rss.get() == 1:
            self.bool_check_rss.set(0)
        self.var_ip.set('')
        self.var_port.set('')
        self.ertry_port.config(state='readonly')
        self.ertry_ip.config(state='readonly')

    def check_rss(self):
        if not self.bool_check_rss.get():
            self.ertry_refresh_time.config(state='readonly')
        else:
            self.ertry_refresh_time.config(state='normal')

    def check_server(self):
        if not self.bool_check_server.get():
            self.ertry_port.config(state='readonly')
            self.ertry_ip.config(state='readonly')
        else:
            self.ertry_port.config(state='normal')
            self.ertry_ip.config(state='normal')

    def check_anony(self):
        if self.bool_check_anony:
            pass
        else:
            pass


# app.py
from flask import Flask, request
from flask_restx import Api, Resource
from flask_sqlalchemy import SQLAlchemy
from marshmallow import Schema, fields

app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['RESTX_JSON'] = {'ensure_ascii': False}

db = SQLAlchemy(app)

class Movie(db.Model):
    __tablename__ = 'movie'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(255))
    description = db.Column(db.String(255))
    trailer = db.Column(db.String(255))
    year = db.Column(db.Integer)
    rating = db.Column(db.Float)
    genre_id = db.Column(db.Integer, db.ForeignKey("genre.id"))
    genre = db.relationship("Genre")
    director_id = db.Column(db.Integer, db.ForeignKey("director.id"))
    director = db.relationship("Director")

class Director(db.Model):
    __tablename__ = 'director'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))

class Genre(db.Model):
    __tablename__ = 'genre'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))

class GenreSchema(Schema):
    id = fields.Int()
    name = fields.Str()

class DirectorSchema(Schema):
    id = fields.Int()
    name = fields.Str()

class MovieSchema(Schema):
    id = fields.Int()
    title = fields.Str()
    description = fields.Str()
    trailer = fields.Str()
    year = fields.Int()
    rating = fields.Int()
    genre = fields.Nested(GenreSchema)
    director = fields.Nested(DirectorSchema)

movie_schema = MovieSchema()
movies_schema = MovieSchema(many=True)

genre_schema = GenreSchema()
genres_schema = GenreSchema(many=True)

director_schema = DirectorSchema()
directors_schema = DirectorSchema(many=True)

api = Api(app)
movie_ns = api.namespace('movies')
director_ns = api.namespace('directors')
genre_ns = api.namespace('genres')

@movie_ns.route('/')
# наследуем класс от класса Resource
class MovieView(Resource):
    def post(self):
        req_json = request.json
        new_movie = Movie(**req_json)
        with db.session.begin():
            db.session.add(new_movie)
        return "", 201

    def get(self):
        director_id = request.args.get("director_id")
        genre_id = request.args.get("genre_id")
        query = Movie.query
        if director_id:
            query = query.filter(Movie.director_id == director_id)
        if genre_id:
            query = query.filter(Movie.genre_id == genre_id)
        return MovieSchema(many=True).dump(query.all()), 200

@movie_ns.route('/<int:uid>')
class MovieView(Resource):
# получение конкретной сущности по идентификатору
    def get(self, uid: int):
        try:
            movie = Movie.query.get(uid)
            return movie_schema.dump(movie), 200
        except Exception as e:
            return "", 404

    def put(self, uid: int):
        movie = Movie.query.get(uid)
        req_json = request.json
        movie.title = req_json.get("title")
        movie.description = req_json.get("description")
        movie.trailer = req_json.get("trailer")
        movie.year = req_json.get("year")
        movie.rating = req_json.get("rating")
        movie.genre_id = req_json.get("genre_id")
        movie.director_id = req_json.get("director_id")
        db.session.add(movie)
        db.session.commit()
        return "", 204

    def delete(self, uid: int):
        movie = Movie.query.get(uid)
        db.session.delete(movie)
        db.session.commit()
        return "", 204

#получение фильмов с определенным режиссеро
@director_ns.route('/')
class DirectorView(Resource):
    def get(self):
        all_directors = Director.query.all()
        return directors_schema.dump(all_directors), 200

    def post(self):
        req_json = request.json
        new_director = Director(**req_json)
        with db.session.begin():
            db.session.add(new_director)
        return "", 201

@director_ns.route('/<int:uid>')
class DirectorView(Resource):
    def get(self, uid: int):

        director = Director.query.get(uid)
        return director_schema.dump(director), 200

    def put(self, uid: int):
        director = Director.query.get(uid)
        req_json = request.json
        director.name = req_json.get("name")
        db.session.add(director)
        db.session.commit()
        return "", 204

    def delete(self, uid: int):
        director = Director.query.get(uid)
        db.session.delete(director)
        db.session.commit()
        return "", 204

@genre_ns.route('/')
class GenreView(Resource):
    def get(self):
      all_genres = Genre.query.all()
      return genres_schema.dump(all_genres), 200

    def post(self):
        req_json = request.json
        new_genre = Genre(**req_json)
        with db.session.begin():
            db.session.add(new_genre)
        return "", 201

@genre_ns.route('/<int:uid>')
class GenreView(Resource):
    def get(self, uid: int):
        genre = Genre.query.get(uid)
        return genre_schema.dump(genre)

    def put(self, uid: int):
        genre = Genre.query.get(uid)
        req_json = request.json
        genre.name = req_json.get("name")
        db.session.add(genre)
        db.session.commit()
        return "", 204

    def delete(self, uid: int):
        genre = Genre.query.get(uid)
        db.session.delete(genre)
        db.session.commit()
        return "", 204

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


import logging
import pytz

from odoo import _, api, fields, models
from odoo.addons.base.models.res_partner import _tz_get
from odoo.tools import format_datetime
from odoo.exceptions import ValidationError
from odoo.tools.translate import html_translate

_logger = logging.getLogger(__name__)

try:
    import vobject
except ImportError:
    _logger.warning("`vobject` Python module not found, iCal file generation disabled. Consider installing this module if you want to generate iCal files")
    vobject = None

class EventType(models.Model):
    _name = 'event.type'
    _description = 'Event Category'
    _order = 'sequence, id'

    @api.model
    def _get_default_event_type_mail_ids(self):
        return [(0, 0, {
            'notification_type': 'mail',
            'interval_unit': 'now',
            'interval_type': 'after_sub',
            'template_id': self.env.ref('event.event_subscription').id,
        }), (0, 0, {
            'notification_type': 'mail',
            'interval_nbr': 10,
            'interval_unit': 'days',
            'interval_type': 'before_event',
            'template_id': self.env.ref('event.event_reminder').id,
        })]

    name = fields.Char('Event Category', required=True, translate=True)
    sequence = fields.Integer()
    # registration
    has_seats_limitation = fields.Boolean('Limited Seats')
    default_registration_min = fields.Integer(
        'Minimum Registrations', default=0,
        help="It will select this default minimum value when you choose this event")
    default_registration_max = fields.Integer(
        'Maximum Registrations', default=0,
        help="It will select this default maximum value when you choose this event")
    auto_confirm = fields.Boolean(
        'Automatically Confirm Registrations', default=True,
        help="Events and registrations will automatically be confirmed "
             "upon creation, easing the flow for simple events.")
    # location
    is_online = fields.Boolean(
        'Online Event', help='Online events like webinars do not require a specific location and are hosted online.')
    use_timezone = fields.Boolean('Use Default Timezone')
    default_timezone = fields.Selection(
        _tz_get, string='Timezone', default=lambda self: self.env.user.tz or 'UTC')
    # communication
    use_hashtag = fields.Boolean('Use Default Hashtag')
    default_hashtag = fields.Char('Twitter Hashtag')
    use_mail_schedule = fields.Boolean(
        'Automatically Send Emails', default=True)
    event_type_mail_ids = fields.One2many(
        'event.type.mail', 'event_type_id', string='Mail Schedule',
        copy=False,
        default=lambda self: self._get_default_event_type_mail_ids())

    @api.onchange('has_seats_limitation')
    def _onchange_has_seats_limitation(self):
        if not self.has_seats_limitation:
            self.default_registration_min = 0
            self.default_registration_max = 0

class EventEvent(models.Model):
    """Event"""
    _name = 'event.event'
    _description = 'Event'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _order = 'date_begin'

    def _get_default_stage_id(self):
        event_stages = self.env['event.stage'].search([])
        return event_stages[0] if event_stages else False

    name = fields.Char(string='Event', translate=True, required=True)
    note = fields.Text(string='Note')
    description = fields.Html(string='Description', translate=html_translate, sanitize_attributes=False)
    active = fields.Boolean(default=True)
    user_id = fields.Many2one(
        'res.users', string='Responsible', tracking=True,
        default=lambda self: self.env.user)
    company_id = fields.Many2one(
        'res.company', string='Company', change_default=True,
        default=lambda self: self.env.company,
        required=False)
    organizer_id = fields.Many2one(
        'res.partner', string='Organizer', tracking=True,
        default=lambda self: self.env.company.partner_id,
        domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
    event_type_id = fields.Many2one('event.type', string='Category', ondelete='set null')
    color = fields.Integer('Kanban Color Index')
    event_mail_ids = fields.One2many('event.mail', 'event_id', string='Mail Schedule', copy=True)
    # Kanban fields
    kanban_state = fields.Selection([('normal', 'In Progress'), ('done', 'Done'), ('blocked', 'Blocked')])
    kanban_state_label = fields.Char(compute='_compute_kanban_state_label', string='Kanban State Label', tracking=True, store=True)
    stage_id = fields.Many2one(
        'event.stage', ondelete='restrict', default=_get_default_stage_id,
        group_expand='_read_group_stage_ids', tracking=True)
    legend_blocked = fields.Char(related='stage_id.legend_blocked', string='Kanban Blocked Explanation', readonly=True)
    legend_done = fields.Char(related='stage_id.legend_done', string='Kanban Valid Explanation', readonly=True)
    legend_normal = fields.Char(related='stage_id.legend_normal', string='Kanban Ongoing Explanation', readonly=True)
    # Seats and computation
    seats_max = fields.Integer(
        string='Maximum Attendees Number',
        help="For each event you can define a maximum registration of seats(number of attendees), above this numbers the registrations are not accepted.")
    seats_availability = fields.Selection(
        [('limited', 'Limited'), ('unlimited', 'Unlimited')],
        'Maximum Attendees', required=True, default='unlimited')
    seats_min = fields.Integer(
        string='Minimum Attendees',
        help="For each event you can define a minimum reserved seats (number of attendees), if it does not reach the mentioned registrations the event can not be confirmed (keep 0 to ignore this rule)")
    seats_reserved = fields.Integer(
        string='Reserved Seats',
        store=True, readonly=True, compute='_compute_seats')
    seats_available = fields.Integer(
        string='Available Seats',
        store=True, readonly=True, compute='_compute_seats')
    seats_unconfirmed = fields.Integer(
        string='Unconfirmed Seat Reservations',
        store=True, readonly=True, compute='_compute_seats')
    seats_used = fields.Integer(
        string='Number of Participants',
        store=True, readonly=True, compute='_compute_seats')
    seats_expected = fields.Integer(
        string='Number of Expected Attendees',
        compute_sudo=True, readonly=True, compute='_compute_seats')
    # Registration fields
    auto_confirm = fields.Boolean(string='Autoconfirm Registrations')
    registration_ids = fields.One2many('event.registration', 'event_id', string='Attendees')
    event_registrations_open = fields.Boolean('Registration open', compute='_compute_event_registrations_open')
    # Date fields
    date_tz = fields.Selection(
        _tz_get, string='Timezone', required=True,
        default=lambda self: self.env.user.tz or 'UTC')
    date_begin = fields.Datetime(string='Start Date', required=True, tracking=True)
    date_end = fields.Datetime(string='End Date', required=True, tracking=True)
    date_begin_located = fields.Char(string='Start Date Located', compute='_compute_date_begin_tz')
    date_end_located = fields.Char(string='End Date Located', compute='_compute_date_end_tz')
    is_one_day = fields.Boolean(compute='_compute_field_is_one_day')
    # Location and communication
    is_online = fields.Boolean('Online Event')
    address_id = fields.Many2one(
        'res.partner', string='Location', tracking=True,
        default=lambda self: self.env.company.partner_id,
        domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]")
    country_id = fields.Many2one('res.country', 'Country',  related='address_id.country_id', store=True, readonly=False)
    twitter_hashtag = fields.Char('Twitter Hashtag')
    # badge fields
    badge_front = fields.Html(string='Badge Front')
    badge_back = fields.Html(string='Badge Back')
    badge_innerleft = fields.Html(string='Badge Inner Left')
    badge_innerright = fields.Html(string='Badge Inner Right')
    event_logo = fields.Html(string='Event Logo')

    @api.depends('seats_max', 'registration_ids.state')
    def _compute_seats(self):
        """ Determine reserved, available, reserved but unconfirmed and used seats. """
        # initialize fields to 0
        for event in self:
            event.seats_unconfirmed = event.seats_reserved = event.seats_used = event.seats_available = 0
        # aggregate registrations by event and by state
        if self.ids:
            state_field = {
                'draft': 'seats_unconfirmed',
                'open': 'seats_reserved',
                'done': 'seats_used',
            }
            query = """ SELECT event_id, state, count(event_id)
                        FROM event_registration
                        WHERE event_id IN %s AND state IN ('draft', 'open', 'done')
                        GROUP BY event_id, state
                    """
            self.env['event.registration'].flush(['event_id', 'state'])
            self._cr.execute(query, (tuple(self.ids),))
            for event_id, state, num in self._cr.fetchall():
                event = self.browse(event_id)
                event[state_field[state]] += num
        # compute seats_available
        for event in self:
            if event.seats_max > 0:
                event.seats_available = event.seats_max - (event.seats_reserved + event.seats_used)
            event.seats_expected = event.seats_unconfirmed + event.seats_reserved + event.seats_used

    @api.depends('date_end', 'seats_available', 'seats_availability')
    def _compute_event_registrations_open(self):
        for event in self:
            event.event_registrations_open = event.date_end > fields.Datetime.now() and (event.seats_available or event.seats_availability == 'unlimited')

    @api.depends('stage_id', 'kanban_state')
    def _compute_kanban_state_label(self):
        for event in self:
            if event.kanban_state == 'normal':
                event.kanban_state_label = event.stage_id.legend_normal
            elif event.kanban_state == 'blocked':
                event.kanban_state_label = event.stage_id.legend_blocked
            else:
                event.kanban_state_label = event.stage_id.legend_done

    @api.depends('date_tz', 'date_begin')
    def _compute_date_begin_tz(self):
        for event in self:
            if event.date_begin:
                event.date_begin_located = format_datetime(
                    self.env, event.date_begin, tz=event.date_tz, dt_format='medium')
            else:
                event.date_begin_located = False

    @api.depends('date_tz', 'date_end')
    def _compute_date_end_tz(self):
        for event in self:
            if event.date_end:
                event.date_end_located = format_datetime(
                    self.env, event.date_end, tz=event.date_tz, dt_format='medium')
            else:
                event.date_end_located = False

    @api.depends('date_begin', 'date_end', 'date_tz')
    def _compute_field_is_one_day(self):
        for event in self:
            # Need to localize because it could begin late and finish early in
            # another timezone
            event = event.with_context(tz=event.date_tz)
            begin_tz = fields.Datetime.context_timestamp(event, event.date_begin)
            end_tz = fields.Datetime.context_timestamp(event, event.date_end)
            event.is_one_day = (begin_tz.date() == end_tz.date())

    @api.onchange('is_online')
    def _onchange_is_online(self):
        if self.is_online:
            self.address_id = False

    @api.onchange('event_type_id')
    def _onchange_type(self):
        if self.event_type_id:
            self.seats_min = self.event_type_id.default_registration_min
            self.seats_max = self.event_type_id.default_registration_max
            if self.event_type_id.default_registration_max:
                self.seats_availability = 'limited'

            if self.event_type_id.auto_confirm:
                self.auto_confirm = self.event_type_id.auto_confirm

            if self.event_type_id.use_hashtag:
                self.twitter_hashtag = self.event_type_id.default_hashtag

            if self.event_type_id.use_timezone:
                self.date_tz = self.event_type_id.default_timezone

            self.is_online = self.event_type_id.is_online

            if self.event_type_id.use_mail_schedule and self.event_type_id.event_type_mail_ids:
                self.event_mail_ids = [(5, 0, 0)] + [
                    (0, 0, {
                        attribute_name: line[attribute_name] if not isinstance(line[attribute_name], models.BaseModel) else line[attribute_name].id
                        for attribute_name in self.env['event.type.mail']._get_event_mail_fields_whitelist()
                        })
                    for line in self.event_type_id.event_type_mail_ids]

    @api.constrains('seats_min', 'seats_max', 'seats_availability')
    def _check_seats_min_max(self):
        if any(event.seats_availability == 'limited' and event.seats_min > event.seats_max for event in self):
            raise ValidationError(_('Maximum attendees number should be greater than minimum attendees number.'))

    @api.constrains('seats_max', 'seats_available')
    def _check_seats_limit(self):
        if any(event.seats_availability == 'limited' and event.seats_max and event.seats_available < 0 for event in self):
            raise ValidationError(_('No more available seats.'))

    @api.constrains('date_begin', 'date_end')
    def _check_closing_date(self):
        for event in self:
            if event.date_end < event.date_begin:
                raise ValidationError(_('The closing date cannot be earlier than the beginning date.'))

    @api.depends('name', 'date_begin', 'date_end')
    def name_get(self):
        result = []
        for event in self:
            date_begin = fields.Datetime.from_string(event.date_begin)
            date_end = fields.Datetime.from_string(event.date_end)
            dates = [fields.Date.to_string(fields.Datetime.context_timestamp(event, dt)) for dt in [date_begin, date_end] if dt]
            dates = sorted(set(dates))
            result.append((event.id, '%s (%s)' % (event.name, ' - '.join(dates))))
        return result

    @api.model
    def _read_group_stage_ids(self, stages, domain, order):
        return self.env['event.stage'].search([])

    @api.model
    def create(self, vals):
        res = super(EventEvent, self).create(vals)
        if res.organizer_id:
            res.message_subscribe([res.organizer_id.id])
        return res

    def write(self, vals):
        res = super(EventEvent, self).write(vals)
        if vals.get('organizer_id'):
            self.message_subscribe([vals['organizer_id']])
        return res

    @api.returns('self', lambda value: value.id)
    def copy(self, default=None):
        self.ensure_one()
        default = dict(default or {}, name=_("%s (copy)") % (self.name))
        return super(EventEvent, self).copy(default)

    def action_set_done(self):
        """
        Action which will move the events
        into the first next (by sequence) stage defined as "Ended"
        (if they are not already in an ended stage)
        """
        first_ended_stage = self.env['event.stage'].search([('pipe_end', '=', True)], order='sequence')
        if first_ended_stage:
            self.write({'stage_id': first_ended_stage[0].id})

    def mail_attendees(self, template_id, force_send=False, filter_func=lambda self: self.state != 'cancel'):
        for event in self:
            for attendee in event.registration_ids.filtered(filter_func):
                self.env['mail.template'].browse(template_id).send_mail(attendee.id, force_send=force_send)

    def _get_ics_file(self):
        """ Returns iCalendar file for the event invitation.
            :returns a dict of .ics file content for each event
        """
        result = {}
        if not vobject:
            return result

        for event in self:
            cal = vobject.iCalendar()
            cal_event = cal.add('vevent')

            cal_event.add('created').value = fields.Datetime.now().replace(tzinfo=pytz.timezone('UTC'))
            cal_event.add('dtstart').value = fields.Datetime.from_string(event.date_begin).replace(tzinfo=pytz.timezone('UTC'))
            cal_event.add('dtend').value = fields.Datetime.from_string(event.date_end).replace(tzinfo=pytz.timezone('UTC'))
            cal_event.add('summary').value = event.name
            if event.address_id:
                cal_event.add('location').value = event.sudo().address_id.contact_address

            result[event.id] = cal.serialize().encode('utf-8')
        return result


import aws_encryption_sdk as aes
import json

from AwAws.Session.session import Session

class KMS:
    '''
    :param region_name: the region we are using

    .. note::  There are two type of regions being used here: \n
        #. the region we are connecting to to run the code
        #. the regions(s) where we want to run the encryption since
           KMS encryption keys are region specific and cannot be copied
           across regions
    .. note:: in order to use multiple regions, multiple master_keys
           also need to be defined
    '''

    def __init__(self, region_name=None):

        self.enc_regions = []
        self.master_keys = []
        self.key_provider = None
        self.kms = Session(region_name).get_client('kms')

    def set_encryption_regions(self, regions=[]):
        'master encryption keys are locked to a specific region'
        if type(regions) == str:
            self.enc_regions.append(regions)
        else:
            self.enc_regions.extend(regions)

    def set_master_keys(self, master_keys=[]):
        'list of master keys to use'
        if type(master_keys) == str:
            self.master_keys.append(master_keys)
        else:
            self.master_keys.extend(master_keys)

    def set_key_provider(self):
        'called by en(de)crypt_it(), get the master key provider'

        if (len(self.enc_regions)) <= 0 or (len(self.master_keys) <= 0):
            raise Exception('Region or Master Keys not set')

        try:
            self.key_provider = aes.KMSMasterKeyProvider(
                botocore_session=self.kms,
                key_ids=self.master_keys,
                region_names=self.enc_regions
            )
        except Exception as e:
            raise Exception('Could not set key_provider', e)

    def encrypt_object(self, obj_to_encrypt):
        'encrypt a python object'
        try:
            # need to convert the object to a string
            json_to_encrypt = json.dumps(obj_to_encrypt)
        except Exception as e:
            raise Exception('Could not serialize object', e)

        return self.encrypt_it(json_to_encrypt)

    def decrypt_object(self, cipher_object):
        'returns python object from a given cipher object'
        decrypted_text = self.decrypt_it(cipher_object)
        return json.loads(bytes.decode(decrypted_text))

    def encrypt_it(self, text_to_encrypt):
        'encrypt a block of text'
        cipher_obj = {}

        self.set_key_provider()
        (cipher_obj['cipher_text'], cipher_obj['encryptor_header']) = aes.encrypt(
            source=text_to_encrypt,
            key_provider=self.key_provider
        )
        return cipher_obj

    def decrypt_it(self, cipher_obj):
        'decrypt encrypted text'
        self.set_key_provider()
        (decrypted_text, decryptor_header) = aes.decrypt(
            source=cipher_obj['cipher_text'],
            key_provider=self.key_provider
        )
        if cipher_obj['encryptor_header'] != decryptor_header:
            raise Exception('Encryption headers do not match!!!')

        return decrypted_text


# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

import bpy

from bpyhullgen.hullgen import chine_helper
from bpyhullgen.bpyutils import material_helper
from bpyhullgen.hullgen import curve_helper
from bpyhullgen.hullgen import hull_maker
from bpyhullgen.hullgen import geometry_helper
from bpyhullgen.hullgen import keel_helper
from bpyhullgen.hullgen import render_helper
from bpyhullgen.bpyutils import bpy_helper

from math import radians

the_hull=hull_maker.hull_maker(width=3,length=7,height=3)
the_hull.make_hull_object()

the_hull.start_bulkhead_location=-3
the_hull.hull_output_scale=1/16
the_hull.target_screw_size=4.1 # mm

new_chine=chine_helper.chine_definition(the_hull,
	name="side",
	length=the_hull.hull_length*1.2,
	width=1,
	offset=[0,0.35,0],
	asymmetry=[1,0])

new_longitudinal=chine_helper.longitudinal_definition(z_offset=-0.2,width=-0.13,thickness=0.1)
new_longitudinal.set_limit_x_length(the_hull.start_bulkhead_location,2)

new_chine.add_longitudinal_definition(new_longitudinal)

the_hull.add_chine(new_chine)

new_chine=chine_helper.chine_definition(the_hull,
	name="upper",
	length=the_hull.hull_length*1.3,
	width=1,
	rotation=[-36,0,0],
	offset=[0,0,-0.84],
	asymmetry=[1,0]
	)

the_hull.add_chine(new_chine)

new_chine=chine_helper.chine_definition(the_hull,
	name="mid",
	length=the_hull.hull_length*1.3,
	width=1,
	rotation=[39,0,0],
	offset=[0,-0.2,0.331],
	asymmetry=[1,0]
	)

the_hull.add_chine(new_chine)

new_chine=chine_helper.chine_definition(the_hull,
	name="low",
	length=the_hull.hull_length*1.4,
	width=1,
	rotation=[82,0,0],
	asymmetry=[1,0]
	)

new_longitudinal=chine_helper.longitudinal_definition(width=-0.13,thickness=0.1)
new_longitudinal.set_limit_x_length(the_hull.start_bulkhead_location,2)
new_chine.add_longitudinal_definition(new_longitudinal)

the_hull.add_chine(new_chine)

new_chine=chine_helper.chine_definition(the_hull,
	name="roof",
	length=the_hull.hull_length*1.4,
	width=0.8,
	rotation=[-90,0,0],
	asymmetry=[1,0],
	offset=[0,0,-0.5],
	symmetrical=False
	)

the_hull.add_chine(new_chine)

# ================ modify hull

	# ================ Add Pilot House
def add_pilot_house():
	bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0, 0, 0.27) )

	bpy.ops.transform.resize(value=(1,0.9,1))
	bpy.ops.object.transform_apply(scale=True,location=False)

	ob = bpy.context.active_object

	ob.name="Pilot House"

	bpy.ops.object.mode_set(mode='EDIT')

	bpy.ops.mesh.select_all(action='DESELECT')
	bpy.ops.object.mode_set(mode='OBJECT')

	for face in ob.data.polygons:
		face.select = geometry_helper.GoingUp( face.normal )

	bpy.ops.object.mode_set(mode='EDIT')

	bpy.ops.transform.resize(value=(1, 0.6, 1))

	bpy.ops.transform.translate(value=(-0.4, 0, 0))

	bpy.ops.mesh.bevel(offset=0.1)

	bpy.ops.object.mode_set(mode='OBJECT')

	bool_new = the_hull.hull_object.modifiers.new(type="BOOLEAN", name="hull_join")
	bool_new.object = ob
	bool_new.operation = 'UNION'

	bpy_helper.hide_object(ob)

add_pilot_house()

def add_extras():
	# ================ Add Rudder
	bpy.ops.mesh.primitive_cube_add(size=1.0, location=(-5.3, 0, -1.25) )

	rudder_object = bpy.context.active_object

	rudder_object.name="Rudder"

	bpy.ops.transform.resize(value=(0.7,0.05,0.8))
	bpy.ops.object.transform_apply(scale=True,location=False)

	bool_new = the_hull.hull_object.modifiers.new(type="BOOLEAN", name="hull_join")
	bool_new.object = rudder_object
	bool_new.operation = 'UNION'

	bpy_helper.hide_object(rudder_object)

	# ================ Add Keel
	bpy.ops.mesh.primitive_cube_add(size=1.0, location=(-1.2, 0, -1.25) )

	ob = bpy.context.active_object

	ob.name="Keel"

	bpy.ops.transform.resize(value=(7,0.05,0.8))
	bpy.ops.object.transform_apply(scale=True,location=False)

	bool_new = the_hull.hull_object.modifiers.new(type="BOOLEAN", name="hull_join")
	bool_new.object = ob
	bool_new.operation = 'UNION'

	bpy_helper.hide_object(ob)

	# ================ Add deck cockpit
	bpy.ops.mesh.primitive_cube_add(size=1.0, location=(-2.2, 0, 0) )

	ob = bpy.context.active_object

	ob.name="deck_cockpit"

	bpy.ops.transform.resize(value=(3,1,1))
	bpy.ops.object.transform_apply(scale=True,location=False)

	bool_new = the_hull.hull_object.modifiers.new(type="BOOLEAN", name="hull_cut")
	bool_new.object = ob
	bool_new.operation = 'DIFFERENCE'

	bpy_helper.hide_object(ob)

the_hull.add_prop(blend_file="assets/actors.blend",target_object="man.sit_chair",location=[0,0,-0.6])
the_hull.add_prop(blend_file="assets/boat_assets.blend",target_object="wheel_axle.8ft",location=[0,0,-0.96])

levels=[ -0.7]

the_keel_builder = keel_helper.keel_builder(the_hull)
the_keel_builder.make_solid_double_keel(top_height=levels[0],start_bulkhead=1,end_bulkhead=6)

def make_fuel_tanks():

	fuel_tank_1L=geometry_helper.create_bilgetank(the_hull,
					top=levels[0],
					x1=bulkhead_definitions[0][0]+bulkhead_definitions[0][3]/2,
					x2=bulkhead_definitions[1][0]-bulkhead_definitions[1][3]/2,
					y_offset=-(keel_middle_space/2)-the_keel.thickness/2,
					name="fuel_1L")

	fuel_tank_1R=geometry_helper.create_bilgetank(the_hull,
					top=levels[0],
					x1=bulkhead_definitions[0][0]+bulkhead_definitions[0][3]/2,
					x2=bulkhead_definitions[1][0]-bulkhead_definitions[1][3]/2,
					y_offset=(keel_middle_space/2)+the_keel.thickness/2,
					name="fuel_1R")

	fuel_tank_1L=geometry_helper.create_bilgetank(the_hull,
					top=levels[0],
					x1=bulkhead_definitions[1][0]+bulkhead_definitions[1][3]/2,
					x2=bulkhead_definitions[2][0]-bulkhead_definitions[2][3]/2,
					y_offset=-(keel_middle_space/2)-the_keel.thickness/2,
					name="fuel_2L")

	fuel_tank_1R=geometry_helper.create_bilgetank(the_hull,
					top=levels[0],
					x1=bulkhead_definitions[1][0]+bulkhead_definitions[1][3]/2,
					x2=bulkhead_definitions[2][0]-bulkhead_definitions[2][3]/2,
					y_offset=(keel_middle_space/2)+the_keel.thickness/2,
					name="fuel_2R")

	fuel_tank_1L=geometry_helper.create_bilgetank(the_hull,
					top=levels[0],
					x1=bulkhead_definitions[4][0]+bulkhead_definitions[4][3]/2,
					x2=bulkhead_definitions[5][0]-bulkhead_definitions[5][3]/2,
					y_offset=-(keel_middle_space/2)-the_keel.thickness/2,
					name="fuel_3L")

	fuel_tank_1R=geometry_helper.create_bilgetank(the_hull,
					top=levels[0],
					x1=bulkhead_definitions[4][0]+bulkhead_definitions[4][3]/2,
					x2=bulkhead_definitions[5][0]-bulkhead_definitions[5][3]/2,
					y_offset=(keel_middle_space/2)+the_keel.thickness/2,
					name="fuel_3R")

the_hull.integrate_components()

framedata=[
[ 1, [2.256688,-9.173357,4.958309],[0.000000,0.000000,0.000000] ],
[ 2, [0.315304,-0.819446,10.211541],[0.000000,0.000000,0.000000] ],
[ 3, [7.223459,-0.424494,0.439452],[0.000000,0.000000,-0.409564] ],
[ 4, [-8.400036,-1.356833,0.990534],[-2.644429,-0.102626,-0.230217] ],
[ 5, [-3.368380,-0.004060,-0.279753],[0.028123,0.029352,-0.230217] ]
]

render_helper.setup_keyframes(framedata)


from .game import Cards, Game
import logging

logging.basicConfig(level=logging.WARN, filename='test_game.log')

setless = [
    {'color': 'green', 'shading': 'open', 'range': range(0, 2),
     'number': 2, 'shape': 'oval', 'id': 42, 'blank': False},
    {'color': 'blue', 'shading': 'open', 'range': range(0, 3),
     'number': 3, 'shape': 'oval', 'id': 78, 'blank': False},
    {'color': 'blue', 'shading': 'open', 'range': range(0, 1),
     'number': 1, 'shape': 'oval', 'id': 60, 'blank': False},
    {'color': 'red', 'shading': 'striped', 'range': range(0, 1),
     'number': 1, 'shape': 'rectangle', 'id': 5, 'blank': False},
    {'color': 'red', 'shading': 'striped', 'range': range(0, 3),
     'number': 3, 'shape': 'oval', 'id': 21, 'blank': False},
    {'color': 'blue', 'shading': 'solid', 'range': range(0, 3),
     'number': 3, 'shape': 'oval', 'id': 72, 'blank': False},
    {'color': 'green', 'shading': 'solid', 'range': range(0, 1),
     'number': 1, 'shape': 'oval', 'id': 27, 'blank': False},
    {'color': 'blue', 'shading': 'open', 'range': range(0, 3),
     'number': 3, 'shape': 'rectangle', 'id': 80, 'blank': False},
    {'color': 'red', 'shading': 'solid', 'range': range(0, 3),
     'number': 3, 'shape': 'oval', 'id': 18, 'blank': False},
    {'color': 'green', 'shading': 'open', 'range': range(0, 3),
     'number': 3, 'shape': 'diamond', 'id': 52, 'blank': False},
    {'color': 'green', 'shading': 'striped', 'range': range(0, 3),
     'number': 3, 'shape': 'rectangle', 'id': 50, 'blank': False},
    {'color': 'red', 'shading': 'solid', 'range': range(0, 2),
     'number': 2, 'shape': 'rectangle', 'id': 11, 'blank': False}]

setless_extra = [
    {'color': 'blue', 'shading': 'solid', 'range': range(0, 1),
     'number': 1, 'shape': 'diamond', 'id': 55, 'blank': False},
    {'color': 'red', 'shading': 'striped', 'range': range(0, 1),
     'number': 1, 'shape': 'diamond', 'id': 4, 'blank': False},
    {'color': 'green', 'shading': 'solid', 'range': range(0, 3),
     'number': 3, 'shape': 'rectangle', 'id': 47, 'blank': False}]

with_set = setless[:]
with_set[-1] = {'color': 'red', 'shading': 'open', 'range': range(0, 1),
                'number': 1, 'shape': 'oval', 'id': 6, 'blank': False}

def test_new_shuffled_deck():
    assert(len(Cards().new_shuffled_deck()) == 81)

def test_new_game():
    game = Game()
    game.new_game()
    assert(len(game.deck) == 69)
    assert(game.results.number_sets_found == 0)
    assert(len(game.cards_open) == 12)
    assert(not game.hint)
    assert(not game.results.end_of_game)
    assert(game.correct_set_call)

def test_open_extra_cards():
    game = Game()
    nr_before = len(game.cards_open)
    game.open_extra_cards()
    assert(len(game.cards_open) == nr_before + 3)

def test_try_find_set():
    game = Game()

    # There is no set
    game.cards_open = setless
    assert(not game.try_find_set()[0])

    # There is a set
    game.cards_open = with_set
    assert(game.try_find_set()[0] == with_set[0])

def test_process_selection():
    game = Game()
    selection = '42,78,6'
    game.cards_open = with_set
    game.process_selection(selection)
    assert(game.correct_set_call)
    assert(game.results.number_sets_found == 1)

def test_indices_extra_cards():
    game = Game()
    assert(game._indices_extra_cards(12) == [])
    assert(game._indices_extra_cards(15) == [4, 9, 14])
    assert(game._indices_extra_cards(18) == [5, 11, 17])
    assert(game._indices_extra_cards(21) == [6, 13, 20])

def test_handling_extra_cards():
    game = Game()
    game.cards_open = setless + setless_extra
    assert(len(game.cards_open) == 15)
    game.try_find_set()
    assert(not game.hint)
    game.open_extra_cards()
    assert(len(game.cards_open) == 18)

def test_full_game():
    logging.info('------------Start new game')
    game = Game()
    game.new_game()
    while not game.results.end_of_game:
        assert(len(game.cards_open) % 3 == 0)
        assert(len(game.deck) % 3 == 0)
        a_set = game.try_find_set()
        if a_set[0]:
            ids = ','.join(str(card['id']) for card in a_set)
            game.process_selection(ids)
            game.results.end_of_game = False
            assert(len(game.cards_open) % 3 == 0)
            logging.info('Found set nr {}'
                         .format(game.results.number_sets_found))
        elif len(game.deck) >= 3:
            game.open_extra_cards()
            assert(len(game.cards_open) <= 21)  # 20 cards garantees a set
            logging.info('No set, nr cards open goes to {}'
                         .format(len(game.cards_open)))
            if len(game.cards_open) > 18:
                logging.warning('This should be really exceptional')
        else:
            game.end_game()

def test_multiple_full_games():
    for i in range(100):
        test_full_game()


import re
import json
import pandas as pd
from dateutil.parser import parse
from dateutil.relativedelta import relativedelta
from datetime import date
from flask import Flask
from flask_restful import Api, Resource, reqparse
import random

app = Flask(__name__)
api = Api(app)

def birthDateToAge(dateStr):
    try:
        birthDate = parse(dateStr)
        realAge = relativedelta(date.today(), birthDate.date()).years
        outAge = str(realAge) if realAge < 90 else "90+"
    except:
        outAge = "ERROR"
    return outAge

def dateToYear(dateStr):
    try:
        fullDate = parse(dateStr)
        outYear = str(fullDate.year)
    except:
        outYear = "ERROR"
    return outYear

def stripZip(zipCode):
    try:
        zipCodeDf = pd.read_csv("population_by_zcta_2010.csv")
        zipHead = zipCode[0:3].ljust(3, "0")

        # Select all zip codes with first 3 digits matching the input zip code.
        zipSeries = zipCodeDf["Zip Code ZCTA"].astype(int)
        zipSubset = zipCodeDf.loc[zipSeries.floordiv(100).eq(int(zipHead))]
        totalPop = zipSubset["2010 Census Population"].astype(int).sum()
        outZipCode = f"{zipHead}00" if totalPop >= 20000 else "00000"
    except FileNotFoundError as e:
        raise e
    except:
        outZipCode = "ERROR"
    return outZipCode

def redactEmail(msg):
    emailPattern = re.compile(r"(\S+)@(\S+)\.([a-zA-Z0-9]+)")
    emailRedact = "XXXXX@XXXXX.XXX"
    msg = emailPattern.sub(emailRedact, msg)
    return msg

def redactSsn(msg):
    ssnPattern = re.compile(
        r"([0-9]{3})[-]?([0-9]{2})[-]?([0-9]{4})")
    ssnRedact = "XXX-XX-XXXX"
    msg = ssnPattern.sub(ssnRedact, msg)
    return msg

def redactPhone(msg):
    phonePattern = re.compile(
        r"[(]?([0-9]{3})[)]?[ -]?([0-9A-Z]{3})[ -]?([0-9]{4})")
    phoneRedact = "(XXX) XXX-XXXX"
    msg = phonePattern.sub(phoneRedact, msg)
    return msg

def redactDate(msg):
    # Not enough time to implement a robust date-searching tool.
    # Would probably use an existing package here for ease of writing.
    return msg

def redactMessage(msg):
    msg = redactEmail(msg)
    msg = redactPhone(msg)
    msg = redactSsn(msg)
    msg = redactDate(msg)
    return msg

parser = reqparse.RequestParser()
parser.add_argument('birthDate', type=str)
parser.add_argument('zipCode', type=str)
parser.add_argument('admissionDate', type=str)
parser.add_argument('dischargeDate', type=str)
parser.add_argument('notes', type=str)
class SafeHarbor(Resource):
    def post(self):
        args = parser.parse_args()

        age = birthDateToAge(args["birthDate"])
        zipCode = stripZip(args["zipCode"])
        admissionYear = dateToYear(args["admissionDate"])
        dischargeYear = dateToYear(args["dischargeDate"])
        notes = redactMessage(args["notes"])

        response = {
            "age": age,
            "zipCode": zipCode,
            "admissionYear": admissionYear,
            "dischargeYear": dischargeYear,
            "notes": notes
        }
        return response, 201

api.add_resource(SafeHarbor, "/")

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


import ctypes
import struct
from .basic_struct import StructBasic
from .cv_struct import *
from .pod_struct import *
from .face_struct import FacePose

#struct Video_Config_Para {
#	int mVedioType {0};
#	int mVedioWidth {1920};
#	int mVedioHeight {1080};
#	int mHasTimeStamp {0}; ///< 是否有时间戳，0--没有，1--有
#	int mFrameRate {25}; ///<视频流帧率
#    int mBigImgFlag {1};   ///< 模组是否提供编码的抓拍大图，0--不提供，1--提供。默认0
#    int mRoiImgFlag {1};   ///< 低16位指示模组是否提供编码的抓拍小图，0--不提供，1--提供，2--小图上报同时附大图；高16位指示识别图，0--不提供，1--提供识别小图
#    float mRoiImgEnlargeRate {1.0}; /*抓拍图在人脸roi宽高基础上扩大比例，大于等于1.0，1.0--只报人脸roi原始大小*/
#    int mImgEncLevel {1};  // 抓拍图Jpeg编码等级，0--ENC_QUALITY_LOW, 1--ENC_QUALITY_NORMAL, 2--ENC_QUALITY_HIGH
#	int mFrameSync {1};
#	int mSnapMode {2}; /* 0:无需抓拍选优， 1：抓拍选优无去重， 2：抓拍选优+去重 */
#	int mSnapCalcFe {0}; /* 0:抓拍结果不做FE，1:抓拍结果做FE*/
#	int mRecMode {0};  /* 0:无需识别选优， 1：识别选优（识别成功不再做识别） 3：识别选优 周期 */
#	std::vector<int> mAttrMode; /* 0:不做属性 */
#};  /* 视频流业务配置 */
class VideoCfgPara(StructBasic):
    #_pack_ = 1
    _fields_ = [ ("mVedioType", ctypes.c_int),
                ("mVedioWidth", ctypes.c_int),
               ("mVedioHeight", ctypes.c_int),
               ("mHasTimeStamp", ctypes.c_int),
               ("mFrameRate", ctypes.c_int),
               ("mBigImgFlag", ctypes.c_int),
               ("mRoiImgFlag", ctypes.c_int),
               ("mRoiImgEnlargeRate", ctypes.c_float),
               ("mImgEncLevel", ctypes.c_int),
               ("mFrameSync", ctypes.c_int),
               ("mSnapMode", ctypes.c_int),
               ("mSnapCalcFe", ctypes.c_int),
               ("mRecMode", ctypes.c_int),
              # ("mAttrMode", VecInt),
               ]

    def __init__(self):
        ctypes.Structure.__init__(self)
        self.mVedioType = 0
        self.mVedioWidth = 1920
        self.mVedioHeight = 1080
        self.mHasTimeStamp = 0
        self.mFrameRate = 25
        self.mBigImgFlag = 1
        self.mRoiImgFlag = 1
        self.mRoiImgEnlargeRate = 1.0
        self.mImgEncLevel = 1
        self.mFrameSync = 1
        self.mSnapMode = 0
        self.mSnapCalcFe = 1
        self.mRecMode = 0
        pass

    def __repr__(self):
        _str = 'mVedioType = %d\n' % (self.mVedioType)
        _str += 'mVedioWidth = %d\n' % (self.mVedioWidth)
        _str += 'mVedioHeight = %d\n' % (self.mVedioHeight)
        _str += 'mHasTimeStamp = %d\n' % (self.mHasTimeStamp)
        _str += 'mFrameRate = %d\n' % (self.mFrameRate)
        _str += 'mBigImgFlag = %d\n' % (self.mBigImgFlag)
        _str += 'mRoiImgFlag = %d\n' % (self.mRoiImgFlag)
        _str += 'mRoiImgEnlargeRate = %f\n' % (self.mRoiImgEnlargeRate)
        _str += 'mImgEncLevel = %d\n' % (self.mImgEncLevel)
        _str += 'mFrameSync = %d\n' % (self.mFrameSync)
        _str += 'mSnapMode = %d\n' % (self.mSnapMode)
        _str += 'mSnapCalcFe = %d\n' % (self.mSnapCalcFe)
        _str += 'mRecMode = %d\n' % (self.mRecMode)
        return _str

    def to_bytes(self):
        return struct.pack('7if5i', self.mVedioType, self.mVedioWidth, self.mVedioHeight,
                          self.mHasTimeStamp, self.mFrameRate, self.mBigImgFlag, self.mRoiImgFlag,
                          self.mRoiImgEnlargeRate,
                          self.mImgEncLevel, self.mFrameSync, self.mSnapMode, self.mSnapCalcFe, self.mRecMode)

    def bytes_sizeof(self):
        return ctypes.sizeof(ctypes.c_int) * 12 + ctypes.sizeof(ctypes.c_float)

#struct Detect_Config_Para {
#	int mAlgSel {1};
#	int mDetMinFace {36} ;
#	int mDetMaxFace {600} ;
#	int mDetPeriods {160};
#	std::vector<cv::Rect> mDetReg;
#}; /* 检测配置参数 */

class DetectCfgPara(StructBasic):
    #_pack_ = 1
    _fields_ = [("mAlgSel", ctypes.c_int),
               ("mDetMinFace", ctypes.c_int),
                ("mDetMaxFace", ctypes.c_int),
                 ("mDetPeriods", ctypes.c_int),
               ("mDetReg", VecRect)
                ]

    @classmethod
    def from_bytes(_cls, _bytes, _offs = 0):
        mAlgSel = ctypes.c_int.from_buffer(_bytes, _offs)
        _offs += ctypes.sizeof(ctypes.c_int)

        mDetMinFace = ctypes.c_int.from_buffer(_bytes, _offs)
        _offs += ctypes.sizeof(ctypes.c_int)

        mDetMaxFace = ctypes.c_int.from_buffer(_bytes, _offs)
        _offs += ctypes.sizeof(ctypes.c_int)

        mDetPeriods = ctypes.c_int.from_buffer(_bytes, _offs)
        _offs += ctypes.sizeof(ctypes.c_int)

        mDetReg = VecRect.from_bytes(_bytes, _offs)
        _offs += mDetReg.bytes_sizeof()

        obj = _cls(mAlgSel,
                mDetMinFace,
                mDetMaxFace,
                mDetPeriods,
                mDetReg)
        return obj

    def bytes_sizeof(self):
        sz = ctypes.sizeof(ctypes.c_int)  * 4
        sz += self. mDetReg.bytes_sizeof()
        return sz

    def __init__(self,
                mAlgSel,
                mDetMinFace,
                mDetMaxFace,
                mDetPeriods,
                mDetReg):
        self.mAlgSel = mAlgSel
        self.mDetMinFace = mDetMinFace
        self.mDetMaxFace = mDetMaxFace
        self.mDetPeriods = mDetPeriods
        self.mDetReg =  mDetReg
        pass

    def __repr__(self):
        str = "mAlgSel = %d \n"   %(self.mAlgSel)
        str += "mDetMinFace = %d \n"   %(self.mDetMinFace)
        str += "mDetMaxFace = %d \n"   %(self.mDetMaxFace)
        str += "mDetPeriods = %d \n"   %(self.mDetPeriods)
        str += "mDetPeriods = %s \n"   %(self.mDetReg)
        return str

    def to_bytes(self):
        return struct.pack('4i', self.mAlgSel, self.mDetMinFace, self.mDetMaxFace,self.mDetPeriods) + self.mDetReg.to_bytes()

#struct Track_Config_Para {
#	int mAlgSel {2};
#	float mTrkUnDetAge {2.0};
#	int mTrkPeriods {0};
#	int mTrkMaxFaceNum {40};
#	int mTrkSyncAddTh {48};
#	int mTrkSyncAdjTh {32};
#	float mTrkSyncBorderAddTh {0.6};
#	float mTrkSyncBorderAdjTh {0.6};
#	float mTrkSyncOverlapAdjTh {0.3};
#	float mTrkSyncOverlapDelTh {0.5};
#	int mTrkOnetAdj {0};
#}; /* 跟踪配置参数 */

class TrackCfgPara(StructBasic):
    #_pack_ = 1
    _fields_ = [ ("mAlgSel", ctypes.c_int),
                ("mTrkUnDetAge", ctypes.c_float),
               ("mTrkPeriods", ctypes.c_int),
               ("mTrkMaxFaceNum", ctypes.c_int),
               ("mTrkSyncAddTh", ctypes.c_int),
               ("mTrkSyncAdjTh", ctypes.c_int),
               ("mTrkSyncBorderAddTh", ctypes.c_float),
               ("mTrkSyncBorderAdjTh", ctypes.c_float),
               ("mTrkSyncOverlapAdjTh", ctypes.c_float),
               ("mTrkSyncOverlapDelTh", ctypes.c_float),
               ("mTrkOnetAdj", ctypes.c_int),
               ]

    def __init__(self):
        ctypes.Structure.__init__(self)
        self.mAlgSel = 2
        self.mTrkUnDetAge = 2.0
        self.mTrkPeriods = 0
        self.mTrkMaxFaceNum = 40
        self.mTrkSyncAddTh = 48
        self.mTrkSyncAdjTh = 32
        self.mTrkSyncBorderAddTh = 0.6
        self.mTrkSyncBorderAdjTh = 0.6
        self.mTrkSyncOverlapAdjTh = 0.3
        self.mTrkSyncOverlapDelTh = 0.5
        self.mTrkOnetAdj = 0
        pass

    def __repr__(self):
        _str = 'mAlgSel = %d\n' % (self.mAlgSel)
        _str += 'mTrkUnDetAge = %f\n' % (self.mTrkUnDetAge)
        _str += 'mTrkPeriods = %d\n' % (self.mTrkPeriods)
        _str += 'mTrkMaxFaceNum = %d\n' % (self.mTrkMaxFaceNum)
        _str += 'mTrkSyncAddTh = %d\n' % (self.mTrkSyncAddTh)
        _str += 'mTrkSyncAdjTh = %d\n' % (self.mTrkSyncAdjTh)
        _str += 'mTrkSyncBorderAddTh = %f\n' % (self.mTrkSyncBorderAddTh)
        _str += 'mTrkSyncBorderAdjTh = %f\n' % (self.mTrkSyncBorderAdjTh)
        _str += 'mTrkSyncOverlapAdjTh = %f\n' % (self.mTrkSyncOverlapAdjTh)
        _str += 'mTrkSyncOverlapDelTh = %f\n' % (self.mTrkSyncOverlapDelTh)
        _str += 'mTrkOnetAdj = %d\n' % (self.mTrkOnetAdj)
        return _str

    def to_bytes(self):
        return struct.pack('if4i4fi', self.mAlgSel, self.mTrkUnDetAge,
                           self.mTrkPeriods, self.mTrkMaxFaceNum,self.mTrkSyncAddTh,self.mTrkSyncAdjTh,
                           self.mTrkSyncBorderAddTh, self.mTrkSyncBorderAdjTh,self.mTrkSyncOverlapAdjTh,self.mTrkSyncOverlapDelTh,
                           self.mTrkOnetAdj)

    def bytes_sizeof(self):
        return ctypes.sizeof(ctypes.c_int) * 6 + ctypes.sizeof(ctypes.c_float) * 5

#struct Face_Snap_Filter_Config_Para {
# int mQualAlgSel {2};
#	int mFltMinMS {1000};
#	int mFltPeriodMS {0};
#	int mFltReportCnt {3};
#	int mFltReportMinSize {36}; - hk
#	int mFltAttriPeriodMS {20000};
#	float mFltMinQual {0.4}; - hk
#	float mFltFirstQual {0.8};
#	float mFltDeltaQual {0.4};
#	int mFltFrontalMinCnt {2};
#	int mFltPoseQualPeriods {160};
#	int mFltBestSelAtLeave {1}; - hk
#	int mFltReportDelayMs {0};
#	Face_Pose mDown {-90, -90, -90}; - hk
#	Face_Pose mUp {90, 90, 90}; - hk
#};

class FaceSnapFilterCfgPara(StructBasic):
    #_pack_ = 1
    _fields_ = [ ("mQualAlgSel", ctypes.c_int),
                ("mFltMinMS", ctypes.c_int),
               ("mFltPeriodMS", ctypes.c_int),
               ("mFltReportCnt", ctypes.c_int),
               ("mFltReportMinSize", ctypes.c_int),
               ("mFltAttriPeriodMS", ctypes.c_int),
               ("mFltMinQual", ctypes.c_float),
               ("mFltFirstQual", ctypes.c_float),
               ("mFltDeltaQual", ctypes.c_float),
               ("mFltFrontalMinCnt", ctypes.c_int),
               ("mFltPoseQualPeriods", ctypes.c_int),
               ("mFltBestSelAtLeave", ctypes.c_int),
               ("mFltReportDelayMs", ctypes.c_int),
               ("mDown", FacePose),
               ("mUp", FacePose),
               ]

    def __init__(self):
        ctypes.Structure.__init__(self)
        self.mQualAlgSel = 2
        self.mFltMinMS = 1000
        self.mFltPeriodMS = 0
        self.mFltReportCnt = 3
        self.mFltReportMinSize = 36
        self.mFltAttriPeriodMS = 20000
        self.mFltMinQual = 0.4
        self.mFltFirstQual = 0.8
        self.mFltDeltaQual = 0.4
        self.mFltFrontalMinCnt = 2
        self.mFltPoseQualPeriods = 160
        self.mFltBestSelAtLeave = 1
        self.mFltReportDelayMs = 0
        self.mDown.pitch = -90
        self.mDown.roll = -90
        self.mDown.yaw = -90
        self.mUp.pitch = 90
        self.mUp.roll = 90
        self.mUp.yaw = 90
        pass

    def __repr__(self):
        _str = 'mQualAlgSel = %d\n' % (self.mQualAlgSel)
        _str += 'mFltMinMS = %d\n' % (self.mFltMinMS)
        _str += 'mFltPeriodMS = %d\n' % (self.mFltPeriodMS)
        _str += 'mFltReportCnt = %d\n' % (self.mFltReportCnt)
        _str += 'mFltReportMinSize = %d\n' % (self.mFltReportMinSize)
        _str += 'mFltAttriPeriodMS = %d\n' % (self.mFltAttriPeriodMS)
        _str += 'mFltMinQual = %f\n' % (self.mFltMinQual)
        _str += 'mFltFirstQual = %f\n' % (self.mFltFirstQual)
        _str += 'mFltDeltaQual = %f\n' % (self.mFltDeltaQual)
        _str += 'mFltFrontalMinCnt = %d\n' % (self.mFltFrontalMinCnt)
        _str += 'mFltPoseQualPeriods = %d\n' % (self.mFltPoseQualPeriods)
        _str += 'mFltBestSelAtLeave = %d\n' % (self.mFltBestSelAtLeave)
        _str += 'mFltReportDelayMs = %d\n' % (self.mFltReportDelayMs)
        _str += 'mDown = %s\n' % (str(self.mDown))
        _str += 'mUp = %s\n' % (str(self.mUp))
        return _str

    def to_bytes(self):
        return struct.pack('6i', self.mQualAlgSel, self.mFltMinMS, self.mFltPeriodMS,
                           self.mFltReportCnt, self.mFltReportMinSize, self.mFltAttriPeriodMS) + \
                    struct.pack('3f', self.mFltMinQual, self.mFltFirstQual, self.mFltDeltaQual) + \
                    struct.pack('4i', self.mFltFrontalMinCnt, self.mFltPoseQualPeriods, self.mFltBestSelAtLeave, self.mFltReportDelayMs) + \
                    self.mDown.to_bytes() + self.mUp.to_bytes()

    def bytes_sizeof(self):
        return ctypes.sizeof(ctypes.c_int) * 10 + ctypes.sizeof(ctypes.c_float) * 3 +  ctypes.sizeof(FacePose) * 2

#struct Face_Snap_Filter_Config_Dedup_Para {
#	//去重参数
#   int mGluonAlgSel {0}
#	int mSnapDedupMode {1}; -hk
#	int mDedupTimeMSTh {5000};  -hk, 新增加脸和库中faceid 脸的时间
#	int mDedupSpaceTh {500};
#	float mDedupCompareTh {0.36};  -hk,
#	int mDedupTimeoutMSTh {15000}; -hk, 删数据库，防止溢出
#	int mDedupIgnorTimeMSTh {600000};
#  int mDedupPosPThres {90}; - hk，满足门限，才启动fe特征
#	int mDedupPosYThres {90};
#	int mDedupPosRThres {90};
#	int mDedupFltMinMs {200}; -hk, 出现多长时间内，必须选择一张做
#	int mDedupFltPeriodMs {0};
#	float mDedupFltMinQual {0.65}; -hk,
#	float mDedupFltFirstQual {0.7}; -hk， 第一次满足要求qual，做
#	float mDedupFltDeltaQual {0.02};  -hk,
#	int mDedupFltMinFace {70}; -hk,
#}; /* 抓拍选优配置参数 */

class FaceSnapFilterCfgDedupPara(StructBasic):
    #_pack_ = 1
    _fields_ = [("mGluonAlgSel", ctypes.c_int),
               ("mSnapDedupMode", ctypes.c_int),
               ("mDedupTimeMSTh", ctypes.c_int),
               ("mDedupSpaceTh", ctypes.c_int),
               ("mDedupCompareTh", ctypes.c_float),
               ("mDedupTimeoutMSTh", ctypes.c_int),
               ("mDedupIgnorTimeMSTh", ctypes.c_int),
               ("mDedupPosPThres", ctypes.c_int),
               ("mDedupPosYThres", ctypes.c_int),
               ("mDedupPosRThres", ctypes.c_int),
               ("mDedupFltMinMs", ctypes.c_int),
               ("mDedupFltPeriodMs", ctypes.c_int),
               ("mDedupFltMinQual", ctypes.c_float),
               ("mDedupFltFirstQual", ctypes.c_float),
               ("mDedupFltDeltaQual", ctypes.c_float),
                ("mDedupFltMinFace", ctypes.c_int),
               ]

    def __init__(self):
        ctypes.Structure.__init__(self)
        self.mGluonAlgSel = 0
        self.mSnapDedupMode = 1
        self.mDedupTimeMSTh = 5000
        self.mDedupSpaceTh = 500
        self.mDedupCompareTh = 0.34
        self.mDedupTimeoutMSTh = 10000
        self.mDedupIgnorTimeMSTh = 600000
        self.mDedupPosPThres = 90
        self.mDedupPosYThres = 90
        self.mDedupPosRThres = 90
        self.mDedupFltMinMs = 2000000
        self.mDedupFltPeriodMs = 0
        self.mDedupFltMinQual = 0.4
        self.mDedupFltFirstQual = 0.7
        self.mDedupFltDeltaQual = 0.02
        self.mDedupFltMinFace = 45
        pass

    def __repr__(self):
        _str = 'mGluonAlgSel = %d\n' % (self.mGluonAlgSel)
        _str += 'mSnapDedupMode = %d\n' % (self.mSnapDedupMode)
        _str += 'mDedupTimeMSTh = %d\n' % (self.mDedupTimeMSTh)
        _str += 'mDedupSpaceTh = %d\n' % (self.mDedupSpaceTh)
        _str += 'mDedupCompareTh = %f\n' % (self.mDedupCompareTh)
        _str += 'mDedupTimeoutMSTh = %d\n' % (self.mDedupTimeoutMSTh)
        _str += 'mDedupIgnorTimeMSTh = %d\n' % (self.mDedupIgnorTimeMSTh)
        _str += 'mDedupPosPThres = %d\n' % (self.mDedupPosPThres)
        _str += 'mDedupPosYThres = %d\n' % (self.mDedupPosYThres)
        _str += 'mDedupPosRThres = %d\n' % (self.mDedupPosRThres)
        _str += 'mDedupFltMinMs = %d\n' % (self.mDedupFltMinMs)
        _str += 'mDedupFltPeriodMs = %d\n' % (self.mDedupFltPeriodMs)
        _str += 'mDedupFltMinQual = %f\n' % (self.mDedupFltMinQual)
        _str += 'mDedupFltFirstQual = %f\n' % (self.mDedupFltFirstQual)
        _str += 'mDedupFltDeltaQual = %f\n' % (self.mDedupFltDeltaQual)
        _str += 'mDedupFltMinFace = %d\n' % (self.mDedupFltMinFace)
        return _str

    def to_bytes(self):
         return struct.pack('4if', self.mGluonAlgSel,self.mSnapDedupMode, self.mDedupTimeMSTh, self.mDedupSpaceTh, self.mDedupCompareTh) + \
                struct.pack('7i', self.mDedupTimeoutMSTh, self.mDedupIgnorTimeMSTh, self.mDedupPosPThres,
                            self.mDedupPosYThres, self.mDedupPosRThres, self.mDedupFltMinMs, self.mDedupFltPeriodMs) + \
                struct.pack('3fi', self.mDedupFltMinQual, self.mDedupFltFirstQual, self.mDedupFltDeltaQual, self.mDedupFltMinFace)

    def bytes_sizeof(self):
        return ctypes.sizeof(ctypes.c_int) * 12 + ctypes.sizeof(ctypes.c_float) * 4

#struct Face_Capture_Config_Para {
#	Video_Config_Para mVideoConfig;
#	Detect_Config_Para mDetectConfig;
#	Track_Config_Para mTrackConfig;
#	Face_Snap_Filter_Config_Para mSnapFilterConfig;
#	Face_Snap_Filter_Config_Dedup_Para mSnapFilterDedupConfig;
#};
class FaceCaptureConfigPara(StructBasic):
    #_pack_ = 1
    _fields_ = [("mVideoConfig", VideoCfgPara),
               ("mDetectConfig", DetectCfgPara),
               ("mTrackConfig", TrackCfgPara),
               ("mSnapFilterConfig", FaceSnapFilterCfgPara),
               ("mSnapFilterDedupConfig", FaceSnapFilterCfgDedupPara)
               ]

    @classmethod
    def from_bytes(_cls, _bytes, _offs = 0):
        mVideoConfig = VideoCfgPara.from_bytes(_bytes, _offs)
        _offs += mVideoConfig.bytes_sizeof()

        mDetectConfig = DetectCfgPara.from_bytes(_bytes, _offs)
        _offs += mDetectConfig.bytes_sizeof()

        mTrackConfig = TrackCfgPara.from_bytes(_bytes, _offs)
        _offs += mTrackConfig.bytes_sizeof()

        mSnapFilterConfig = FaceSnapFilterCfgPara.from_bytes(_bytes, _offs)
        _offs += mSnapFilterConfig.bytes_sizeof()

        mSnapFilterDedupConfig = FaceSnapFilterCfgDedupPara.from_bytes(_bytes,_offs)
        _offs += mSnapFilterDedupConfig.bytes_sizeof()

        # 构造对象并拷贝
        obj = _cls( mVideoConfig, mDetectConfig, mTrackConfig, mSnapFilterConfig, mSnapFilterDedupConfig)
        return obj

    def __init__(self, mVideoConfig, mDetectConfig, mTrackConfig, mSnapFilterConfig, mSnapFilterDedupConfig):
        self.mVideoConfig = mVideoConfig
        self.mDetectConfig = mDetectConfig
        self.mTrackConfig = mTrackConfig
        self.mSnapFilterConfig = mSnapFilterConfig
        self.mSnapFilterDedupConfig = mSnapFilterDedupConfig

    def bytes_sizeof(self):
        sz = self.mVideoConfig.bytes_sizeof()
        sz += self.mDetectConfig.bytes_sizeof()
        sz += self.mTrackConfig.bytes_sizeof()
        sz +=  self.mSnapFilterConfig.bytes_sizeof()
        sz += self. mSnapFilterDedupConfig.bytes_sizeof()
        return sz

    def __repr__(self):
        return 'mVideoConfig=%s,\nmDetectConfig =%s,\nmTrackConfig=%s,\nmSnapFilterConfig=%s,\nmSnapFilterDedupConfig=%s'  % (self.mVideoConfig, self.mDetectConfig, self.mTrackConfig, self.mSnapFilterConfig, self.mSnapFilterDedupConfig)

    def to_bytes(self):
        return self.mVideoConfig.to_bytes() + \
            self.mDetectConfig.to_bytes() + \
            self.mTrackConfig.to_bytes() + \
            self.mSnapFilterConfig.to_bytes() + \
            self.mSnapFilterDedupConfig.to_bytes()


import os.path
import jsonpickle
import getopt
import sys
from model.contact import Contact
from random import randint
import random
import string

try:
    opts, args = getopt.getopt(sys.argv[1:], "n:f:", ["number of groups", "file"])
except getopt.GetoptError as err:
    getopt.usage()
    sys.exit(2)
n = 5
f = "data/contacts.json"

for o, a in opts:
    if o == "-n":
        n = int(a)
    elif o == "-f":
        f = a

def random_name(length):
    symbols = string.ascii_letters
    return "".join(random.choice(symbols) for i in range(random.randrange(length)))

def random_address(length):
    symbols = string.ascii_letters + string.digits + " "*10
    return "".join(random.choice(symbols) for i in range(random.randrange(length)))

def random_phone():
    return str(randint(10000, 99999))

def random_email(length):
    symbols = string.ascii_letters + string.digits
    return "".join(random.choice(symbols) for i in range(random.randrange(1, length))) + "@" + \
           "".join(random.choice(symbols) for i in range(random.randrange(1, length))) + ".com"

testdata = [
    Contact(firstname=random_name(7), lastname=random_name(10), address=random_address(20),
            home=random_phone(), work=random_phone(), phone2=random_phone(),
            email=random_email(5), email2=random_email(6), email3=random_email(7))
    for i in range(3)
]

file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", f)
with open(file, "w") as out:
    jsonpickle.set_encoder_options("json", indent=2)
    out.write(jsonpickle.encode(testdata))


import ttkbootstrap as ttk
from ttkbootstrap.constants import *

my_w = ttk.Window()
my_w.geometry("400x150") # width and height of the window

b4= ttk.Checkbutton(my_w, text="Button Primary", bootstyle=INFO)
b4.grid(row=0, column=0, padx=30, pady=30)

b5= ttk.Checkbutton(my_w, text="Button Primary", bootstyle="success-toolbutton")
b5.grid(row=0, column=1, padx=30, pady=30)

b6= ttk.Checkbutton(my_w, text="Button Primary", bootstyle="success-toolbutton-outline")
b6.grid(row=1, column=0, padx=30, pady=30)

b7= ttk.Checkbutton(my_w, text="Button Primary", bootstyle="success-round-toggle")
b7.grid(row=1, column=1, padx=30, pady=30)

b7= ttk.Checkbutton(my_w, text="Button Primary", bootstyle="success-square-toggle",state="disable")
b7.grid(row=2, column=0, padx=30, pady=30)

my_w.mainloop()


# -*- coding:utf-8 -*-
"""
Created on '2016/1/26'

@author: '119937'
"""
import smtplib
from smtplib import SMTPException

from email.mime.text import MIMEText

sender = 'zhouyang014@deppon.com'
receivers = ['zhouyang014@deppon.com', 'gaoli005@deppon.com']

mailobj = smtplib.SMTP('client.deppon.com', '25')
message = """From:test
To:test,test2
Subject:test

    This is test e-mail.
"""

try:
    msg = MIMEText("Hello ,this is test e-mail", _subtype='plain', _charset='utf-8')
    msg['From'] = sender
    msg['To'] = receivers
    msg['Subject'] = "test"
    mailobj.sendmail(sender, receivers, msg.as_string())
    print("发送邮件成功！")
except SMTPException:
    print("Error:unable to send email")