import base64
import json
import os
import time
import yaml
from io import BytesIO
import logging
import logging.config

import numpy as np
import tensorflow as tf
from azureml.core.model import Model
from PIL import Image

from utils import label_map_util
from azureml.monitoring import ModelDataCollector
from azure.storage.blob import BlockBlobService
from azure.storage.blob.models import ContentSettings

MODEL_NAME = '__REPLACE_MODEL_NAME__'
PASCAL_LABEL_MAP_FILE = 'pascal_label_map.pbtxt'
THRESHOLD = float(os.getenv('MIN_CONFIDENCE', '0.8'))
IMAGE_STORAGE_ACCOUNT_NAME = '__REPLACE_IMAGE_STORAGE_ACCOUNT_NAME__'
IMAGE_STORAGE_ACCOUNT_KEY = '__REPLACE_IMAGE_STORAGE_ACCOUNT_KEY__'
IMAGE_STORAGE_CONTAINER_NAME = '__REPLACE_IMAGE_STORAGE_CONTAINER_NAME__'

def init():
  global logger
  global model
  global pred_collector
  global blob_service
  init_logger()
  pred_collector = ModelDataCollector(MODEL_NAME, identifier="imgpred", feature_names=["detection"])
  model = load_model()
  blob_service = BlockBlobService(IMAGE_STORAGE_ACCOUNT_NAME, IMAGE_STORAGE_ACCOUNT_KEY)
  blob_service.create_container(IMAGE_STORAGE_CONTAINER_NAME) #fail_on_exist=False by default

def init_logger():
  global logger
  logconf = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'logging.yml')
  print('logconf {}'.format(logconf))
  if os.path.exists(logconf):
    with open(logconf, 'rt') as f:
      config = yaml.safe_load(f.read())
      logging.config.dictConfig(config)
      print('logconf loaded')
  else:
      logging.basicConfig(level=default_level)
      print('logconf fall back to default')
  logger = logging.getLogger('score')

def load_model():
  # figure out how many classes
  label_map_dict = label_map_util.get_label_map_dict(PASCAL_LABEL_MAP_FILE)
  num_classes = len(label_map_dict)
  logger.info('num_of_classes in pascal_label_map: {}'.format(num_classes))

  # Load label map
  label_map = label_map_util.load_labelmap(PASCAL_LABEL_MAP_FILE)
  categories = label_map_util.convert_label_map_to_categories(
    label_map, max_num_classes=num_classes, use_display_name=True)
  category_index = label_map_util.create_category_index(categories)

  # Load a frozen Tensorflow model into memory
  model_path = Model.get_model_path(MODEL_NAME)
  logger.info('getting model {} from {}'.format(MODEL_NAME, model_path))

  detection_graph = tf.Graph()
  with detection_graph.as_default():
    od_graph_def = tf.GraphDef()
    with tf.gfile.GFile(model_path, 'rb') as fid:
      serialized_graph = fid.read()
      od_graph_def.ParseFromString(serialized_graph)
      tf.import_graph_def(od_graph_def, name='')

      # Get handles to input and output tensors
      ops = tf.get_default_graph().get_operations()
      all_tensor_names = {output.name for op in ops for output in op.outputs }
      tensor_dict = {}
      for key in ['num_detections', 'detection_boxes', 'detection_scores', 'detection_classes']:
        tensor_name = key + ':0'
        if tensor_name in all_tensor_names:
          tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(tensor_name)

      image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')
      sess = tf.Session(graph=detection_graph)
  return {
    'session': sess,
    'image_tensor': image_tensor,
    'tensor_dict': tensor_dict,
    'category_index': category_index
  }

def run(raw_data):
  logger.debug('raw_data: {}'.format(raw_data))
  try:
    response = inference(raw_data)
  except Exception as e:
    response = str(e)
  return response

def inference(raw_data):
  logger.info('parse input json raw_data to get image')
  parsed_json = json.loads(raw_data)
  image_raw = parsed_json['file']
  logger.info('base64 decode input image')
  image_bytes = base64.b64decode(image_raw)
  image = Image.open(BytesIO(image_bytes))
  logger.info('turn decoded image to np_array')
  (im_width, im_height) = image.size
  image_np = np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
  image_np_expanded = np.expand_dims(image_np, axis=0)

  # Run inference
  start_time = time.time()
  output_dict = model['session'].run(
    model['tensor_dict'], feed_dict={model['image_tensor']: image_np_expanded})
  latency = time.time() - start_time
  logger.info('scoring took {} seconds'.format(latency))

  # all outputs are float32 numpy arrays, so convert types as appropriate
  output_dict['num_detections'] = int(output_dict['num_detections'][0])
  output_dict['detection_classes'] = output_dict['detection_classes'][0].astype(np.uint8).tolist()
  output_dict['detection_boxes'] = output_dict['detection_boxes'][0].tolist()
  output_dict['detection_scores'] = output_dict['detection_scores'][0].tolist()
  logger.info('num of detections: {}'.format(output_dict['num_detections']))

  result = []
  for idx, score in enumerate(output_dict['detection_scores']):
    if score > THRESHOLD:
      result.append({
        'class': output_dict['detection_classes'][idx],
        'label': model['category_index'][output_dict['detection_classes'][idx]]['name'],
        'confidence': output_dict['detection_scores'][idx],
        'bounding_box': output_dict['detection_boxes'][idx]
      })
    else:
      logger.debug('idx {} detection score too low {}'.format(idx, score))
  #store the input image in blob storage and get the path to the image as correlation_id for prediction
  image_id = '{}/{}.jpg'.format(MODEL_NAME, int(start_time))
  StoreImage(image_id, image_bytes)
  pred_collector.collect(result, user_correlation_id=image_id)
  return result

def StoreImage(image_id, image_bytes):
  blob_service.create_blob_from_bytes(IMAGE_STORAGE_CONTAINER_NAME, image_id, image_bytes,
    content_settings=ContentSettings('image/jpeg'))


# This test must be executed after test_account_transfer_funds tests in order to work properly
from ...parabank.src.base_element import BaseElement
from ...parabank.src.pages.account_services_pages.find_transactions_page import FindTransactionsPage
# from web.parabank.tests.test_account_transfer_funds import transfer_data
from datetime import date
from typing import List, Union
import pytest

"""
!!! Please run 'test_account_transfer_funds.py' tests before executing this module !!!
"""

account_link = "find_transactions"

id_incorrect = ["00000", "aaa"]
date_incorrect = ["01-01-2020", "11-11-1111", str(date.today())]
date_incorrect_format = ["2020_01_01", "01.01.2020", "aaa"]
amount_incorrect = ["1.1", "-11", "0011"]
amount_incorrect_format = ["1_1", "aaa"]
transfer_data = ["10", "0", "-10"]

@pytest.fixture(scope="function")
def find_page(driver, user_login) -> FindTransactionsPage:
    page = user_login.logged_in_panel.click_link(account_link)
    page.dropdown_account.wait_until_not_empty()
    return page

@pytest.fixture(scope="function")
def transaction_id(user_login) -> str:
    page = user_login.logged_in_panel.click_accounts_overview()
    page = page.click_account_link()
    transaction_id = page.get_transaction_id()
    page.logged_in_panel.click_find_transactions()
    return transaction_id

@pytest.fixture(scope="module")
def current_date() -> str:
    today = str(date.today())
    today_format = today[5:10] + '-' + today[0:4]
    return today_format

def submit_form_with_params(fields: Union[BaseElement, List[BaseElement]], button: BaseElement, form: BaseElement,
                            values: Union[str, List[str]]):
    if isinstance(fields, BaseElement) and isinstance(values, str):
        fields.set_text(values)
    elif isinstance(fields, List) and isinstance(values, str):
        for field in fields:
            field.set_text(values)
    elif isinstance(fields, List) and isinstance(values, List):
        for field, value in zip(fields, values):
            field.set_text(value)
    else:
        raise Exception("You can't assign the list of values to the single input field")
    button.click()
    form.wait_to_appear()

def test_find_transaction_by_correct_transaction_id(find_page, transaction_id):
    submit_form_with_params(find_page.input_by_id, find_page.button_by_id, find_page.success_form, transaction_id)
    assert find_page.is_success()
    assert find_page.get_transaction_id() == transaction_id
    find_page.print_transaction_results()
    page = find_page.click_transaction_link()
    page.print_transaction_details()
    assert page.is_on_correct_page()

@pytest.mark.parametrize("data", id_incorrect,
                         ids=[f"Negative test {i+1} with id '{id_incorrect[i]}'"
                              for i in range(len(id_incorrect))]
                         )
def test_find_transaction_by_incorrect_transaction_id(find_page, data):
    submit_form_with_params(find_page.input_by_id, find_page.button_by_id, find_page.error_form, data)
    assert not find_page.is_success()

def test_find_transaction_by_correct_date(find_page, current_date):
    submit_form_with_params(find_page.input_by_date, find_page.button_by_date, find_page.success_form, current_date)
    assert find_page.is_success()
    find_page.print_transaction_results()
    page = find_page.click_transaction_link()
    assert page.is_on_correct_page()

@pytest.mark.parametrize("data", date_incorrect,
                         ids=[f"Negative test {i+1} with date '{date_incorrect[i]}'"
                              for i in range(len(date_incorrect))]
                         )
def test_find_transaction_by_incorrect_date(find_page, data):
    submit_form_with_params(find_page.input_by_date, find_page.button_by_date, find_page.success_form, data)
    assert find_page.is_success() and not find_page.transactions_table_line.exists()

@pytest.mark.parametrize("data", date_incorrect_format,
                         ids=[f"Negative test {i+1} with date '{date_incorrect_format[i]}'"
                              for i in range(len(date_incorrect_format))]
                         )
def test_find_transaction_by_incorrect_date_format(find_page, data):
    submit_form_with_params(find_page.input_by_date, find_page.button_by_date, find_page.error_form, data)
    assert not find_page.is_success()

def test_find_transaction_by_correct_dates(find_page, current_date):
    submit_form_with_params([find_page.input_from_date, find_page.input_to_date], find_page.button_by_date_range,
                            find_page.success_form, current_date)
    assert find_page.is_success()
    find_page.print_transaction_results()
    page = find_page.click_transaction_link()
    assert page.is_on_correct_page()

@pytest.mark.parametrize("data", date_incorrect,
                         ids=[f"Negative test {i+1} with date '{date_incorrect[i]}'"
                              for i in range(len(date_incorrect))]
                         )
def test_find_transaction_by_incorrect_dates(find_page, data):
    submit_form_with_params([find_page.input_from_date, find_page.input_to_date], find_page.button_by_date_range,
                            find_page.success_form, data)
    assert find_page.is_success() and not find_page.transactions_table_line.exists()

@pytest.mark.parametrize("data", date_incorrect_format,
                         ids=[f"Negative test {i+1} with date '{date_incorrect_format[i]}'"
                              for i in range(len(date_incorrect_format))]
                         )
def test_find_transaction_by_incorrect_dates_format(find_page, data):
    submit_form_with_params([find_page.input_from_date, find_page.input_to_date], find_page.button_by_date_range,
                            find_page.error_form, data)
    assert not find_page.is_success()

@pytest.mark.parametrize("data", transfer_data,
                         ids=[f"Positive test {i+1} with amount '{transfer_data[i]}'"
                              for i in range(len(transfer_data))]
                         )
def test_find_transaction_by_correct_amount(find_page, data):
    submit_form_with_params(find_page.input_by_amount, find_page.button_by_amount, find_page.success_form, data)
    assert find_page.is_success()
    find_page.print_transaction_results()
    page = find_page.click_transaction_link()
    assert page.is_on_correct_page()

@pytest.mark.parametrize("data", amount_incorrect,
                         ids=[f"Negative test {i+1} with amount '{amount_incorrect[i]}'"
                              for i in range(len(amount_incorrect))]
                         )
