# -*- coding: utf-8 -*-
import csv
import requests
import config as cfg
from requests.packages.urllib3.exceptions import InsecureRequestWarning
#import subprocess
#import sys
import os
#from requests.auth import HTTPBasicAuth
import json
import re
from dbconn import Dbconn
#from fulltext import Fulltext

_author_ = "Colin Sippl"
_organization_ = "University Library of Regensburg"
_email_ = "colin.sippl@ur.de"
_license_ = "GPL 3"

"""
VLP data parser for Invenio.
"""

class Parser:
    """
    This class parses CSV files.
    """

    INVENIO_SERVICE_URL = cfg.INVENIO_SERVICE_URL
    ROW_LIMIT = cfg.ROW_LIMIT
    REQUESTS_SSL_VERIFY = cfg.REQUESTS_SSL_VERIFY
    query_a = 'SELECT * FROM vl_literature and id >= 1 and id <=' + \
        str(ROW_LIMIT)
    #query_a = "SELECT * FROM vl_literature where volumeid is not null or startpages is not null LIMIT " + str(ROW_LIMIT)
    query_b = "SELECT * FROM vl_literature where volumeid is null and startpages is null and referencetype != 'Journal Article' LIMIT " + \
        str(ROW_LIMIT)

    # hide InsecureRequestWarning
    # https://stackoverflow.com/questions/27981545/suppress-insecurerequestwarning-unverified-https-request-is-being-made-in-pytho
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

    @staticmethod
    def parse_file(path):
        print(path)
        # https://docs.python.org/2/library/csv.html
        #response_array = []

        with open(path, 'r') as csvfile:
            reader = csv.DictReader(csvfile)
            number_rows = 0
            for row in reader:
                if number_rows < Parser.ROW_LIMIT:
                    record = Parser.create_records(row, True)
                    # response_array.append(record)
                    # Parser.create_people(row)
                    print(
                        "==========================================================================")
                    print("Zeile " + str(number_rows))
                    number_rows += 1

    # generate people entries from vl-people2.csv
    @staticmethod
    def parse_people_file(path):
        print(path)
        # https://docs.python.org/2/library/csv.html
        with open(path, 'rU') as csvfile:
            reader = csv.DictReader(csvfile, delimiter=';')
        #reader = csv.reader(open(path, 'rU'), dialect=csv.excel_tab, delimiter=';')
            number_rows = 0
            for row in reader:
                if number_rows < Parser.ROW_LIMIT:
                    # print(row)
                    Parser.create_people(row)
                    number_rows += 1

    @staticmethod
    def create_records_db(query, do_lines):
        dbconn = Dbconn()
        dbconn.connect()
        # reference, id, referencetype, author, title, "year", "date", volume,
        # secondarytitle, startpages, pages, sql_year, sql_date, fullreference,
        # shortreference, liseurl, lastupdate, volumeid, authorized, online, cd,
        # project, authorrefdisplay, yearrefdisplay, titlerefdisplay, detailsrefdisplay,
        # related, endnoteexport, volumeid_search, notes, transcription, url

        # id, author, title, "year", "date", volume,
        # secondarytitle, startpages, pages, sql_year, sql_date, fullreference,
        # shortreference, liseurl, lastupdate, volumeid, authorized, online, cd,
        # project, authorrefdisplay, yearrefdisplay, titlerefdisplay, detailsrefdisplay,
        # related, endnoteexport, volumeid_search, notes, transcription, url
        dbconn.execute_st(query)
        result = dbconn.fetch_result()
        dbconn.disconnect()
        records = []
        for data in result:

            json_data = {}
            json_data['identifier'] = data['reference']
            cref_data = {}
            cref = Parser.get_related_authors(data['reference'])
            if cref is not None:
                cref_data['$ref'] = "https://vlp.ur.de/api/resolver/author/" + cref
                json_data['authid'] = cref
                json_data['creator'] = cref_data
            json_data['title'] = data['title']
            if 'secondarytitle' in data:
                json_data['alternative'] = data['secondarytitle']
            #json_data['keywords'] = [data['referencetype']]
            json_data['type'] = data['referencetype']
            if 'year' in data:
                json_data['issued'] = data['year']
            #else:
            #    json_data['issued'] = data['created']
            #json_data['ocr'] = Fulltext.parse_ocr_files_for_id(data['reference'])

            if data['author'] is not None:
                #json_data['creator'] = data['author']
                #print(data[year'author'])
                json_data['contributors'] = Parser.get_authors(data['author'], cref, "author")
                #json_data['contributors'] = Parser.rebuild_refs_sites(data['author'], cref, "author")

            if 'volume' in data and data['volume'] is not None:
                json_data['volume'] = data['volume']

            if 'volume' in data and data['volume'] is not None:
                json_data['pages'] = data['pages']

            if data['referencetype'] == '(Journal)' or data['referencetype'] == '(JournalVolume)':
                json_data['title'] = data['secondarytitle']
            # else:
            # if  data['secondarytitle'] is not None and not Parser.is_empty(data['secondarytitle']):

            if 'detailsrefdisplay' in data and data['detailsrefdisplay'] is not None and not Parser.is_empty(data['detailsrefdisplay']):
                json_data['detailsRefDisplay'] = data['detailsrefdisplay']

            if 'volumeid' in data and data['volumeid'] is not None and not Parser.is_empty(data['volumeid']) and data['volumeid'] is not '':
                json_data['volume_id'] = data['volumeid']
                ref = {}
                ref['$ref'] = "https://vlp.ur.de/api/resolver/record/" + \
                    data['volumeid']
                json_data['record'] = ref

            if do_lines:
                Parser.post_record(json_data, 'records')
            else:
                records.append(json_data)

        return records

    @staticmethod
    def is_empty(field):
        return field.isspace()

    @staticmethod
    def get_related_authors(lit_reference):
        dbconn = Dbconn()
        dbconn.connect()
        query = "SELECT vl_people.reference FROM vl_literature, vl_people WHERE vl_people.fullname=vl_literature.author AND vl_literature.reference='" + lit_reference + "'"
        dbconn.execute_st(query)
        result = dbconn.fetch_result()
        dbconn.disconnect()
        if result is not None:
            for row in result:
                print(result)
                return row['reference']

    @staticmethod
    def create_people(query):
        dbconn = Dbconn()
        dbconn.connect()
        # id, created, created_by, modified_by, reference, marker, clip,
        # complete, "name", experiments, related, born, died, born_day, born_month,
        # born_year, died_day, died_month, died_year, first_name, career, degrees,
        # positions, technologies, main1, born_place, died_place, shortreference,
        # main2, main3, main4, main5, sources, image, comment_intern, literature,
        # sources2, fullname, lifespan4frontier, works, sourceslist, variationsname,
        # variationsfirstname, clip2, searchstring, lifespandisplay, marker2,
        # category, statistik, completed, customsearchstring, in_essay, bibliography,
        # imagesource, modified, article_autor, article_autor_url
        dbconn.execute_st(query)
        result = dbconn.fetch_result()
        dbconn.disconnect()
        people = []
        for row in result:
            people_data = {}
            #people_data['name'] = row['shortreference']
            # https://invenio-indexer.readthedocs.io/en/latest/usage.html#indexing-a-record
            people_data['$schema'] = 'http://vlp.ur.de/schemas/authors/author-v1.0.0.json'
            people_data['name'] = row['name']
            related_literature_ids = []
            if row['first_name'] is not None and row['first_name'] is not '':
                people_data['first_name'] = row['first_name']
            people_data['identifier'] = row['reference']
            if row['career'] is not None:
                people_data['career'] = Parser.rebuild_hyperlinks(row['career'], None)[0]
            if row['born_year'] is not None and row['died_year'] is not None:
                people_data['life_span'] = {"year_of_birth": int(
                    row['born_year']), "year_of_death": int(row['died_year'])}
            #life_span = Parser.get_life_span(row['shortReference'])
            #people_data['life_span'] = life_span
            if row['born_place'] is not None:
                people_data['born_place'] = row['born_place']
            if row['died_place'] is not None:
                people_data['died_place'] = row['died_place']
            if row['image'] is not None:
                people_data['image'] = row['image']
            if row['degrees'] is not None:
                people_data['degrees'] = row['degrees']

            if row['works'] is not None:
                people_data['references'] = Parser.rebuild_refs_sites(row['works'], None , None)

            #if do_lines:
            #    Parser.post_record(people_data, 'authors')
            #else:
            people.append(people_data)
            #Parser.post_record(people_data, 'authors')
            # people.append(people_data)

        for person in people:
            if 'references' in person:
                for reference in person['references']:
                    if 'identifier' in reference:
                        if reference['identifier'].startswith('lit'):
                            related_literature_ids.append(reference['identifier'])

        #print(related_literature_ids)
        people_literature = Parser.create_sites_literature(list(set(related_literature_ids)))
        Parser.create_json_file(people_literature, 'people_literature')

        return people

    @staticmethod
    def create_sites():
        #query = "SELECT * FROM public.vl_sites where reference='sit137'"
        query = 'SELECT * FROM vl_sites LIMIT ' + str(Parser.ROW_LIMIT)
        dbconn = Dbconn()
        dbconn.connect()
        dbconn.execute_st(query)
        result = dbconn.fetch_result()
        dbconn.disconnect()
        sites = []
        related_literature_ids = []
        for row in result:
            site = {}
            site['$schema'] = 'http://vlp.ur.de/schemas/sites/site-v1.0.0.json'
            site['identifier'] = row['reference']
            site['name'] = row['labname']

            if row['established'] is not None:
                site['date'] = row['established']
            if row['location'] is not None:
                site['location'] = row['location']

            keywordsb = Parser.get_labs_disciplines(row['labs_disciplines'])
            if len(keywordsb) > 0:
                site['keywordsb'] = keywordsb

            #site['keywordsb'] = [{'tag':'text'},{'tag':'toll'}]

            contributors = []
            contributor = {}
            if row['people_head'] is not None:
                contributors = contributors + Parser.rebuild_refs_sites(row['people_head'], None , "head")
            if row['people_architect'] is not None:
                contributors = contributors + Parser.rebuild_refs_sites(row['people_architect'], None, "architect")
            if row['people_deptheads'] is not None:
                contributors = contributors + Parser.rebuild_refs_sites(row['people_deptheads'], None, "depthead")
            if row['people_others'] is not None:
                contributors = contributors + Parser.rebuild_refs_sites(row['people_others'],None, "N/A")
            if row['people_assistants'] is not None:
                contributors = contributors + Parser.rebuild_refs_sites(row['people_assistants'],None, "assistant")

            if len(contributors) > 0:
                site['contributors'] = contributors
                #print(contributors)

            images = []
            if row['img1id'] is not None and row['img1id'] != '':
                images.append({"identifier" : row['img1id']})
            if row['img2id'] is not None and row['img2id'] != '':
                images.append({"identifier" : row['img2id']})
            if row['img3id'] is not None and row['img3id'] != '':
                images.append({"identifier" : row['img3id']})
            if row['img4id'] is not None and row['img4id'] != '':
                images.append({"identifier" : row['img4id']})

            if len(images) > 0:
                site['images'] = images
                #print(images)

            if row['further_descriptions'] != '':
                site['references'] = Parser.rebuild_refs_sites(row['further_descriptions'], None , None)

            sites.append(site)

        for site in sites:
            if 'references' in site:
                for reference in site['references']:
                    if 'identifier' in reference:
                        if reference['identifier'].startswith('lit'):
                            related_literature_ids.append(reference['identifier'])

        #print(related_literature_ids)
        site_literature = Parser.create_sites_literature(list(set(related_literature_ids)))
        Parser.create_json_file(site_literature, 'site_literature')

        return sites

    @staticmethod
    def create_sites_literature(related_literature_ids):
        literature = []
        for reference in related_literature_ids:
            query = "SELECT * FROM vl_literature WHERE reference='" + reference + "'"
            result = Parser.create_records_db(query, False)
            literature.append(result[0])

        return literature

    @staticmethod
    def create_people_old(data):
        people_data = {}
        people_data['name'] = data['shortReference']
        people_data['reference'] = data['reference']
        life_span = Parser.get_life_span(data['shortReference'])
        people_data['life_span'] = life_span
        Parser.post_record(people_data, 'authors')

    # delete?
    @staticmethod
    def get_authors(authors_string, pid, role):
        if authors_string is not None:
            authors_string = authors_string + '\n'
            authors = []
            pattern = re.compile(r"(.*?)\n")
            #x = re.findall(r"(.*?)\n", authors_string)
            # for author in x:
            #    print(author)
            for m in re.finditer(pattern, authors_string):
                contributor = {}
                if pid is not None and pid is not '':
                    contributor['identifier'] = pid
                if role is not None:
                    contributor['role'] = role
                if role is None:
                    contributor['role'] = "author"
                #if authors_string != "\n" and m.group(1) != "" and pid is not None:
                if authors_string != "\n" and m.group(1) != "":
                    contributor['name'] =  m.group(1)
                    print(contributor)
                    authors.append(contributor)

            # print(authors)
            return authors
        #else:
        #    return [{"name": "none"}]

    # delete?
    @staticmethod
    def get_date_span(shortReference):
        life_span = {}
        x = re.search(r"\((\d{4}) - (\d{4})\)", shortReference)
        if x:
            life_span["issued"] = int(x.group(1))
            life_span["year_of_death"] = int(x.group(2))
        else:
            life_span["year_of_birth"] = 0
            life_span["year_of_death"] = 0
        #print(x.group(1) + ' ' + x.group(2))
        return life_span

    # delete?
    @staticmethod
    def get_life_span(shortReference):
        life_span = {}
        x = re.search(r"\((\d{4}) - (\d{4})\)", shortReference)
        if x:
            life_span["year_of_birth"] = int(x.group(1))
            life_span["year_of_death"] = int(x.group(2))
        else:
            life_span["year_of_birth"] = 0
            life_span["year_of_death"] = 0
        #print(x.group(1) + ' ' + x.group(2))
        return life_span

    @staticmethod
    def get_labs_disciplines(labsdisciplines):
        labs_disciplines = []
        pattern = re.compile(r"(.*?)\n")
        for m in re.finditer(pattern, labsdisciplines):
            if m.group() is not '\n':
                labs_disciplines.append({"tag":m.group(1)})
        print(labs_disciplines)
        return labs_disciplines

    @staticmethod
    def rebuild_hyperlinks(pers_career, pid):
        #print(pers_career, pid)
        hit = re.search(r"(<link (.*?)>)(.*?)(<\/link>)", pers_career)
        #pid = None
        #print(pers_career, pid, hit)
        if hit is None:
            return pers_career, pid
        if hit is not None:
            pid = re.search(r"(ref=\"(.*?)\")",
                            hit.group().replace('""', '"')).group(2)
            replacement = hit.group().replace('""', '"').replace('<link ref', '<a href').replace('</link', '</a').replace(pid, Parser.get_url_from_pid(pid))
            pers_career = pers_career[:hit.span()[0]] + \
                    replacement + pers_career[hit.span()[1]:]
            pers_career, pid = Parser.rebuild_hyperlinks(pers_career, pid)
            return pers_career, pid

        #return '', ''
        return Parser.rebuild_hyperlinks(pers_career, pid)

    @staticmethod
    def rebuild_refs_sites(pers_career, references, role):
        hit = re.search(r"(<link (.*?)>)(.*?)(<\/link>)", pers_career)
        if references is None:
            references = []
        if hit is None and pers_career == '':
            return references
        if hit is None and pers_career != '':
            pattern = re.compile(r"(.*?)\n")
            for m in re.finditer(pattern, pers_career):
                if m.group() is not '\n':
                    reference = dict()
                    reference['name'] = m.group().replace('\n', '')
                    if role is not None:
                        reference['role'] = role
                    references.append(reference)
            return references
        if hit is not None:
            reference = {}
            if role is not None:
                reference['role'] = role
            #print(pers_career, "hit " + str(hit))
            pid_hit = re.search(r"(ref=\"(.*?)\")",
                            hit.group().replace('""', '"'))
            if pid_hit is None:
                return references
            pid = pid_hit.group(2)
            if pid.startswith('per'):
                reference['identifier'] = pid
                reference['$ref'] = "https://vlp.ur.de/api/resolver/author/" + \
                    pid
                pers_career = pers_career[hit.span()[1]:]
                references.append(reference)
                return Parser.rebuild_refs_sites(pers_career, references, role)
            if pid.startswith('lit'):
                reference['identifier'] = pid
                reference['$ref'] = "https://vlp.ur.de/api/resolver/record/" + \
                    pid
                pers_career = pers_career[hit.span()[1]:]
                references.append(reference)
                return Parser.rebuild_refs_sites(pers_career, references, None)
            # TODO Essays!!

            #if pid.startswith('sit') and pid:
            #    reference['$ref'] = "https://vlp.ur.de/api/resolver/site/" + \
            #        pid
            #    pers_career = pers_career[hit.span()[1]:]
            #    references.append(reference)
            #    return Parser.rebuild_refs_sites(pers_career, references, None)
            reference['identifier'] = pid
            replacement = hit.group().replace('""', '"').replace('<link ref', '<a href').replace('</link', '</a').replace(pid, Parser.get_url_from_pid(pid))
            reference['name'] = hit.group(3)
            reference['link'] = replacement
            pers_career = pers_career[hit.span()[1]:]
            references.append(reference)
            return Parser.rebuild_refs_sites(pers_career, references, role)

    @staticmethod
    def get_url_from_pid(pid):
        if pid.startswith('lit'):
            return "/records/" + pid
        if pid.startswith('per'):
            return "/authors/" + pid
        if pid.startswith('sit'):
            return "/sites/" + pid
        return "/records/" + pid

    @staticmethod
    def post_record(json_data, api_root):
        url = Parser.INVENIO_SERVICE_URL + "/api/" + api_root + "/?prettyprint=1"
        data = json.dumps(json_data, ensure_ascii=False).encode('utf-8')
        headers = {'content-type': 'application/json'}
        print("==================================" +
              json_data['identifier'] + "===================================")
        response = requests.post(
            url, data=data, headers=headers, verify=Parser.REQUESTS_SSL_VERIFY)
        if response.ok:
            print("Status code: " + str(response.status_code))
            print(json_data['identifier'] + " - success!")
            print("Message: " + response.text)
        else:
            print("Status code: " + str(response.status_code))
            print("Message: " + response.text)
            print(json.dumps(json_data, sort_keys=True, indent=4))
        print("===================================END====================================")

    @staticmethod
    def create_json_file(records_array, name):

        outfile = open(name + '.json', 'w', encoding='utf-8')
        #print(name)
        data = json.dumps(records_array, ensure_ascii=False, sort_keys=True, indent=4)
        #print(data)
        outfile.write(data)
        outfile.close()
        #json.dump(data, outfile, ensure_ascii=False, indent=4)

    @staticmethod
    def do_reindex_via_cli():
        """
        $ pipenv run invenio index reindex --pid-type recid --yes-i-know
        $ pipenv run invenio index run
        """
        p = os.popen(
            "pipenv run invenio index reindex --pid-type recid --yes-i-know")
        print(p.read())
        p = os.popen("pipenv run invenio index run")
        print(p.read())

