# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import pytest
from packaging.version import (
    Version,
)

from landoapi.phabricator import (
    PhabricatorClient,
)
from landoapi.stacks import (
    build_stack_graph,
)
from landoapi.uplift import (
    add_original_revision_line_if_needed,
    create_uplift_bug_update_payload,
    get_latest_non_commit_diff,
    get_revisions_without_bugs,
    parse_milestone_version,
    strip_depends_on_from_commit_message,
)

MILESTONE_TEST_CONTENTS_1 = """
# Holds the current milestone.
# Should be in the format of
#
#    x.x.x
#    x.x.x.x
#    x.x.x+
#
# Referenced by build/moz.configure/init.configure.
# Hopefully I'll be able to automate replacement of *all*
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------

84.0a1
"""

MILESTONE_TEST_CONTENTS_2 = """
# Holds the current milestone.
# Should be in the format of
#
#    x.x.x
#    x.x.x.x
#    x.x.x+
#
# Referenced by build/moz.configure/init.configure.
# Hopefully I'll be able to automate replacement of *all*
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------

105.0
"""

def test_parse_milestone_version():
    assert parse_milestone_version(MILESTONE_TEST_CONTENTS_1) == Version(
        "84.0a1"
    ), "Test milestone file 1 should have 84 as major milestone version."

    assert parse_milestone_version(MILESTONE_TEST_CONTENTS_2) == Version(
        "105.0"
    ), "Test milestone file 2 should have 84 as major milestone version."

    bad_milestone_contents = "blahblahblah"
    with pytest.raises(ValueError, match=bad_milestone_contents):
        parse_milestone_version(bad_milestone_contents)

DEPENDS_ON_MESSAGE = """
bug 123: testing r?sheehan

Something something Depends on D1234

Differential Revision: http://phab.test/D234

Depends on D567
""".strip()

def test_strip_depends_on_from_commit_message():
    assert strip_depends_on_from_commit_message(DEPENDS_ON_MESSAGE) == (
        "bug 123: testing r?sheehan\n"
        "\n"
        "Something something Depends on D1234\n"
        "\n"
        "Differential Revision: http://phab.test/D234\n"
    ), "`Depends on` line should be stripped from commit message."

@pytest.mark.xfail
def test_uplift_creation(
    db,
    monkeypatch,
    phabdouble,
    client,
    auth0_mock,
    mock_repo_config,
    release_management_project,
):
    def _call_conduit(client, method, **kwargs):
        if method == "differential.revision.edit":
            # Load transactions
            transactions = kwargs.get("transactions")
            assert transactions is not None
            transactions = {t["type"]: t["value"] for t in transactions}

            # Check the state of the added transactions is valid for the first uplift.
            if transactions["update"] == "PHID-DIFF-1":
                # Check the expected transactions
                expected = {
                    "update": "PHID-DIFF-1",
                    "title": "Add feature XXX",
                    "summary": (
                        "some really complex stuff\n"
                        "\n"
                        "Original Revision: http://phabricator.test/D1"
                    ),
                    "bugzilla.bug-id": "",
                    "reviewers.add": ["blocking(PHID-PROJ-0)"],
                }
                for key in expected:
                    assert (
                        transactions[key] == expected[key]
                    ), f"key does not match: {key}"

            depends_on = []
            if "parents.set" in transactions:
                depends_on.append({"phid": transactions["parents.set"][0]})

            # Create a new revision
            new_rev = phabdouble.revision(
                title=transactions["title"],
                summary=transactions["summary"],
                depends_on=depends_on,
            )
            return {
                "object": {"id": new_rev["id"], "phid": new_rev["phid"]},
                "transactions": [
                    {"phid": "PHID-XACT-DREV-fakeplaceholder"} for t in transactions
                ],
            }

        else:
            # Every other request fall back in phabdouble
            return phabdouble.call_conduit(method, **kwargs)

    # Intercept the revision creation to avoid transactions support in phabdouble
    monkeypatch.setattr(PhabricatorClient, "call_conduit", _call_conduit)

    diff = phabdouble.diff()
    revision = phabdouble.revision(
        title="Add feature XXX",
        summary=(
            "some really complex stuff\n"
            "\n"
            "Differential Revision: http://phabricator.test/D1"
        ),
        diff=diff,
    )
    repo_mc = phabdouble.repo()
    user = phabdouble.user(username="JohnDoe")
    repo_uplift = phabdouble.repo(name="mozilla-uplift")

    payload = {
        "landing_path": [
            {"revision_id": f"D{revision['id']}", "diff_id": diff["id"]},
        ],
        "repository": repo_mc["shortName"],
    }

    # No auth
    response = client.post("/uplift", json=payload)
    assert response.json["title"] == "X-Phabricator-API-Key Required"
    assert response.status_code == 401

    # API key but no auth0
    headers = {"X-Phabricator-API-Key": user["apiKey"]}
    response = client.post("/uplift", json=payload, headers=headers)
    assert response.status_code == 401
    assert response.json["title"] == "Authorization Header Required"

    # Invalid repository (not uplift)
    headers.update(auth0_mock.mock_headers)
    response = client.post("/uplift", json=payload, headers=headers)
    assert response.status_code == 400
    assert (
        response.json["title"]
        == "Repository mozilla-central is not an uplift repository."
    )

    # Only one revision at first
    assert len(phabdouble._revisions) == 1

    # Valid uplift repository
    payload["repository"] = repo_uplift["shortName"]
    response = client.post("/uplift", json=payload, headers=headers)
    assert response.status_code == 201
    assert response.json == {
        "PHID-DREV-1": {
            "mode": "uplift",
            "repository": "mozilla-uplift",
            "diff_id": 2,
            "diff_phid": "PHID-DIFF-1",
            "revision_id": 2,
            "revision_phid": "PHID-DREV-1",
            "url": "http://phabricator.test/D2",
        },
        "tip_differential": {
            "mode": "uplift",
            "repository": "mozilla-uplift",
            "diff_id": 2,
            "diff_phid": "PHID-DIFF-1",
            "revision_id": 2,
            "revision_phid": "PHID-DREV-1",
            "url": "http://phabricator.test/D2",
        },
    }

    # Now we have a new uplift revision on Phabricator
    assert len(phabdouble._revisions) == 2
    new_rev = phabdouble._revisions[-1]
    assert new_rev["title"] == "Add feature XXX"
    assert (
        new_rev["summary"]
        == "some really complex stuff\n\nOriginal Revision: http://phabricator.test/D1"
    )

    # Add some more revisions to test uplifting a stack.
    diff2 = phabdouble.diff()
    rev2 = phabdouble.revision(
        title="bug 1: xxx r?reviewer",
        summary=("summary info.\n\nDifferential Revision: http://phabricator.test/D3"),
        diff=diff2,
    )
    diff3 = phabdouble.diff()
    rev3 = phabdouble.revision(
        title="bug 1: yyy r?reviewer",
        summary=("summary two.\n\nDifferential Revision: http://phabricator.test/D4"),
        depends_on=[rev2],
        diff=diff3,
    )
    diff4 = phabdouble.diff()
    rev4 = phabdouble.revision(
        title="bug 1: yyy r?reviewer",
        summary=("summary two.\n\nDifferential Revision: http://phabricator.test/D4"),
        depends_on=[rev3],
        diff=diff4,
    )

    # Send an uplift request for a stack.
    payload["landing_path"] = [
        {"revision_id": f"D{rev2['id']}", "diff_id": diff2["id"]},
        {"revision_id": f"D{rev3['id']}", "diff_id": diff3["id"]},
        {"revision_id": f"D{rev4['id']}", "diff_id": diff4["id"]},
    ]
    response = client.post("/uplift", json=payload, headers=headers)
    assert response.status_code == 201, "Response should have status code 201."
    assert len(response.json) == 4, "API call should have created 3 revisions."
    assert response.json == {
        "PHID-DREV-5": {
            "mode": "uplift",
            "repository": "mozilla-uplift",
            "diff_id": 7,
            "diff_phid": "PHID-DIFF-6",
            "revision_id": 6,
            "revision_phid": "PHID-DREV-5",
            "url": "http://phabricator.test/D6",
        },
        "PHID-DREV-6": {
            "mode": "uplift",
            "repository": "mozilla-uplift",
            "diff_id": 9,
            "diff_phid": "PHID-DIFF-8",
            "revision_id": 7,
            "revision_phid": "PHID-DREV-6",
            "url": "http://phabricator.test/D7",
        },
        "PHID-DREV-7": {
            "mode": "uplift",
            "repository": "mozilla-uplift",
            "diff_id": 11,
            "diff_phid": "PHID-DIFF-10",
            "revision_id": 8,
            "revision_phid": "PHID-DREV-7",
            "url": "http://phabricator.test/D8",
        },
        "tip_differential": {
            "mode": "uplift",
            "repository": "mozilla-uplift",
            "diff_id": 11,
            "diff_phid": "PHID-DIFF-10",
            "revision_id": 8,
            "revision_phid": "PHID-DREV-7",
            "url": "http://phabricator.test/D8",
        },
    }, "Response JSON does not match expected."

    # Check that parent-child relationships are preserved.
    phab = phabdouble.get_phabricator_client()
    last_phid = response.json["tip_differential"]["revision_phid"]
    _nodes, edges = build_stack_graph(phab, last_phid)

    assert edges == {
        ("PHID-DREV-7", "PHID-DREV-6"),
        ("PHID-DREV-6", "PHID-DREV-5"),
    }, "Uplift does not preserve parent/child relationships."
    # We still have the same revision
    assert len(phabdouble._revisions) == 1
    new_rev = phabdouble._revisions[0]
    assert new_rev["title"] == "my test revision title"