def test_find_transaction_by_incorrect_amount(find_page, data):
    submit_form_with_params(find_page.input_by_amount, find_page.button_by_amount, find_page.success_form, data)
    assert find_page.is_success() and not find_page.transactions_table_line.exists()

@pytest.mark.parametrize("data", amount_incorrect_format,
                         ids=[f"Negative test {i+1} with amount '{amount_incorrect_format[i]}'"
                              for i in range(len(amount_incorrect_format))]
                         )
def test_find_transaction_by_incorrect_amount_format(find_page, data):
    submit_form_with_params(find_page.input_by_amount, find_page.button_by_amount, find_page.error_form, data)
    assert not find_page.is_success()

def test_find_transaction_with_blank_inputs(find_page):
    find_page.button_by_id.click()
    assert find_page.is_on_correct_page() and not find_page.is_success()
    find_page.button_by_date.click()
    assert find_page.is_on_correct_page() and not find_page.is_success()
    find_page.button_by_date_range.click()
    assert find_page.is_on_correct_page() and not find_page.is_success()
    find_page.button_by_amount.click()
    assert find_page.is_on_correct_page() and not find_page.is_success()


from itertools import permutations as permu

INF = 10**18

N = int(input())
A = [list(map(int, input().split())) for _ in range(N)]
M = int(input())
XY = [list(map(int, input().split())) for _ in range(M)]

invalids = set()
for x, y in XY:
    x -= 1
    y -= 1
    invalids.add((x, y))
    invalids.add((y, x))

def solve_cost(l):
    ans = 0
    for i in range(N):
        if i+1 < N:
            ab = (l[i], l[i+1])
            if ab in invalids:
                return INF
        ans += A[l[i]][i]
    return ans

ans = INF
for l in permu(range(N)):
    score = solve_cost(l)
    # print(l, score)
    ans = min(ans, score)
if ans == INF:
    print(-1)
else:
    print(ans)


"""
Handles /templates endpoint
Doc: https://developers.mailersend.com/api/v1/templates.html
"""

import requests
from mailersend.base import base

class NewTemplate(base.NewAPIClient):
    """
    Instantiates the /templates endpoint object
    """

    def __init__(self):
        """
        NewTemplate constructor
        """
        baseobj = base.NewAPIClient()
        super().__init__(
            baseobj.api_base,
            baseobj.headers_default,
            baseobj.headers_auth,
            baseobj.mailersend_api_key,
        )

    def get_templates(self):
        """
        Returns a JSON response from the MailerSend API
        """
        request = requests.get(
            f"{self.api_base}/templates", headers=self.headers_default
        )
        return request.text

    def get_template_by_id(self, template_id):
        """
        Returns a JSON response from the MailerSend API
        """
        request = requests.get(
            f"{self.api_base}/templates/{template_id}", headers=self.headers_default
        )
        return request.text

    def delete_template(self, template_id):
        """
        Returns a JSON response from the MailerSend API
        """
        request = requests.delete(
            f"{self.api_base}/templates/{template_id}", headers=self.headers_default
        )
        return request.text


from .metric import *
from scipy.spatial.distance import cosine
import torch

from feerci import feerci

def asnorm(enroll_test_scores, enroll_xv, test_xv, cohort_xv):
    """
    Calculate adaptive s-norm

    A direct and continuous measurement of speaker confusion between all
    training samples is computationally expensive. Hence, an option is to
    compute speaker similarities from the weights of the AAM-softmax layer as
    approximations of the class-centers.

    :param enroll_test_scores: Score between enrollment and test utterances. Must be in torch.tensor format
    :param enroll_xv: Extracted xvectors from enrollment utterances. Must be in torch.tensor format
    :param test_xv: Extracted xvectors from test utterances. Must be in torch.tensor format
    :param cohort_xv: xvectors from cohort speakers. Must be in torch.tensor format
    :return: The adaptive S-Norm (ref https://www.isca-speech.org/archive/pdfs/interspeech_2017/matejka17_interspeech.pdf)
    """

    # Calculate scores between enroll and cohort
    #  print(enroll_xv.shape, cohort_xv.shape, flush=True)
    enroll_cohort_scores = torch.einsum('ij,kj', enroll_xv, cohort_xv)
    k = 200
    if cohort_xv.shape[0] < k:
        k = cohort_xv.shape[0]
    # Calculate mean and std from top 200 scores
    topk_cohort_enroll = enroll_cohort_scores.topk(k, dim=1).values
    calib_mean_enroll = topk_cohort_enroll.mean(dim=1)
    calib_std_enroll = topk_cohort_enroll.std(dim=1)

    # Calculate scores between test and cohort
    cohort_test_scores = torch.einsum('ij,kj', test_xv, cohort_xv)
    # Calculate mean and std from top 200 scores
    topk_cohort_test = cohort_test_scores.topk(k, dim=1).values
    calib_mean_test = topk_cohort_test.mean(dim=1)
    calib_std_test = topk_cohort_test.std(dim=1)

    # Calculate S-norm from z_Norm and t_norm
    z_Norm = ((enroll_test_scores - calib_mean_enroll) / calib_std_enroll)
    t_Norm = (enroll_test_scores - calib_mean_test) / calib_std_test
    return 0.5 * (z_Norm + t_Norm)

def cosine_scoring(embd1s, embd2s):
    scores = []
    for embd1, embd2 in zip(embd1s, embd2s):
        # Multiplying by -1 to ensure compatibility with affinity
        # Now lower value will indicate less affinity as compared
        # to original cosine distance
        score = 1 - cosine(embd1, embd2)
        scores.append(score)
    return scores


import argparse
import os

import chc.util.fileutil as UF
import chc.reporting.ProofObligations as RP

from chc.app.CApplication import CApplication

def parse():
    parser = argparse.ArgumentParser()
    parser.add_argument("cwe", help="name of cwe, e.g., CWE121")
    parser.add_argument("test", help="name of test case, e.g., CWE129_large")
    args = parser.parse_args()
    return args

if __name__ == "__main__":

    args = parse()

    try:
        cpath = UF.get_juliet_testpath(args.cwe, args.test)
        UF.check_analysis_results(cpath)
    except UF.CHError as e:
        print(str(e.wrap()))
        exit(1)

    sempath = os.path.join(cpath, "semantics")

    excludefiles = ["io.c", "main_linux.c", "std_thread.c"]

    summary = UF.read_project_summary_results(cpath)
    if summary is not None:
        print(RP.project_proofobligation_stats_dict_to_string(summary))
        exit(0)

    capp = CApplication(sempath, excludefiles=excludefiles)

    filterout = ["io", "main_linux", "std_thread"]
    dc = ["deadcode"]

    def filefilter(f):
        return f not in filterout

    print(
        RP.project_proofobligation_stats_tostring(
            capp, extradsmethods=dc, filefilter=filefilter
        )
    )

    contract_condition_violations = capp.get_contract_condition_violations()

    if len(contract_condition_violations) > 0:
        print("=" * 80)
        print(str(len(contract_condition_violations)) + " CONTRACT CONDITION FAILURES")
        print("=" * 80)
        for (fn, cc) in contract_condition_violations:
            print(fn + ":")
            for (name, desc) in cc:
                print("   " + name + ":" + desc)
        print("=" * 80)


from django.urls import path
from . import views

app_name = 'todo'
urlpatterns = [
    path('', views.index, name='index'),
    path('completed', views.get_completed, name='get_completed'),
    path('unfinished', views.get_unfinished, name='get_unfinished'),
    path('add', views.add, name='add'),
    path('edit/<int:identifier>', views.edit, name='edit'),
    path('delete/<int:identifier>', views.delete, name='delete'),
    path('complete/<int:identifier>', views.complete, name='complete'),
    path('remove_complete/<int:identifier>', views.remove_complete, name='remove_complete')
]


import cv2
import numpy as np

cap = cv2.VideoCapture(r'Copy_of_offsside7.mp4')
fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = cap.get(cv2.CAP_PROP_FPS)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
out = cv2.VideoWriter('output.avi', fourcc, fps, size)

while(cap.isOpened()):

    # Take each frame
    ret, frame = cap.read()
    if ret:

    # Convert BGR to HSV
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # define range of blue color in HSV
        lower_blue = np.array([110, 50, 50])
        upper_blue = np.array([130, 255, 255])

        # Threshold the HSV image to get only blue colors
        mask = cv2.inRange(hsv, lower_blue, upper_blue)

        # Bitwise-AND mask and original image
        res = cv2.bitwise_and(frame, frame, mask= mask)

        cv2.imshow('frame', frame)
        cv2.imshow('mask', mask)
        cv2.imshow('res', res)

        # draw bounding box for the players
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
        cnt_thresh = 180
        if len(cnts) > 0:
            c = sorted(cnts, key=cv2.contourArea, reverse=True)
            for i in range(len(c)):
                if cv2.contourArea(c[i]) < cnt_thresh:
                    break

                x, y, w, h = cv2.boundingRect(c[i])
                h += 10
                y -= 5
                if h < 0.8 * w:
                    continue
                elif h / float(w) > 3:
                    continue

                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
                M = cv2.moments(c[i])
                # find the center of gravity of the players
                center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
                # find the foot of the players
                foot = (center[0], int(center[1] + h*1.1))
                cv2.circle(frame, foot, 5, (0, 0, 255), -1)

        out.write(frame)
    else:
        break

    if cv2.waitKey(25) & 0xFF == ord('q'):
        break
cap.release()
out.release()
cv2.destroyAllWindows()


from typing import (
    Any,
    Dict,
    List,
    Tuple,
    Union,
)

from eth_utils import (
    to_canonical_address,
    decode_hex,
    big_endian_to_int,
)
from eth_typing import (
    Address,
)

from sharding.contracts.utils.smc_utils import (
    get_smc_json,
)
from sharding.handler.exceptions import (
    LogParsingError,
)

class LogParser(object):
    def __init__(self, *, event_name: str, log: Dict[str, Any]) -> None:
        event_abi = self._extract_event_abi(event_name=event_name)

        topics = []
        data = []
        for item in event_abi["inputs"]:
            if item['indexed'] is True:
                topics.append((item['name'], item['type']))
            else:
                data.append((item['name'], item['type']))

        self._set_topic_value(topics=topics, log=log)
        self._set_data_value(data=data, log=log)

    def _extract_event_abi(self, *, event_name: str) -> Dict[str, Any]:
        for func in get_smc_json()['abi']:
            if func['name'] == event_name and func['type'] == 'event':
                return func
        raise LogParsingError("Can not find event {}".format(event_name))

    def _set_topic_value(self, *, topics: List[Tuple[str, Any]], log: Dict[str, Any]) -> None:
        if len(topics) != len(log['topics'][1:]):
            raise LogParsingError(
                "Error parsing log topics, expect"
                "{} topics but get {}.".format(len(topics), len(log['topics'][1:]))
            )
        for (i, topic) in enumerate(topics):
            val = self._parse_value(val_type=topic[1], val=log['topics'][i + 1])
            setattr(self, topic[0], val)

    def _set_data_value(self, *, data: List[Tuple[str, Any]], log: Dict[str, Any]) -> None:
        data_bytes = decode_hex(log['data'])
        if len(data) * 32 != len(data_bytes):
            raise LogParsingError(
                "Error parsing log data, expect"
                "{} data but get {}.".format(len(data), len(data_bytes))
            )
        for (i, (name, type_)) in enumerate(data):
            val = self._parse_value(val_type=type_, val=data_bytes[i * 32: (i + 1) * 32])
            setattr(self, name, val)

    def _parse_value(self, *, val_type: str, val: bytes) -> Union[bool, Address, bytes, int]:
        if val_type == 'bool':
            return bool(big_endian_to_int(val))
        elif val_type == 'address':
            return to_canonical_address(val[-20:])
        elif val_type == 'bytes32':
            return val
        elif 'int' in val_type:
            return big_endian_to_int(val)
        else:
            raise LogParsingError(
                "Error parsing the type of given value. Expect bool/address/bytes32/int*"
                "but get {}.".format(val_type)
            )