if __name__ == "__main__":
    # Parser.parse_file('data/vlp.csv')
    # Parser.parse_people_file('data/VL-People2.csv')
    aut_str = """
Delacroix, Henri
E.Cassirer
L.Jordan
A.Sechehaye
W.Doroszewski
R.A.S.Paget
K.Bühler
H.Pongs
A.Meillet
J.Vendryes
P.Meriggi
V.Broendal
N.Trubetzkoy
Edward Sapir
J.van Ginneken
A.Sommerfelt
A.W.de Groot
O.Jespersen
Ch.Bally
Gustave Guillaume
A.Grégoire
M.Cohen
A.Gelb
K.Goldstein
"""
    Parser.get_authors(aut_str)

    vlp_links = '1633-1635 studied medicine in Leiden and Basel; M.D. 1637, University of Basel; 1641 moved to Amsterdam and worked there as a physician and was member of the <i>Amsterdam College of Physicians</i>; 1658 professor of medicine, University of Leiden; 1669-1670 vice chancellor of the University; 1671-1674 his main work <i>Praxeos medicae idea nova</i> was published in four volumes." \
"1858 studies of medicine at the University of Breslau under <link ref=""per86"">Rudolf Heidenhain</link> and in Berlin under <link ref=""per64"">Emil Du Bois-Reymond</link>; 1862 medical degree from the University of Berlin with a dissertation on invertebrate muscle physiology; 1864 assistant to <link ref=""per87"">Helmholtz</link> at the <link ref=""sit108"">Physiological Institute of the University of Heidelberg</link>; 1870 Privatdozent; 1871 associate professor and acting head of the Physiological Institute at Heidelberg; later that year return to Berlin; 1872 professor of physiology at the University of Halle in succession to <link ref=""per169"">Friedrich Goltz</link>; founder and director of the physiology institute at Halle (1881)." \
"Studied medicine for several years in Göttingen; 1823 M.D. at the University of Göttingen with a dissertation entitled <i>De cauterio actuali seu de igne ut medicamento</i>; 1824 worked on practical medicine at the University of Berlin and 1825 on zoology and comparative anatomy at the Sorbonne, Paris; 1825 habilitation, University of Göttingen; 1835 associate professor, same institution; 1836 professor of zoology and comparative anatomy at the faculty of medicine, University of Göttingen; since 1840 director of the zoological collection; founded the scientific study of hormones; 1861 retirement.<link ref="lit15702" page="p0007tablevii">Rabbit holder according to Czermak</link>'
    Parser.rebuild_hyperlinks(vlp_links)


"""Marshmallow bindings for indy proofs."""

from typing import Mapping, Sequence

from marshmallow import EXCLUDE, fields, validate

from ...messaging.models.base import BaseModel, BaseModelSchema
from ...messaging.valid import (
    INDY_CRED_DEF_ID_EXAMPLE,
    INDY_CRED_DEF_ID_VALIDATE,
    INDY_REV_REG_ID_EXAMPLE,
    INDY_REV_REG_ID_VALIDATE,
    INDY_SCHEMA_ID_EXAMPLE,
    INDY_SCHEMA_ID_VALIDATE,
    INT_EPOCH_EXAMPLE,
    INT_EPOCH_VALIDATE,
    NUM_STR_ANY_EXAMPLE,
    NUM_STR_ANY_VALIDATE,
    NUM_STR_WHOLE_EXAMPLE,
    NUM_STR_WHOLE_VALIDATE,
)
from ...utils.tracing import AdminAPIMessageTracingSchema
from .predicate import Predicate
from .requested_creds import (
    IndyRequestedCredsRequestedAttrSchema,
    IndyRequestedCredsRequestedPredSchema,
)