def test_create_uplift_bug_update_payload():
    bug = {
        "cf_status_firefox100": "---",
        "id": 123,
        "keywords": [],
        "whiteboard": "[checkin-needed-beta]",
    }
    payload = create_uplift_bug_update_payload(
        bug, "beta", 100, "cf_status_firefox{milestone}"
    )

    assert payload["ids"] == [123], "Passed bug ID should be present in the payload."
    assert (
        payload["whiteboard"] == ""
    ), "checkin-needed flag should be removed from whiteboard."
    assert (
        payload["cf_status_firefox100"] == "fixed"
    ), "Custom tracking flag should be set to `fixed`."

    bug = {
        "cf_status_firefox100": "---",
        "id": 123,
        "keywords": ["leave-open"],
        "whiteboard": "[checkin-needed-beta]",
    }
    payload = create_uplift_bug_update_payload(
        bug, "beta", 100, "cf_status_firefox{milestone}"
    )

    assert (
        "cf_status_firefox100" not in payload
    ), "Status should not have been set with `leave-open` keyword on bug."

def test_add_original_revision_line_if_needed():
    uri = "http://phabricator.test/D123"

    summary_no_original = "Bug 123: test summary r?sheehan"
    summary_with_original = (
        "Bug 123: test summary r?sheehan\n"
        "\n"
        "Original Revision: http://phabricator.test/D123"
    )

    assert (
        add_original_revision_line_if_needed(summary_no_original, uri)
        == summary_with_original
    ), "Passing summary without `Original Revision` should return with line added."

    assert (
        add_original_revision_line_if_needed(summary_with_original, uri)
        == summary_with_original
    ), "Passing summary with `Original Revision` should return the input."

def test_get_revisions_without_bugs(phabdouble):
    phab = phabdouble.get_phabricator_client()

    rev1 = phabdouble.revision(bug_id=123)
    revs = phabdouble.differential_revision_search(
        constraints={"phids": [rev1["phid"]]},
    )
    revisions = phab.expect(revs, "data")

    assert (
        get_revisions_without_bugs(phab, revisions) == set()
    ), "Empty set should be returned if all revisions have bugs."

    rev2 = phabdouble.revision()
    revs = phabdouble.differential_revision_search(
        constraints={"phids": [rev1["phid"], rev2["phid"]]},
    )
    revisions = phab.expect(revs, "data")

    assert get_revisions_without_bugs(phab, revisions) == {
        rev2["id"]
    }, "Revision without associated bug should be returned."

def test_get_latest_non_commit_diff():
    test_data = [
        {"creationMethod": "commit", "id": 3},
        {"creationMethod": "moz-phab-hg", "id": 1},
        {"creationMethod": "commit", "id": 4},
        {"creationMethod": "moz-phab-hg", "id": 2},
        {"creationMethod": "commit", "id": 5},
    ]

    diff = get_latest_non_commit_diff(test_data)

    assert (
        diff["id"] == 2
    ), "Returned diff should have the highest diff ID without `commit`."
    assert (
        diff["creationMethod"] != "commit"
    ), "Diffs with a `creationMethod` of `commit` should be skipped."


import sys
import os
import os.path as osp
import numpy as np
import pandas as pd
from tqdm import tqdm
from PIL import Image

def get_images_and_masks(classes_id, min_pixels, partition, path_annot, mode=""):
    df = pd.read_csv(osp.join(path_annot, 'validation', 'validation-annotations-object-segmentation.csv'))
    kept = df.loc[df['LabelName'].isin(classes_id)]
    mv = [osp.join('validation/masks', e) for e in kept['MaskPath'].tolist()]
    iv = [osp.join('validation', e+'.jpg') for e in kept['ImageID'].tolist()]

    df = pd.read_csv(osp.join(path_annot, 'test', 'test-annotations-object-segmentation.csv'))
    kept = df.loc[df['LabelName'].isin(classes_id)]
    mte = [osp.join('test/masks', e) for e in kept['MaskPath'].tolist()]
    ite = [osp.join('test', e+'.jpg') for e in kept['ImageID'].tolist()]

    maskpaths = mv + mte
    impaths = iv + ite

    if partition != "val" and mode != "lite":
        df = pd.read_csv(osp.join(path_annot, 'train', 'train-annotations-object-segmentation.csv'))
        kept = df.loc[df['LabelName'].isin(classes_id)]
        mtr = [osp.join('train/masks', e) for e in kept['MaskPath'].tolist()]
        itr = [osp.join('train', e+'.jpg') for e in kept['ImageID'].tolist()]

        maskpaths += mtr
        impaths += itr

    if mode == "default":
        mode_flag = ""
    else:
        mode_flag = "_" + mode

    masksfile = "{}_masks{}.txt".format(partition, mode_flag)
    imagesfile = "{}_images{}.txt".format(partition, mode_flag)

    fm = open(osp.join(path_annot, masksfile), 'w')
    fi = open(osp.join(path_annot, imagesfile), 'w')
    for i in tqdm(range(len(maskpaths))):
        m = maskpaths[i]
        im = impaths[i]
        mask = np.array(Image.open(osp.join(path_annot, m)))

        pos = np.where(mask)
        if len(pos[0]) == 0:
            continue
        xmin = np.min(pos[1])
        xmax = np.max(pos[1])
        ymin = np.min(pos[0])
        ymax = np.max(pos[0])
        w = xmax - xmin
        h = ymax - ymin
        if np.min((h, w)) < min_pixels or h*w < min_pixels*80:
            continue
        fm.write('{}\n'.format(m))
        fi.write('{}\n'.format(im))
    fm.close()
    fi.close()

if len(sys.argv) > 1:
    mode = sys.argv[1]
else:
    mode = ""

if mode == "lite":
    min_pixels = 80
else:
    min_pixels = 50

root = osp.join(os.environ['DB_ROOT'], 'OpenImages')
path_images = osp.join(root, 'images')
path_annot = osp.join(root, 'annotations')

all_classes = pd.read_csv(osp.join(root, 'metadata/class-descriptions-boxable.csv'), names=['ID', 'name'])

val_classes = ['Lion', 'Duck', 'Bus', 'Croissant', 'Panda', 'Parrot', 'Hammer', 'Airplane', 'Apple', 'Ambulance', 'Harmonica', 'Washing machine', 'Lighthouse', 'Hot dog', 'Hamburger']

val_classes_id = set(all_classes.loc[all_classes['name'].isin(val_classes)]['ID'].tolist())
train_classes_id = set(all_classes.loc[~all_classes['name'].isin(val_classes)]['ID'].tolist())

get_images_and_masks(val_classes_id, min_pixels, 'val', path_annot, mode)
get_images_and_masks(train_classes_id, min_pixels, 'train', path_annot, mode)


import functools
import operator
import sys

chars = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.?:;'

alphanum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

def get_page_num(levels):
    x = 0
    for l in levels:
        if l[2] > l[1]: raise Exception('value out of range')
        x *= l[1]
        x += l[2]
    return x

def get_page_num_rev(x, levels):

    for l in reversed(levels):
        n = l[1]

        y = x % n
        x -= y
        x //= n

        l[2] = y

def get_page_rev(string):
    x = 0
    for s in reversed(string):
        x *= len(chars)
        x += chars.index(s)
    return x

def get_page(x, n):
    s = ''
    for i in range(n):
        n = len(chars)

        y = x % n
        x -= y
        x //= n

        s += chars[y]
    return s

def int_to_alphanum(x):
    s = ''
    while True:
        m = len(alphanum) + 1

        y = x % m
        x -= y
        x //= m

        s += alphanum[y-1]

        if x == 0: break
    return s

def alphanum_to_int(string):
    x = 0
    for s in reversed(string):
        y = alphanum.index(s) + 1
        x *= len(alphanum) + 1
        x += y
    return x

def block_print(s, w, h):
    s = get_page(x, 64)
    print('+'+'-'*w+'+')
    for i in range(h):
        print('|'+s[i*h:i*h+w]+'|')
    print('+'+'-'*w+'+')

######################################################33

#x = alphanum_to_int('abcd')
#s = int_to_alphanum(x)
#print(x,s)
#sys.exit(0)

levels = [
    ['room',     36**100,   0],
    ['bookcase',       4,   0],
    ['shelf',          5,   0],
    ['volume',        32,   0],
    ['page',         410,   0]
    ]

get_page_num_rev(get_page_rev(' hello'), levels)

n = functools.reduce(operator.mul, [l[1] for l in levels], 1)

x = get_page_num(levels)

w = 8
h = 8

s = get_page(x, w*h)

block_print(s, w, h)


#!/usr/bin/env python3

import sys
import numpy as np
import cv2
# import dlib
import face_recognition
import time
import os

cvXMLPath = '/usr/share/opencv4/haarcascades/'

# Load the cascade # set the correct path
face_cascade = cv2.CascadeClassifier(cvXMLPath + 'haarcascade_frontalface_default.xml')

cap = cv2.VideoCapture(0)

def prepare_data():
    known_face_encodings_map = {}
    files = os.listdir('images')
    for f in files:
        image  = face_recognition.load_image_file("images/{}".format(f))
        image_encoding = face_recognition.face_encodings(image)[0]
        f = f[ : f.find('.')]
        f = f.replace("_", " ")
        known_face_encodings_map.update({f: image_encoding})
    return known_face_encodings_map