from flask import Blueprint, render_template
from flask import current_app as app

about_bp = Blueprint(
    name = "about_bp",
    import_name = __name__,
    template_folder = "templates",
    static_folder = 'assets'
)

@about_bp.route("/about")
def about_page():
    return render_template(
        "about.html", title = 'Brasil em Números'
    )


import os
import subprocess
import unittest
from click.testing import CliRunner
from impulsare_config import Reader as ConfigReader
from impulsare_distributer.queue_listener import cli
base_path = os.path.abspath(os.path.dirname(__file__))

# https://docs.python.org/3/library/unittest.html#assert-methods
class TestQueueListener(unittest.TestCase):
    base_cmd = ['python', base_path + '/../impulsare_distributer/queue_listener.py']

    def test_requires_config(self):
        runner = CliRunner()
        result = runner.invoke(cli)
        self.assertIs(result.exit_code, 2)
        self.assertRegex(result.output, '.*Missing option "--host"')

    def test_bad_host(self):
        cmd = ['queue-listener', '-h', '127.0.0.1', '-p', '80', '-q', 'wrong']
        res = self._exec_cmd(cmd)
        self.assertIs(res['status'], 1, "Can't get status 1, message: {} ('{}')".format(res['stderr'], cmd))
        self.assertEqual(res['stdout'], '')
        self.assertRegex(res['stderr'], '.*Error 111 connecting to 127.0.0.1:80. Connection refused.*')
        self.assertNotRegex(res['stderr'], '.*redis.exceptions.ConnectionError: Error 111 connecting to 127.0.0.1:80. Connection refused.*')

    def test_bad_host_debug(self):
        cmd = self.base_cmd + ['--debug', '-h', '127.0.0.1', '-p', '80', '-q', 'wrong']
        res = self._exec_cmd(cmd)
        self.assertIs(res['status'], 1, "Can't get status 1, message: {} ('{}')".format(res['stderr'], cmd))
        self.assertEqual(res['stdout'], '')
        self.assertRegex(res['stderr'], '.*redis.exceptions.ConnectionError: Error 111 connecting to 127.0.0.1:80. Connection refused.*')

    def test_right_config(self):
        config = self._get_config()
        cmd = self.base_cmd + ['-h', config['distributer']['host'], '-q', config['testqueue']['queue']]
        res = self._exec_cmd(cmd)
        self.assertIs(res['status'], 0, "Can't get status 0, message: {} ('{}')".format(res['stderr'], cmd))
        self.assertEqual(res['stdout'], '')
        self.assertRegex(res['stderr'], '.*RQ worker.*started')

    def _get_config(self):
        config_specs = base_path + '/../impulsare_distributer/static/specs.yml'
        config_default = base_path + '/../impulsare_distributer/static/default.yml'

        config_file = base_path + '/static/config_valid.yml'
        # Use another server, make sure to have the right configuration file
        if 'REDIS' in os.environ and os.environ['REDIS'] != '127.0.0.1':
            config_file = base_path + '/static/config_valid_{}.yml'.format(os.environ['REDIS'])

        config = ConfigReader().parse(config_file, config_specs, config_default)

        return config

    def _exec_cmd(self, cmd: list):
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        try:
            stdout, stderr = p.communicate(timeout=3)
        except subprocess.TimeoutExpired:
            p.terminate()
            stdout, stderr = p.communicate()

        stdout = stdout.decode().strip().replace('\n', '')
        stderr = stderr.decode().strip().replace('\n', '')

        return {'stdout': stdout, 'stderr': stderr, 'status': p.returncode}


import argparse
from cmath import e
import enum
import logging
from collections import OrderedDict
import os
import random
from shutil import copyfile
import sys
import time

import numpy as np
from sklearn import metrics
from tensorboardX import SummaryWriter
import torch
import torch.backends.cudnn as cudnn
import torch.nn.parallel
import torch.utils.data
import torch.nn.functional as F

sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../")
from bin import dataset_LGAImers
from model import models
# from model.model_factory import create_model
# from loss.loss_factory import create_loss
from optimization.optimizer_factory import create_optimizer
from scheduler.scheduler_factory import create_scheduler

from util import config
from util.logger import print_train_log, print_val_log
from util.metrics import AverageMeter
# from util.utils import make_bbox

def get_parser():
    parser = argparse.ArgumentParser(description="DACON LG")
    parser.add_argument("--config", type=str, default="config/LGAImers_test.yaml", help="config file")
    parser.add_argument("--weight", type=str, default=None, help="weight file")
    args = parser.parse_args()

    assert args.config is not None
    cfg = config.load_cfg_from_cfg_file(args.config)
    if args.weight is not None:
        cfg.weight = args.weight
    os.makedirs(cfg.save_path, exist_ok=True)
    copyfile(args.config, os.path.join(cfg.save_path, os.path.split(args.config)[-1]))
    return cfg

def get_logger():
    logger_name = "main-logger"
    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.INFO)
    handler = logging.StreamHandler()
    fmt = "[%(asctime)s] %(message)s"
    handler.setFormatter(logging.Formatter(fmt, "%Y-%m-%d %H:%M:%S"))
    logger.addHandler(handler)
    output_log = os.path.join(args.save_path, "log")
    os.makedirs(output_log, exist_ok=True)
    logging.basicConfig(filename=os.path.join(output_log, "log.txt"), filemode="w")
    return logger

def set_seed(manual_seed):
    if manual_seed is not None:
        random.seed(manual_seed)
        np.random.seed(manual_seed)
        torch.manual_seed(manual_seed)
        torch.cuda.manual_seed(manual_seed)
        torch.cuda.manual_seed_all(manual_seed)
        cudnn.benchmark = False
        cudnn.deterministic = True

def main():
    global args
    args = get_parser()

    os.environ["CUDA_VISIBLE_DEVICES"] = ",".join(str(x) for x in args.train_gpu)

    set_seed(args.manual_seed)
    main_worker()

def main_worker():
    global logger, writer
    logger = get_logger()
    logger.info(args)
    writer = SummaryWriter(args.save_path)

    model = models.CustomModel(input_dim = 56, output_dim = 14)
    optimizer = create_optimizer(model.parameters(), args)
    # optimizer = torch.optim.Adam(model.parameters(), lr = 0.01)

    lr_scheduler, args.epochs  = create_scheduler(args, optimizer)

    # CUDA
    model = torch.nn.DataParallel(model.cuda())

    # if args.weight:
    #     if os.path.isfile(args.weight):
    #         logger.info("=> loading weight '{}'".format(args.weight))
    #         checkpoint = torch.load(args.weight)
    #         model.load_state_dict(checkpoint["state_dict"], strict=False)

    #         # For loading a old version model
    #         if args.arch == "chestCAD_seg_cls" and len(
    #             checkpoint["state_dict"]["module.backbone._conv_stem_no_stride.weight"]
    #         ):
    #             model.module.backbone._conv_stem.weight = torch.nn.Parameter(
    #                 checkpoint["state_dict"]["module.backbone._conv_stem_no_stride.weight"]
    #             )
    #             model.module.backbone._conv_stem.bias = torch.nn.Parameter(
    #                 checkpoint["state_dict"]["module.backbone._conv_stem_no_stride.bias"]
    #             )

    #         logger.info("=> loaded weight '{}'".format(args.weight))
    #     else:
    #         logger.info("=> no weight found at '{}'".format(args.weight))

    if args.resume:
        if os.path.isfile(args.resume):
            logger.info("=> loading checkpoint '{}'".format(args.resume))
            # checkpoint = torch.load(args.resume)
            checkpoint = torch.load(args.resume, map_location=lambda storage, loc: storage.cuda())
            args.start_epoch = checkpoint["epoch"]
            model.load_state_dict(checkpoint["state_dict"])
            optimizer.load_state_dict(checkpoint["optimizer"])
            logger.info("=> loaded checkpoint '{}' (epoch {})".format(args.resume, checkpoint["epoch"]))
        else:
            logger.info("=> no checkpoint found at '{}'".format(args.resume))

    train_data = dataset_LGAImers.Dataset_LGAImers(
        split="train",
        data_path=args.data_path_train,
        transform=None,
        features_X=56,
        features_Y=14,
    )

    train_loader = torch.utils.data.DataLoader(
        train_data,
        batch_size=args.batch_size,
        shuffle=True,
        num_workers=args.workers,
        pin_memory=True,
        drop_last=True,
    )

    if args.evaluate:
        val_data = dataset_LGAImers.Dataset_LGAImers(
        split="val",
        data_path=args.data_path_val,
        transform=None,
        features_X=56,
        features_Y=14,
        )

        val_loader = torch.utils.data.DataLoader(
            val_data,
            batch_size=args.batch_size_val,
            shuffle=False,
            num_workers=args.workers,
            pin_memory=True,
        )

    best_dict = {
        "loss": float("inf"),
        "best_idx": 1,
    }

    # loss_func = torch.nn.MSELoss()
    from loss.loss_lg_nrmse import lg_nrmse_loss
    loss_func = lg_nrmse_loss()
    loss_func.cuda()

    for epoch in range(args.start_epoch, args.epochs):
        epoch_log = epoch + 1

        train_metrics = train(train_loader, model, optimizer, epoch, loss_func, lr_scheduler)

        for k, v in train_metrics.items():
            writer.add_scalar("train_" + k,
                              v, epoch_log)

        if epoch_log % args.save_freq == 0:
            filename = args.save_path + "/train_epoch_" + str(epoch_log) + ".pth"
            logger.info("Saving checkpoint to: " + filename)
            torch.save(
                {
                    "epoch": epoch_log,
                    "state_dict": model.state_dict(),
                    "optimizer": optimizer.state_dict(),
                },
                filename,
                _use_new_zipfile_serialization=False,
            )

            if epoch_log / args.save_freq > 2:
                deletename = args.save_path + "/train_epoch_" + str(epoch_log - args.save_freq * 2) + ".pth"
                try:
                    os.remove(deletename)
                except:
                    print("no file at : " + deletename)

        if lr_scheduler is not None:
            lr_scheduler.step(epoch + 1)
            # writer.add_scalar("lr", optimizer.param_groups[0]["lr"], epoch)
            # writer.add_scalar("lrx10", optimizer.param_groups[1]["lr"], epoch)

        if args.evaluate:
            val_metrics = validate(val_loader, model, loss_func)

            for k, v in val_metrics.items():
                writer.add_scalar("val_" + k, v, epoch_log)

            if best_dict[args.best_target] >= val_metrics[args.best_target]: # loss : 부등호 반대
                best_dict[args.best_target] = val_metrics[args.best_target]

                filename = os.path.join(args.save_path, "best{}.pth".format(best_dict["best_idx"]))
                torch.save(
                    {
                        "epoch": epoch_log,
                        "state_dict": model.state_dict(),
                        "optimizer": optimizer.state_dict(),
                    },
                    filename,
                    _use_new_zipfile_serialization=False,
                )
                best_dict["best_idx"] += 1
                best_dict["best_idx"] = (best_dict["best_idx"] % args.save_top_k) + 1
                logger.info("Saving best model: " + filename)