class IndyEQProof(BaseModel):
    """Equality proof for indy primary proof."""

    class Meta:
        """Equality proof metadata."""

        schema_class = "IndyEQProofMeta"

    def __init__(
        self,
        revealed_attrs: Mapping[str, str] = None,
        a_prime: str = None,
        e: str = None,
        v: str = None,
        m: Mapping[str, str] = None,
        m2: str = None,
        **kwargs,
    ):
        """Initialize equality proof object."""
        super().__init__(**kwargs)
        self.revealed_attrs = revealed_attrs
        self.a_prime = a_prime
        self.e = e
        self.v = v
        self.m = m
        self.m2 = m2

class IndyEQProofSchema(BaseModelSchema):
    """Indy equality proof schema."""

    class Meta:
        """Indy equality proof metadata."""

        model_class = IndyEQProof
        unknown = EXCLUDE

    revealed_attrs = fields.Dict(
        keys=fields.Str(metadata={"example": "preference"}),
        values=fields.Str(
            validate=NUM_STR_ANY_VALIDATE, metadata={"example": NUM_STR_ANY_EXAMPLE}
        ),
    )
    a_prime = fields.Str(
        validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
    )
    e = fields.Str(
        validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
    )
    v = fields.Str(
        validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
    )
    m = fields.Dict(
        keys=fields.Str(metadata={"example": "master_secret"}),
        values=fields.Str(
            validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
        ),
    )
    m2 = fields.Str(
        validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
    )

class IndyGEProofPred(BaseModel):
    """Indy GE proof predicate."""

    class Meta:
        """Indy GE proof predicate metadata."""

        schema_class = "IndyGEProofPredSchema"

    def __init__(
        self,
        attr_name: str = None,
        p_type: str = None,
        value: int = None,
        **kwargs,
    ):
        """Initialize indy GE proof predicate."""
        super().__init__(**kwargs)
        self.attr_name = attr_name
        self.p_type = p_type
        self.value = value

class IndyGEProofPredSchema(BaseModelSchema):
    """Indy GE proof predicate schema."""

    class Meta:
        """Indy GE proof predicate metadata."""

        model_class = IndyGEProofPred
        unknown = EXCLUDE

    attr_name = fields.Str(
        metadata={"description": "Attribute name, indy-canonicalized"}
    )
    p_type = fields.Str(
        validate=validate.OneOf([p.fortran for p in Predicate]),
        metadata={"description": "Predicate type"},
    )
    value = fields.Integer(
        metadata={"strict": True, "description": "Predicate threshold value"}
    )

class IndyGEProof(BaseModel):
    """Greater-than-or-equal-to proof for indy primary proof."""

    class Meta:
        """GE proof metadata."""

        schema_class = "IndyGEProofMeta"

    def __init__(
        self,
        u: Mapping[str, str] = None,
        r: Mapping[str, str] = None,
        mj: str = None,
        alpha: str = None,
        t: Mapping[str, str] = None,
        predicate: IndyGEProofPred = None,
        **kwargs,
    ):
        """Initialize GE proof object."""
        super().__init__(**kwargs)
        self.u = u
        self.r = r
        self.mj = mj
        self.alpha = alpha
        self.t = t
        self.predicate = predicate

class IndyGEProofSchema(BaseModelSchema):
    """Indy GE proof schema."""

    class Meta:
        """Indy GE proof schema metadata."""

        model_class = IndyGEProof
        unknown = EXCLUDE

    u = fields.Dict(
        keys=fields.Str(),
        values=fields.Str(
            validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
        ),
    )
    r = fields.Dict(
        keys=fields.Str(),
        values=fields.Str(
            validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
        ),
    )
    mj = fields.Str(
        validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
    )
    alpha = fields.Str(
        validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
    )
    t = fields.Dict(
        keys=fields.Str(),
        values=fields.Str(
            validate=NUM_STR_WHOLE_VALIDATE, metadata={"example": NUM_STR_WHOLE_EXAMPLE}
        ),
    )
    predicate = fields.Nested(IndyGEProofPredSchema)

class IndyPrimaryProof(BaseModel):
    """Indy primary proof."""

    class Meta:
        """Indy primary proof metadata."""

        schema_class = "IndyPrimaryProofSchema"

    def __init__(
        self,
        eq_proof: IndyEQProof = None,
        ge_proofs: Sequence[IndyGEProof] = None,
        **kwargs,
    ):
        """Initialize indy primary proof."""
        super().__init__(**kwargs)
        self.eq_proof = eq_proof
        self.ge_proofs = ge_proofs

class IndyPrimaryProofSchema(BaseModelSchema):
    """Indy primary proof schema."""

    class Meta:
        """Indy primary proof schema metadata."""

        model_class = IndyPrimaryProof
        unknown = EXCLUDE

    eq_proof = fields.Nested(
        IndyEQProofSchema,
        allow_none=True,
        metadata={"description": "Indy equality proof"},
    )
    ge_proofs = fields.Nested(
        IndyGEProofSchema,
        many=True,
        allow_none=True,
        metadata={"description": "Indy GE proofs"},
    )

class IndyNonRevocProof(BaseModel):
    """Indy non-revocation proof."""

    class Meta:
        """Indy non-revocation proof metadata."""

        schema_class = "IndyNonRevocProofSchema"

    def __init__(
        self,
        x_list: Mapping = None,
        c_list: Mapping = None,
        **kwargs,
    ):
        """Initialize indy non-revocation proof."""
        super().__init__(**kwargs)
        self.x_list = x_list
        self.c_list = c_list

class IndyNonRevocProofSchema(BaseModelSchema):
    """Indy non-revocation proof schema."""

    class Meta:
        """Indy non-revocation proof schema metadata."""

        model_class = IndyNonRevocProof
        unknown = EXCLUDE

    x_list = fields.Dict(keys=fields.Str(), values=fields.Str())
    c_list = fields.Dict(keys=fields.Str(), values=fields.Str())

class IndyProofProofProofsProof(BaseModel):
    """Indy proof.proof.proofs constituent proof."""

    class Meta:
        """Indy proof.proof.proofs constituent proof schema."""

        schema_class = "IndyProofProofProofsProofSchema"

    def __init__(
        self,
        primary_proof: IndyPrimaryProof = None,
        non_revoc_proof: IndyNonRevocProof = None,
        **kwargs,
    ):
        """Initialize proof.proof.proofs constituent proof."""
        super().__init__(**kwargs)
        self.primary_proof = primary_proof
        self.non_revoc_proof = non_revoc_proof

class IndyProofProofProofsProofSchema(BaseModelSchema):
    """Indy proof.proof.proofs constituent proof schema."""

    class Meta:
        """Indy proof.proof.proofs constituent proof schema metadata."""

        model_class = IndyProofProofProofsProof
        unknown = EXCLUDE

    primary_proof = fields.Nested(
        IndyPrimaryProofSchema, metadata={"description": "Indy primary proof"}
    )
    non_revoc_proof = fields.Nested(
        IndyNonRevocProofSchema,
        allow_none=True,
        metadata={"description": "Indy non-revocation proof"},
    )

class IndyProofProofAggregatedProof(BaseModel):
    """Indy proof.proof aggregated proof."""

    class Meta:
        """Indy proof.proof aggregated proof metadata."""

        schema_class = "IndyProofProofAggregatedProofSchema"

    def __init__(
        self,
        c_hash: str = None,
        c_list: Sequence[Sequence[int]] = None,
        **kwargs,
    ):
        """Initialize indy proof.proof agreggated proof."""
        super().__init__(**kwargs)
        self.c_hash = c_hash
        self.c_list = c_list

class IndyProofProofAggregatedProofSchema(BaseModelSchema):
    """Indy proof.proof aggregated proof schema."""

    class Meta:
        """Indy proof.proof aggregated proof schema metadata."""

        model_class = IndyProofProofAggregatedProof
        unknown = EXCLUDE

    c_hash = fields.Str(metadata={"description": "c_hash value"})
    c_list = fields.List(
        fields.List(fields.Int(metadata={"strict": True})),
        metadata={"description": "c_list value"},
    )

class IndyProofProof(BaseModel):
    """Indy proof.proof content."""

    class Meta:
        """Indy proof.proof content metadata."""

        schema_class = "IndyProofProofSchema"

    def __init__(
        self,
        proofs: Sequence[IndyProofProofProofsProof] = None,
        aggregated_proof: IndyProofProofAggregatedProof = None,
        **kwargs,
    ):
        """Initialize indy proof.proof content."""
        super().__init__(**kwargs)
        self.proofs = proofs
        self.aggregated_proof = aggregated_proof

class IndyProofProofSchema(BaseModelSchema):
    """Indy proof.proof content schema."""

    class Meta:
        """Indy proof.proof content schema metadata."""

        model_class = IndyProofProof
        unknown = EXCLUDE

    proofs = fields.Nested(
        IndyProofProofProofsProofSchema,
        many=True,
        metadata={"description": "Indy proof proofs"},
    )
    aggregated_proof = fields.Nested(
        IndyProofProofAggregatedProofSchema,
        metadata={"description": "Indy proof aggregated proof"},
    )

class RawEncoded(BaseModel):
    """Raw and encoded attribute values."""

    class Meta:
        """Raw and encoded attribute values metadata."""

        schema_class = "RawEncodedSchema"

    def __init__(
        self,
        raw: str = None,
        encoded: str = None,
        **kwargs,
    ):
        """Initialize raw and encoded attribute values."""
        super().__init__(**kwargs)
        self.raw = raw
        self.encoded = encoded

class RawEncodedSchema(BaseModelSchema):
    """Raw and encoded attribute values schema."""

    class Meta:
        """Raw and encoded attribute values schema metadata."""

        model_class = RawEncoded
        unknown = EXCLUDE

    raw = fields.Str(metadata={"description": "Raw value"})
    encoded = fields.Str(
        validate=NUM_STR_ANY_VALIDATE,
        metadata={"description": "Encoded value", "example": NUM_STR_ANY_EXAMPLE},
    )

class IndyProofRequestedProofRevealedAttr(RawEncoded):
    """Indy proof requested proof revealed attr."""

    class Meta:
        """Indy proof requested proof revealed attr metadata."""

        schema_class = "IndyProofRequestedProofRevealedAttrSchema"

    def __init__(
        self,
        sub_proof_index: int = None,
        **kwargs,
    ):
        """Initialize indy proof requested proof revealed attr."""
        super().__init__(**kwargs)
        self.sub_proof_index = sub_proof_index

class IndyProofRequestedProofRevealedAttrSchema(RawEncodedSchema):
    """Indy proof requested proof revealed attr schema."""

    class Meta:
        """Indy proof requested proof revealed attr schema metadata."""

        model_class = IndyProofRequestedProofRevealedAttr
        unknown = EXCLUDE

    sub_proof_index = fields.Int(
        metadata={"strict": True, "description": "Sub-proof index"}
    )

class IndyProofRequestedProofRevealedAttrGroup(BaseModel):
    """Indy proof requested proof revealed attr group."""

    class Meta:
        """Indy proof requested proof revealed attr group metadata."""

        schema_class = "IndyProofRequestedProofRevealedAttrGroupSchema"

    def __init__(
        self,
        sub_proof_index: int = None,
        values: Mapping[str, RawEncoded] = None,
        **kwargs,
    ):
        """Initialize indy proof requested proof revealed attr."""
        super().__init__(**kwargs)
        self.sub_proof_index = sub_proof_index
        self.values = values