def main():

    known_face_encodings_map = prepare_data()

    while(True):
        # Here we store data about recognized faces
        recognized_faces = {}

        # Capture frame-by-frame
        ret, frame = cap.read()

        # get it into the correct format
        rgb_frame = frame[:, :, ::-1]

        # Detect the faces
        min_face_distances = 1
        min_face_distances_name = ""
        faces = face_cascade.detectMultiScale(rgb_frame)
        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
            # print ("Rectangle coords: {} {} {} {}".format(x, y, x+w, y+h))

            cropped = frame[y: y+h, x: x+w]
            rgb_cropped = cropped[:, :, ::-1]
            face_image = rgb_cropped

            # cv2.imshow("face image", face_image)
            face_encoding_list = face_recognition.face_encodings(face_image)

            if len(face_encoding_list) < 1:
                # print ("No face recognized")
                break

            # continue
            face_encoding = face_encoding_list[0]
            # print ("len (face_encoding) = {}".format(len (face_encoding)))

            min_face_distances = 1
            for name, face in known_face_encodings_map.items():
                face_distances = face_recognition.face_distance([face], face_encoding)
                if min_face_distances > face_distances:
                    min_face_distances = face_distances
                    min_face_distances_name = name

            recognized_faces[min_face_distances_name] = {'distance':min_face_distances, 'coords':(x, y, w, h)}
            # print(recognized_faces)

        # Display
        font = cv2.FONT_HERSHEY_SIMPLEX #cv2.FONT_HERSHEY_DUPLEX
        for name, data in recognized_faces.items():
            distance = data['distance']
            # print ("name '{}' distance '{}'".format(name, distance))
            if name != "" and distance < 1:
                (x, y, w, h) = data['coords']
                cv2.putText(frame, "{} - {}".format(name, distance), (x + 6, y - 6), font, 0.5, (255, 255, 255), 1)
        cv2.imshow('face detector', frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

        time.sleep(0.1)

    # When everything done, release the capture
    cap.release()
    cv2.destroyAllWindows()

if __name__ == '__main__':
    main()


import sys
import typing
from typing import Any, Callable, Dict, List, Tuple, TypeVar, Union

from docutils import nodes
from docutils.parsers.rst.states import Inliner

# An entry of Directive.option_spec
DirectiveOption = Callable[[str], Any]

# Text like nodes which are initialized with text and rawsource
TextlikeNode = Union[nodes.Text, nodes.TextElement]

# type of None
NoneType = type(None)

# path matcher
PathMatcher = Callable[[str], bool]

# common role functions
RoleFunction = Callable[[str, str, str, int, Inliner, Dict[str, Any], List[str]],
                        Tuple[List[nodes.Node], List[nodes.system_message]]]

# title getter functions for enumerable nodes (see sphinx.domains.std)
TitleGetter = Callable[[nodes.Node], str]

# inventory data on memory
Inventory = Dict[str, Dict[str, Tuple[str, str, str, str]]]

def stringify(annotation: Any) -> str:
    res = _stringify(annotation)
    return res

def _stringify(annotation: Any) -> str:
    """Stringify type annotation object."""
    if isinstance(annotation, str):
        return annotation
    elif isinstance(annotation, TypeVar):  # type: ignore
        return annotation.__name__
    elif not annotation:
        return repr(annotation)
    elif annotation is NoneType:  # type: ignore
        return 'None'
    elif getattr(annotation, '__module__', None) == 'builtins':
        return annotation.__qualname__
    elif annotation is Ellipsis:
        return '...'

    if sys.version_info >= (3, 7):  # py37+
        return _stringify_py37(annotation)
    else:
        return _stringify_py36(annotation)

def _stringify_py37(annotation: Any) -> str:
    """stringify() for py37+."""
    module = getattr(annotation, '__module__', None)
    if module == 'typing':
        if getattr(annotation, '_name', None):
            qualname = annotation._name
        elif getattr(annotation, '__qualname__', None):
            qualname = annotation.__qualname__
        elif getattr(annotation, '__forward_arg__', None):
            qualname = annotation.__forward_arg__
        else:
            qualname = stringify(annotation.__origin__)  # ex. Union
    elif hasattr(annotation, '__qualname__'):
        qualname = '%s.%s' % (module, annotation.__qualname__)
    else:
        qualname = repr(annotation)

    if getattr(annotation, '__args__', None):
        if qualname == 'Union':
            if len(annotation.__args__) == 2 and annotation.__args__[1] is NoneType:  # type: ignore  # NOQA
                return 'Optional[%s]' % stringify(annotation.__args__[0])
            else:
                args = ', '.join(stringify(a) for a in annotation.__args__)
                return '%s[%s]' % (qualname, args)
        elif qualname == 'Callable':
            args = ', '.join(stringify(a) for a in annotation.__args__[:-1])
            returns = stringify(annotation.__args__[-1])
            return '%s[[%s], %s]' % (qualname, args, returns)
        elif annotation._special:
            return qualname
        else:
            args = ', '.join(stringify(a) for a in annotation.__args__)
            return '%s[%s]' % (qualname, args)

    return qualname

def _stringify_py36(annotation: Any) -> str:
    """stringify() for py35 and py36."""
    module = getattr(annotation, '__module__', None)
    if module == 'typing':
        if getattr(annotation, '_name', None):
            qualname = annotation._name
        elif getattr(annotation, '__qualname__', None):
            qualname = annotation.__qualname__
        elif getattr(annotation, '__forward_arg__', None):
            qualname = annotation.__forward_arg__
        elif getattr(annotation, '__origin__', None):
            qualname = stringify(annotation.__origin__)  # ex. Union
        else:
            qualname = repr(annotation).replace('typing.', '')
    elif hasattr(annotation, '__qualname__'):
        qualname = '%s.%s' % (module, annotation.__qualname__)
    else:
        qualname = repr(annotation)

    if (isinstance(annotation, typing.TupleMeta) and  # type: ignore
            not hasattr(annotation, '__tuple_params__')):  # for Python 3.6
        params = annotation.__args__
        if params:
            param_str = ', '.join(stringify(p) for p in params)
            return '%s[%s]' % (qualname, param_str)
        else:
            return qualname
    elif isinstance(annotation, typing.GenericMeta):
        params = None
        if hasattr(annotation, '__args__'):
            # for Python 3.5.2+
            if annotation.__args__ is None or len(annotation.__args__) <= 2:  # type: ignore  # NOQA
                params = annotation.__args__  # type: ignore
            else:  # typing.Callable
                args = ', '.join(stringify(arg) for arg
                                 in annotation.__args__[:-1])  # type: ignore
                result = stringify(annotation.__args__[-1])  # type: ignore
                return '%s[[%s], %s]' % (qualname, args, result)
        elif hasattr(annotation, '__parameters__'):
            # for Python 3.5.0 and 3.5.1
            params = annotation.__parameters__  # type: ignore
        if params is not None:
            param_str = ', '.join(stringify(p) for p in params)
            return '%s[%s]' % (qualname, param_str)
    elif (hasattr(typing, 'UnionMeta') and
          isinstance(annotation, typing.UnionMeta) and  # type: ignore
          hasattr(annotation, '__union_params__')):  # for Python 3.5
        params = annotation.__union_params__
        if params is not None:
            if len(params) == 2 and params[1] is NoneType:  # type: ignore
                return 'Optional[%s]' % stringify(params[0])
            else:
                param_str = ', '.join(stringify(p) for p in params)
                return '%s[%s]' % (qualname, param_str)
    elif (hasattr(annotation, '__origin__') and
          annotation.__origin__ is typing.Union):  # for Python 3.5.2+
        params = annotation.__args__
        if params is not None:
            if len(params) == 2 and params[1] is NoneType:  # type: ignore
                return 'Optional[%s]' % stringify(params[0])
            else:
                param_str = ', '.join(stringify(p) for p in params)
                return 'Union[%s]' % param_str
    elif (isinstance(annotation, typing.CallableMeta) and  # type: ignore
          getattr(annotation, '__args__', None) is not None and
          hasattr(annotation, '__result__')):  # for Python 3.5
        # Skipped in the case of plain typing.Callable
        args = annotation.__args__
        if args is None:
            return qualname
        elif args is Ellipsis:
            args_str = '...'
        else:
            formatted_args = (stringify(a) for a in args)
            args_str = '[%s]' % ', '.join(formatted_args)
        return '%s[%s, %s]' % (qualname,
                               args_str,
                               stringify(annotation.__result__))
    elif (isinstance(annotation, typing.TupleMeta) and  # type: ignore
          hasattr(annotation, '__tuple_params__') and
          hasattr(annotation, '__tuple_use_ellipsis__')):  # for Python 3.5
        params = annotation.__tuple_params__
        if params is not None:
            param_strings = [stringify(p) for p in params]
            if annotation.__tuple_use_ellipsis__:
                param_strings.append('...')
            return '%s[%s]' % (qualname,
                               ', '.join(param_strings))

    return qualname


# Author: Ronaldlee Ejalu
# Course: DSC 450
# HomeWork Assignment 5 Module part 2
import os
import csv
import urllib.request
import sqlite3

os.chdir("C:/Users/rejalu1/OneDrive - Henry Ford Health System/DSC450/Assignments/Week5")

createtbl = """

CREATE TABLE Chauffeurs
(
    LicenseNumber NUMBER,
    Renewed VARCHAR2(50),
    Status VARCHAR2(50),
    StatusDate DATE,
    DriverType VARCHAR2(25),
    LicenseType VARCHAR2(25),
    OriginalIssue DATE,
    CName VARCHAR2(100),
    Sex VARCHAR2(10),
    ChauffeurCity VARCHAR2(50),
    ChauffeurState VARCHAR2(50),
    RecordNumber VARCHAR(50)--,
    --CONSTRAINT Chauffeurs_PK PRIMARY KEY (LicenseNumber)
);
"""

insertScript = """
INSERT  INTO Chauffeurs VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')
"""
conn = sqlite3.connect('dsc450.db')                                                                             # open the connection
cur = conn.cursor()                                                                                # instanciate a cursor object

# Drop the table if it exist
cur.execute("DROP TABLE IF EXISTS Chauffeurs;")

# execute the ddl to cretate the respective tables.
cur.execute(createtbl)

url_link = "http://dbgroup.cdm.depaul.edu/DSC450/Public_Chauffeurs_Short_hw3.csv"
response = urllib.request.urlopen(url_link)

# decode urlopen's response, which is in bytes, into a valid local encoding
responseLines = [row.decode('utf-8') for row in response.readlines()]
csvRow = csv.reader(responseLines)                                          # use the reader method to return a reader object which we iterate over lines in the given csv file

# extracting the field names
fields = next(csvRow)

for row in csvRow:
    # if row[7] == 'CORONA,  JUAN M' or row[7] == 'HUSSAIN, TARIQ':                                                  # This is for debugging purposes
    if len(row[7].split(', ')) == 2:
        # print("The length of %s is %s" %(row[7].split(', '), len(row[7].split(', '))))                             # This is for debugging purposes
        cleansedRow = row[7].split(', ')
        # print(cleansedRow)                                                                                # This is for debugging purposes
        cName = cleansedRow[1] + ' '+ cleansedRow[0]
        # print(cName)
        cur.execute(insertScript %(int(row[0]), row[1], row[2], row[3], row[4], row[5], row[6], cName, row[8], row[9], row[10], row[11]))

    # elif len(row[7].split(', ')) == 1 and row[7] == "PATRICK J. O'BRIEN":                                                                  # This is for debugging purposes
    #     cur.execute(insertScript %(int(row[0]), row[1], row[2], row[3], row[4], row[5], row[6], row[7].replace("'",""), row[8], row[9], row[10], row[11]))
    else:
        cur.execute(insertScript %(int(row[0]), row[1], row[2], row[3], row[4], row[5], row[6], row[7].replace("'","''"), row[8], row[9], row[10], row[11]))

outPutRes = cur.execute("SELECT COUNT(*) FROM Chauffeurs;")
outPutResIObj = outPutRes.fetchall()

print("SELECT COUNT(*) FROM Chauffeurs is \n %s" %(outPutResIObj))

conn.commit()
conn.close()


import pycountry
from os import system
import msvcrt

players = ["Alex", "Patric"]

def main(players, max_rounds = 1):
    countries = {c.name: c for c in pycountry.countries}
    score = {p: {} for p in players}
    guessed_countries = {}
    exit_word = "123"

    round = 1

    print("Welcome to our Geography Quiz!")
    print(f"To give up, please type in '{exit_word}' as a guess at any time.")
    input(f"Press ENTER to start!!")

    while round <= max_rounds:
        system("cls")
        print(f"Round {round}!")
        for p in players:
            while True:
                is_hit = False
                guess = input(f"Please enter your guess, {p}:\n")

                if guess == exit_word:
                    print(f"{p} has given up. This is the last round.")
                    max_rounds = 0
                    break

                if countries.get(guess):
                    hit = guess
                else:
                    try:
                        all_hits = [hit.name for hit in pycountry.countries.search_fuzzy(guess)]
                        hits = [hit for hit in all_hits if not guessed_countries.get(hit)]
                    except Exception:
                        hits = []

                    if len(hits) > 1:
                        print("Your guess generated more than one result. Please be more specific.")
                        continue
                    if not len(hits):
                        print(f"There is no country called {guess}. Please try again.")
                        continue

                    hit = hits[0]

                prev_guess = guessed_countries.get(hit)
                if prev_guess:
                    print(f"{hit} has already been guessed by {prev_guess}. Please try again.")
                elif countries.get(hit):
                    guessed_countries[hit] = countries.pop(hit)
                    print(f"{hit} is a country! Good Job, {p}!")
                    score[p][hit] = None
                    guessed_countries.update({hit:p})
                    break
                else:
                    print(f"There is no country called {guess}. Please try again.")

        print(f"Score after round {round}:")
        for player, guesses in score.items():
            print(f"{player}: {len(guesses)}")

        if round < max_rounds:
            input("Press ENTER to the next round")

        round += 1

    max_score = 0
    for p, s in score.items():
        if len(s) > max_score:
            max_score = len(s)
            winner = p

    print(f"The winner is {winner}!")
    return score

if __name__ == "__main__":
    score = main(players, max_rounds=300)


from plone.app.content.interfaces import INameFromTitle
from plone.app.dexterity import _ as _PMF
from plone.app.textfield import RichText
from plone.autoform.directives import read_permission
from plone.dexterity.content import Item
from plone.namedfile.field import NamedBlobImage
from plone.rfc822.interfaces import IPrimaryField
from plone.supermodel.directives import fieldset
from plone.supermodel.model import Schema
from ploneorg import _
from ploneorg.vocabularies import org_size_vocabulary
from ploneorg.vocabularies import payment_currency_vocabulary
from ploneorg.vocabularies import payment_frequency_vocabulary
from ploneorg.vocabularies import payment_method_vocabulary
from zope import schema
from zope.interface import alsoProvides
from zope.interface import implementer
from zope.interface import Invalid

import re

# TODO: add workflow state Waiting for Initial Payment
# TODO: display effective and expiry date in view template
# TODO: display status in view template
# TODO: use logo as lead image
# TODO: add button to send an email to the primary contact
# TODO: set effective and expiry dates from payment start and end dates
# TODO: make payment date not required (e.g. waiting for payment)
# TODO: enable commenting/discussion instead of commenting with change comments?

# email re w/o leading '^'
EMAIL_RE = "([0-9a-zA-Z_&.'+-]+!)*[0-9a-zA-Z_&.'+-]+@(([0-9a-zA-Z]([0-9a-zA-Z-]*[0-9a-z-A-Z])?\.)+[a-zA-Z]{2,}|([0-9]{1,3}\.){3}[0-9]{1,3})$"  # noQA

def isEmail(value):
    prog = re.compile("^" + EMAIL_RE)
    result = prog.match(value)
    if result is None:
        raise Invalid(_PMF("is not a valid email address."))
    return True

def isHTTP(value):
    if not value.startswith("http://") and not value.startswith("https://"):
        raise Invalid(_PMF("web address must start with http:// or https://"))
    return True

class IFoundationSponsor(Schema):
    """A Foundation sponsor"""

    fieldset(
        "Contacts",
        label="Contacts",
        fields=[
            "fname",
            "lname",
            "email",
            "alt_fname",
            "alt_lname",
            "alt_email",
        ],
    )

    fieldset(
        "Address",
        label="Address",
        fields=[
            "address",
            "address2",
            "city",
            "state",
            "postalCode",
            "country",
        ],
    )

    fieldset(
        "Payment",
        label="Payment",
        fields=[
            "payment_frequency",
            "payment_method",
            "payment_amount",
            "payment_currency",
            "payment_date",
        ],
    )

    fieldset(
        "Status",
        label="Status",
        fields=[
            "start_date",
            "end_date",
            "last_verified_date",
            "notes",
        ],
    )

    title = schema.TextLine(
        title=_PMF("Organization name", default="Organization name"), required=True
    )

    logo = NamedBlobImage(
        title=_("Logo"),
        required=False,
    )

    sponsorship_type = schema.Choice(
        title=_PMF("Sponsor Type", default="Sponsor Type"),
        vocabulary="ploneorg.vocabulary.sponsorship_types",
        required=True,
    )

    read_permission(orgsize="ploneorg.foundationsponsor.view")
    orgsize = schema.Choice(
        title=_("Organization size"),
        description=_("Number of people in your organization. It's fine to estimate."),
        vocabulary=org_size_vocabulary,
        required=True,
    )

    is_provider = schema.Bool(
        title=_PMF("Is a Plone provider", default="Is a Plone provider"),
        required=False,
        default=False,
    )

    website = schema.URI(
        title=_PMF("Web Site", default="Web Site"),
        description=_("Enter a http:// or https:// web address"),
        required=False,
        constraint=isHTTP,
    )

    provider_listing_url = schema.URI(
        title=_PMF("Plone.com provider listing", default="Plone.com provider listing"),
        description=_("Enter a http:// or https:// web address"),
        required=False,
        constraint=isHTTP,
    )

    read_permission(fname="ploneorg.foundationsponsor.view")
    fname = schema.TextLine(
        title=_PMF("Contact first name", default="Contact first name"), required=True
    )

    read_permission(lname="ploneorg.foundationsponsor.view")
    lname = schema.TextLine(
        title=_PMF("Contact last name", default="Contact last name"), required=True
    )

    read_permission(email="ploneorg.foundationsponsor.view")
    email = schema.TextLine(
        title=_PMF("Email", default="Email"), constraint=isEmail, required=True
    )

    read_permission(address="ploneorg.foundationsponsor.view")
    address = schema.TextLine(title=_PMF("Address", default="Address"), required=False)

    read_permission(address2="ploneorg.foundationsponsor.view")
    address2 = schema.TextLine(
        title=_PMF("Address 2", default="Address 2"), required=False
    )

    city = schema.TextLine(title=_PMF("City", default="City"), required=True)

    read_permission(state="ploneorg.foundationsponsor.view")
    state = schema.TextLine(title=_PMF("State", default="State"), required=False)

    read_permission(postalCode="ploneorg.foundationsponsor.view")
    postalCode = schema.TextLine(
        title=_PMF("Postal code", default="Postal code"), required=False
    )

    country = schema.Choice(
        title=_PMF("Country", default="Country"),
        vocabulary="ploneorg.vocabulary.countries",
        required=True,
    )

    read_permission(alt_fname="ploneorg.foundationsponsor.view")
    alt_fname = schema.TextLine(
        title=_PMF(
            "Alternate contact first name", default="Alternate contact first name"
        ),
        required=False,
    )

    read_permission(alt_lname="ploneorg.foundationsponsor.view")
    alt_lname = schema.TextLine(
        title=_PMF(
            "Alternate contact last name", default="Alternate contact last name"
        ),
        required=False,
    )

    read_permission(alt_email="ploneorg.foundationsponsor.view")
    alt_email = schema.TextLine(
        title=_PMF("Alternate email", default="Alternate email"),
        constraint=isEmail,
        required=False,
    )

    twitter = schema.TextLine(
        title=_PMF("Twitter account", default="Twitter account"),
        description=_PMF(
            "(without the leading " "@" ")", default="(without the leading " "@" ")"
        ),
        required=False,
    )

    read_permission(connection_to_plone="ploneorg.foundationsponsor.view")
    connection_to_plone = RichText(
        title=_PMF("Connection to Plone", default="Connection to Plone"),
        description=_(
            "What is your connection to Plone? How is Plone used by your organization?"
        ),
        required=False,
    )

    read_permission(payment_frequency="ploneorg.foundationsponsor.view")
    payment_frequency = schema.Choice(
        title=_PMF("Payment frequency", default="Payment frequency"),
        vocabulary=payment_frequency_vocabulary,
    )

    read_permission(payment_method="ploneorg.foundationsponsor.view")
    payment_method = schema.Choice(
        title=_PMF("Payment method", default="Payment method"),
        vocabulary=payment_method_vocabulary,
        default="PayPal",
        required=True,
    )

    read_permission(payment_amount="ploneorg.foundationsponsor.view")
    payment_amount = schema.Float(
        title=_PMF("Payment Amount", default="Payment Amount"), min=0.0, required=True
    )

    read_permission(payment_currency="ploneorg.foundationsponsor.view")
    payment_currency = schema.Choice(
        title=_PMF("Currency", default="Currency"),
        vocabulary=payment_currency_vocabulary,
        default="USD",
        required=True,
    )

    start_date = schema.Date(
        title=_PMF("Start Date", default="Start Date"), required=False
    )

    end_date = schema.Date(title=_PMF("End Date", default="End Date"), required=False)

    read_permission(payment_date="ploneorg.foundationsponsor.view")
    payment_date = schema.Date(
        title=_PMF("Payment Date", default="Payment Date"), required=False
    )

    read_permission(last_verified_date="ploneorg.foundationsponsor.view")
    last_verified_date = schema.Date(
        title=_PMF("Status last verified date", default="Status last verified date"),
        required=False,
    )

    read_permission(notes="ploneorg.foundationsponsor.view")
    notes = RichText(
        title=_PMF("Private notes", default="Private notes"), required=False
    )

    public_notes = RichText(
        title=_PMF("Public notes", default="Public notes"), required=False
    )

alsoProvides(IFoundationSponsor["logo"], IPrimaryField)

@implementer(IFoundationSponsor)
class FoundationSponsor(Item):
    def get_full_name(self):
        names = [
            self.title,
            self.fname,
            self.lname,
        ]
        return " ".join([name for name in names if name])

    @property
    def preview_image(self):
        return self.logo

    @preview_image.setter
    def preview_image(self, value):
        self.logo = value

    @property
    def preview_caption(self):
        return self.title

    @preview_caption.setter
    def preview_caption(self, value):
        pass

    @property
    def remoteUrl(self):
        return self.website

    @remoteUrl.setter
    def remoteUrl(self, value):
        self.website = value

    def toXML(self, schematas=["contact", "survey"]):
        """To XML for Paul ;)"""

        out = ""
        out += '<foundationsponsor id="%s">' % self.getId()
        fields = [
            f
            for f in self.Schema().fields()
            if (f.schemata in schematas) and f.getName() != "id"
        ]
        for f in fields:
            out += "<%s>%s</%s>" % (
                f.getName(),
                getattr(self, f.accessor)(),
                f.getName(),
            )
        out += "</foundationsponsor>"
        return out

class INameFromPersonNames(INameFromTitle):
    def title():
        """Return a processed title"""

@implementer(INameFromPersonNames)
class NameFromPersonNames(object):
    def __init__(self, context):
        self.context = context

    @property
    def title(self):
        return self.context.title


import json
import logging
import time
from concurrent.futures import ThreadPoolExecutor, as_completed

from grubbers.chpic import chpic_stickers_grubber
from grubbers.combot import combot_stickers_grubber
from grubbers.tlgrm import tlgrm_stickers_grubber

def main():
    begin = time.time()
    logger_main = logging.getLogger(__name__)
    logger_main.setLevel(logging.INFO)
    handler = logging.FileHandler(f"logs/main.log", mode='w')
    formatter = logging.Formatter("%(name)s %(asctime)s %(levelname)s %(message)s")
    handler.setFormatter(formatter)
    logger_main.addHandler(handler)

    try:
        with ThreadPoolExecutor(max_workers=3) as executor:
            future_list = []
            result_list = []

            future1 = executor.submit(tlgrm_stickers_grubber)
            future3 = executor.submit(chpic_stickers_grubber)
            future_list.append(future1)
            future_list.append(future3)
            logger_main.info("Запустил процессы скрапинга")

            for f in as_completed(future_list):
                worker_done = f.result()
                result_list = result_list + (f.result())
                logger_main.info(f'отработал {worker_done}')

    except Exception as e:
        logger_main.error(f'Ошибка в main с процессами -  {e}')

        try:
            with open("files/stickers_total.files", "w", encoding="utf-8") as f:
                json.dump(result_list, f, indent=4, ensure_ascii=False)
            logger_main.info("записал список в итоговый файл")
            logger_main.info(
                f'Общее время работы скрипта - {time.time() - begin}. В итоговм списке {len(result_list)} записей.')
        except Exception as eeee:
            logger_main.error(f"Проблеммы с записью в файл stickers_total.files - {eeee}")

#
# if __name__ == "__main__":
#     logging.basicConfig(level=logging.INFO, filename="stickers_log_tlgrm.log", filemode="w",
#                         format="%(asctime)s %(levelname)s %(message)s")
#     main()

q
# def collect_stickers():
#     with open("files/stickers_chpic.files", "r", encoding="utf-8") as file:
#         chpic_list = files.load(file)
#     with open("files/stickers_combot.files", "r", encoding="utf-8") as file:
#         combot_list = files.load(file)
#     with open("files/stickers_tlgrm.files", "r", encoding="utf-8") as file:
#         tlgrm_list = files.load(file)
#
#     result_list = combot_list + chpic_list + tlgrm_list
#     print(len(result_list))
#     return result_list

if __name__ == "__main__":
    main()


#!/usr/bin/python3
import os
import sys
import argparse
import gettext
import registering

gettext.install('gooroom-client-server-register', '/usr/share/gooroom/locale')

example_regkey = """>v1.0)gooroom-client-server-register noninteractive-regkey -d gkm.gooroom.kr
                                            [-C /usr/local/share/ca-certificates/server.crt]
                                            [ -r 2] #0:create 1:update 2:create or update
                                            [ -m ipaddress]
                                            [-u gooroom]
                                            [-t Default]
                                             -k registration key
                                            [-e 2020-01-01]
                                            [-c 2F ooo]"""

autoregisteration_help ="""To automatically register your client to Gooroom Platform Management Server(GPMS) on boot, configure /etc/gooroom/gooroom-client-server-register/gcsr_auto.conf accordingly."""

def usage():
    print('ex)gooroom-client-server-register gui\n')
    print('ex)gooroom-client-server-register cli\n')
    print(example_regkey)
    print('\n')
    print(autoregisteration_help)

def argument_parser():
    clientip = os.popen('hostname --all-ip-addresses').read().split(' ')[0]
    parser = argparse.ArgumentParser(description=_('Register certificate of gooroom root CA & gooroom platform management server'))

    subparsers = parser.add_subparsers(dest='cmd', help=_('commands'))
    subparsers.required = True
    gui_parser = subparsers.add_parser('gui', help=_('Run as gtk graphical user interface'))
    cli_parser = subparsers.add_parser('cli', help=_('Run as command line interface'))
    ni_parser = subparsers.add_parser('noninteractive',
                                      help=_('Run as Noninteractive with shell.'),
                                      formatter_class=argparse.RawTextHelpFormatter)
    ni_help = subparsers.add_parser('noninteractive --help', help=_('Print help on the noninteractive command'))
    ni_parser.add_argument('-d', '--domain', required=True, help=_('Key management server hostname'))
    ni_parser.add_argument('-C', '--CAfile', help=_('(Option)PEM format file of gooroom root CA certificate'), nargs='?')
    ni_parser.add_argument('-n', '--cn', help=_('Unique CN to use for the client certificate'))
    ni_parser.add_argument('-m', '--name', help=_('(Option)Client name to distinguish from others:default=ip'), default=clientip)
    ni_parser.add_argument('-u', '--unit', help=_('Client organizational unit to use for the client certificate'))
    ni_parser.add_argument('-t', '--password-system-type', help=_('Password system type to use for the password hashing.'), default='Default', nargs='?')
    ni_parser.add_argument('-i', '--id', help=_('GPMS admin ID'))
    ni_parser.add_argument('-p', '--password', help=_('GPMS admin password'))
    ni_parser.add_argument('-e', '--expiration-date', help=_('(Option)Certificates expiration date(format:YYYY-MM-DD)'), default='', nargs='?')
    ni_parser.add_argument('-c', '--comment', help=_('(Option)Description of the certificate'), nargs='?')
    ni_parser.add_argument('-r', '--cert-reg-type', help=_('(Option)Certificate Registration Type(0:create 1:update 2:create or update) default=create or update'), default='2', nargs='?')

    ni_regkey_parser = subparsers.add_parser('noninteractive-regkey', description=example_regkey,
                                      help=_('Run as NoninteractiveRegKey with shell using regstration key but id/pwd.'),
                                      formatter_class=argparse.RawTextHelpFormatter)
    ni_regkey_help = subparsers.add_parser('noninteractive-regkey --help', help=_('Print help on the noninteractive-regkey command'))
    ni_regkey_parser.add_argument('-d', '--domain', required=True, help=_('Key management server hostname'))
    ni_regkey_parser.add_argument('-I', '--IP', help=_('Key management server IP'))
    ni_regkey_parser.add_argument('-C', '--CAfile', help=_('(Option)PEM format file of gooroom root CA certificate'), nargs='?')
    ni_regkey_parser.add_argument('-m', '--name', help=_('Option)Client name to distinguish from others:default=ip'), default=clientip)
    ni_regkey_parser.add_argument('-u', '--unit', help=_('Client organizational unit to use for the client certificate'))
    ni_regkey_parser.add_argument('-t', '--password-system-type', help=_('Password system type to use for the password hashing.'), default='Default', nargs='?')
    ni_regkey_parser.add_argument('-e', '--expiration-date', help=_('(Option)Certificates expiration date(format:YYYY-MM-DD)'), default='', nargs='?')
    ni_regkey_parser.add_argument('-c', '--comment', help=_('(Option)Description of the certificate'), nargs='?')
    ni_regkey_parser.add_argument('-k', '--regkey', required=True, help=_('GPMS registration key'))
    ni_regkey_parser.add_argument('-r', '--cert-reg-type', help=_('(Option)Certificate Registration Type(0:create 1:update 2:create or update) default=create or update'), default='2', nargs='?')

    arguments = parser.parse_args()
    return arguments

if __name__ == '__main__':
    '''
    main
    '''

    if len(sys.argv) == 1:
        usage()
        exit(1)

    args = argument_parser()
    if os.getuid():
        print(_("Permission denied."))
        exit(1)

    if args.cmd == 'gui':
        registering.GUIRegistering()
    else:
        shell_register = registering.ShellRegistering()
        shell_register.run(args)


import os
import requests
from lxml import html as html
from rich import print

clear = lambda: os.system('cls')

DEBUG = True
BASE_URL = 'https://www.larepublica.co/'
XPATH_LINK_TO_ARTICLES = '//a[@class="{0}Sect"]/@href'
XPATH_NEWS_TITLES = '//a[@class="{0}Sect"]/text()' # The title showed in the news list
XPATH_NEW_TITLE = '//div[@class="mb-auto"]/h2/span/text()'
XPATH_NEW_ABSTRACT = '//div[@class="lead"]/p/text()'
XPATH_NEW_CONTENT = '//div[@class="html-content"]/p/text()'

def run():
    ''''Ask for the news category to see'''
    clear()
    print('[yellow]NOTICIERO[/yellow] [cyan]COLOMBIANO[/cyan] [red]AL INSTANTE[red]')
    print('[yellow]Qué noticias deseas explorar?[/yellow]')
    print('''
    [1]-> Finanzas
    [2]-> Economía
    [3]-> Empresas
    [4]-> Ocio
    [5]-> Globoeconomía
    [6]-> Caja fuerte
    ''')
    option = input('')

    url = BASE_URL
    section = ''

    if option == '1':
        section = 'finanzas'
    elif option == '2':
        section = 'economia'
    elif option == '3':
        section = 'empresas'
    elif option == '4':
        section = 'ocio'
    elif option == '5':
        section = 'globoeconomia'
    elif option == '6':
        section = 'caja-fuerte'
    else:
        print('[red]Opción incorrecta[/red]')
        return

    url += section  # Creating URL to request

    try:
        response = requests.get(url)
        if response.status_code == 200:
            page = response.content.decode('utf-8')
            parsed = html.fromstring(page)

            links_of_news = parsed.xpath(XPATH_LINK_TO_ARTICLES.format(section))
            titles_of_news = parsed.xpath(XPATH_NEWS_TITLES.format(section))

            news = []
            print(len(links_of_news))
            print(len(titles_of_news))
            for i in range(len(links_of_news) ):
                buffer = dict(link=links_of_news[i], title=titles_of_news[i])
                news.append(buffer)
            display_news(news)

        else:
            raise ValueError(f'Error:{response.status_code}')
    except ValueError as ve:
        if DEBUG:
            print(f'[red]{ve}[/red]')
        else:
            print('[red]Ocurrió un error[/red]')

def display_news(news):
    '''Shows all news of the selected category'''
    clear()
    news_to_display = 15
    grouped_news = [news[i:i+news_to_display] for i in range(0,len(news), news_to_display)]
    page = 0
    selected = ''
    absolute_id = 0
    while True:
        print('[yellow]Escoge el número de la noticia que quieras leer[/yellow]')
        print('[yellow]Ingresa "<" o ">" para cambiar de página[/yellow]\n')
        print(f'[cyan]Página {page + 1}[/cyan]\n')
        for new in grouped_news[page]:
            print(f"[{absolute_id + 1}]-> {new['title']}")
            absolute_id += 1
        print('')
        selected = input('')

        if selected == '<':
            clear()
            page -= 1
            if page < 0:
                page = len(grouped_news) - 1
                absolute_id = len(news) - len(grouped_news[page])
            else:
                absolute_id -= (news_to_display + len(grouped_news[page + 1]))
        elif selected == '>':
            clear()
            page += 1
            if page >= len(grouped_news):
                page = 0
                absolute_id = 0
        elif selected.isnumeric():
            selected = int(selected)
            if selected > len(news) or selected <= 0:
                clear()
                print('[red]Noticia escogida fuera de rango[/red]')
            else:
                break
        else:
            print('[red]Opción inválida[/red]')

    show_new(news[selected - 1])

def show_new(new):
    '''Show the title, abstract and content of selected new'''
    clear()
    response = requests.get(new['link'])
    if response.status_code == 200:
        page = response.content.decode('utf-8')
        parsed = html.fromstring(page)

        title = new['title']
        abstract = parsed.xpath(XPATH_NEW_ABSTRACT)
        paragraphs = parsed.xpath(XPATH_NEW_CONTENT)

        full_content = ''
        for p in paragraphs:
            full_content += p + '\n'

        abstract = abstract[0].replace('\n', '')
        full_content = full_content.replace('\n', '\n\n')

        title = title.strip()
        abstract = abstract.strip()
        full_content.strip()

        print(f'[cyan]{title}[/cyan]\n\n')
        print(f'[green]{abstract}[/green]\n')
        print(f'[yellow]{full_content}[/yellow]\n\n')
        answer = ''
        while answer.capitalize() != 'S' and answer.capitalize() != 'N':
            print('[green]Desea ver más noticias?[/green] (S/N)')
            answer = input('')
            answer = answer.capitalize()
            if answer != 'S' and answer != 'N':
                print('[red]Opción incorrecta[/red]')
        if answer == 'S':
            clear()
            run()

    else:
        print(f'[red]Error: {response.status_code}[/red]')

if __name__ == '__main__':
    run()


import argparse
import os
from pathlib import Path

import tensorflow as tf
from tensorflow.keras import layers, models

import flwr as fl
import csv
from datetime import datetime
import numpy as np

from models import load_model
import time

# Make TensorFlow logs less verbose
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"

# Define Flower client
class CustomClient(fl.client.NumPyClient):
    def __init__(self, model, x_train, y_train, x_test, y_test, id):
        self.model = model
        self.x_train, self.y_train = x_train, y_train
        self.x_test, self.y_test = x_test, y_test
        self.id = id
        self.round = 0
        self.create_result_file()

    def create_result_file(self):
        row = "round & loss & accuracy & precision & time \\\\ \hline \n"
        now = datetime.now()
        postfix = now.strftime('%Y%m%d%H%M')

        file_path = "./results/client0" + str(self.id) + "-" + postfix

        self.result_file = file_path

        # with open(self.result_file, 'w') as f:
        #     f.write(row)

    def get_properties(self, config):
        """Get properties of client."""
        raise Exception("Not implemented")

    def get_parameters(self, config):
        """Get parameters of the local model."""
        raise Exception("Not implemented (server-side parameter initialization)")

    def fit(self, parameters, config):
        """Train parameters on the locally held training set."""
        start = time.time()
        # Update local model parameters
        self.model.set_weights(parameters)

        # Get hyperparameters for this round
        batch_size: int = config["batch_size"]
        epochs: int = config["local_epochs"]

        print("tamanho da base que estou treinando: ", len(self.x_train))

        # Train the model using hyperparameters from config
        history = self.model.fit(
            self.x_train,
            self.y_train,
            batch_size,
            epochs,
            validation_split=0.1,
        )

        # Return updated model parameters and results
        parameters_prime = self.model.get_weights()
        num_examples_train = len(self.x_train)
        results = {
            "loss": history.history["loss"][0],
            "accuracy": history.history["accuracy"][0],
            "val_loss": history.history["val_loss"][0],
            "val_accuracy": history.history["val_accuracy"][0],
        }

        end = time.time()
        self.elapse = end - start

        return parameters_prime, num_examples_train, results

    def evaluate(self, parameters, config):
        """Evaluate parameters on the locally held test set."""

        # Update local model with global parameters
        self.model.set_weights(parameters)

        # Get config values
        steps: int = config["val_steps"]

        # Evaluate global model parameters on the local test data and return results
        loss, accuracy, pre = self.model.evaluate(self.x_test, self.y_test, 32, steps=steps)

        num_examples_test = len(self.x_test)

        # row = " & " + str(self.round) + " & " + str(round(loss,3)) + " & " + str(round(accuracy,2)) + " & " + str(round(pre,2)) + " & " + str(int(self.elapse)) + " \\\\ \n"
        # with open(self.result_file, 'a') as f:
        #     f.write(row)

        self.round = self.round + 1

        return loss, num_examples_test, {"accuracy": accuracy}

def main() -> None:
    # Parse command line argument `partition`
    parser = argparse.ArgumentParser(description="Flower")
    parser.add_argument("--partition", type=int, choices=range(0, 5), required=True)
    parser.add_argument("--epochs", type=int, choices=range(1, 30), required=True)
    parser.add_argument("--clients", type=int, choices=range(1, 6), required=True)
    args = parser.parse_args()

    # Load and compile Keras model
    model = load_model("efinet", (45, 45, 3), 1)

    # Load a subset of dataset to simulate the local data partition
    (x_train, y_train), (x_test, y_test) = load_partition(args.partition, args.clients)

    # Start Flower client
    client = CustomClient(model, x_train, y_train, x_test, y_test, args.partition)

    fl.client.start_numpy_client(
        server_address="127.0.0.1:8080",
        client=client,
        root_certificates=Path(".cache/certificates/ca.crt").read_bytes(),
    )

def load_partition(idx: int, clients: int):
    """Load 1/10th of the training and test data to simulate a partition."""
    assert idx in range(clients)

    print("CLIENT %s --- Lendo dados para treino", idx)
    # read dataset
    train_ds = tf.keras.utils.image_dataset_from_directory(
        f'./datasource/hospital_detector_seed123/train',
        shuffle=True,
        batch_size=None,
        image_size=(45, 45)
    )

    test_ds = tf.keras.utils.image_dataset_from_directory(
        f'./datasource/hospital_detector_seed123/test',
        shuffle=True,
        batch_size=None,
        image_size=(45, 45)
    )

    print("CLIENT %s --- Fazendo treino", idx)

    x_train, y_train = tuple(zip(*train_ds))
    x_train, y_train = np.array(x_train), np.array(y_train)

    x_test, y_test = tuple(zip(*test_ds))
    x_test, y_test = np.array(x_test), np.array(y_test)

    # s_client_data_train_0 = int(len(x_train)*0.15)
    # s_client_data_train_1 = int(len(x_train)*0.10)
    # s_client_data_train_2 = int(len(x_train)*0.20)
    # s_client_data_train_3 = int(len(x_train)*0.30)
    # s_client_data_train_4 = int(len(x_train)*0.25)

    s_client_data_train = int(len(x_train)/clients)

    # print("----------- data size: ", str(s_client_data_train), " ------------------")
    # s_client_data_test = int(len(x_test)/clients)
    #x_test, y_test = tf.keras.datasets.cifar10.load_data()

    # start = 0
    # end = s_client_data_train_0

    # if idx == 1:
    #     start = s_client_data_train_0
    #     end = s_client_data_train_0 + s_client_data_train_1
    # elif idx == 2:
    #     start = s_client_data_train_0 + s_client_data_train_1
    #     end = s_client_data_train_0 + s_client_data_train_1 + s_client_data_train_2
    # elif idx == 3:
    #     start = s_client_data_train_0 + s_client_data_train_1 + s_client_data_train_2
    #     end = s_client_data_train_0 + s_client_data_train_1 + s_client_data_train_2 + s_client_data_train_3
    # elif idx == 4:
    #     start = s_client_data_train_0 + s_client_data_train_1 + s_client_data_train_2 + s_client_data_train_3
    #     end = len(x_train)

    # print("Start: ", start, "End: ", end)

    return (
        # x_train[start : end],
        # y_train[start : end],
        x_train[idx * s_client_data_train : (idx + 1) * s_client_data_train],
        y_train[idx * s_client_data_train : (idx + 1) * s_client_data_train],
    ), (
        # x_test[idx * s_client_data_test : (idx + 1) * s_client_data_test],
        # y_test[idx * s_client_data_test : (idx + 1) * s_client_data_test],
        x_test, y_test
    )

if __name__ == "__main__":
    main()


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import sys
import time
import argparse
import numpy as np
import cv2

from tensorflow.lite.python.interpreter import Interpreter

def mkdir(path):
    path=path.rstrip("\\")
    isExists=os.path.exists(path)
    if not isExists:
        os.makedirs(path)
        return True
    else:
        return False

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-i',
      '--image',
      default='/tmp/grace_hopper.bmp',
      help='image to be classified')
  parser.add_argument(
      '-m',
      '--model_file',
      default='/tmp/mobilenet_v1_1.0_224_quant.tflite',
      help='.tflite model to be executed')
  parser.add_argument(
      '--input_mean',
      default=127.5, type=float,
      help='input_mean')
  parser.add_argument(
      '--input_std',
      default=0.0078125, type=float,
      help='input standard deviation')
  args = parser.parse_args()
  print(args.model_file)
  print(args.image)
  print(args.input_mean)
  print(args.input_std)
  interpreter = Interpreter(model_path=args.model_file)
  interpreter.allocate_tensors()

  input_details = interpreter.get_input_details()
  print(input_details)
  output_details = interpreter.get_output_details()
  print(output_details)
  # check the type of the input tensor
  floating_model = input_details[0]['dtype'] == np.float32

  # NxHxWxC, H:1, W:2
  height = input_details[0]['shape'][1]
  width = input_details[0]['shape'][2]
  #print(height)
  #print(width)
  img_list=[]
  with open(args.image, 'r') as f:
      for line in f:
          img_list.append(line.strip())
  #print(img_list)
  i = 0
  for img_path in img_list:
    print(img_path)
    out_img_path = img_path.replace("/Users/leejohnnie/nfs/lfw-matlab-112x112", "./result")
    #out_img_path = img_path.replace("/Users/leejohnnie/dataset", "./result")
    print(out_img_path)
    out_img_path = os.path.splitext(out_img_path)
    print(out_img_path)
    newname = out_img_path[0] + ".bin"
    print(newname)
    mkdir(os.path.dirname(newname))
    start = time.time()
    img = cv2.imread(img_path, 0)
    input_data = np.expand_dims(img, axis=2)
    input_data = np.expand_dims(input_data, axis=0)
    print(input_data.shape)
    print("===========================")
    i = i + 1
    print(i)

    if floating_model:
      input_data = (np.float32(input_data) - args.input_mean) * args.input_std
    interpreter.set_tensor(input_details[0]['index'], input_data)

    interpreter.invoke()
    output_data = interpreter.get_tensor(output_details[0]['index'])
    output_data.astype('float32').tofile(newname)
    stop = time.time()
    print("time(s):", stop-start)