def train(train_loader, model, optimizer, epoch, loss_func, lr_scheduler=None):
    batch_time = AverageMeter()
    data_time = AverageMeter()

    loss_meter = AverageMeter()

    model.train()
    end_time = time.time()
    max_iter = args.epochs * len(train_loader)

    for batch_idx, (X_tensor, Y_tensor, df_ID) in enumerate(train_loader):
        data_time.update(time.time() - end_time)
        # X_tensor = torch.FloatTensor(X_list)
        # Y_tensor = torch.FloatTensor(Y_list)
        X_tensor = X_tensor.cuda(non_blocking=True)
        Y_tensor = Y_tensor.cuda(non_blocking=True)

        Y_pred = model(X_tensor)

        loss = loss_func(Y_pred, Y_tensor)

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

        loss_meter.update(loss.item(), X_tensor.size(0))

        batch_time.update(time.time() - end_time)
        end_time = time.time()

        current_iter = epoch * len(train_loader) + batch_idx + 1

        if lr_scheduler is not None:
            lr_scheduler.step_update(num_updates=current_iter)

        remain_iter = max_iter - current_iter
        remain_time = remain_iter * batch_time.avg
        t_m, t_s = divmod(remain_time, 60)
        t_h, t_m = divmod(t_m, 60)
        remain_time = "{:02d}:{:02d}:{:02d}".format(int(t_h), int(t_m), int(t_s))

        if (batch_idx + 1) % args.print_freq == 0:
            print_train_log(
                logger,
                epoch,
                args.epochs,
                batch_idx,
                len(train_loader),
                batch_time,
                data_time,
                remain_time,
                loss_meter,
            )

    logger.info("Train result at epoch [{}/{}]: loss {:.4f}.".format(epoch + 1, args.epochs, loss))
    train_metrics_dict = OrderedDict([("loss", loss_meter.avg)])

    return train_metrics_dict

def validate(val_loader, model, loss_func):
    logger.info(">>>>>>>>>>>>>>>> Start Evaluation >>>>>>>>>>>>>>>>")
    batch_time = AverageMeter()
    data_time = AverageMeter()

    loss_meter = AverageMeter()

    model.eval()
    end_time = time.time()

    with torch.no_grad():
        for batch_idx, (X_tensor, Y_tensor, df_ID) in enumerate(val_loader):
            data_time.update(time.time() - end_time)
            # X_tensor = torch.FloatTensor(X_list)
            # Y_tensor = torch.FloatTensor(Y_list)
            X_tensor = X_tensor.cuda(non_blocking=True)
            Y_tensor = Y_tensor.cuda(non_blocking=True)

            Y_pred = model(X_tensor)

            loss = loss_func(Y_pred, Y_tensor)

            loss_meter.update(loss.item(), X_tensor.size(0))

            batch_time.update(time.time() - end_time)
            end_time = time.time()

            if (batch_idx + 1) % args.print_freq == 0:
                print_val_log(
                    logger,
                    batch_idx,
                    len(val_loader),
                    data_time,
                    batch_time,
                    loss_meter,
                )

        logger.info("Val result: loss {:.4f}.".format(loss))
        logger.info("<<<<<<<<<<<<<<<<< End Evaluation <<<<<<<<<<<<<<<<<")

    val_metrics_dict = OrderedDict([("loss", loss_meter.val)])

    return val_metrics_dict

if __name__ == "__main__":
    main()


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

import sys

sys.path.append('.')

from src import *

from joblib import Parallel, delayed
from multiprocessing import cpu_count

from multiprocessing import Pool
from src.data import *
from src.dataset.base import *
from src.utils.util import *
from src.utils.util_data import *
from src.utils.util_file import *

class UnilangDataloader(object):
    __slots__ = ('batch_size', 'modes', 'lng', 'token_dicts', 'data_loaders', 'LENGTH',)

    def __init__(self, *args: Any, **kwargs: Any) -> None:
        self._construct(*args, **kwargs)

    def _construct(self,
                   # base parameters
                   base_dataset: Union[sBaseDataset],
                   collate_fn: Union[sbase_collate_fn],
                   params: Dict,

                   # loader parameters
                   batch_size: int,
                   modes: List[str],
                   thread_num: int,
                   ) -> None:
        self.batch_size = batch_size
        self.modes = modes

        self.lng = params.get('data_lng')
        self.LENGTH = {}
        self.data_loaders = {}
        self._load_dict(params.get('token_dicts'))
        params['token_dicts'] = self.token_dicts
        LOGGER.info("before _load_data in UnilangDataloader")
        self._load_data(thread_num, base_dataset, collate_fn, params)

    def _load_data(self,
                   thread_num: int,
                   base_dataset: Union[sBaseDataset],
                   collate_fn: Union[sbase_collate_fn],
                   params: Dict,
                   ) -> None:
        # 18.2358
        LOGGER.debug('read unilang dataset loader')
        LOGGER.info('read unilang dataset loader')

        tmp_param = deepcopy(params)
        is_dtrl = params['src_ruby'] != params['src_other']
        if is_dtrl:  # dtrl
            if tmp_param['data_lng'] == 'ruby':
                tmp_param['portion'] = tmp_param['src_ruby']
            else:
                tmp_param['portion'] = tmp_param['src_other']

        paralleler = Parallel(len(self.modes))
        datasets = paralleler(delayed(base_dataset)(**dict(tmp_param, **{'mode': mode})) for mode in self.modes)
        LOGGER.debug("after paralleler in  UnilangDataloader's  _load_data")
        for mode, ds in zip(self.modes, datasets):
            assert mode == ds.mode
            self.LENGTH[mode] = ds.size
            data_loader = DataLoader(
                ds, batch_size=256 if mode == 'valid' else self.batch_size,
                # shuffle=True if mode == 'train' else False,
                shuffle=False,
                collate_fn=collate_fn,
                num_workers=thread_num,
                # drop_last=True if is_dtrl else False
            )
            self.data_loaders[mode] = data_loader
        LOGGER.debug("UnilangDataloader load_data finished")
        # # slow, but for debug
        # for mode in self.modes:
        #     dataset = base_dataset(**dict(params, **{'mode': mode}))
        #     self.LENGTH[mode] = dataset.size
        #     data_loader = DataLoader(
        #         dataset, batch_size=self.batch_size,
        #         shuffle=False if mode == 'test' else True,
        #         collate_fn=collate_fn,
        #         num_workers=thread_num,
        #     )
        #     self.data_loaders[mode] = data_loader

    def _load_dict(self, token_dicts: Union[TokenDicts, Dict], ) -> None:
        if isinstance(token_dicts, dict):
            self.token_dicts = TokenDicts(token_dicts)
        elif isinstance(token_dicts, TokenDicts):
            self.token_dicts = token_dicts
        else:
            raise NotImplementedError('{}} token_dicts is wrong'.format(self.__class__.__name__))

    def __getitem__(self, key: str) -> Any:
        return self.data_loaders[key]

    @property
    def size(self, ) -> Dict:
        return self.LENGTH

    def __repr__(self):
        return str(self)

    def __str__(self):
        return '{}: {} - {}, batch_size({})'.format(
            self.__class__.__name__, self.lng, self.LENGTH, self.batch_size
        )


from tkinter import *
from tkinter.ttk import *
import ttkbootstrap as ttk
from ttkbootstrap.tooltip import ToolTip
from tkinter import filedialog
import sys, os, re
import tkinter
from tkinter import messagebox
from Excel_optimize import settings
from cle.data_clean import CleanWOExcel, CleanBugExcel
from sum.data_transfer import Transfer
from mod.modify_sheet import Modification, TBTJ, SJTJ_old

"""
全局通用函数
"""

def find_books(path):
    file_list = [i for i in os.walk(path)]  # 返回二维列表[路径，文件夹，文件]
    book_list = file_list[0][2]  # 获取目标目录第一级目录下的表格文件
    pattern_wo = re.compile(r'.*工单.*', flags=re.I)
    pattern_unclosed_bug = re.compile(r'.*未关闭.*', flags=re.I)
    pattern_all_bug = re.compile(r'.*所有.*', flags=re.I)
    pattern_together = re.compile(r'.*汇总.*', flags=re.I)
    wo_list, all_bug, unclosed_bug, together = [], '所有Bug', '未关闭Bug', '汇总表'
    for i in book_list:
        if re.search(pattern_wo, string=i):
            wo_list.append(i)
        elif re.search(pattern_all_bug, string=i):
            all_bug = i
        elif re.search(pattern_unclosed_bug, string=i):
            unclosed_bug = i
        elif re.search(pattern_together, string=i):
            together = i
    return together, unclosed_bug, all_bug, wo_list

# 初始化函数处理每一个目标工作簿，返回字典
# {book_name:工作簿名,sheet_name_list:[表名],X_sheet_max_row:某表的最大有效行}
# 获取到最大有效行数，最后的一个单元格，表头
def init():
    pass

def start(together, unclosed_bug, all_bug, wo_list):
    CleanBugExcel(all_bug, 'Bug')
    CleanBugExcel(unclosed_bug, 'Bug')
    CleanWOExcel(*wo_list)  # 这个方式可以直接将一个列表的所有元素当作不定参数
    Transfer(together, unclosed_bug, all_bug, wo_list[0])  # 顺序不能搞乱
    mod = Modification(together, unclosed_bug, all_bug, wo_list[0])
    mod.save()
    tbtj = TBTJ(together, unclosed_bug, all_bug, wo_list[0])
    tbtj.save()
    sjtj = SJTJ_old(together, unclosed_bug, all_bug, wo_list[0])
    sjtj.save()

class mystdout(object):
    def __init__(self, text):
        self.stdoutbak = sys.stdout
        self.stderrbak = sys.stderr
        sys.stdout = self
        sys.stderr = self
        self.text = text

    def write(self, info):  # 外部的print语句将执行本write()方法，并由当前sys.stdout输出
        # t = tkinter.Text()
        self.text.insert('end', info)
        self.text.update()
        self.text.see(tkinter.END)

    def restore_std(self):
        sys.stdout = self.stdoutbak
        sys.stderr = self.stderrbak

# 自动隐藏滚动条
def scrollbar_auto_hide(bar, widget):
    def show():
        bar.lift(widget)

    def hide():
        bar.lower(widget)

    hide()
    widget.bind("<Enter>", lambda e: show())
    bar.bind("<Enter>", lambda e: show())
    widget.bind("<Leave>", lambda e: hide())
    bar.bind("<Leave>", lambda e: hide())