class IndyProofRequestedProofRevealedAttrGroupSchema(BaseModelSchema):
    """Indy proof requested proof revealed attr group schema."""

    class Meta:
        """Indy proof requested proof revealed attr group schema metadata."""

        model_class = IndyProofRequestedProofRevealedAttrGroup
        unknown = EXCLUDE

    sub_proof_index = fields.Int(
        metadata={"strict": True, "description": "Sub-proof index"}
    )
    values = fields.Dict(
        keys=fields.Str(),
        values=fields.Nested(RawEncodedSchema),
        metadata={
            "description": "Indy proof requested proof revealed attr groups group value"
        },
    )

class IndyProofRequestedProofPredicate(BaseModel):
    """Indy proof requested proof predicate."""

    class Meta:
        """Indy proof requested proof requested proof predicate metadata."""

        schema_class = "IndyProofRequestedProofPredicateSchema"

    def __init__(
        self,
        sub_proof_index: int = None,
        **kwargs,
    ):
        """Initialize indy proof requested proof predicate."""
        super().__init__(**kwargs)
        self.sub_proof_index = sub_proof_index

class IndyProofRequestedProofPredicateSchema(BaseModelSchema):
    """Indy proof requested prrof predicate schema."""

    class Meta:
        """Indy proof requested proof requested proof predicate schema metadata."""

        model_class = IndyProofRequestedProofPredicate
        unknown = EXCLUDE

    sub_proof_index = fields.Int(
        metadata={"strict": True, "description": "Sub-proof index"}
    )

class IndyProofRequestedProof(BaseModel):
    """Indy proof.requested_proof content."""

    class Meta:
        """Indy proof.requested_proof content metadata."""

        schema_class = "IndyProofRequestedProofSchema"

    def __init__(
        self,
        revealed_attrs: Mapping[str, IndyProofRequestedProofRevealedAttr] = None,
        revealed_attr_groups: Mapping[
            str,
            IndyProofRequestedProofRevealedAttrGroup,
        ] = None,
        self_attested_attrs: Mapping = None,
        unrevealed_attrs: Mapping = None,
        predicates: Mapping[str, IndyProofRequestedProofPredicate] = None,
        **kwargs,
    ):
        """Initialize indy proof requested proof."""
        super().__init__(**kwargs)
        self.revealed_attrs = revealed_attrs
        self.revealed_attr_groups = revealed_attr_groups
        self.self_attested_attrs = self_attested_attrs
        self.unrevealed_attrs = unrevealed_attrs
        self.predicates = predicates

class IndyProofRequestedProofSchema(BaseModelSchema):
    """Indy proof requested proof schema."""

    class Meta:
        """Indy proof requested proof schema metadata."""

        model_class = IndyProofRequestedProof
        unknown = EXCLUDE

    revealed_attrs = fields.Dict(
        keys=fields.Str(),
        values=fields.Nested(IndyProofRequestedProofRevealedAttrSchema),
        allow_none=True,
        metadata={"description": "Proof requested proof revealed attributes"},
    )
    revealed_attr_groups = fields.Dict(
        keys=fields.Str(),
        values=fields.Nested(IndyProofRequestedProofRevealedAttrGroupSchema),
        allow_none=True,
        metadata={"description": "Proof requested proof revealed attribute groups"},
    )
    self_attested_attrs = fields.Dict(
        metadata={"description": "Proof requested proof self-attested attributes"}
    )
    unrevealed_attrs = fields.Dict(metadata={"description": "Unrevealed attributes"})
    predicates = fields.Dict(
        keys=fields.Str(),
        values=fields.Nested(IndyProofRequestedProofPredicateSchema),
        metadata={"description": "Proof requested proof predicates."},
    )

class IndyProofIdentifier(BaseModel):
    """Indy proof identifier."""

    class Meta:
        """Indy proof identifier metadata."""

        schema_class = "IndyProofIdentifierSchema"

    def __init__(
        self,
        schema_id: str = None,
        cred_def_id: str = None,
        rev_reg_id: str = None,
        timestamp: int = None,
        **kwargs,
    ):
        """Initialize indy proof identifier."""
        super().__init__(**kwargs)
        self.schema_id = schema_id
        self.cred_def_id = cred_def_id
        self.rev_reg_id = rev_reg_id
        self.timestamp = timestamp

class IndyProofIdentifierSchema(BaseModelSchema):
    """Indy proof identifier schema."""

    class Meta:
        """Indy proof identifier schema metadata."""

        model_class = IndyProofIdentifier
        unknown = EXCLUDE

    schema_id = fields.Str(
        validate=INDY_SCHEMA_ID_VALIDATE,
        metadata={
            "description": "Schema identifier",
            "example": INDY_SCHEMA_ID_EXAMPLE,
        },
    )
    cred_def_id = fields.Str(
        validate=INDY_CRED_DEF_ID_VALIDATE,
        metadata={
            "description": "Credential definition identifier",
            "example": INDY_CRED_DEF_ID_EXAMPLE,
        },
    )
    rev_reg_id = fields.Str(
        allow_none=True,
        validate=INDY_REV_REG_ID_VALIDATE,
        metadata={
            "description": "Revocation registry identifier",
            "example": INDY_REV_REG_ID_EXAMPLE,
        },
    )
    timestamp = fields.Int(
        allow_none=True,
        validate=INT_EPOCH_VALIDATE,
        metadata={
            "strict": True,
            "description": "Timestamp epoch",
            "example": INT_EPOCH_EXAMPLE,
        },
    )

class IndyProof(BaseModel):
    """Indy proof."""

    class Meta:
        """Indy proof metadata."""

        schema_class = "IndyProofSchema"

    def __init__(
        self,
        proof: IndyProofProof = None,
        requested_proof: IndyProofRequestedProof = None,
        identifiers: Sequence[IndyProofIdentifier] = None,
        **kwargs,
    ):
        """Initialize indy proof."""
        super().__init__(**kwargs)
        self.proof = proof
        self.requested_proof = requested_proof
        self.identifiers = identifiers

class IndyProofSchema(BaseModelSchema):
    """Indy proof schema."""

    class Meta:
        """Indy proof schema metadata."""

        model_class = IndyProof
        unknown = EXCLUDE

    proof = fields.Nested(
        IndyProofProofSchema, metadata={"description": "Indy proof.proof content"}
    )
    requested_proof = fields.Nested(
        IndyProofRequestedProofSchema,
        metadata={"description": "Indy proof.requested_proof content"},
    )
    identifiers = fields.Nested(
        IndyProofIdentifierSchema,
        many=True,
        metadata={"description": "Indy proof.identifiers content"},
    )

class IndyPresSpecSchema(AdminAPIMessageTracingSchema):
    """Request schema for indy proof specification to send as presentation."""

    self_attested_attributes = fields.Dict(
        required=True,
        keys=fields.Str(metadata={"example": "attr_name"}),
        values=fields.Str(
            metadata={
                "example": "self_attested_value",
                "description": (
                    "Self-attested attribute values to use in requested-credentials"
                    " structure for proof construction"
                ),
            }
        ),
        metadata={"description": "Self-attested attributes to build into proof"},
    )
    requested_attributes = fields.Dict(
        required=True,
        keys=fields.Str(metadata={"example": "attr_referent"}),
        values=fields.Nested(IndyRequestedCredsRequestedAttrSchema),
        metadata={
            "description": (
                "Nested object mapping proof request attribute referents to"
                " requested-attribute specifiers"
            )
        },
    )
    requested_predicates = fields.Dict(
        required=True,
        keys=fields.Str(metadata={"example": "pred_referent"}),
        values=fields.Nested(IndyRequestedCredsRequestedPredSchema),
        metadata={
            "description": (
                "Nested object mapping proof request predicate referents to"
                " requested-predicate specifiers"
            )
        },
    )
    trace = fields.Bool(
        required=False,
        metadata={
            "description": "Whether to trace event (default false)",
            "example": False,
        },
    )


# -*- coding: utf-8 -*-
# from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from django.conf import settings

import hashlib

# TPL
from lxml import etree

from receive_message import BasicReceive, TextMsg, ImageMsg
from response_message import BasicResponse, Text
from how_old import handle_how_old
from tuling_robot import handle_tuling_robot

# Receive message type from wechat user.
REC_MESSAGE_TYPE_TEXT = u'text'
REC_MESSAGE_TYPE_IMAGE = u'image'
REC_MESSAGE_TYPE_VOICE = u'voice'
REC_MESSAGE_TYPE_VIDEO = u'video'
REC_MESSAGE_TYPE_SHORTVIDEO = u'shortvideo'
REC_MESSAGE_TYPE_LOCATION = u'location'
REC_MESSAGE_TYPE_LINK = u'link'
REC_MESSAGE_TYPE_EVENT = u'event'

# Event type from wechat user.
EVENT_SUBSCRIBE = u'subscribe'
EVENT_UNSUBSCRIBE = u'unsubscribe'
EVENT_SCAN = u'SCAN'
EVENT_LOCATION = u'LOCATION'
EVENT_CLICK = u'CLICK'
EVENT_VIEW = u'VIEW'

# Response message types to wechat user.
RESP_MESSAGE_TYPE_TEXT = u'text'
RESP_MESSAGE_TYPE_IMAGE = u'image'
RESP_MESSAGE_TYPE_VOICE = u'voice'
RESP_MESSAGE_TYPE_VIDEO = u'video'
RESP_MESSAGE_TYPE_MUSIC = u'music'
RESP_MESSAGE_TYPE_NEWS = u'news'
MESSAGE_TYPE = [u'text', u'image', u'voice', u'video', u'music', u'news']

# 订阅号或服务号的token
TOKEN = settings.WECHAT_TOKEN

@csrf_exempt
def wechat_varify(request):
    """Basic function used to conmunicate with wechat.

    GET means wechat server make connection with django server.
    POST means wechat user send message to wechat server and transfer to django server,
    And django server response message back to wechat server and transfer to wechat user.
    """
    if request.method == "GET":
        # Wechat server sent GET request to the URL to verify.
        return HttpResponse(WechatRequest.get_request(request), content_type="text/plain")
    elif request.method == "POST":
        # Wechat user POST the message to the URL with XML format.
        return HttpResponse(WechatRequest.post_request(request), content_type="application/xml")
    else:
        return None