import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft, ifft
from scipy.signal import lfilter,freqz

def signal_function(t):
	# t is a list of numbers.
	return np.cos(2*np.pi*10*t) + np.cos(2*np.pi*100*t) + np.cos(2*np.pi*200*t)

def fft_plots(t, v, signal_xt, abs_fft_out, ifft_out):
	###########################
	### FFT and IFTTT PLOTS ###
	###########################

	# Set up three subplots.
	f, xarr = plt.subplots(3)

	# Change the color of the plots.
	plt.style.use('seaborn-dark') 	#print(plt.style.available)

	# Add space between the subplots.
	plt.subplots_adjust(hspace = 1.25)

	# NOISY SIGNAL
	xarr[0].set_title("Noisy Signal") 	# subplot[index]
	xarr[0].set_xlabel("Time t")
	xarr[0].set_ylabel("Volts V")
	xarr[0].plot(t, signal_xt)

	# FFT SIGNAL
	xarr[1].set_title("FFT Amplitude Spectrum")
	xarr[1].set_xlabel("Frequency")
	xarr[1].set_ylabel("Amplitude")
	xarr[1].plot(v[0:499], abs_fft_out[0:499])

	# IFFT SIGNAL
	xarr[2].set_title("Inverse FFT Amplitude Spectrum")
	xarr[2].set_xlabel("Time t")
	xarr[2].set_ylabel("Volts V")
	xarr[2].plot(t, ifft_out)

	return 0