# 容器类，继承于Frame，本类实现了许多组件的自动挂载
class Frame(ttk.Frame):
    def __init__(self):
        super().__init__()  # 对继承自父类的属性进行初始化，并且用父类的初始化方法初始化继承的属性。
        """
        super()的使用
        python2必须写成 super(子类，self).方法名(参数)
        python3也可直接写成 super().方法名(参数)
        """
        self.locate()  # 调用自身的方法，把自身放置到某个坐标位置。
        label = Label(self, text="报表整合工具", anchor="center")
        label.grid(row=1, column=1, padx=100, pady=20)
        label = Label(self, text="更换皮肤", anchor="center")
        label.grid(row=1, column=3)
        select_skin = self.tk_select_box_sele_skin()
        select_skin.grid(row=1, column=4)
        # 工单
        label = Label(self, text="选择工单报表（多选）", anchor="center")
        label.grid(row=2, column=1, pady=0)
        self.select_path_WO = ttk.StringVar()
        ipt = Entry(self, textvariable=self.select_path_WO, width=30)
        ipt.grid(row=3, column=1, padx=30, pady=0)
        btn = Button(self, text="选择文件", command=self.select_file_wo)
        btn.grid(row=3, column=2)
        # 未关闭报表
        label = Label(self, text="未关闭Bug报表", anchor="center")
        label.grid(row=4, column=1)
        self.select_path_Un = ttk.StringVar()
        ipt = Entry(self, textvariable=self.select_path_Un, width=30)
        ipt.grid(row=5, column=1)
        btn = Button(self, text="选择文件", command=self.select_file_un)
        btn.grid(row=5, column=2)
        # 所有报表
        label = Label(self, text="所有Bug报表", anchor="center")
        label.grid(row=6, column=1)
        self.select_path_All = ttk.StringVar()
        ipt = Entry(self, textvariable=self.select_path_All, width=30)
        ipt.grid(row=7, column=1)
        btn = Button(self, text="选择文件", command=self.select_file_all)
        btn.grid(row=7, column=2)
        # 目标文件
        label = Label(self, text="目标文件", anchor="center")
        label.grid(row=8, column=1)
        self.select_path_Tag = ttk.StringVar()
        ipt = Entry(self, textvariable=self.select_path_Tag, width=30)
        ipt.grid(row=9, column=1)
        btn = Button(self, text="选择文件", command=self.select_file_tag)
        btn.grid(row=9, column=2)
        # 选择文件夹
        label = Label(self, text="选择文件夹", anchor="center")
        label.grid(row=9, column=1)
        self.select_path_folder = ttk.StringVar()
        ipt = Entry(self, textvariable=self.select_path_folder, width=30)
        ipt.grid(row=9, column=1)
        btn = Button(self, text="选择文件夹", command=self.select_folder)
        btn.grid(row=9, column=2)
        # 启动按钮
        btn = Button(self, text="合并", command=self.read_log)  # 注意不能带括号。
        # default tooltip
        ToolTip(btn, text="请不要重复点击！")
        btn.grid(row=10, column=1)
        # 输出框
        self.text = Text(self, borderwidth=5, bg='#B0E0E6', width=80, height=38)
        # self.text.tag_add('tag',)
        # self.text.tag_config(foreground='red')
        self.text.grid(row=2, column=3, rowspan=20, columnspan=10, padx=10, pady=30, sticky=ttk.SE)

    def locate(self):  # 调用自己的方法，把自己放置到某个位置
        self.grid(row=0, column=0, rowspan=20, columnspan=20)

    def tk_select_box_sele_skin(self):
        style = ttk.Style()
        theme_names = style.theme_names()  # 以列表的形式返回多个主题名
        cb = ttk.Combobox(self, values=theme_names)
        cb.current(theme_names.index(theme_names[8]))

        def change_theme(event):
            theme_cbo_value = cb.get()
            style.theme_use(theme_cbo_value)
            cb.selection_clear()

        cb.bind('<<ComboboxSelected>>', change_theme)
        return cb

    # 执行函数
    def select_file_wo(self):
        # 多个文件选择
        selected_files_path = filedialog.askopenfilenames()  # askopenfilenames函数选择多个文件
        self.select_path_WO.set('\n'.join(selected_files_path))  # 多个文件的路径用换行符隔开

    def select_file_un(self):
        # 单个文件选择
        selected_file_path = filedialog.askopenfilename()  # 使用askopenfilename函数选择单个文件
        self.select_path_Un.set(selected_file_path)

    def select_file_all(self):
        # 单个文件选择
        selected_file_path = filedialog.askopenfilename()  # 使用askopenfilename函数选择单个文件
        self.select_path_All.set(selected_file_path)

    def select_file_tag(self):
        # 单个文件选择
        selected_file_path = filedialog.askopenfilename()  # 使用askopenfilename函数选择单个文件
        self.select_path_Tag.set(selected_file_path)

    def select_folder(self):
        # 文件夹选择
        selected_folder = filedialog.askdirectory()  # 使用askdirectory函数选择文件夹
        self.select_path_folder.set(selected_folder)

    def read_log(self):
        # 清空输出框
        if not self.text.compare("end-1c", "==", "1.0"):
            self.text.delete("1.0", END)
        out = mystdout(self.text)  # 实例化了本mystdout类，print输出就换了地方了
        if not self.select_path_folder.get():
            messagebox.showerror(title='出错', message='请先选择操作路径！')
        else:
            try:
                os.chdir(self.select_path_folder.get())
                self.send_folder_path()
                to, un, al, wo = find_books(self.select_path_folder.get())
                start(to, un, al, wo)
            except Exception as e:
                messagebox.showerror(title='出错', message=str(e))

    def send_folder_path(self):
        folder_path = self.select_path_folder.get()
        settings.basic_path = folder_path

# 窗口类，继承于Tk
class WinGUI(ttk.Window):  # 让这个窗口继承于ttk的Window
    def __init__(self):
        super().__init__()
        self.set_attr()
        self.frame = Frame()  # 实例化本窗口类或者他的子类时，就会自动实例化一个容器类Frame，同时这个容器马上就有了各种组件
        self.themename = 'solar'

    def set_attr(self):
        self.title("报表整理工具")
        # 设置窗口大小、居中
        width = 1200
        height = 900
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 3)
        self.geometry(geometry)
        self.resizable(width=False, height=False)

class Win(WinGUI):
    def __init__(self):
        super().__init__()
        self.event_bind()

    def event_bind(self):
        pass

if __name__ == "__main__":
    win = Win()
    win.mainloop()


import torch
"""

"""
import time
class data_prefetcher():
    def __init__(self, loader):
        st = time.time()
        self.loader = iter(loader)

        self.origin_loader = iter(loader)
        # print('Generate loader took', time.time() - st)
        self.stream = torch.cuda.Stream()
        self.preload()

    def preload(self):
        try:
            self.next_batch = next(self.loader)
        except StopIteration:
            self.next_batch = None
            return
        with torch.cuda.stream(self.stream):
            self.next_batch = self.next_batch.cuda(non_blocking=True)

    def next(self):
        torch.cuda.current_stream().wait_stream(self.stream)
        batch = self.next_batch
        self.preload()
        return batch


from django.utils.translation import gettext_lazy as _
from .base import ModelBase
from django.db import models

class Entity(ModelBase):
    class Meta:
        db_table = "nlp_entity"
        ordering = ["pk"]
        verbose_name = _("entity")
        verbose_name_plural = _("entities")

    bot = models.ForeignKey(
        "nlp.NLPBot", on_delete=models.CASCADE, verbose_name=_("nlp bot")
    )
    entity_name = models.CharField(
        max_length=100, null=False, verbose_name=_("entity name")
    )

    entity_category = models.ForeignKey(
        "nlp.EntityCategory",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_("entity category"),
    )

    synonym = models.CharField(null=True, blank=True, verbose_name=_("synonym"))

    def __str__(self):
        return self.entity_name


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2022/5/2 9:48
# @Author  : yaomy

# real+render+fuse 所有物体
import json
import torch
import random
import torch.utils.data
import torch.nn.functional as F
import torchvision.transforms as transforms
import pickle as pkl
import numpy as np
import yaml
import os
import pickle
from pathlib import Path
from PIL import Image
import cv2
import numpy.ma as ma
from mmcv import Config
from lib.transform.coordinate import crop_resize_by_warp_affine

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJETCT_PATH = Path(os.path.realpath(__file__)).parent.parent.parent
CONFIG = Config.fromfile(f'{PROJETCT_PATH}/config/linemod/lm_v3.py')