class WechatRequest(object):

    """Implement the basic function for GET and POST.

    request is django.http.HttpRequest object.
    response is django.http.HttpResponse object.
    """

    @staticmethod
    def get_request(request):
        u"""Wechat server use http GET to make connect with django server.

        将token、timestamp、nonce三个参数进行字典序排序
        将三个参数字符串拼接成一个字符串进行sha1加密
        开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        """
        signature = request.GET.get("signature", None)
        timestamp = request.GET.get("timestamp", None)
        nonce = request.GET.get("nonce", None)
        echostr = request.GET.get("echostr", None)
        token = TOKEN

        tmp_list = [token, timestamp, nonce]
        tmp_list.sort()

        # Wechat office method
        sha1 = hashlib.sha1()
        map(sha1.update, tmp_list)
        hashcode = sha1.hexdigest()

        # My own method
        # tmp_str = '%s%s%s' % tuple(tmp_list)
        # hashcode = hashlib.sha1(tmp_str).hexdigest()

        if hashcode == signature:
            return echostr
        else:
            return None

    @staticmethod
    def post_request(request):
        """When get message or event from wechat user(wechat server), django server response something.

        This is just reply the message and event.
        Not django server use http to post message to wechat server(wechat user).
        """
        request_map = MessageUtil.parse_xml(request)
        receive_basic_object = BasicReceive(request_map)
        MsgType = receive_basic_object.MsgType
        ToUserName = receive_basic_object.ToUserName
        FromUserName = receive_basic_object.FromUserName

        # Response to different request message type.
        if MsgType == REC_MESSAGE_TYPE_TEXT:
            receive_text_object = TextMsg(request_map)
            receive_content = receive_text_object.Content
            response_content = handle_tuling_robot(receive_content, FromUserName)
            # If return nothing from tuling robot.
            if not response_content:
                response_content = u"只识别人话哦，别说鸟语!"
            response_text_object = Text(FromUserName, ToUserName, response_content)
            return response_text_object.response()
        elif MsgType == REC_MESSAGE_TYPE_IMAGE:
            receive_image_object = ImageMsg(request_map)
            PicUrl = receive_image_object.PicUrl
            response_content = handle_how_old(PicUrl)
            # If return nothing from how-old.net.
            if not response_content:
                response_content = u"只识别男女哦，不要发人妖!"
            response_image_object = Text(FromUserName, ToUserName, response_content)
            return response_image_object.response()
        elif MsgType == REC_MESSAGE_TYPE_VOICE:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_VIDEO:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_SHORTVIDEO:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_LOCATION:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_LINK:
            return BasicResponse().response()
        elif MsgType == REC_MESSAGE_TYPE_EVENT:
            return BasicResponse().response()
            Event = request_map.get(u'Event')
            if Event == EVENT_SUBSCRIBE:
                return BasicResponse().response()
            elif Event == EVENT_UNSUBSCRIBE:
                return BasicResponse().response()
            elif Event == EVENT_SCAN:
                return BasicResponse().response()
            elif Event == EVENT_LOCATION:
                return BasicResponse().response()
            elif Event == EVENT_CLICK:
                return BasicResponse().response()
            elif Event == EVENT_VIEW:
                return BasicResponse().response()
            else:
                return BasicResponse().response()
        else:
            return BasicResponse().response()

class MessageUtil(object):

    """Tools to transfer xml and string format messages.

    Wechat server POST the xml format message to django server,
    And django server need to POST xml format message to wechat server too.
    Define the message type, and get the message with xml format and parser it.
    """

    @staticmethod
    def parse_xml(request):
        """Parse receive message with xml format from wechat server."""
        str_xml = request.body.decode(u'utf-8')
        req_xml = etree.fromstring(str_xml)
        dict_xml = {}
        for node0 in req_xml:
            dict_tmp0 = {}
            for node1 in node0.getchildren():
                dict_tmp0[node1.tag] = node1.text
            if any(dict_tmp0):
                dict_xml[node0.tag] = dict_tmp0
            else:
                dict_xml[node0.tag] = node0.text
        return dict_xml


import datetime
import uuid
import threading
from flet import (
    AlertDialog,
    AppBar,
    Column,
    Container,
    ElevatedButton,
    Icon,
    Page,
    PopupMenuButton,
    PopupMenuItem,
    UserControl,
    View,
    colors,
    Row,
    Text,
    TextField,
    TextButton,
    ButtonStyle,
    icons,
    padding,
    theme,
    IconButton,
    RoundedRectangleBorder
)

from add_patient_view import AddPatientView
from patients_list_view import PatientsListView
from data_simulator import Simulator
from users import Patient, PatientList