def time_domain_filtering_plots(t, signal_xt, b, bn, filter_out):
	###################################
	### TIME DOMAIN FILTERING PLOTS ###
	###################################

	# TDFP = Time Domain Filtering Plots
	# Set up a column of subplots.
	f, tdfp = plt.subplots(3)

	# Change the style of the plots.
	plt.style.use("seaborn-dark")

	# Add space between the subplots.
	plt.subplots_adjust(hspace = 1.25)

	# NOISY SIGNAL
	tdfp[0].set_title("Noisy Signal") 	# subplot[index]
	tdfp[0].set_xlabel("Time t")
	tdfp[0].set_ylabel("Volts V")
	tdfp[0].plot(t, signal_xt)

	# FILTER IMPULSE
	tdfp[1].set_title("Filter Impulse (YOU CAN IGNORE THIS SUBPLOT)") 	# subplot[index]
	tdfp[1].set_xlabel("Time t")
	tdfp[1].set_ylabel("Volts V")
	tdfp[1].stem(bn, b)

	# FILTER OUTPUT (CONVOLUTION)
	tdfp[2].set_title("Filter Output (Convolution)") 	# subplot[index]
	tdfp[2].set_xlabel("Time t")
	tdfp[2].set_ylabel("Volts V")
	tdfp[2].plot(t, filter_out)

	return 0