class PoseDataset(torch.utils.data.Dataset):
    def __init__(self, mode, num_point, add_noise, root, noise_trans, num_kps, cls_type=None, cfg=CONFIG):
        self.obj_dict = {
            'ape': 1, 'benchvise': 2, 'bowl': 3, 'cam': 4, 'can': 5, 'cat': 6, 'cup': 7, 'driller': 8,
            'duck': 9, 'eggbox': 10, 'glue': 11, 'holepuncher': 12, 'iron': 13, 'lamp': 14, 'phone': 15,
        }

        self.obj_name = {v: k for k, v in self.obj_dict.items()}

        if cls_type is None or cls_type == 'all':
            self.objlist = [1, 2, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15]
        else:
            self.objlist = [self.obj_dict[cls_type]]

        print(f'{mode} Use Object: ', self.objlist)
        self.mode = mode
        self.num_point = num_point
        self.num_kps = num_kps
        self.cfg = cfg

        self.back = cfg.Data.BACK
        self.num_pt_mesh = num_point
        self.num_pt_mesh_large = 2600
        self.num_pt_mesh_small = num_point

        self.noise_trans = noise_trans
        self.add_noise = add_noise
        self.height = 480.0
        self.width = 640.0
        self.scale = 1000.0

        self.ymap = np.array([[j for i in range(640)] for j in range(480)])
        self.xmap = np.array([[i for i in range(640)] for j in range(480)])
        self.trancolor = transforms.ColorJitter(0.2, 0.2, 0.2, 0.05)
        # 要归一化后才能用这个
        self.norm = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
        self.transform = transforms.Compose([
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
        ])
        self.sym_obj = [7, 8]
        self.obj_dict_name = {v: k for k, v in self.obj_dict.items()}

        self.intrinsic_matrix = {
            'linemod': np.array([[572.4114, 0., 325.2611],
                                 [0., 573.57043, 242.04899],
                                 [0., 0., 1.]]),
            'blender': np.array([[700., 0., 320.],
                                 [0., 700., 240.],
                                 [0., 0., 1.]]),
        }

        self.ori_iamge = np.zeros((480, 640))
        self.gt_pose = torch.zeros((4, 4))
        self.root = root
        self.backgrounds = []
        self.synthetic_all = []
        self.real_all = []
        self.diameter = []
        self.pt = {}
        self.extent = {}
        self.lf_border = {}
        self.meta = {}
        self.kps = {}
        self.centers = {}
        info_yml = open(f'{CURRENT_DIR}/dataset_config/models_info.yml', 'r')
        info = yaml.load(info_yml, Loader=yaml.FullLoader)

        with open(f'{self.root}/test/test_bboxes/bbox_yolov3_all.json', 'r') as f:
            eval_bbox_all = json.load(f)

        for item in self.objlist:
            if self.mode == 'train':
                cls_type = self.obj_dict_name[item]

                if item == 4:
                    cls_type = 'camera'

                # real_img_pth = os.path.join(cls_root, "train.txt")
                render_root = os.path.join(self.root, 'train', f'{item:06d}')
                real_root = os.path.join(self.root, 'test', f'{item:06d}')
                real_img_pth = os.path.join(self.root, 'image_set', f"{cls_type}_train.txt")
                real_lst = read_lines(real_img_pth)
                rnd_paths = sorted(Path(f'{render_root}/rgb').glob('*.png'))

                with open(f'{render_root}/scene_gt.json', 'r') as f:
                    render_gt = json.load(f)
                with open(f'{real_root}/scene_gt.json', 'r') as f:
                    real_gt= json.load(f)

                with open(f'{render_root}/scene_gt_info.json', 'r') as f:
                    render_gt_info = json.load(f)
                with open(f'{real_root}/scene_gt_info.json', 'r') as f:
                    real_gt_info = json.load(f)

                with open(f'{render_root}/scene_camera.json', 'r') as f:
                    render_gt_camera = json.load(f)
                with open(f'{real_root}/scene_camera.json', 'r') as f:
                    real_gt_camera = json.load(f)

                self.synthetic_all += [{
                    'cls_id': item, 'im_id': syn.stem,
                    'cam_R_m2c': render_gt[f'{int(syn.stem)}'][0]['cam_R_m2c'],
                    'cam_t_m2c': render_gt[f'{int(syn.stem)}'][0]['cam_t_m2c'],
                    'bbox': render_gt_info[f'{int(syn.stem)}'][0]['bbox_visib'],
                    'cam_K': render_gt_camera[f'{int(syn.stem)}']['cam_K'],
                    # 'depth_scale': render_gt_camera[f'{int(syn.stem)}']['depth_scale'],
                    'depth_scale': 1000.,
                    'type': 'syn'
                } for syn in rnd_paths]

                self.real_all += [{
                    'cls_id': item, 'im_id': real_id,
                    'cam_R_m2c': real_gt[f'{int(real_id)}'][0]['cam_R_m2c'],
                    'cam_t_m2c': real_gt[f'{int(real_id)}'][0]['cam_t_m2c'],
                    'bbox': real_gt_info[f'{int(real_id)}'][0]['bbox_visib'],
                    'cam_K': real_gt_camera[f'{int(real_id)}']['cam_K'],
                    # 'depth_scale': real_gt_camera[f'{int(real_id)}']['depth_scale'],
                    'depth_scale': 1000.,
                    'type': 'real'
                } for real_id in real_lst]

                self.backgrounds += sorted(Path(self.back).glob('*.jpg'))
            else:
                tst_img_pth = os.path.join(self.root, 'image_set', f"{cls_type}_test.txt")
                real_lst = read_lines(tst_img_pth)
                real_root = os.path.join(self.root, 'test', f'{item:06d}')
                with open(f'{real_root}/scene_gt.json', 'r') as f:
                    real_gt= json.load(f)
                with open(f'{real_root}/scene_gt_info.json', 'r') as f:
                    real_gt_info = json.load(f)
                with open(f'{real_root}/scene_camera.json', 'r') as f:
                    real_gt_camera = json.load(f)
                self.real_all += [{
                    'cls_id': item, 'im_id': real_id,
                    'cam_R_m2c': real_gt[f'{int(real_id)}'][0]['cam_R_m2c'],
                    'cam_t_m2c': real_gt[f'{int(real_id)}'][0]['cam_t_m2c'],
                    'bbox': real_gt_info[f'{int(real_id)}'][0]['bbox_visib'],
                    'eval_bbox': eval_bbox_all[f'{int(item)}/{int(real_id)}'][0]['bbox_est'],
                    'cam_K': real_gt_camera[f'{int(real_id)}']['cam_K'],
                    # 'depth_scale': real_gt_camera[f'{int(real_id)}'][0]['depth_scale'],
                    'depth_scale': 1000.,
                    'type': 'real'
                } for real_id in real_lst]

            self.pt[item], self.extent[item], self.lf_border[item] = self._load_model('{0}/models/obj_{1}.ply'.format(self.root, '%06d' % item))
            self.diameter.append(info[item]['diameter'] / 1000.0)

            kps_pattern = os.path.join(CURRENT_DIR, 'dataset_config', 'kps_orb9_fps',
                                       f"{self.obj_name[item]}_8_kps.txt")
            corner_pattern = os.path.join(CURRENT_DIR, 'dataset_config', 'kps_orb9_fps',
                                          f"{self.obj_name[item]}_corners.txt")

            kps = np.loadtxt(kps_pattern, dtype=np.float32)
            corners = np.loadtxt(corner_pattern, dtype=np.float32)
            # center = np.mean(corners, axis=0).reshape(1, 3)
            center = np.mean(self.pt[item], axis=0).reshape(1, 3)
            self.kps[item] = kps
            self.centers[item] = center

        self.all_lst = self.real_all + self.synthetic_all

        # self.all_lst = self.synthetic_all

        print(f'len of real {self.mode}: ', len(self.real_all))
        print(f'len of synthetic {self.mode}: ', len(self.synthetic_all))
        print(f'len of background {self.mode}: ', len(self.backgrounds))
        print(f'len of all {self.mode}: ', len(self.all_lst), '\n')

    def _load_real_data(self, item):
        im_id = item['im_id']
        cls_id = item['cls_id']
        if item['type'] == 'syn':
            cls_root = os.path.join(self.root, 'train', f'{cls_id:06d}')
        else:
            cls_root = os.path.join(self.root, 'test', f'{cls_id:06d}')

        with Image.open(os.path.join(cls_root, "depth/{}.png".format('%06d' % int(im_id)))) as di:
            depth = np.array(di)

        with open(f'{cls_root}/normal/{int(im_id):06d}-normal.pkl', 'rb') as f_n:
            normal = pickle.load(f_n)

        with open(f'{cls_root}/xyz/{int(im_id):06d}-coordinate.pkl', 'rb') as f_c:
            coordinate = pickle.load(f_c)

        with open(f'{cls_root}/xyz/{int(im_id):06d}-region.pkl', 'rb') as f_r:
            region = pickle.load(f_r)

        # if self.mode == 'eval':
        #     with Image.open(
        #             os.path.join(self.root, "segnet_results", f'{int(cls_id):02d}_label/{int(im_id):04d}_label.png')
        #     ) as li:
        #         label = np.array(li)
        # else:
        with Image.open(os.path.join(cls_root, "mask_visib/{}_000000.png".format('%06d' % int(im_id)))) as li:
            label = np.array(li)

        with Image.open(os.path.join(cls_root, "rgb/{}.png".format('%06d' % int(im_id)))) as ri:
            # if self.add_noise:
            #     ri = self.trancolor(ri)
            img = np.array(ri)[:, :, :3]

            if item['type'] == 'render':
                with Image.open(os.path.join(cls_root, "mask/{}_000000.png".format('%06d' % int(im_id)))) as li:
                    label_back = np.array(li)
                mask_back = ma.getmaskarray(ma.masked_equal(label_back, 0))
                seed = random.choice(self.backgrounds)
                with Image.open(seed) as bf:
                    background = np.asarray(bf.convert("RGB"))

                back = cv2.resize(np.array(self.trancolor(background)), (self.width, self.height))
                img = back * mask_back + img

        self.ori_image = img.copy()
        cam_scale = item['depth_scale']

        target_r = np.resize(np.array(item['cam_R_m2c']), (3, 3))
        target_t = np.array(item['cam_t_m2c']) / cam_scale
        self.gt_pose = self.rt2matrix(target_r, target_t)
        if self.mode == 'eval':
            bbox = item['eval_bbox']
        else:
            bbox = item['bbox']

        mask_label = np.ma.getmaskarray(np.ma.masked_equal(label, np.array(255)))
        # mask_depth = np.ma.getmaskarray(np.ma.masked_not_equal(depth, 0))
        # mask_label = mask_label * mask_depth

        return {
            'img': img,
            'depth': depth,
            'normal': normal,
            'coordinate': coordinate,
            'region': region,
            # 'croped_normal': croped_normal,
            'mask_label': mask_label,
            'cls_id': cls_id,
            'K': np.asarray(item['cam_K']).reshape(3, 3),
            'bbox': bbox,
            'cam_scale': cam_scale,
            'target_r': target_r,
            'target_t': target_t,
            'type': item['type'],
        }

    def _load_data(self, item):
        while True:
            ds = self._load_real_data(item)
            if ds is None:
                print(f'Real data error pass ! {item["type"]}')
                item = random.choice(self.all_lst)
            else:
                break

        out_size = self.cfg.Data.OUT_SIZE
        input_size = self.cfg.Data.INPUT_SIZE
        resize_type = self.cfg.Data.RESIZE_TYPE
        rmin, rmax, cmin, cmax = get_square_bbox(ds['bbox'])

        img_masked = np.array(ds['img'])[rmin:rmax, cmin:cmax, :]

        cam_fx, cam_fy, cam_cx, cam_cy = ds['K'][0, 0], ds['K'][1, 1], ds['K'][0, 2], ds['K'][1, 2]

        cls_id = ds['cls_id']
        target_r, target_t = ds['target_r'], ds['target_t']

        if ds['normal'].shape == (self.height, self.width, 3):
            normal_ = ds['normal'][rmin:rmax, cmin:cmax, :]
        else:
            normal_ = ds['normal']
        hole_normal = np.ones((int(self.height), int(self.width), 3))
        hole_normal[rmin:rmax, cmin:cmax, :] = normal_
        normal = hole_normal * (hole_normal != [1, 1, 1])

        if resize_type == 'resize':
            resize_normal = cv2.resize(normal, (out_size, out_size), interpolation=cv2.INTER_NEAREST)
        else:
            resize_normal= crop_resize_by_warp_affine(
                normal, [(cmin + cmax) / 2, (rmin + rmax) / 2], int(rmax - rmin), out_size, interpolation=cv2.INTER_NEAREST
            )

        # croped_normal_ = ds['croped_normal']
        # croped_normal = croped_normal_ * (croped_normal_ != [1, 1, 1])
        #
        # if resize_type == 'resize':
        #     resize_croped_normal = cv2.resize(croped_normal, (out_size, out_size), interpolation=cv2.INTER_NEAREST)
        # else:
        #     resize_croped_normal= crop_resize_by_warp_affine(
        #         croped_normal, [(cmin + cmax) / 2, (rmin + rmax) / 2], int(rmax - rmin), 64, interpolation=cv2.INTER_NEAREST
        #     )

        if ds['coordinate'].shape == (self.height, self.width, 3):
            coordinate = ds['coordinate'][rmin:rmax, cmin:cmax, :]
        else:
            coordinate = ds['coordinate']

        # 变成[0, 1]
        # coordinate_map = np.ones_like(coordinate)
        hole_coordinate = np.zeros((int(self.height), int(self.width), 3))
        hole_coordinate[rmin:rmax, cmin:cmax, :] = coordinate
        coordinate_map = np.zeros_like(hole_coordinate)
        lf_border = self.lf_border[cls_id]
        extent = self.extent[cls_id]

        mask_obj = (hole_coordinate != [0, 0, 0])[..., 0]
        mask = (ds['mask_label']*mask_obj).astype(np.float32)

        if resize_type == 'resize':
            resize_mask = cv2.resize(mask[:, :, None], (out_size, out_size), interpolation=cv2.INTER_NEAREST)
        else:
            resize_mask = crop_resize_by_warp_affine(
                mask[:, :, None], [(cmin + cmax) / 2, (rmin + rmax) / 2], int(rmax - rmin), out_size,
                interpolation=cv2.INTER_NEAREST
            )

        choose = mask[rmin:rmax, cmin:cmax, None].flatten().nonzero()[0]
        if len(choose) > self.num_point:
            c_mask = np.zeros(len(choose), dtype=int)
            c_mask[:self.num_point] = 1
            np.random.shuffle(c_mask)
            # num_points+8
            choose = choose[c_mask.nonzero()]
        else:
            try:
                choose = np.pad(choose, (0, self.num_point - len(choose)), 'wrap')
            except ValueError:
                print('choose error:', item)
                return None
        choose = np.array([choose])

        resize_choose = resize_mask.flatten().nonzero()[0]
        if len(resize_choose) > self.num_point:
            c_mask = np.zeros(len(resize_choose), dtype=int)
            c_mask[:self.num_point] = 1
            np.random.shuffle(c_mask)
            # num_points+8
            resize_choose = resize_choose[c_mask.nonzero()]
        else:
            try:
                resize_choose = np.pad(resize_choose, (0, self.num_point - len(resize_choose)), 'wrap')
            except ValueError:
                print('choose error:', item)
                return None

        resize_choose = np.array([resize_choose])

        if resize_type == 'resize':
            hole_coordinate_map = cv2.resize(hole_coordinate, (out_size, out_size), interpolation=cv2.INTER_NEAREST)
        else:
            hole_coordinate_map = crop_resize_by_warp_affine(
                hole_coordinate, [(cmin + cmax) / 2, (rmin + rmax) / 2], int(rmax - rmin), out_size,
                interpolation=cv2.INTER_NEAREST
            )

        coordinate_choosed = hole_coordinate_map.reshape(-1, 3)[resize_choose[0]].T

        coordinate_map[:, :, 0] = (hole_coordinate[:, :, 0] - lf_border[0]) / extent[0]
        coordinate_map[:, :, 1] = (hole_coordinate[:, :, 1] - lf_border[1]) / extent[1]
        coordinate_map[:, :, 2] = (hole_coordinate[:, :, 2] - lf_border[2]) / extent[2]
        coordinate_map = coordinate_map * (hole_coordinate != [0, 0, 0])

        if resize_type == 'resize':
            resize_coordinate_map = cv2.resize(coordinate_map, (out_size, out_size), interpolation=cv2.INTER_NEAREST)
        else:
            resize_coordinate_map = crop_resize_by_warp_affine(
                coordinate_map, [(cmin + cmax) / 2, (rmin + rmax) / 2], int(rmax - rmin), out_size,
                interpolation=cv2.INTER_NEAREST
            )

        if ds['region'].shape == (self.height, self.width, 3):
            region = ds['region'][rmin:rmax, cmin:cmax]
        else:
            region = ds['region']
        hole_region = np.zeros((int(self.height), int(self.width)))
        hole_region[rmin:rmax, cmin:cmax] = region
        if resize_type == 'resize':
            resize_region = cv2.resize(hole_region, (out_size, out_size), interpolation=cv2.INTER_NEAREST)
        else:
            resize_region = crop_resize_by_warp_affine(
                hole_region, [(cmin + cmax) / 2, (rmin + rmax) / 2], int(rmax - rmin), out_size,
                interpolation=cv2.INTER_NEAREST
            )

        ori_kps = self.kps[cls_id] / 1.0
        # ori_center = self.centers[cls_id] / 1.0
        ori_center = np.array([[0., 0., 0.]])
        all_kps = np.concatenate([ori_kps, ori_center], axis=0)

        kps = np.dot(ori_kps, target_r.T) + target_t
        center = np.dot(ori_center, target_r.T) + target_t
        kps = np.concatenate([kps, center], axis=0)
        u = kps[:, 0] * cam_fx / kps[:, 2] + cam_cx
        v = kps[:, 1] * cam_fy / kps[:, 2] + cam_cy

        # [8, 3]
        uvd1 = np.stack([u, v, kps[:, 2]], axis=1)

        model_points = self.pt[cls_id]
        model_points:np.array
        target = model_points @ target_r.T + target_t
        add_t = np.array([random.uniform(-self.noise_trans, self.noise_trans) for _ in range(3)])

        if self.add_noise:
            target = np.add(target, add_t)

        if resize_type == 'resize':
            reize_img = cv2.resize(img_masked/255., (input_size, input_size), interpolation=cv2.INTER_LINEAR)
        else:
            reize_img = crop_resize_by_warp_affine(
                ds['img']/255., [(cmin+cmax)/2, (rmin+rmax)/2], int(rmax-rmin), input_size, interpolation=cv2.INTER_LINEAR
            )

        kps_scale = float(rmax-rmin) / self.cfg.Data.INPUT_SIZE
        resize_scale = float(rmax-rmin) / self.cfg.Data.OUT_SIZE

        resize_uvd = uvd1.copy()
        resize_uvd[..., 0] -= cmin
        resize_uvd[..., 1] -= rmin
        resize_uvd[..., :2] /= kps_scale

        resize_xmap = torch.LongTensor([[i for i in range(out_size)] for _ in range(out_size)]) / out_size
        resize_ymap = torch.LongTensor([[j for _ in range(out_size)] for j in range(out_size)]) / out_size

        resize_cam_fx, resize_cam_fy, resize_cam_cx, resize_cam_cy = cam_fx / resize_scale, cam_fy / resize_scale, out_size / 2, out_size / 2

        if resize_type == 'resize':
            x_map = cv2.resize(self.xmap[rmin:rmax, cmin:cmax], (out_size, out_size), cv2.INTER_LINEAR)/640.
            y_map = cv2.resize(self.ymap[rmin:rmax, cmin:cmax], (out_size, out_size), cv2.INTER_LINEAR)/480.
        else:
            x_map = crop_resize_by_warp_affine(
                self.xmap/640., [(cmin+cmax)/2, (rmin+rmax)/2], int(rmax-rmin), out_size, interpolation=cv2.INTER_NEAREST
            )

            y_map = crop_resize_by_warp_affine(
                self.ymap/480., [(cmin+cmax)/2, (rmin+rmax)/2], int(rmax-rmin), out_size, interpolation=cv2.INTER_NEAREST
            )

        return {
            'target': torch.from_numpy(target.astype(np.float32)),  # [Np, 3]
            'model_points': torch.from_numpy(model_points.astype(np.float32)),
            'cls_id': torch.LongTensor([self.objlist.index(cls_id)]),
            'choose': torch.LongTensor(choose.astype(np.int32)),
            'intrinsic': torch.FloatTensor([cam_fx, cam_fy, cam_cx, cam_cy]),
            'uvd1': torch.from_numpy(uvd1),  # [9, 3]
            'trans_kps': torch.from_numpy(kps.astype(np.float32)),
            'kps': torch.from_numpy(ori_kps.astype(np.float32)),
            'all_kps': torch.from_numpy(all_kps.astype(np.float32)),
            'trans_center': torch.from_numpy(center.astype(np.float32)),
            'center': torch.from_numpy(ori_center.astype(np.float32)),
            'target_r': torch.from_numpy(target_r.astype(np.float32)),
            'target_t': torch.from_numpy(target_t.astype(np.float32)),
            'bbox': torch.FloatTensor([rmin, rmax, cmin, cmax]),
            'type': ds['type'],
            'xmap': torch.from_numpy(x_map.astype(np.float32)).unsqueeze(dim=0),
            'ymap': torch.from_numpy(y_map.astype(np.float32)).unsqueeze(dim=0),
            'ori_mask': torch.from_numpy(ds['mask_label'].astype(np.float32)),
            'ori_depth': torch.from_numpy(ds['depth'].astype(np.float32)),
            'ori_coordinate': torch.from_numpy(hole_coordinate.astype(np.float32)),
            'coordinate_choosed': torch.from_numpy(coordinate_choosed.astype(np.float32)),
            'resize_img': torch.from_numpy(reize_img.astype(np.float32)).permute(2, 0, 1),
            'resize_normal': F.normalize(torch.from_numpy(resize_normal).permute(2, 0, 1), p=2, dim=0).float(),
            'resize_uvd': torch.from_numpy(resize_uvd),
            'resize_scale': torch.tensor(resize_scale),
            'kps_scale': torch.tensor(kps_scale),
            'resize_xmap': resize_xmap,
            'resize_ymap': resize_ymap,
            'resize_choose': torch.LongTensor(resize_choose.astype(np.int32)),
            'resize_intrinsic': torch.FloatTensor([resize_cam_fx, resize_cam_fy, resize_cam_cx, resize_cam_cy]),
            'resize_coordinate': torch.from_numpy((resize_coordinate_map*resize_mask[:, :, None]).astype(np.float32)).permute(2, 0, 1),
            'extent': torch.from_numpy(extent),  # [3]
            'lfborder': torch.from_numpy(lf_border),  # [3]
            # 'resize_croped_normal': F.normalize(torch.from_numpy(resize_croped_normal).permute(2, 0, 1), p=2, dim=0).float(),  # [3]
            'resize_mask': torch.from_numpy(resize_mask.astype(np.float32)).unsqueeze(dim=0),
            'resize_region': torch.from_numpy(resize_region*resize_mask).long(),
        }

    def __getitem__(self, index):
        item = self.all_lst[index]
        ds = None
        while ds is None:
            ds = self._load_data(item)
            item = random.choice(self.all_lst)

        if self.ori_image.any():
            ds['ori_img'] = self.ori_image
        return ds

    def __len__(self):
        return len(self.all_lst)

    @property
    def _error_data(self):
        cc = torch.tensor([0.])
        return {'img': cc, 'flag': False}

    def _load_model(self, model_path):
        if self.mode == 'eval':
            num_pt_mesh = self.num_pt_mesh_large
        else:
            num_pt_mesh = self.num_pt_mesh_small
        model_points = ply_vtx(model_path) / self.scale

        xmax, xmin = model_points[:, 0].max(), model_points[:, 0].min()
        ymax, ymin = model_points[:, 1].max(), model_points[:, 1].min()
        zmax, zmin = model_points[:, 2].max(), model_points[:, 2].min()
        extent = np.array([xmax-xmin, ymax-ymin, zmax-zmin])
        lf_border = np.array([xmin, ymin, zmin])
        dellist = [j for j in range(0, len(model_points))]
        dellist = random.sample(dellist, len(model_points) - num_pt_mesh)
        model_points = np.delete(model_points, dellist, axis=0)

        return model_points, extent, lf_border

    @staticmethod
    def rt2matrix(r, t):
        ext = np.eye(4, 4)
        ext[:3, :3] = r
        ext[:3, 3] = t
        return ext