class PatientsView(UserControl):
    def __init__(self, app, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.app = app
        self.patients_list = PatientList()
        self.patients_list_view = PatientsListView(self)
        self.data_simulator=Simulator(self)
        self.build()
        threading.Thread(target=self.data_simulator.simulate).start()

    def build(self):
        self.layout =Container(
             Column([
                Row(
                    [
                     Text(value="Waiting Patients", style="headlineMedium",text_align="center"),
                     TextButton(
                                "Add new Patient",
                                icon=icons.ADD,
                                on_click=self.add_patient_dialog,
                                style=ButtonStyle(
                                    bgcolor=colors.BLUE_400,
                                    shape={"": RoundedRectangleBorder(radius=3)},
                                ),

                            )

                    ],
                ),
                Row(
                    [
                        TextField(
                            hint_text="Search all Patients",
                            autofocus=False,
                            content_padding=padding.only(left=10),
                            width=400,
                            height=40,
                            text_size=12,
                            border_color=colors.BLACK26,
                            focused_border_color=colors.BLUE_ACCENT,
                            suffix_icon=icons.SEARCH,

                        )
                    ]
                ),
                Row([Container(self.patients_list_view,height=600,width=800)]),
            ],
            expand=True,
        ),
        padding=padding.only(top=15, left=15),
        )

        return self.layout

    def add_patient_dialog(self, e):
        self.page.dialog = AddPatientView(self)
        self.page.dialog.open=True
        self.page.update()

    def add_patient(self, e):
        self.page.dialog.open=False
        self.page.update()
        name = self.page.dialog.content.controls[0].value
        age = self.page.dialog.content.controls[1].value
        address = self.page.dialog.content.controls[2].value
        location = self.page.dialog.content.controls[3].value
        complaint = self.page.dialog.content.controls[4].value
        Ctas = self.page.dialog.content.controls[5].value
        current_time = datetime.datetime.now()
        p=Patient(str(uuid.uuid4()),name,age,address,location,current_time,complaint,Ctas)
        self.patients_list.add_patient(p)
        self.patients_list_view.refresh()

    def refresh(self):
        self.patients_list_view.refresh()

    def cancel_add_patient(self, e):
        self.page.dialog.open=False
        self.page.update()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import csv
from io import StringIO
from string import Template
import requests
import json
from xml.etree import ElementTree

# get Brazilian states

filein = 'unidades-federativas.csv'

states = {}

with open(filein) as f:
    reader = csv.DictReader(f)
    for row in reader:
        states[row['Sigla']] = {
            'nome': row['Nome'],
            'ativo': False
            }

# get list of data catalogs

csv_url = 'https://github.com/dadosgovbr/catalogos-dados-brasil/raw/master/dados/catalogos.csv'

catalogs = []

r = requests.get(csv_url)

if r.status_code != 200:
    raise IOError('Cannot download data catalogs table from Github repository.')

reader = csv.DictReader(StringIO(r.text))

for row in reader:
    catalogs.append(row)

# check which states have catalogs

for catalog in catalogs:
    if catalog['UF'] in list(states.keys()):
        states[catalog['UF']]['ativo'] = True

# generate area activation script

filein = 'activate_areas.js'

with open(filein) as f:
    activate_script_template = Template(f.read())

habilitados_dict = {}

for state in list(states.keys()):
    if states[state]['ativo']:
        habilitados_dict[states[state]['nome']] = '1'

activate_areas_script = activate_script_template.substitute({'habilitados_dict': json.dumps(habilitados_dict)})

# generate map colors

filein = 'mapa.svg'

ns = {'svg': 'http://www.w3.org/2000/svg'}
ElementTree.register_namespace('', 'http://www.w3.org/2000/svg')

tree = ElementTree.parse(filein)

for a in tree.findall('svg:g[@id="Estados"]/svg:a', ns):
    state = a.get('data-target')[-2:]
    path = a.find('svg:path', ns)
    if states[state]['ativo']:
        xml_class = path.get('class').replace(' inactive','')
        xml_class += ' active'
        path.set('class', xml_class)

map_svg = ElementTree.tostring(tree.getroot()).decode()

# generate modals

filein = 'modal_template.html'

with open(filein) as f:
    modal_template = Template(f.read())

filein = 'catalog_template.html'

with open(filein) as f:
    catalog_template = Template(f.read())

modal_section = ''

for state in sorted(states.keys()):
    if states[state]['ativo']:
        modal_html = ''
        catalog_list = ''
        municipal_catalogs = {}

        for catalog in catalogs:
            if catalog['UF'] == state:
                catalog_type = ''
                if catalog['Solução'] == 'CKAN':
                    catalog_type = ''
                # add state catalogs
                if not catalog['Município']:
                    catalog_list += catalog_template.substitute({
                        'catalog_title': catalog['Título'],
                        'catalog_url': catalog['URL'],
                        'catalog_type': catalog_type,
                        })
                else:
                    catalogs_in_this_municipality = municipal_catalogs.setdefault(catalog['Município'], [])
                    catalogs_in_this_municipality.append(catalog)

        # add municipal catalogs
        for municipality, municipal_catalogs in list(municipal_catalogs.items()):
            municipality_html = '
{}
'.format(municipality)
            municipality_html += "
"
            for catalog in municipal_catalogs:
                catalog_type = ''
                if catalog['Solução'] == 'CKAN':
                    catalog_type = ''
                municipality_html += catalog_template.substitute({
                    'catalog_title': catalog['Título'],
                    'catalog_url': catalog['URL'],
                    'catalog_type': catalog_type,
                    })
            municipality_html += "
"
            catalog_list += municipality_html

        modal_html = modal_template.substitute({
            'state_abbr': state,
            'state_name': states[state]['nome'],
            'catalog_list': catalog_list
            })
        modal_section += modal_html

# national catalogs

catalog_list = ''
for catalog in catalogs:
    if not catalog['UF']:
        catalog_type = ''
        if catalog['Solução'] == 'CKAN':
            catalog_type = ''
        catalog_list += catalog_template.substitute({
            'catalog_title': catalog['Título'],
            'catalog_url': catalog['URL'],
            'catalog_type': catalog_type,
            })
modal_section += modal_template.substitute({
            'state_abbr': 'BR',
            'state_name': 'Nacionais',
            'catalog_list': catalog_list
            })

# generate page

filein = 'template-pagina.html'

with open(filein) as f:
    page_template = Template(f.read())

page_html = page_template.substitute({
    'activate_areas_script': activate_areas_script,
    'map_svg': map_svg,
    'modal_section': modal_section
    })

fileout = 'outras-iniciativas.html'

with open(fileout, 'w') as f:
    f.write(page_html)


from flask import Flask, render_template, request, url_for, redirect, flash
import tmdb_client
import datetime

app = Flask(__name__)
app.secret_key = b'2MSjdNsi7n@!N@#@$!@#sd'

@app.route("/")
def homepage():
    movie_lists = ["now_playing", "top_rated", "popular", "upcoming"]
    selected_list = request.args.get("list_type", "popular")
    if selected_list not in movie_lists:
        movies = tmdb_client.get_movies(8, list_name="popular")
        return render_template("homepage.html", movies=movies, selected_list="", movie_lists=movie_lists)
    else:
        movies = tmdb_client.get_movies(8, list_name=selected_list)
    return render_template("homepage.html", movies=movies, selected_list=selected_list, movie_lists=movie_lists)

@app.context_processor
def utility_processor():
    def tmdb_image_url(path, size):
        return tmdb_client.get_poster_url(path, size)
    return {"tmdb_image_url": tmdb_image_url}

@app.route("/movie/<movie_id>")
def movie_details(movie_id):
    details = tmdb_client.get_single_movie(movie_id)
    people = tmdb_client.get_single_movie_cast(movie_id)[:12]
    image_url = tmdb_client.get_poster_url(tmdb_client.get_single_image(movie_id), "w780")
    return render_template("movie_details.html", movie=details, people=people, image=image_url)

@app.route("/search")
def search():
    search_query = request.args.get("q", "")
    if search_query:
        movies = tmdb_client.search_movie(search_query=search_query)
    else:
        movies = []
    return render_template("search.html", movies=movies, search_query=search_query)

@app.route("/airing")
def airing():
    today = datetime.date.today()
    movies = tmdb_client.airing_today()
    return render_template("airing.html", movies=movies, today=today)

FAVORITES = set()

@app.route("/favorites/add", methods=["POST"])
def add_to_favorites():
    data = request.form
    movie_id = data.get("movie_id")
    title = data.get("movie_title")
    if movie_id and title:
        FAVORITES.add(movie_id)
    flash(f"{title} added to favourites")
    return redirect(url_for("homepage"))

@app.route("/favorites")
def favorites():
    movies = []
    if FAVORITES:
        for item in FAVORITES:
            result = tmdb_client.get_single_movie(item)
            movies.append(result)

    return render_template("favorites.html", movies=movies)

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


class Solution:
    def countWords(self, words1: List[str], words2: List[str]) -> int:
        w1 = Counter(words1)
        w2 = Counter(words2)
        ans = 0

        for word in words1:
            if w1[word] == 1 and w2[word] == 1:
                ans += 1

        return ans

String/2085. Count Common Words With One Occurrence.py


'''
write simple python code to scrape ads from website bazos.cz parse them and store its data in pandas dataframe
Here is a simple Python code to scrape ads from the website bazos.cz, parse the data, and store it in a Pandas DataFrame:
'''

import pandas as pd
import requests
from bs4 import BeautifulSoup

#url = 'https://www.bazos.cz/search.php?hledat=mazda+mx5&rubriky=www&hlokalita=&humkreis=25&cenaod=&cenado=&Submit=Hledat&kitx=ano'
#res = requests.get(url)
#soup = BeautifulSoup(res.text, 'html.parser')

read_from_web = 0

if (read_from_web):
    page = requests.get('https://www.bazos.cz/search.php?hledat=mazda+mx5&hlokalita=&humkreis=25&cenaod=10000&cenado=&order=1')
    # Create a BeautifulSoup object
    soup = BeautifulSoup(page.text, 'html.parser')
    # get the repo list
else:
    with open("ad.html") as fp:
        soup = BeautifulSoup(fp, 'html.parser')

ads = soup.find_all('div', {'class': 'inzeraty inzeratyflex'})

data = []
for ad in ads:
    title = ad.find('h2', {'class': 'nadpis'}).text
    price = ad.find('div', {'class': 'inzeratycena'}).text
    location = ad.find('div', {'class': 'inzeratylok'}).text
    data.append([title, price, location])
    #print(type(ad))
    #print(ad.text)
    #break

df = pd.DataFrame(data, columns=['Title', 'Price', 'Location', 'Text'])
#df = pd.DataFrame(data, columns=['Title', 'Price', 'Location'])

print(df)


import dash_core_components as dcc
import dash_bootstrap_components as dbc
import dash_html_components as html
import datetime
from dash.dependencies import Input, Output
import time

import pandas as pd
import plotly.express as px

from app import app
from components import range_slider as RangeSlider, default_card, country_dropdown
from helpers import time_helper

df_clean = None

def layout(data):
    global df_clean
    df_clean = data.sort_values(by='date')

    return html.Div(children=[
        dbc.Alert("Overzicht totale omzet per land", color="info",
                  style={'text-align': 'center'}),
        html.Div(
            country_dropdown.show(
                dropdownId="country-rev-select",
                placeholder="Selecteer een of meerdere landen",
                df_clean=data,
                labelsColumn='country_name',
                valuesColumn='country_name'
            )
        ),
        html.Br(),
        dcc.Tabs(id='country-rev-tabs', value='tab-1', children=[
            dcc.Tab(label='Cirkel diagram',
                    value='tab-1'),
            dcc.Tab(label='Lijn diagram', value='tab-2')]),
        html.Div(id='country-rev-tabs-content'),
        html.Br(),
        default_card.showCard(
            RangeSlider.show(df_clean, 'country-rev-date-slider')
        )
    ])

@app.callback(Output('country-rev-tabs-content', 'children'),
              [Input('country-rev-tabs', 'value')])
def render_country_rev_content(tab):
    global df_clean

    if tab == 'tab-1':
        countryPieChart = px.pie(
            df_clean['omzet']
            .groupby(df_clean['country_name'])
            .sum()
            .reset_index(),
            values='omzet',
            names='country_name'
        )
        countryPieChart.update_traces(
            textposition='inside',
            textinfo='percent+label'
        )

        return html.Div([
            dcc.Graph(id='country-rev-pie',
                      figure=countryPieChart)
        ])

    elif tab == 'tab-2':
        return html.Div([
            dcc.Graph(id="country-rev-line",
                      figure=px.line(
                        df_clean.groupby([df_clean.date.dt.strftime(
                            '%Y-%m-%d'), df_clean.country_name])['omzet']
                        .sum().reset_index(), x='date', y='omzet', color='country_name'))
        ])

@app.callback(
    Output('country-rev-pie', 'figure'),
    [Input('country-rev-select', 'value'),
     Input('country-rev-date-slider', 'value')])
def update_country_rev_fig_pie(countries_selected, between_date):
    country_rev_df = df_clean

    if between_date is not None:
        country_rev_df = country_rev_df[
            df_clean['date'].between(time_helper.unix_to_datetime(between_date[0]),
                                     time_helper.unix_to_datetime(between_date[1]))]

    if countries_selected is not None and len(countries_selected) > 0:
        country_rev_df = country_rev_df.loc[df_clean['country_name'].isin(
            countries_selected)]

    country_rev_df = country_rev_df['omzet'].groupby(
        df_clean['country_name']).sum().reset_index()

    countryPieChart = px.pie(
        country_rev_df, values='omzet', names='country_name')
    countryPieChart.update_traces(
        textposition='inside',
        textinfo='percent+label'
    )

    return countryPieChart

@app.callback(
    Output('country-rev-line', 'figure'),
    [Input('country-rev-select', 'value'),
     Input('country-rev-date-slider', 'value')])
def update_country_rev_fig_line(countries_selected, between_date):
    global df_clean
    country_rev_df = df_clean

    if between_date is not None:
        country_rev_df = country_rev_df[df_clean['date'].between(
            time_helper.unix_to_datetime(between_date[0]), time_helper.unix_to_datetime(between_date[1]))]

    if countries_selected is not None and len(countries_selected) > 0:
        country_rev_df = country_rev_df.loc[df_clean['country_name'].isin(
            countries_selected)]

    country_rev_df = country_rev_df.groupby([df_clean.date.dt.strftime(
        '%Y-%m-%d'), df_clean.country_name])['omzet'].sum().reset_index()

    return px.line(country_rev_df, x='date', y='omzet', color='country_name')


import time
import pygame
import logging
from constants import *
from client.utils import *

log = logging.getLogger(__name__)

DEBUG_SERVER_POSITION = 1 << 0
DEBUG_NO_PLAYER = 1 << 1
DEBUG_PREDICTED_POSITION = 1 << 2

DEBUG = DEBUG_SERVER_POSITION | DEBUG_PREDICTED_POSITION
DEBUG = 0

# by how much we predict the position and move to it
PREDICTION = 0

class Player:

    def __init__(self, username, pos, color, fonts):

        self.server_pos = pos
        self.pos = list(self.server_pos)

        self.color = color
        self.username = username

        self.rect = pygame.Rect((0, 0), PLAYER_SIZE)

        # the predicted position
        self.predicted_pos = None

        self.last_server_update = time.time()
        self.fonts = fonts

    def update_state(self, new_server_pos):
        """ Update state from the server

        Rule #1:

        Every time I receive a server update, I make a prediction about where the
        player will be at the next server update. We assume that the direction
        of the player between the 2 server updates will be the same in the next
        update (this will obviously be wrong sometimes, but it will be
        corrected by rule #2)

        Rule #2:

        Whatever happens, I have to get to the predicted position  exactly on
        the next server update.
        """

        self.last_server_update = time.time()

        self.predicted_pos = [
            new_server_pos[0] + (new_server_pos[0] - self.server_pos[0]) * PREDICTION,
            new_server_pos[1] + (new_server_pos[1] - self.server_pos[1]) * PREDICTION
        ]

        self.server_pos = new_server_pos

        # direction = [
        #     arg(new_server_pos[0] - self.server_pos[0]),
        #     arg(new_server_pos[1] - self.server_pos[1])
        # ]
        # self.last_pos = self.pos
        # self.server_pos = new_server_pos

        # predicted_change = [
        #     direction[0] * PLAYER_SPEED * SERVER_REFRESH_RATE,
        #     direction[1] * PLAYER_SPEED * SERVER_REFRESH_RATE,
        # ]

        # self.prediction =

    def update(self):
        """ Update state in between server updates """
        if self.predicted_pos:
            percentage_done = (time.time() - self.last_server_update) / SERVER_REFRESH_RATE
            dx = percentage_done * (self.predicted_pos[0] - self.pos[0])
            dy = percentage_done * (self.predicted_pos[1] - self.pos[1])
            self.pos = [self.pos[0] + dx, self.pos[1] + dy]

        self.rect.left = int(round(self.pos[0]))
        self.rect.top = int(round(self.pos[1]))

    def render(self, surf, srect):
        if self.pos is None:
            log.warning(f"{self} position is None")
            return

        with fontedit(self.fonts.mono, fgcolor=self.color) as font:
            rect = font.get_rect(self.username)
            rect.midbottom = self.rect.midtop
            rect.top -= 10
            font.render_to(surf, rect, self.username)

        if not DEBUG & DEBUG_NO_PLAYER:
            pygame.draw.rect(surf, self.color, self.rect)

        if DEBUG & DEBUG_SERVER_POSITION:
            pygame.draw.rect(surf, self.color,
                             pygame.Rect(self.server_pos, PLAYER_SIZE), 1)

        if DEBUG & DEBUG_PREDICTED_POSITION and self.predicted_pos:
            r = pygame.Rect(self.predicted_pos, PLAYER_SIZE)
            pygame.draw.rect(surf, self.color, r, 1)
            pygame.draw.rect(surf, self.color, r.inflate(-4, -4), 1)

    def __str__(self):
        return f"<c.Player {self.username!r} {self.pos}>"

    def __repr__(self):
        return str(self)


# -*- coding:utf-8 -*-
# ！/usr/bin/env python
# @Time : 2023/7/28 14:25
# @Author : waxberry
# @File : 2. Python xlwt 写入 操作Excel（仅限xls格式！）.py
# @Software : PyCharm

import xlwt

# 2.2 使用xlwt创建新表格并写入

# 编写xlwt新表格写入程序:
# 3.2.2 使用xlwt创建新表格并写入
def fun3_2_2():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')
    # 保存
    worksheet.save('新创建的表格.xls')

# 2.3 xlwt 设置字体格式
def fun3_2_3():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 初始化样式
    style = xlwt.XFStyle

    # 为样式创建字体
    font = xlwt.Font()
    font.name = 'Times New Roman'#字体
    font.bold = True # 加粗
    font.underline = True #下划线
    font.italic = True #斜体
    # 设置样式
    style.font = font

    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')
    # 保存
    worksheet.save('新创建的表格.xls')

# 2.4 xlwt 设置列宽
def fun3_2_4():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')

    # 设置列宽
    worksheet.col(0).width = 256*20

    # 保存
    worksheet.save('新创建的表格.xls')

# 2.5 xlwt 设置行高
def fun3_2_5():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')

    # 设置行高
    style = xlwt.easyxf('font:height 360;')# 18pt,类型小初的字号
    row = worksheet.row(0)
    row.set_style(style)

    # 保存
    worksheet.save('新创建的表格.xls')

# 2.6 xlwt 合并列和行
def fun3_2_6():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')

    # 合并第1行到第2行的第0列到第3列
    worksheet.write_merge(1, 2, 0, 3, 'Merge Test')

    # 保存
    worksheet.save('新创建的表格.xls')

# 2.7 xlwt 添加边框
def fun3_2_7():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')

    # 设置边框样式
    borders = xlwt.Borders()# Create Borders

    # May be:   NO_LINE, THIN, MEDIUM, DASHED, DOTTED, THICK, DOUBLE, HAIR,
    #           MEDIUM_DASHED, THIN_DASH_DOTTED, MEDIUM_DASH_DOTTED, THIN_DASH_DOT_DOTTED,
    #           MEDIUM_DASH_DOT_DOTTED, SLANTED_MEDIUM_DASH_DOTTED, or 0x00 through 0x0D.
    # DASHED虚线
    # NO_LINE没有
    # THIN实线
    borders.left = xlwt.Borders.DASHED
    borders.right = xlwt.Borders.DASHED
    borders.top = xlwt.Borders.DASHED
    borders.bottom = xlwt.Borders.DASHED
    borders.left_colour = 0x40
    borders.right_colour = 0x40
    borders.top_colour = 0x40
    borders.bottom_colour = 0x40

    style = xlwt.XFStyle() # Create Style
    style.borders = borders# Add Borders to Style
    worksheet.write(0, 0, '内容1', style)
    worksheet.write(2, 1, '内容2')
    # 保存
    worksheet.save('新创建的表格.xls')

# 2.8 xlwt为单元格设置背景色
def fun3_2_8():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')

    # 创建样式
    pattern = xlwt.Pattern()

    # May be: NO_PATTERN, SOLID_PATTERN, or 0x00 through 0x12
    pattern.pattern = xlwt.Pattern.SOLID_PATTERN

    # May be: 8 through 63. 0 = Black, 1 = White, 2 = Red, 3 = Green, 4 = Blue, 5 = Yellow,
    # 6 = Magenta, 7 = Cyan, 16 = Maroon, 17 = Dark Green, 18 = Dark Blue, 19 = Dark Yellow ,
    # almost brown), 20 = Dark Magenta, 21 = Teal, 22 = Light Gray, 23 = Dark Gray, the list goes on...
    pattern.pattern_fore_colour = 5
    style = xlwt.XFStyle()
    style.pattern = pattern

    # 使用样式
    worksheet.write(2, 1, '内容2', style)

# 2.9 xlwt设置单元格对齐
def fun3_2_9():
    # 创建新的workbook（其实就是创建新的excel）
    workbook = xlwt.Workbook(encoding='ascii')
    # 创建新的sheet表
    worksheet = workbook.add_sheet('My New Sheet')
    # 往表格写入内容
    worksheet.write(0, 0, '内容1')
    worksheet.write(2, 1, '内容2')

    # 设置样式
    style = xlwt.XFStyle()
    al = xlwt.Alignment()
    # VERT_TOP = 0x00       上端对齐
    # VERT_CENTER = 0x01    居中对齐（垂直方向上）
    # VERT_BOTTOM = 0x02    低端对齐
    # HORZ_LEFT = 0x01      左端对齐
    # HORZ_CENTER = 0x02    居中对齐（水平方向上）
    # HORZ_RIGHT = 0x03     右端对齐
    al.horz = 0x02# 设置水平居中
    al.vert = 0x01# 设置垂直居中
    style.alignment = al

    # 对齐写入
    worksheet.write(2, 1, '内容2', style)
    # 保存
    worksheet.save('新创建的表格.xls')

tools/Python办公自动化excel/2. Python xlwt 写入 操作Excel（仅限xls格式！）.py


#!/usr/bin/env python
#
# Title: observer pattern implementation for App Engine
# Author: Domenico Pontari
# Email: fairsayan@gmail.com
# Website: http://it.linkedin.com/in/pontari/
#
# Rif about observer design pattern: http://it.wikipedia.org/wiki/Observer_pattern
# Basic idea: http://stackoverflow.com/questions/1904351/python-observer-pattern-examples-tips?answertab=votes#tab-top
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
import Called

class Caller():
  def resume(self, event):
    logging.info ('Resumed caller...')

  def __init__(self):
    called = Called.Called()
    called.subscribe('resume', __name__, self)
    logging.info ('Running called object method...')
    called.run()


import operator
import pytesseract
import timeit
import difflib
from appenv import app_multiprocessing
from difflib import get_close_matches
from pytesseract import Output
from difflib import SequenceMatcher
from mongo.Ingredient import Ingredient
from mongo.IngredientRead import IngredientRead
from rust.PreProcess import *

class Tesseract:
    def __init__(self, image):
        self.image = image

    def pre_process(self):
        image = self.image
        # image = resize_compress(image)
        image = grayscale(image)
        # image = opening(image)
        image = thresholding(image)
        # image = invert_color(image)
        image = deskew(image)

        return image

    def get_text(self):
        image = self.pre_process()
        user_words_path = __file__.replace('rust/Tesseract.py', 'assets/user-words.txt')
        text = pytesseract.image_to_string(image, lang='por+eng', config='--user-words ' + user_words_path)
        return text.replace('\n', '')

        # load_freq_dawg
        # load_punc_dawg
        # load_number_dawg
        # load_unambig_dawg
        # load_bigram_dawg
        # load_fixed_length_dawgs')

    def get_matches(self):
        async def ingredients_p():
            return Ingredient.objects.values_list('name')
        async def image_text_p():
            image_text = self.get_text().replace(';', ',').replace(':', ',')
            return [text.strip() for text in image_text.split(',')]

        [ingredients, texts] = app_multiprocessing.process_all([ingredients_p(), image_text_p()])
        async def find_best_match(text):
            matches = difflib.get_close_matches(text, ingredients)
            best_match = matches[0] if matches else None
            accuracy = SequenceMatcher(None, best_match, text).ratio() if best_match else 0
            return IngredientRead(name=text, accuracy=accuracy, best_match=Ingredient(name=best_match))

        matches_tasks = [find_best_match(text) for text in texts]
        matches = app_multiprocessing.process_all(matches_tasks)
        matches_names = [match['best_match']['name'] for match in matches if match['best_match']['name']]
        matches_search = Ingredient.objects(name__in=matches_names)

        for match in matches:
            match_search = [search for search in matches_search if search['name'] == match['best_match']['name']]
            if match_search:
                match['best_match'] = match_search[0]

        return matches

    def get_matches_deadline(self, deadline):
        start = timeit.default_timer()
        matches = list(self.get_matches())
        end = timeit.default_timer()
        diff = end - start
        return [match for match in matches if match['accuracy'] > deadline]


from flask import Blueprint, render_template, redirect, request, url_for, flash , Flask , Response , session, flash, send_file
from app import app, bcrypt, mysql
from app.forms import *
from PIL import Image
from uuid import uuid4
import os
from app.utils import *
basedir = os.getcwd()

endpoint = Blueprint("product", __name__)

@endpoint.route('/product')
@is_admin
def product():
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT * FROM product')
    products = cursor.fetchall()
    return render_template('admin/product/product.html', products=products)

@endpoint.route('/addproduct', methods=['GET', 'POST'])
@is_admin
def addproduct():
    form = ProductForm(request.form)
    if request.method == 'POST' and form.validate():
        cursor = mysql.connection.cursor()
        cursor.execute('SELECT * FROM product WHERE product_name = %s', (form.productname.data,))
        product = cursor.fetchone()
        if product is None:
            product_id = str(uuid4())[:8]
            cursor.execute('INSERT INTO product VALUES (%s, %s, %s, %s, %s, %s)', (product_id, form.productname.data, form.productdesc.data, form.productprice.data, form.productstock.data, 'Active',))
            cursor.connection.commit()
            img = Image.open(request.files["productimage"])
            img.load()
            img.resize((1200, 600))
            img.convert("RGB")
            img.save(f"{basedir}/app/static/media/product_img/{product_id}.png")
            return redirect(url_for('product.product'))
        else:
            flash('Product Exists', category='error')
            return redirect(request.referrer)
    return render_template('admin/product/product_form.html', form=form)

@endpoint.route('/productdetails/<id>')
@is_admin
def productdetails(id):
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT * FROM product WHERE product_id = %s', (id,))
    product = cursor.fetchone()
    return render_template('admin/product/productdetails.html', product=product)

# @endpoint.route('/updateproduct/<id>', methods=['GET', 'POST'])
# def updateproduct(id):
#     form = ProductForm(request.form)
#     if request.method == 'POST' and form.validate():
#         cursor = mysql.connection.cursor()
#         cursor.execute('UPDATE product SET WHERE')

@endpoint.route('/deleteproduct/<id>', methods=['POST'])
@is_admin
def deleteproduct(id):
    cursor = mysql.connection.cursor()
    cursor.execute('DELETE FROM product WHERE product_id = %s', (id,))
    cursor.connection.commit()
    return redirect(request.referrer)

@endpoint.route('/status_product/<id>', methods=['POST'])
@is_admin
def product_status(id):
    cursor = mysql.connection.cursor()
    cursor.execute('SELECT * FROM product WHERE product_id = %s', (id,))
    product = cursor.fetchone()
    if product['product_status'] == 'Active':
        cursor.execute('UPDATE product SET product_status = %s WHERE product_id = %s', ('Inactive', id,))
    else:
        cursor.execute('UPDATE product SET product_status = %s WHERE product_id = %s', ('Active', id,))
    cursor.connection.commit()
    return redirect(request.referrer)

@endpoint.route('/deleteimg/')
def deleteimg():
    filepath = request.args.get('filepath', type=str, default="")
    if filepath != '':
        try:
            if os.path.isfile('app/'+filepath):
                os.remove('app/'+filepath)
            else:
                print('error deleting')
        except:
            print('some error idk')
    else:
        print('error')
    return redirect(request.referrer)


# -*- coding: utf-8 -*-
"""
@author: Wojciech Jankowiak
"""
from os import path, walk
from copy import deepcopy
import numpy as np

def load_data_from_coords(IMAGES_DIRECTORY):
    data = []
    labels = []
    for current_dir, dirs, filenames in walk(IMAGES_DIRECTORY):
      label = path.basename(path.normpath(current_dir))
      converted = convertLabel(label)
      for filename in filenames:
          extracted = extractData(path.join(current_dir, filename))
          for part in extracted:
              image = load_image_from_coord(part)
              data.append(image)
              labels.append(converted)
    return labels, np.asarray(data)

def load_image_from_coord(part):
    image_template = np.zeros((128,128))
    for x_coord, y_coord in part:
        if x_coord <128 and y_coord <128:
            image_template[x_coord, y_coord] = 1
    return image_template

def extractData(file):
    extracted =[]
    with open(file) as f:
        f.readline()
        f.readline()
        part = []
        for line in f:
          if 'snap' in line :
              c = deepcopy(part)
              extracted.append(c)
          else:
            part.append([int(x) for x in line.split()])
    return extracted

def convertLabel(label):
    if(label == "accident"):
        return 0
    elif label == "bomb" :
        return 1
    elif label == "car" :
        return 2
    elif label == "casualty" :
        return 3
    elif label == "electricity" :
        return 4
    elif label == "fire" :
        return 5
    elif label == "fire_brigade" :
        return 6
    elif label == "flood" :
        return 7
    elif label == "gas" :
        return 8
    elif label == "injury" :
        return 9
    elif label == "paramedics" :
        return 10
    elif label == "person" :
        return 11
    elif label == "police" :
        return 12
    elif label == "roadblock" :
        return 13


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

df=pd.read_csv('https://gist.githubusercontent.com/pravalliyaram/5c05f43d2351249927b8a3f3cc3e5ecf/raw/8bd6144a87988213693754baaa13fb204933282d/Mall_Customers.csv')
print(df)

#Let us perform grouping of the customers based on Annual Income and Spending score

x=df.iloc[:,3:]
x2=df.iloc[:,3:]
x3=df.iloc[:,3:]
print(x)

#Let us find the number of clusters k is required
wcss=[]

for i in range(1,15):
    alg_kmean=KMeans(n_clusters=i,init='k-means++',random_state=30)
    alg_kmean.fit(x)
    wcss.append(alg_kmean.inertia_) # inertia is = within cluster summation square)

print(wcss)
#Let us build the elbow graph to find the number of k
plt.plot(range(1,15),wcss)
plt.show()

#From the elbow graph we can find the k as 5

alg_Kmean2=KMeans(n_clusters=5,init='k-means++',random_state=30)
alg_Kmean2.fit_predict(x)

x['cluster_numbers']=alg_Kmean2.fit_predict(x)
print(x)

print(x[x['cluster_numbers']==4])

print(x[x['cluster_numbers']==0])

print(alg_Kmean2.predict([[55,31]]))

#Let us see using mini batch Kmean

from sklearn.cluster import MiniBatchKMeans
alg_minibatch=MiniBatchKMeans(n_clusters=5)
alg_minibatch.fit_predict(x2)

x2['mini_labels']=alg_minibatch.fit_predict(x2)
print(x2)
print(x2[x2['mini_labels']==2])
print(alg_minibatch.predict([[55,31]]))

#Let us perform using DBSCAN

from sklearn.cluster import DBSCAN
alg_dbscan=DBSCAN(eps=1,min_samples=3)
alg_dbscan.fit(x3)
print(alg_dbscan.labels_)
#Total number of clusters
print(set(alg_dbscan.labels_))
#Total lenght of the clusters
print(len(set(alg_dbscan.labels_)))
#Group -1 indicates that it is a noise or outlier where it is not able to accupi it to any of the cluster

x3['dbscan_labels']=alg_dbscan.labels_
print(x3)

#Let us see the accuracy of the cluster algorithm

from sklearn.metrics import jaccard_score,accuracy_score,rand_score,adjusted_rand_score

#Take Kmean out put as client label or ground truth table
print(jaccard_score(x['cluster_numbers'],x3['dbscan_labels'],average='macro'))


import torch
import torch.optim as optim
from models.umberto_custom import UmbertoCustom
from data.loaders import get_train_valid_test_coarse, get_train_valid_test_fine
from test import evaluate
from utils.training_utils import save_checkpoint, load_checkpoint
import time

def train(model, optimizer, train_loader, valid_loader, num_epochs, eval_every,
          file_path, best_valid_loss=float("Inf")):
    # initialize running values
    running_loss = 0.0
    valid_running_loss = 0.0
    global_step = 0
    train_loss_list = []
    valid_loss_list = []
    global_steps_list = []

    # training loop
    model.train()
    print("init train")
    for epoch in range(num_epochs):
        for labels, text in train_loader:
            labels = labels.type(torch.LongTensor)
            labels = labels.to(device)
            text = text.type(torch.LongTensor)
            text = text.to(device)
            output = model(text, labels)
            loss, _ = output

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            # update running values
            running_loss += loss.item()
            global_step += 1

            # evaluation step
            if global_step % eval_every == 0:
                model.eval()
                with torch.no_grad():

                    # validation loop
                    for val_labels, val_text in valid_loader:
                        val_labels = val_labels.type(torch.LongTensor)
                        val_labels = val_labels.to(device)
                        val_text = val_text.type(torch.LongTensor)
                        val_text = val_text.to(device)
                        output = model(val_text, val_labels)
                        loss, _ = output

                        valid_running_loss += loss.item()

                # evaluation
                average_train_loss = running_loss / eval_every
                average_valid_loss = valid_running_loss / len(valid_loader)
                train_loss_list.append(average_train_loss)
                valid_loss_list.append(average_valid_loss)
                global_steps_list.append(global_step)

                # resetting running values
                running_loss = 0.0
                valid_running_loss = 0.0
                model.train()

                # print progress
                print('Epoch [{}/{}], Step [{}/{}], Train Loss: {:.4f}, Valid Loss: {:.4f}'
                      .format(epoch + 1, num_epochs, global_step, num_epochs * len(train_loader),
                              average_train_loss, average_valid_loss))

                # checkpoint
                if best_valid_loss > average_valid_loss:
                    best_valid_loss = average_valid_loss
                    save_checkpoint(file_path + '/' + 'model2.pt', model, best_valid_loss)

    print('Finished Training!')

if __name__ == "__main__":
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    print(device)

    bert_model = "Musixmatch/umberto-commoncrawl-cased-v1"
    # bert_model = "idb-ita/gilberto-uncased-from-camembert"
    num_classes = 11

    bert = UmbertoCustom(bert_model=bert_model, num_classes=num_classes).to(device)

    train_iter, valid_iter, test_iter = get_train_valid_test_fine(bert_model=bert_model, max_seq_lenght=512)

    opt = optim.Adam(bert.parameters(), lr=2e-5)
    init_time = time.time()

    train(model=bert, optimizer=opt, train_loader=train_iter, valid_loader=valid_iter, num_epochs=5,
          eval_every=len(train_iter) // 2, file_path="../data/models/")

    tot_time = time.time() - init_time
    print("time taken:", int(tot_time // 60), "minutes", int(tot_time % 60), "seconds")

    best_model = UmbertoCustom(bert_model=bert_model, num_classes=num_classes).to(device)

    load_checkpoint("../data/models" + '/model2.pt', best_model, device)

    evaluate(best_model, test_iter, num_classes, device)


# 20200811 - Input()
x, k = map(int, input().split())
pol = list(input().split())
ans = ""
for i in range(len(pol)):
    ans = ans + pol[i]
result = eval(ans)
if int(result) == k:
    print("True")
else:
    print("False")


from tests import SpiderTestCase
from tests.fixtures import response_from_file
from desafio_xkcd.spiders.xkcd_spider import XKCDSpider

class TestXKCDSpider(SpiderTestCase):

    def setUp(self) -> None:
        self.spider = XKCDSpider()

    def test_find_all_attr_href(self) -> None:
        response = response_from_file('html/archive_page.html')
        hrefs = self.spider.extract_hrefs_from_archive(response)
        self.assertEqual(len(hrefs), 2582)

    def test_parse_archive_page_call_find_url_image_to_download(self) -> None:
        response = self.execute_method(
            name_method='parse_archive_page',
            fixture='html/archive_page.html'
        )
        url = 'http://www.exemplo.com/2583/'
        requests = response['requests']
        self.assertEqual(len(requests), 2582)
        self.assertEqual(requests[0].url, url)
        self.assertEqual(requests[0].callback, self.spider.find_url_image_to_download)
        self.assertEqual(requests[0].cb_kwargs['href'], '/2583/')

    def test_find_attr_src(self) -> None:
        response = response_from_file('html/2583_page.html')
        src = self.spider.extract_src_from_image(response)
        self.assertEqual(src, '//imgs.xkcd.com/comics/chorded_keyboard.png')

    def test_find_url_image_to_download_return_items(self) -> None:
        response = self.execute_method(
            name_method='find_url_image_to_download',
            fixture='html/2583_page.html',
            cb_kwarks=dict(href='/2583/')
        )
        items = [{
            'image_urls': [
                'http://imgs.xkcd.com/comics/chorded_keyboard.png'
            ]
        }]
        self.assertEqual(response['items'], items)


from django.contrib.auth.models import User
from django.core import mail
from django.test import TestCase
from hc.api.models import Check

class LoginTestCase(TestCase):

    def test_it_sends_link(self):
        check = Check()
        check.save()

        session = self.client.session
        session["welcome_code"] = str(check.code)
        session.save()

        form = {"email": "alice@example.org"}

        # assert the user doesn't exist before post operation
        self.assertEqual(len(User.objects.filter(email=form["email"])), 0)
        self.old_user_count = User.objects.count()

        response = self.client.post("/accounts/login/", form)
        self.assertEqual(response.status_code, 302)

        # Assert that a user was created
        self.new_user_count = User.objects.count()
        self.test_user_list = User.objects.filter(email=form["email"])
        self.assertEqual(self.test_user_list[0].email, form["email"])
        self.assertEqual(self.new_user_count - self.old_user_count, 1)

        # And email sent
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Log in to healthchecks.io')
        # Assert contents of the email body
        self.assertIn("To log into healthchecks.io, please open the link below",
                      mail.outbox[0].body)

        # Assert that check is associated with the new user
        self.test_check = Check.objects.get(user=self.test_user_list[0].id)
        self.assertEqual(self.test_user_list[0].id, self.test_check.user_id)

    def test_it_pops_bad_link_from_session(self):
        self.client.session["bad_link"] = True
        self.client.get("/accounts/login/")
        assert "bad_link" not in self.client.session


import tensorflow as tf
from tensorflow import keras
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing

#read the dataset
df = pd.read_csv('pokemon_set.csv')

#removing unnecessary columns from dataframe
df = df[['isLegendary','Generation', 'Type_1', 'Type_2', 'HP', 'Attack', 'Defense', 'Sp_Atk', 'Sp_Def', 'Speed','Color','Egg_Group_1','Height_m','Weight_kg','Body_Style']]

#It's not possible to calculate with strings or boolean, in order to create graphs I need to convert them into numbers
#Converting a boolean value into numerical boolean, 0 or 1
df['isLegendary'].astype(int)

#in order to stick with the numerical boolean and not create a scale with e.g. 5 = Water; 6 = Ground, I need to create new columns like 'isWater',...,

#create a dummy df with the numerical boolean values for the non-numerical (dummy)columns
#concatenate them into one df
#remove the original columns that were 'dummied'
def dummy_creation(df, dummy_categories):
    for i in dummy_categories:
        df_dummy = pd.get_dummies(df[i])
        df = pd.concat([df, df_dummy],axis=1)
        df = df.drop(i, axis=1)
    return(df)

df = dummy_creation(df, ['Egg_Group_1', 'Body_Style', 'Color','Type_1', 'Type_2'])

#spllitting data to train a model and test it afterwards
def train_test_splitter(DataFrame, column):
    df_train = DataFrame.loc[df[column] != 1]
    df_test = DataFrame.loc[df[column] == 1]

    df_train = DataFrame.drop(column, axis = 1)
    df_test = DataFrame.drop(column, axis = 1)

    return df_train, df_test

df_train, df_test = train_test_splitter(df,'Generation')


#!/usr/bin/python3

"""
Script that queries the Reddit API and returns the number of
subscribers (not active users, total subscribers) for a given subreddit
"""

import requests

def number_of_subscribers(subreddit):
    """Fetches a subreddits number of subscribers"""

    url = "https://www.reddit.com/r/{}/about.json".format(subreddit)
    headers = {"User-agent": "Mozilla/5.0"}
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        json_data = response.json()
        return json_data["data"]["subscribers"]
    else:
        return 0


import os

from flask import Flask

def create_app():
    app = Flask(__name__)
    app.config.from_mapping(
        SECRET_KEY='dev',
        DATABASE=os.path.join(app.instance_path, 'EventCal.sqlite'),
    )

    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    from . import db, auth, calendarview

    db.init_app(app)
    app.register_blueprint(auth.bp)
    app.register_blueprint(calendarview.bp)
    app.add_url_rule('/', endpoint='index')
    return app

app = create_app()

@app.before_first_request
def on_startup():
    from . import db
    # db.update_db()