def frequency_domain_filtering_plots(v, abs_fft_out, hzTrue, H, w_filter_out):
	########################################
	### FREQUENCY DOMAIN FILTERING PLOTS ###
	########################################

	# fdf = Frequency Domain Filtering
	f, fdf = plt.subplots(3)

	# Change the style of the plots.
	plt.style.use("seaborn-dark")

	# Add space between the subplots.
	plt.subplots_adjust(hspace = 1.25)

	# Amplitude Spectrum (Real Half)
	fdf[0].set_title("Amplitude Spectrum (Real Half)") 	# subplot[index]
	fdf[0].set_xlabel("Frequency Hz")
	fdf[0].set_ylabel("Amplitude")
	fdf[0].plot(v[0:499], abs_fft_out[0:499])

	# Frequency Response of Filter
	fdf[1].set_title("Frequency Response of Filter") 	# subplot[index]
	fdf[1].set_xlabel("Frequency Hz")
	fdf[1].set_ylabel("Amplitude")
	fdf[1].plot(hzTrue[0:499], H[0:499])

	# Filter Output (Fast Fourier Transform)
	fdf[2].set_title("Filter Output (fft)") 	# subplot[index]
	fdf[2].set_xlabel("Frequency Hz")
	fdf[2].set_ylabel("Amplitude")
	fdf[2].plot(v[0:499], w_filter_out[0:499])

	return 0