border_list = [-1, 40, 80, 120, 160, 200, 240, 280, 320, 360, 400, 440, 480, 520, 560, 600, 640, 680]
# border_list = [-1] + list(range(8, 680, 8)) + [680]

def read_lines(p):
    with open(p, 'r') as f:
        return [line.strip() for line in f.readlines()]

def ply_vtx(path):
    f = open(path)
    assert f.readline().strip() == "ply"
    f.readline()
    f.readline()
    N = int(f.readline().split()[-1])
    while f.readline().strip() != "end_header":
        continue
    pts = []
    for _ in range(N):
        pts.append(np.float32(f.readline().split()[:3]))
    return np.array(pts)

def get_bbox(bbox):
    bbx = [bbox[1], bbox[1] + bbox[3], bbox[0], bbox[0] + bbox[2]]
    if bbx[0] < 0:
        bbx[0] = 0
    if bbx[1] >= 480:
        bbx[1] = 479
    if bbx[2] < 0:
        bbx[2] = 0
    if bbx[3] >= 640:
        bbx[3] = 639
    rmin, rmax, cmin, cmax = bbx[0], bbx[1], bbx[2], bbx[3]
    r_b = rmax - rmin
    for tt in range(len(border_list)):
        if border_list[tt] < r_b < border_list[tt + 1]:
            r_b = border_list[tt + 1]
            break
    c_b = cmax - cmin
    for tt in range(len(border_list)):
        if border_list[tt] < c_b < border_list[tt + 1]:
            c_b = border_list[tt + 1]
            break
    center = [int((rmin + rmax) / 2), int((cmin + cmax) / 2)]
    rmin = center[0] - int(r_b / 2)
    rmax = center[0] + int(r_b / 2)
    cmin = center[1] - int(c_b / 2)
    cmax = center[1] + int(c_b / 2)
    if rmin < 0:
        delt = -rmin
        rmin = 0
        rmax += delt
    if cmin < 0:
        delt = -cmin
        cmin = 0
        cmax += delt
    if rmax > 480:
        delt = rmax - 480
        rmax = 480
        rmin -= delt
    if cmax > 640:
        delt = cmax - 640
        cmax = 640
        cmin -= delt
    return rmin, rmax, cmin, cmax

def get_square_bbox(bbox, height_px=480, width_px=640):
    bbx = [bbox[1], bbox[1] + bbox[3], bbox[0], bbox[0] + bbox[2]]
    if bbx[0] < 0:
        bbx[0] = 0
    if bbx[1] >= 480:
        bbx[1] = 479
    if bbx[2] < 0:
        bbx[2] = 0
    if bbx[3] >= 640:
        bbx[3] = 639
    rmin, rmax, cmin, cmax = bbx[0], bbx[1], bbx[2], bbx[3]

    rmax += 1
    cmax += 1
    r_b = rmax - rmin  # h
    c_b = cmax - cmin  # w
    if r_b <= c_b:
        r_b = c_b
    else:
        c_b = r_b
    for tt in range(len(border_list)):
        if border_list[tt] < r_b < border_list[tt + 1]:
            r_b = border_list[tt + 1]
            break

    for tt in range(len(border_list)):
        if border_list[tt] < c_b < border_list[tt + 1]:
            c_b = border_list[tt + 1]
            break

    center = [int((rmin + rmax) / 2), int((cmin + cmax) / 2)]
    rmin = center[0] - int(r_b / 2)
    rmax = center[0] + int(r_b / 2)
    cmin = center[1] - int(c_b / 2)
    cmax = center[1] + int(c_b / 2)
    if rmin < 0:
        delt = -rmin
        rmin = 0
        rmax += delt
    if cmin < 0:
        delt = -cmin
        cmin = 0
        cmax += delt
    if rmax > height_px:
        delt = rmax - height_px
        rmax = height_px
        rmin -= delt
        if rmin < 0:
            rmax = rmax - rmin
            rmin = 0
            if rmax >= height_px:
                rmax = height_px - 1

    if cmax > width_px:
        delt = cmax - width_px
        cmax = width_px
        cmin -= delt
        if cmin < 0:
            cmax = cmax - cmin
            cmin = 0
            if cmax >= width_px:
                cmax = width_px - 1

    m = (rmax - rmin) - (cmax - cmin)
    if m > 0:
        rmax = rmax - np.floor(m / 2)
        rmin = rmin + np.floor(m / 2)
    elif m < 0:
        cmax = cmax + np.floor(m / 2)
        cmin = cmin - np.floor(m / 2)

    return int(rmin), int(rmax), int(cmin), int(cmax)