def final_plot(t, v, filter_out, filter_out_fft_out, w_filter_out, ifft_tdf):
	# fp = Final Plot
	f, fp = plt.subplots(4)

	# Change the style of the plots.
	plt.style.use("seaborn-dark")

	# Add space between the subplots.
	plt.subplots_adjust(hspace = 1.25)

	# FILTER OUTPUT (CONVOLUTION)
	fp[0].set_title("Filter Output (Convolution)") 	# subplot[index]
	fp[0].set_xlabel("Time t")
	fp[0].set_ylabel("Volts V")
	fp[0].plot(t, filter_out)

	# FFT of Convolution
	fp[1].set_title("FFT of Time Domain Filtering (Convolution)") 	# subplot[index]
	fp[1].set_xlabel("Time t")
	fp[1].set_ylabel("Amplitude")
	fp[1].plot(v[0:499], filter_out_fft_out[0:499])

	# Filter Output of Frequency Domain Filtering (Fast Fourier Transform)
	fp[2].set_title("Filter Output of Frequency Domain Filter (fft)") 	# subplot[index]
	fp[2].set_xlabel("Frequency Hz")
	fp[2].set_ylabel("Amplitude")
	fp[2].plot(v[0:499], w_filter_out[0:499])

	# The Inverse Fast Fourier Transform of the output of the filtered waveform from FFT.
	fp[3].set_title("IFFT of FFT of Frequency Domain Filtering") 	# subplot[index]
	fp[3].set_xlabel("Time t")
	fp[3].set_ylabel("Amplitude")
	#fp[3].plot(v[0:499], ifft_tdf[0:499])
	fp[3].plot(t, ifft_tdf)
	return 0

if __name__ == "__main__":
	#####################
	### FFT and IFTTT ###
	#####################

	# t is of length 1000. Numbers range from 0 to 2.
	t = np.linspace(0, 2, 1000)

	# Making a list of numbers which will make the list of frequencies.
	n = np.linspace(0, 1, 1000) # n goes from 0 to 1 with 1000 points in-between.

	# Create the signal xt
	signal_xt = signal_function(t)

	# T is the sample period
	# T = (endTime - startTime)/(signalLength)
	T = (2-0)/len(signal_xt) # T = 0.002

	# v is the sample frequency multiplies by the length of the function to make an array of frequencies.
	v = n/T # v ranges from 0 to 500 with 1000 samples in between.

	# Obtain the absolute value of the fast Fourier transform of the signal xt
	fft_out = fft(signal_xt)
	abs_fft_out = abs(fft_out)

	# Get the inverse Fourier transform from the fast Fourier transform.
	ifft_out = ifft(fft_out)

	#############################
	### TIME DOMAIN FILTERING ###
	#############################

	# 15 point moving average filter
	N = 15

	# Make list of 15 ones, and divide every single one by 15.
	b = (1/N)*np.ones(N)

	# Make 15 different points for graphing.
	bn = np.arange(15)

	# Generate a filtered output of the signal_xt, This convolves the sequence b, with the noisy data.
	filter_out = lfilter(b, 1, signal_xt)

	##################################
	### FREQUENCY DOMAIN FILTERING ###
	##################################

	# The rate at which the frequency is sampled.
	sample_rate = 1/T # sample_rate = 500

	# H is a representation of our moving average filter called the frequency response.
	hz, H = freqz(b, 1, worN = v*2*np.pi/sample_rate)
	hzTrue = hz*sample_rate/(2*np.pi)

	# Filter the fast Fourier transform of the signal xt
	w_filter_out = H*fft_out

	##################
	### FINAL PLOT ###
	##################

	# From the Time Domain Filtering.
	filter_out_fft_out = fft(filter_out) # Plot amplitude spectrum.

	# Take the Inverse Fast Fourier Transform of the FFT of the Time Domain Filtering.
	ifft_tdf = ifft(w_filter_out)

	#################
	### ALL PLOTS ###
 	#################

	# FFT and IFFT Filtering Plots
	fft_plots(t, v, signal_xt, abs_fft_out, ifft_out)

	# Time Domain Filtering Plots
	time_domain_filtering_plots(t, signal_xt, b, bn, filter_out)

	# Frequency Domain Filtering Plots
	frequency_domain_filtering_plots(v, abs_fft_out, hzTrue, H, w_filter_out)

	# Final Plots
	final_plot(t, v, filter_out, filter_out_fft_out, w_filter_out, ifft_tdf)

	# Show all the plots.
	plt.show()


from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from .models import Order, Option, Product, Price, Cart, Cart_Item
# from django.contrib.auth.models import User
from users.models import User
@receiver(post_save, sender=Order)
def create_options(sender, instance, created, **kwargs):
    if created:
        for t in range(instance.selection_limit + 1):
            Option.objects.get_or_create(order=instance, selection_count=t)

@receiver(post_save, sender=Option)
def create_prices(sender, instance, created, **kwargs):
    if created:
        if instance.order.size_choice:
            Price.objects.get_or_create(option=instance, size="Large")
            Price.objects.get_or_create(option=instance, size="Small")
        else:
            Price.objects.get_or_create(option=instance)

@receiver(post_save, sender=User)
def create_cart(sender, instance, created, **kwargs):
    if created:
        Cart.objects.get_or_create(user=instance)

@receiver(pre_delete, sender=Cart)
def remove_cart_item(sender, instance, using, **kwargs):
    for cart_item in instance.cart_items.all():
        Cart_Item.objects.filter(id=cart_item.id).delete()


from ctypes import windll
from win32api import GetSystemMetrics
from PIL import ImageGrab
import pynput
import time
import pytesseract
import sys

myKeyboard = pynput.keyboard.Controller()
myMouse = pynput.mouse.Controller()
screensize = windll.user32.GetSystemMetrics(
    0), windll.user32.GetSystemMetrics(1)
# path to tesseract's executable, this should be the standard path
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
image = None
limit = 30

if (screensize[0] == 1920 and screensize[1] == 1080):
    myMouse.position = (953, 574)
    myMouse.click(pynput.mouse.Button.left, 1)
    myMouse.position = (953, 430)
elif (screensize[0] == 2560 and screensize[1] == 1440):
    myMouse.position = (1273, 574)
    myMouse.click(pynput.mouse.Button.left, 1)
    myMouse.position = (1270, 427)
else:
    print("Sorry, your screen resolution isn't supported.")
    sys.exit(1)

time.sleep(0.2)

for lvl in range(0, limit):
    if (screensize[0] == 1920 and screensize[1] == 1080):
        image = ImageGrab.grab(bbox=(540, 340, 1344, 470))
    elif (screensize[0] == 2560 and screensize[1] == 1440):
        image = ImageGrab.grab(bbox=(1000, 300, 1546, 520))

    if (image is not None):
        #print(pytesseract.image_to_string(image, config='digits'))
        image = image.convert("RGBA")
        pixeldata = image.load()
        # convert the blue background to white and number to black in order to help tesseract recognize the number
        for y in range(0, image.size[1]):
            for x in range(0, image.size[0]):
                if pixeldata[x, y] < (250, 250, 250, 255):
                    pixeldata[x, y] = (255, 255, 255, 255)
                else:
                    pixeldata[x, y] = (0, 0, 0, 255)

        number = ""
        if (lvl == 0):
            # supposedly better psm (page segmentation mode) for single characters
            number = pytesseract.image_to_string(image, config='--psm 10')
        else:
            # config for digits
            number = pytesseract.image_to_string(image, config='digits')
        # try and filter out some consistent mistakes made by tesseract
        print("Tesseract read: " + number)
        if (not number.isdigit()):
            number = number.replace("i", "1").replace(
                "&", "6").replace("t", "7").replace("a", "4").replace("G", "6")

        # if (lvl >= 10):
        #     image.show()

        if (not number.isdigit() or len(number) != lvl + 1):
            print("Tesseract OCR failed to recognize the number")
            sys.exit(1)

        print("Writing: " + number)

        delay = 2
        # click on text feld to focus it
        if (lvl >= 2):
            delay += (lvl - 1) * 1
        print("Waiting: " + str(delay) + "s")
        time.sleep(delay)
        myMouse.click(pynput.mouse.Button.left, 1)
        myKeyboard.type(number)
        myKeyboard.press(pynput.keyboard.Key.enter)
        myKeyboard.release(pynput.keyboard.Key.enter)
        time.sleep(0.1)
        myKeyboard.press(pynput.keyboard.Key.enter)
        myKeyboard.release(pynput.keyboard.Key.enter)
        time.sleep(0.5)