def main():
    root_path = '/root/Source/ymy_dataset/lm-bop'
    from numpy import array, float32
    from torch.utils.data import DataLoader
    import matplotlib.pyplot as plt

    dataset = PoseDataset('train', 500, True, root_path, 0.000, 8, cls_type='ape')

    dataloader_test = torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=True, num_workers=0)
    ds_iter = dataloader_test.__iter__()
    for _ in range(5):
        datas = ds_iter.__next__()
        datas = {k:v for k,v in datas.items() if type(v).__name__ == 'Tensor'}
        print(datas['cls_id'].size())

def tst():
    # p = '/root/Source/ymy_dataset/lm-bop/train/000001/rgb'
    # paths = sorted(Path(p).glob('*.png'))
    # print(paths[0].stem)
    p = '/root/Source/ymy_dataset/lm-bop/train/000001/scene_gt.json'
    with open(p) as f:
        files = json.load(f)

    print(type(files))

if __name__ == '__main__':
    # tst()
    main()


from pymysql import cursors
import math
from api.common.db import get_db

class UserAccess:
    def __init__(self):
        self.db = get_db()

    def user_all(self, page, size):
        cursor = self.db.cursor(cursor=cursors.DictCursor)
        query_sql = ' where 1=1 '
        query_param_limit = []
        query_param_limit.append((int(page) - 1) * int(size))
        query_param_limit.append(int(size))
        cursor.execute("select *  from  user_people"
                       + format(query_sql) +
                       " limit %s,%s", query_param_limit)
        info = cursor.fetchall()
        data = {'data': info, 'totalCount': len(info), 'totalPage': math.ceil(len(info) / 10),
                'pageNo': page, 'pageSize': size}
        return data


#!/usr/bin/env python
import os
from flask import Flask, render_template
import tmdb
import settings

app = Flask(__name__)

themoviedb = tmdb.TMDB(settings.API_KEY)

@app.route('/')
def index():
    movies = themoviedb.now_playing()
    return render_template('index.html', movies=movies)

@app.route('/movie/')
@app.route('/movie/<id>')
def movie(id=None):
    movie = None
    if id is not None:
        movie = themoviedb.movie_info(id)
        cast = themoviedb.movie_casts(id)
    return render_template('movie.html', movie=movie, cast=cast)

@app.route('/person/<id>')
def person(id):
    person = themoviedb.person_info(id)
    return render_template('person.html', person=person)

@app.context_processor
def inject_globals():
    return dict(urls=themoviedb.image_urls)

if __name__ == "__main__":
    app.debug = True
    # app.run()
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)


from datetime import datetime
from sqlalchemy import func, select
from sqlalchemy.orm import SessionTransaction
from app.infra.constants import InventoryOperation
from app.infra import models

async def increase_inventory(
    product_id: int,
    *,
    quantity: int,
    transaction: SessionTransaction,
) -> models.InventoryDB:
    """Increase inventory."""
    inventory = models.InventoryDB(
        product_id=product_id,
        quantity=quantity,
        operation=InventoryOperation.INCREASE,
    )
    transaction.session.add(inventory)
    return inventory

async def total_inventory(
    product_id: int,
    *,
    transaction: SessionTransaction,
) -> int:
    """Get total inventory by product_id."""
    products_query = select(func.sum(models.InventoryDB.quantity)).where(
        models.InventoryDB.product_id == product_id,
    )
    products = await transaction.session.execute(products_query)
    total = products.fetchone()
    return total[0]

async def decrease_inventory(
    product_id: int,
    *,
    quantity: int,
    order_id: int,
    transaction: SessionTransaction,
) -> models.InventoryDB:
    """Decrease product in stock."""
    inventory = models.InventoryDB(
        product_id=product_id,
        quantity=-quantity,
        operation=InventoryOperation.DECREASE.value,
        order_id=order_id,
        created_at=datetime.now(),
    )
    transaction.session.add(inventory)
    await transaction.session.flush()
    return inventory


import os, shutil, tkinter.filedialog, tqdm, hashlib
#Can be used to search for bitwise identical files and separate them from the main set
src_dir = tkinter.filedialog.askdirectory()
temp_dir = os.path.join(src_dir, 'Duplicates')
os.makedirs(temp_dir, exist_ok=True)
map = set()

def hash(file):
    with open(file, "rb") as f:
        data = f.read()
        hash_object = hashlib.sha256(data)
    return hash_object.hexdigest()

for file in tqdm.tqdm(os.listdir(src_dir), smoothing=0, desc='Проверка'):
    if '.mp3' in file:
        src_file = os.path.join(src_dir, file)
        sum = hash(src_file)
        if sum in map:
            dst_file = os.path.join(temp_dir, file)
            shutil.move(src_file, dst_file)
        else:
            map.add(sum)


import warnings
from argparse import ArgumentParser
from os.path import join

import joblib
import numpy
from optuna import create_study
from sklearn.impute import SimpleImputer

with warnings.catch_warnings():
    warnings.simplefilter("ignore")
    import tensorflow as tf
# Local packages
try:
    import RARinterpret
except ModuleNotFoundError:
    import sys
    sys.path.append("../")
    import RARinterpret

# Argument parsing
parser = ArgumentParser()
parser.add_argument("--features", type=str)
parser.add_argument("--target", type=str, choices=["Vobs", "gobs"])
parser.add_argument("--n_trials", type=int)
parser.add_argument("--n_splits", type=int)
parser.add_argument("--test_size", type=float)
parser.add_argument("--epochs", type=int)
parser.add_argument("--patience", type=int)
parser.add_argument("--seed", type=int, default=42)
args = parser.parse_args()
features = RARinterpret.parse_features(args.features)

# Set up paths
dumpdir = "/mnt/extraspace/rstiskalek/rar/nn"
fout = join("../results/hyper", "{}_{}_{}.p".format("NN", args.target,
                                                    args.features))

# Load up all data
frame = RARinterpret.RARFrame()
test_masks = RARinterpret.make_test_masks(frame["index"], args.n_splits,
                                          test_size=args.test_size,
                                          random_state=args.seed)
X_, y, features = frame.make_Xy(target=args.target, features=features,
                                append_variances=True, dtype=numpy.float32)

def reg_from_trial(trial, X):
    width = trial.suggest_int("width", 4, 128)
    dropout_rate = trial.suggest_float("dropout_rate", 0.001, 0.1)

    schedule = tf.keras.optimizers.schedules.CosineDecayRestarts(
        initial_learning_rate=0.005, first_decay_steps=500, alpha=1e-3)
    opt = tf.keras.optimizers.Adam(learning_rate=schedule, amsgrad=True)
    return RARinterpret.PLModel.from_hyperparams(X, layers=[width], opt=opt,
                                                 dropout_rate=dropout_rate,)

def objective(trial):
    loss = 0.

    for n in range(args.n_splits):
        train, test = RARinterpret.train_test_from_mask(test_masks[n, :])

        # Run the imputer. Train only on train and apply everywhere.
        X = numpy.copy(X_)
        imputer = SimpleImputer()
        imputer.fit(X[train])  # Fit only on train
        X = imputer.transform(X)

        # Create the regressor and score it
        reg = reg_from_trial(trial, X[train])
        reg.train(X[train], y[train], epochs=args.epochs,
                  patience=args.patience, batch_fraction=1/3,
                  verbose=False)
        loss += reg.score(X[test], y[test])
    return loss

study = create_study(direction="minimize")
study.optimize(objective, n_trials=args.n_trials)

# Evaluate the average scaled loss
loss = numpy.asanyarray([tr.value for tr in study.trials])
loss *= len(frame) / test_masks.sum()

out = {"trials": study.trials,
       "best_params": study.best_params,
       "loss": loss,
       }
print("Saving to `{}`...".format(fout), flush=True)
joblib.dump(out, fout)
print("All finished!", flush=True)


import json
import mimetypes
import os

from django.shortcuts import render
from django.core import serializers
from .models import Log
from django.http import HttpResponse
from django.http import JsonResponse
from django.core.serializers.json import DjangoJSONEncoder
from datetime import date, datetime, timedelta
from django.db.models import Count, Q

# This view saves all logs to a file the serves the file
def jsonData(request):

    # Writing logs to the file 'logs.json'
    logs = Log.objects.all()
    with open('logs.json', "w") as out:
        logs_json = serializers.serialize("json", logs)
        out.write(logs_json)

    # sending file to user
    file_path = 'logs.json'

    file = open(file_path, 'r')
    mime_type, _ = mimetypes.guess_type(file_path)
    response = HttpResponse(file, content_type=mime_type)
    response['Content-Disposition'] = "attachment; filename=%s" % file_path

    size = os.path.getsize(file_path)
    response['Content-Length'] = size

    return response

# This view serves the homepage
def index(request):

    # number of time a user visits the homepage
    num_visits = request.session.get('num_visits', 0)
    request.session['num_visits'] = num_visits + 1

    context = {
        'num_visits': num_visits
    }

    return render(request, 'homepage.html', context)

def dashboard(request):
    total_requests = Log.objects.all().count()
    total_anonymous_requests = Log.objects.filter(visited_by='').count()
    total_signed_in_requests = total_requests - total_anonymous_requests
    total_signed_in_users = Log.objects.values('visited_by').distinct().count() - 1 # -1 to discard anonymous users

    # if there are no authenticated users, total_signed_in_users will be -1
    if total_signed_in_users == -1:
        total_signed_in_users = 0

    total_requests_today = Log.objects.filter(timestamp__contains=date.today()).count()

    todays_date = datetime.today()
    week_before_date = datetime.today() - timedelta(days=7)

    # get number of requests of last 7 days
    total_requests_in_previous_week = Log.objects.filter(Q(timestamp__gte=week_before_date)&Q(timestamp__lte=todays_date)).count()

    # get diffents countries stored in database
    countries = Log.objects.values('location_country').distinct()

    context = {
        'total_requests': total_requests,
        'total_signed_in_requests': total_signed_in_requests,
        'total_anonymous_requests': total_anonymous_requests,
        'todays_date': todays_date.strftime("%Y-%m-%d"),
        'total_signed_in_users': total_signed_in_users,
        'total_requests_today': total_requests_today,
        'week_before_date': week_before_date.strftime("%Y-%m-%d"),
        'total_requests_in_previous_week': total_requests_in_previous_week,
        'countries': countries,
    }
    return render(request, 'dashboard.html', context)

# this view serves the data required to plot graph on dashboard
def graphData(request):
    # Getting data
    obj = Log.objects.extra({'timestamp' : "date(timestamp)"}).values('timestamp').annotate(total=Count('id'))
    data = json.dumps(list(obj), cls=DjangoJSONEncoder) # converting data to json
    return JsonResponse(data, safe=False) # sending data

# this view returns the number of requests of particular date
def requestsOnDate(request):
    # Getting data
    requests_on_date = Log.objects.filter(timestamp__contains=request.GET['date']).count()
    return JsonResponse({'requests_on_date': requests_on_date }, safe=False) # sending data

# this view returns the number of requests between two dates
def requestsBetweenDates(request):
    from_date = request.GET['from_date']
    to_date = request.GET['to_date']
    # Getting data
    requests_between_dates = Log.objects.filter(Q(timestamp__gte=from_date)&Q(timestamp__lte=to_date)).count()
    return JsonResponse({'requests_between_dates': requests_between_dates }, safe=False) # sending data

# this view reuturns the number of requests came from different countries
def requestsFromCountry(request):
    country = request.GET['country']
    # Getting data
    requests_from_countries = Log.objects.filter(location_country=country).count()
    return JsonResponse({'requests_from_countries': requests_from_countries}, safe=False) # sending data