from django.db import migrations

def batch_update(queryset, batch=1000, **changes):
    """Update per batch"""
    is_done = False
    current = 0

    while not is_done:
        current = current + 1
        start = (current - 1) * batch
        end = start + batch
        pks = queryset.values_list("pk", flat=True)[start:end][::1]
        if pks:
            queryset.model.objects.filter(pk__in=pks).update(**changes)

        is_done = len(pks) < batch

def set_computed_file_svd_algorithm_arpack(apps, schema_editor):
    """Set svd_algorithm for computed files - ARPACK when is_compendia"""
    ComputedFile = apps.get_model("data_refinery_common", "ComputedFile")
    arpack_queryset = ComputedFile.objects.filter(is_compendia=True).order_by("id")
    batch_update(arpack_queryset, svd_algorithm="ARPACK")

def set_computed_file_svd_algorithm_none(apps, schema_editor):
    """Set svd_algorithm for computed files - None when not is_compendia"""
    ComputedFile = apps.get_model("data_refinery_common", "ComputedFile")
    none_queryset = ComputedFile.objects.filter(is_compendia=False).order_by("id")
    batch_update(none_queryset, svd_algorithm="NONE")

def set_dataset_svd_algorithm_none(apps, schema_editor):
    """Apply default svd_algorithm via pagination to dataset"""
    Dataset = apps.get_model("data_refinery_common", "Dataset")
    queryset = Dataset.objects.all().order_by("id")
    batch_update(queryset, svd_algorithm="NONE")

class Migration(migrations.Migration):

    dependencies = [
        ("data_refinery_common", "0037_auto_20190925_1309"),
    ]

    operations = [
        migrations.RunPython(set_computed_file_svd_algorithm_arpack),
        migrations.RunPython(set_computed_file_svd_algorithm_none),
        migrations.RunPython(set_dataset_svd_algorithm_none),
    ]


import time, random
import numpy as np
from absl import app, flags, logging
from absl.flags import FLAGS
import cv2
import matplotlib.pyplot as plt
import tensorflow as tf
from yolov3_tf2.models import (
    YoloV3, YoloV3Tiny
)
from yolov3_tf2.dataset import transform_images
from yolov3_tf2.utils import draw_outputs, convert_boxes

from deep_sort import preprocessing
from deep_sort import nn_matching
from deep_sort.detection import Detection
from deep_sort.tracker import Tracker
from tools1 import generate_detections as gdet
from PIL import Image
from collections import deque
import velocity
import csv
out_csv = "position.csv"

flags.DEFINE_string('classes', './data/labels/coco.names', 'path to classes file')
flags.DEFINE_string('weights', './weights/yolov3.tf',
                    'path to weights file')
flags.DEFINE_boolean('tiny', False, 'yolov3 or yolov3-tiny')
flags.DEFINE_integer('size', 516, 'resize images to')
flags.DEFINE_string('video', './data/video/test.mp4',
                    'path to video file or number for webcam)')
flags.DEFINE_string('output', None, 'path to output video')
flags.DEFINE_string('output_format', 'XVID', 'codec used in VideoWriter when saving video to file')
flags.DEFINE_integer('num_classes', 80, 'number of classes in the model')
pts = [deque(maxlen=3) for _ in range(9999)]
count = 1
Real_rate = 1   ## If the tracking accuracy is not 100%, the script counts some vehicles as double.
                ## Therefore, the number of vehicles is greater than the actual number.
                ## This parameter compensates for the effect of tracking accuracy on counting accuracy.
                ## If tracking accuracy is 90%, set this value to 0.9.
def initialize_csv():
    with open(out_csv, 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(["frame", "vehicle_id", "pixel_x", "pixel_y"])

def main(_argv):
    initialize_csv()
    # Definition of the parameters
    max_cosine_distance = 0.5
    nn_budget = None
    nms_max_overlap = 1.0

    #initialize deep sort
    model_filename = 'model_data/mars-small128.pb'
    encoder = gdet.create_box_encoder(model_filename, batch_size=1)
    metric = nn_matching.NearestNeighborDistanceMetric("cosine", max_cosine_distance, nn_budget)
    tracker = Tracker(metric)

    physical_devices = tf.config.experimental.list_physical_devices('GPU')
    if len(physical_devices) > 0:
        tf.config.experimental.set_memory_growth(physical_devices[0], True)

    if FLAGS.tiny:
        yolo = YoloV3Tiny(classes=FLAGS.num_classes)
    else:
        yolo = YoloV3(classes=FLAGS.num_classes)

    yolo.load_weights(FLAGS.weights)
    logging.info('weights loaded')

    class_names = [c.strip() for c in open(FLAGS.classes).readlines()]
    logging.info('classes loaded')

    try:
        vid = cv2.VideoCapture(int(FLAGS.video))
    except:
        vid = cv2.VideoCapture(FLAGS.video)

    out = None

    if FLAGS.output:
        # by default VideoCapture returns float instead of int
        width = int(vid.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT))
        fps = int(vid.get(cv2.CAP_PROP_FPS))
        codec = cv2.VideoWriter_fourcc(*FLAGS.output_format)
        # out = cv2.VideoWriter(FLAGS.output, codec, fps, (width, height))
        out = cv2.VideoWriter(FLAGS.output, codec, fps, (1024, 768))
        list_file = open('detection.txt', 'w')
        frame_index = -1
    velocity_tracker = velocity.VelocityTracker()
    number_of_frame_in_video = 0
    fps = 0.0
    T_count = 0
    go_count = 0
    come_count = 0
    tails = []
    while True:
        _, img = vid.read()

        if img is None:
            logging.warning("Empty Frame")
            time.sleep(0.1)
            count+=1
            if count < 3:
                continue
            else:
                break
        number_of_frame_in_video += 1

        img = cv2.resize(img, (1024, 768))

        img_in = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img_in = tf.expand_dims(img_in, 0)
        img_in = transform_images(img_in, FLAGS.size)

        t1 = time.time()
        boxes, scores, classes, nums = yolo.predict(img_in)
        classes = classes[0]
        names = []
        for i in range(len(classes)):
            names.append(class_names[int(classes[i])])
        names = np.array(names)
        converted_boxes = convert_boxes(img, boxes[0])
        features = encoder(img, converted_boxes)
        detections = [Detection(bbox, score, class_name, feature) for bbox, score, class_name, feature in zip(converted_boxes, scores[0], names, features)]

        #initialize color map
        cmap = plt.get_cmap('tab20b')
        colors = [cmap(i)[:3] for i in np.linspace(0, 1, 20)]

        # run non-maxima suppresion
        boxs = np.array([d.tlwh for d in detections])
        scores = np.array([d.confidence for d in detections])
        classes = np.array([d.class_name for d in detections])
        indices = preprocessing.non_max_suppression(boxs, classes, nms_max_overlap, scores)
        detections = [detections[i] for i in indices]

        # Call the tracker
        tracker.predict()
        tracker.update(detections)

        for track in tracker.tracks:
            if not track.is_confirmed() or track.time_since_update > 1:
                continue
            bbox = track.to_tlbr()
            class_name = track.get_class()
            color = colors[int(track.track_id) % len(colors)]
            color = [i * 255 for i in color]
            # cv2.rectangle(img, (int(bbox[0]), int(bbox[1]-30)), (int(bbox[0])+(len(class_name)+len(str(track.track_id)))*17, int(bbox[1])), color, -1)
            center = (int(((bbox[0])+(bbox[2]))/2),int(((bbox[1])+(bbox[3]))/2))
            pts[int(track.track_id)].append(center[1])
            if len(pts[int(track.track_id)]) > 2 and abs(pts[int(track.track_id)][0] - pts[int(track.track_id)][2]) > 1:
                cv2.putText(img, class_name,(int(bbox[0]), int(bbox[1]-10)),0, 0.6, color,2)
                cv2.rectangle(img, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])), color, 1)
                cv2.circle(img, (int(((bbox[0])+(bbox[2]))/2),int(((bbox[1])+(bbox[3]))/2)), 2, (0, 0xFF, 0), thickness=2)
            ## Speed estimation and check entering status for counting.
            entered = velocity_tracker.entering_check(fps, number_of_frame_in_video, track.track_id, center, img, bbox)
            if entered == 1:
                if center[0] > 500:
                    go_count = go_count + 1
                else:
                    come_count = come_count + 1

            ## Write position per vehicle and frame
            pos_vicl_fram = [str(number_of_frame_in_video), str(track.track_id), str(center[0]), str(center[1])]
            with open(out_csv, 'a', newline='') as f:
                writer = csv.writer(f)
                writer.writerow(pos_vicl_fram)

        T_count = come_count * Real_rate + go_count * Real_rate
        # print count per frame on console.
        print("Frame: ", number_of_frame_in_video, "  ,  Count: ", nums)
        cv2.putText(img, "Frame: {:.2f}".format(number_of_frame_in_video), (0, 60), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 2)
        cv2.putText(img, "Vehicles/Frame: {:.2f}".format(nums[0]), (0, 90), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 2)
        # print count on screen
        cv2.putText(img, "Total Vehicles: {:.2f}".format(int(T_count)), (500, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (5, 5, 255), 2)
        cv2.putText(img, "Coming Vehicles: {:.2f}".format(int(come_count * Real_rate)), (500, 60), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (5, 5, 255), 2)
        cv2.putText(img, "Going Vehicles: {:.2f}".format(int(go_count * Real_rate)), (500, 90), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (5, 5, 255), 2)
        # print fps on screen
        fps  = ( fps + (1./(time.time()-t1)) ) / 2
        cv2.putText(img, "FPS: {:.2f}".format(fps), (0, 30),
                          cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 2)
        cv2.imshow('output', img)
        if FLAGS.output:
            out.write(img)
            frame_index = frame_index + 1
            list_file.write(str(frame_index)+' ')
            if len(converted_boxes) != 0:
                for i in range(0,len(converted_boxes)):
                    list_file.write(str(converted_boxes[i][0]) + ' '+str(converted_boxes[i][1]) + ' '+str(converted_boxes[i][2]) + ' '+str(converted_boxes[i][3]) + ' ')
            list_file.write('\n')

        # press q to quit
        if cv2.waitKey(1) == ord('q'):
            break
    vid.release()
    if FLAGS.output:
        out.release()
        list_file.close()
    cv2.destroyAllWindows()

if __name__ == '__main__':
    try:
        app.run(main)
    except SystemExit:
        pass

# python object_tracker.py --video ./data/video/test.mp4 --output ./data/video/results.avi


import tensorflow as tf
import numpy as np
import gym
from oned import OneDProblem
from atari import AtariProblem

def copy_trainable_vars(to_model, from_model):
    to_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=to_model.name)
    from_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=from_model.name)

    # y <- x
    ops = [y.assign(x) for x,y in zip(from_vars,to_vars)]

    return ops

import random
class ReplayBuffer(object):
    def __init__(self, len):
        self.buf = []
        self.len = len
    def __len__(self):
        return len(self.buf)
    def add(self, new):
        if len(self.buf) >= self.len:
            self.buf.pop(0)
        self.buf.append(new)
    def sample(self, count):
        s = random.sample(self.buf, count)
        return [x for x in zip(*s)]

class PriorityBuffer(object):
    def __init__(self, len, alpha=1, beta=1):
        self.buf = []
        self.priorities = []
        self.priorities_max = 1
        self.alpha = alpha
        self.beta = beta
        self.len = len
    def __len__(self):
        return len(self.buf)
    def add(self, new):
        if len(self.buf) >= self.len:
            self.buf.pop(0)
            self.priorities.pop(0)
        self.buf.append(new)
        self.priorities.append(self.priorities_max)
    def sample(self, count):
        buffer_size = len(self.buf)
        p = np.array(self.priorities) ** self.alpha
        p = p / np.sum(p)
        idxs = np.random.choice(buffer_size, count, p=p)
        p_choice = p[idxs]
        buf_choice = [self.buf[x] for x in idxs]
        is_weights = (count * p_choice) ** ( - self.beta)
        is_weights = is_weights / np.max(is_weights)
        sample = [x for x in zip(*buf_choice)]
        return sample + [idxs, is_weights]
    def update_priorities(self, idxs, td_error):
        for i,e in zip(idxs,td_error):
            self.priorities[i] = e
        self.priorities_max = max(self.priorities)

def train(problem, sess=None,
          lr=1e-2, gamma=0.99, n_iters=50, batch_size=5000, eps=0.1,
          n_samples=100, buffer_size = 10000, update_period = 10,
          target_replace_period=100,
          ):
    env = problem.make_env()
    n_acts = env.action_space.n

    dqn_train = problem.make_net(env, name='train_model')
    dqn_target = problem.make_net(env, name='target_model')

    obs_ph = problem.make_obs_ph(env)
    predicted_values_target = dqn_target.apply(obs_ph)
    greedy_action = tf.argmax(predicted_values_target, 1)
    greedy_value = tf.reduce_max(predicted_values_target, 1)

    buffer = PriorityBuffer(buffer_size)

    act_ph = tf.placeholder(shape=(None,), dtype=tf.int32)
    done_ph = tf.placeholder(shape=(None,), dtype=tf.float32)
    reward_ph = tf.placeholder(shape=(None,), dtype=tf.float32)
    weight_ph = tf.placeholder(shape=(None,), dtype=tf.float32)
    next_state_value_ph = tf.placeholder(shape=(None,), dtype=tf.float32)

    predicted_values_train = dqn_train.apply(obs_ph)
    discounted_reward = reward_ph + gamma * (1 - done_ph) * next_state_value_ph
    action_one_hots = tf.one_hot(act_ph, n_acts)
    estimated_reward = tf.reduce_sum(predicted_values_train * action_one_hots, 1)

    td_error = discounted_reward - estimated_reward
    loss = tf.reduce_sum(td_error * td_error * weight_ph)
    train_op = tf.train.AdamOptimizer(learning_rate=lr).minimize(loss)
    copy_op = copy_trainable_vars(dqn_target, dqn_train)

    if (sess==None):
        sess=tf.InteractiveSession()

    sess.run(tf.global_variables_initializer())
    sess.run(copy_op)

    for i in range(n_iters):
        batch_rets, batch_lens = [], []

        obs_raw, rew, done, ep_rews = env.reset(), 0, False, []
        obs = problem.preprocess_obs(obs_raw)
        batch_loss, batch_steps = 0, 0
        while True:
            batch_steps += 1
            act = sess.run(greedy_action, {obs_ph: obs})[0]
            if random.random() < eps:
                act = random.randrange(n_acts)
            next_obs_raw, rew, done, _ = env.step(act)
            next_obs = problem.preprocess_obs(next_obs_raw)
            buffer.add((obs, act, rew, done, next_obs))
            obs = next_obs
            ep_rews.append(rew)

            if len(buffer) > n_samples and (batch_steps % update_period) == 0:
                obss, acts, rews, dones, next_obss, idxs, weights = buffer.sample(n_samples)
                next_values = sess.run(greedy_value, {obs_ph: np.vstack(next_obss)})
                # print(next_values)
                new_priorities, step_loss, _ = sess.run([td_error, loss, train_op], feed_dict={
                                              act_ph: np.array(acts),
                                              reward_ph: np.array(rews),
                                              done_ph: np.array(dones),
                                              obs_ph: np.vstack(obss),
                                              next_state_value_ph: np.array(next_values),
                                              weight_ph: weights,
                                          })
                buffer.update_priorities(idxs, np.abs(new_priorities))
                batch_loss += step_loss / batch_size
            if batch_steps > 0 and (batch_steps % target_replace_period) == 0:
                sess.run(copy_op)

            if done:
                batch_rets.append(sum(ep_rews))
                batch_lens.append(len(ep_rews))
                obs, rew, done, ep_rews = env.reset(), 0, False, []
                if batch_steps > batch_size:
                    break

        print('itr: %d \t loss: %.3f \t return: %.3f \t ep_len: %.3f'%
                (i, batch_loss, np.mean(batch_rets), np.mean(batch_lens)))

if __name__ == '__main__':
    try:
        problem = AtariProblem()
        with tf.Session() as sess:
            train(problem, sess)
    except KeyboardInterrupt:
        print('bye')


from constants import *
from classes.template import Template
from vars import screen_width, screen_height
from prefabs.bodies import *

template_data = ([],
                 [sun, mercury, venus, earth, moon, mars, phobos, deimos, jupiter, saturn, uranus, neptune, pluto],
                 [earth, moon, mars, venus],
                 [sun, mercury, venus, earth, moon, mars, phobos, deimos],
                 [earth, moon_orbital_1],
                 [earth, moon_orbital_1, moon_orbital_2, moon_orbital_3, moon_orbital_4, moon_orbital_5, moon_orbital_6],
                 [earth_debug, moon5, moon6, moon7, moon8, moon9],
                 [earth_debug, moon_debug],
                 [earth_debug,  perspective_upleft, perspective_left, perspective_front, perspective_back, perspective_up, perspective_down, perspective_upleft, perspective_backdown],
                 [jupiter_pattern, earth_pattern_1, earth_pattern_2, moon_pattern_1, moon_pattern_2]
                 )

orbital_moons_circles_of_influence = [[-1],
                                      [0],
                                      [0],
                                      [0],
                                      [0],
                                      [0],
                                      [0],
                                      ]
orbital_moons_around = Template(template_data[5],
                                name='Moons Around Earth',
                                circles_of_influence=orbital_moons_circles_of_influence,
                                orbit_first_body=True,
                                focused_body_index=0)

orbital_moons_aligned = Template(template_data[6],
                                 name='Moons Beside Earth',
                                 circles_of_influence=orbital_moons_circles_of_influence,
                                 orbit_first_body=True,
                                 focused_body_index=0,
                                 starting_camera_zoom=-1)

solar_system_circles_of_influence = [[-1],
                                     [0],
                                     [0],
                                     [0],
                                     [0, 3],  # Moon orbiting Earth
                                     [0],
                                     [0, 5],  # Phobos orbiting Mars
                                     [0, 5],  # Deimos orbiting Mars
                                     [0],
                                     [0],
                                     [0],
                                     [0],
                                     [0]]
solar_system = Template(template_data[1],
                        name='Solar System',
                        circles_of_influence=solar_system_circles_of_influence,
                        starting_camera_zoom=-1,
                        starting_camera_position=(3000000, screen_height / 2),
                        orbit_first_body=True,
                        collisions=False,
                        focused_body_index=3)

test_system_test_circles_of_influence = [[-1]]  # empty circle of influence
for i in range(len(template_data[8])):
    test_system_test_circles_of_influence.append([0])
test_system = Template(template_data[8], name='Collision Test System', circles_of_influence=test_system_test_circles_of_influence,
                                   starting_camera_zoom=-4, orbit_first_body=False, influenced_by_gravity=True,
                                   can_move=True, number_random_bodies=0, focused_body_index=0, collisions=True)

perspective_test_circles_of_influence = [[-1]]  # empty circle of influence
for i in range(len(template_data[8])):
    perspective_test_circles_of_influence.append([0])
perspective_test_system = Template(template_data[8], circles_of_influence=perspective_test_circles_of_influence,
                                   starting_camera_zoom=-4, orbit_first_body=False, influenced_by_gravity=True, collisions=True,
                                   can_move=True, number_random_bodies=0)

cool_pattern_circles_of_influence = [[-1],
                                     [0],
                                     [0],
                                     [0],
                                     [0],
                                     ]
cool_pattern = Template(template_data[-1], name='Cool Pattern',
                        circles_of_influence=cool_pattern_circles_of_influence,
                        focused_body_index=0,
                        starting_camera_zoom=-3,
                        timescale=500)

keplerian_list = [sun_kepler,
                  earth_kepler_1,
                  moon_kepler_1,
                  earth_kepler_2,
                  moon_kepler_2,
                #   earth_kepler_3,  # keplerian orbit function does not work with more than 2 moons/earths
                #   moon_kepler_3,
                #   earth_kepler_4,
                #   moon_kepler_4,
                 ]
keplerian_circles_of_influences = [[-1],
                                    [0],
                                    [0, 1],
                                    [0],
                                    [0, 3]]
keplerian_orbits = Template(keplerian_list, name='Keplerian Orbits',
                            orbit_first_body=True,
                            circles_of_influence=keplerian_circles_of_influences,
                            focused_body_index=0,
                            starting_camera_zoom=-2)

free_for_all = Template(template_data[-3], name='Free For All')

randoms_only = Template(template_data[0], name='Random Planets', number_random_bodies=5,
                        starting_camera_zoom=-4, orbit_first_body=False, collisions=False)

templates = [solar_system,
             orbital_moons_around,
             orbital_moons_aligned,
             cool_pattern,
             keplerian_orbits,
             free_for_all,
             test_system,
             randoms_only]


strings = input("Enter string: ")
vowels = ["a", "e", "i", "o", "u"]

vowels_count = 0
consonent_count = 0

for i in strings:
    if i in vowels:
        vowels_count += 1

    else:
        consonent_count += 1

print(f"The total number of vowels in {strings} is: ", vowels_count)

print(f"The total number of consonents in {strings} is: ", consonent_count)


from tkinter import ttk, Frame, Entry, Scrollbar, messagebox
from ttkbootstrap import Style
from ttkbootstrap.constants import *
from pandas import ExcelWriter, DataFrame
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from time import sleep
from datetime import datetime, date
from clipboard import copy
from json import load

class Funcoes:
    def iniciar_testes(self):
        # Coletando opções
        self.resp_squad = self.box_squad.get() if self.box_squad.get() != 'Todos os Squads' else 0
        self.salvar = self.box_salvar.get()
        self.sites = self.url_lps()
        self.resultado_etapas = []
        self.resultado_geral = dict()
        self.resultado_final = []

        # Desativando botões da interface
        self.box_salvar.configure(state='disable')
        self.box_squad.configure(state='disable')
        self.bt_iniciar.destroy()
        try:
            self.entry_destino_arquivo.configure(state='disable')
        except:
            pass
        # Meios técnicos para recriar o botão
        self.bt_iniciar = ttk.Button(self.frame_um, text='Testes Finalizados!', width=50, style=SUCCESS)
        self.bt_iniciar.pack(pady=(164, 0))

        # Alterando e inserindo elementos
        self.root.geometry('450x530')
        self.frame_um.place(relx=0.02, rely=0.01, relwidth=0.96, relheight=0.4985)
        self.frame_2()
        self.frame_de_lista()

        #Iniciando o fluxo
        self.fluxo_completo()
        self.salvar_arquivo()
        self.bt_copiar = ttk.Button(self.frame_dois, text='Copiar Mensagem Selecionada', width=46, style=OUTLINE,
                                    command=self.copiar_dados_lista)
        self.bt_copiar.place(relx=0.01, rely=0.745, relheight=0.14)

    def tratar_cidade(self, navegador):
        try:
            navegador.find_element(By.XPATH, '//*[@id="modal-portal"]/div/div/form/div/div/select').click()
            navegador.find_element(By.XPATH, '//*[@id="modal-portal"]/div/div/form/div/div/select/option[2]').click()
            navegador.find_element(By.XPATH, '//*[@id="modal-portal"]/div/div/form/button').click()
            return 'Cidade OK'
        except:
            try:
                navegador.find_element(By.XPATH, '//*[@id="__next"]/section/div/div/main/section/div/select').click()
                navegador.find_element(By.XPATH,
                                       '//*[@id="__next"]/section/div/div/main/section/div/select/option[2]').click()
                return 'Cidade OK'
            except:
                try:
                    navegador.find_element(By.XPATH, '//*[@id="modal-portal"]/div/div/form/div/div/div/select').click()
                    navegador.find_element(By.XPATH,
                                           '//*[@id="modal-portal"]/div/div/form/div/div/div/select/option[2]').click()
                    navegador.find_element(By.XPATH, '//*[@id="modal-portal"]/div/div/form/button').click()
                    return 'Cidade OK'
                except:
                    return 'N/A'
                    pass

    def abrir_snippet(self, navegador):
        try:
            sleep(1)
            navegador.execute_script('document.querySelector("#dots-cta > img").click()')  # clica snippet
            navegador.execute_script('document.querySelector("#dots-chat-cta > img").click()')  # clica no ícone webchat
            return 'Snippet OK'
        except:
            return 'Snippet Não OK'

    def url_lps(self):
        with open('url_lps.json', encoding='utf-8') as arquivo_urls:
            sites = load(arquivo_urls)
        return sites.copy()

    def mapeamento_steps(self, cep='30000000', numero='01', dt_vencimento='não sei'):
        with open('mapeamento_steps.json', encoding='utf-8') as mapeamento:
            palavras_chave = load(mapeamento)
        palavras_chave['CEP'].append(cep)
        palavras_chave['CEP_2'].append(cep)
        palavras_chave['Número Ende.'].append(numero)
        palavras_chave['Data Vencimento'].append(dt_vencimento)
        palavras_chave['Data Vencimento2'].append(dt_vencimento)

        return palavras_chave.copy()

    def encontra_chave_step(self, navegador, cep='30000000', numero='01', dt_vencimento='não sei'):
        steps_local = self.mapeamento_steps(cep, numero, dt_vencimento)
        cont = 0
        while True:
            n_bloco_atual = len(navegador.find_elements(By.XPATH, '//*[@id="messages-list"]/div[1]/div/div/div[2]/div'))
            if n_bloco_atual % 2 == 0 and n_bloco_atual > 0:
                try:
                    WebDriverWait(navegador, 1).until(
                        expected_conditions.presence_of_element_located(
                            (By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual + 1}]')))
                except:
                    break
                else:
                    continue
            else:
                sleep(0.5)
                cont += 0.5
                if cont >= 1:
                    break

        n_ultima_msg = len(navegador.find_elements(
            By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual}]/div[2]/div'))
        try:
            for cont in range(1, n_ultima_msg + 1):
                mensagem = str(navegador.find_element(
                    By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual}]'
                              f'/div[2]/div[{cont}]/div/div/div/div/div[1]/div[1]').text)
                for key, valor in steps_local.items():
                    if valor[0].upper() in mensagem.upper():
                        return key
        except:
            return '1'
        else:
            return '1'

    def interacao_chat(self, navegador, operacao, CEP='30000000', num='01', dt_vencimento='não sei', squad_atual='Null'):
        steps = self.mapeamento_steps(CEP, num, dt_vencimento)
        lista_aux_chat = []
        tempo_erro = apoio = 0

        while True:
            chave_step = self.encontra_chave_step(navegador, CEP, num, dt_vencimento)
            if chave_step.isnumeric():
                tempo_erro += int(chave_step)
            elif apoio == chave_step:
                tempo_erro += 1
            else:
                lista_aux_chat.append(f'{chave_step} - OK')
                tempo_erro = 0

            if chave_step in 'Oferta Planos':
                sleep(3.5)

            try:
                navegador.find_element(By.ID, 'msg-textarea').send_keys(steps[chave_step][1], Keys.ENTER)
            except:
                pass
            n_bloco_atual = len(navegador.find_elements(By.XPATH, '//*[@id="messages-list"]/div[1]/div/div/div[2]/div'))
            n_ultima_msg = len(navegador.find_elements(
                By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual}]/div[2]/div'))
            if chave_step.split()[0].upper() in 'ERRO':
                mensagem = str(navegador.find_element(
                    By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual}]'
                              f'/div[2]/div[{n_ultima_msg - 1}]/div/div/div/div/div[1]/div[1]').text)
                self.lista_observacoes.insert('', END, values=(squad_atual, operacao, chave_step, mensagem))
                if self.salvar == 'Sim':
                    pasta_arquivo = self.entry_destino_arquivo.get()
                    navegador.save_screenshot(f'{pasta_arquivo}/{operacao} - {chave_step} ({date.today()}).png')
                break
            if chave_step in 'Consultor Indisponível, Finalização' or chave_step.split()[0].upper() in 'TRANSBORDO_ATH':
                break
            elif chave_step == '1' and n_bloco_atual % 2 == 0 and n_bloco_atual > 0 and tempo_erro >= 15:
                chave_step = 'Chave não mapeada'
                lista_aux_chat.append(chave_step)
                mensagem = str(navegador.find_element(
                    By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual}]'
                              f'/div[2]/div[{n_ultima_msg - 1}]/div/div/div/div/div[1]/div[1]').text)
                self.lista_observacoes.insert('', END, values=(squad_atual, operacao, chave_step, mensagem))
                if self.salvar == 'Sim':
                    pasta_arquivo = self.entry_destino_arquivo.get()
                    navegador.save_screenshot(f'{pasta_arquivo}/{operacao} - {chave_step} ({date.today()}).png')
                break
            elif n_bloco_atual > 0 and tempo_erro >= 15:
                chave_step = f'ERROR TIMEOUT'
                lista_aux_chat.append(chave_step)
                mensagem = str(navegador.find_element(
                    By.XPATH, f'//*[@id="messages-list"]/div[1]/div/div/div[2]/div[{n_bloco_atual}]'
                              f'/div[2]/div[{n_ultima_msg - 1}]/div/div/div/div/div[1]/div[1]').text)
                self.lista_observacoes.insert('', END, values=(squad_atual, operacao, chave_step, mensagem))
                if self.salvar == 'Sim':
                    pasta_arquivo = self.entry_destino_arquivo.get()
                    navegador.save_screenshot(f'{pasta_arquivo}/{operacao} - {chave_step} ({date.today()}).png')
                break
            apoio = chave_step
        return lista_aux_chat[:]

    def fluxo_completo(self):
        try:
            self.navegador = Chrome()
            lista_auxiliar = []
            if self.resp_squad == 0:
                nome_squad_1 = list(self.sites)[0]
                nome_lp_1 = list(self.sites[nome_squad_1])[0]
                primeira_url = self.sites[nome_squad_1][nome_lp_1][0]
                for k, squad in self.sites.items():
                    for k2, lp in squad.items():
                        self.resultado_geral[k2] = []
                        try:
                            if self.sites[k][k2][0] == primeira_url:
                                self.navegador.get(lp[0])
                            else:
                                self.navegador.switch_to.new_window('tab')
                                self.navegador.get(lp[0])
                        except:
                            self.resultado_geral[k2] = ['LP Fora do Ar']
                            self.lista_observacoes.insert('', END, values=(k, k2,
                                                                           'LP Fora do Ar', 'LP Fora do Ar'))
                            continue
                        else:
                            c = self.sites[k][k2][1]
                            n = self.sites[k][k2][2]
                            venci = 'Não sei'
                            try:
                                venci = self.sites[k][k2][3]
                            except:
                                pass
                            self.resultado_etapas.append('LP OK')
                            self.resultado_etapas.append(self.tratar_cidade(self.navegador))
                            self.resultado_etapas.append(self.abrir_snippet(self.navegador))
                            try:
                                self.navegador.switch_to.frame(self.navegador.find_element(By.ID, 'blip-chat-iframe'))
                                WebDriverWait(self.navegador, 30).until(
                                    expected_conditions.presence_of_element_located(
                                        (By.XPATH,
                                         '//*[@id="messages-list"]/div[1]/div/div/div[2]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div')))
                            except:
                                self.resultado_etapas.append('CHAT TIMEOUT')
                                for cont in range(0, len(lista_auxiliar)):
                                    self.resultado_geral[k2].append(self.resultado_etapas[cont])
                                if self.resultado_etapas[-1] == 'Snippet Não OK':
                                    self.lista_observacoes.insert('', END, values=(k, k2,
                                                                                'Snippet Não OK', 'CHAT TIMEOUT'))
                                self.resultado_etapas.clear()
                                continue
                            else:
                                self.resultado_etapas.append('CHAT OK')

                            lista_auxiliar = self.interacao_chat(self.navegador, k2, c, n, venci, k)
                            for cont in range(0, len(lista_auxiliar)):
                                self.resultado_etapas.append(lista_auxiliar[cont])

                            self.resultado_geral[k2] = self.resultado_etapas[:]
                            self.resultado_etapas.clear()
                            lista_auxiliar.clear()

                    tamanho_maximo_etapas = 0
                    for operacao in self.resultado_geral.values():
                        if len(operacao) > tamanho_maximo_etapas:
                            tamanho_maximo_etapas = len(operacao)

                    for operacao in self.resultado_geral.values():
                        if len(operacao) < tamanho_maximo_etapas:
                            dif = tamanho_maximo_etapas - len(operacao)
                            for cont in range(0, dif):
                                operacao.append('-')

                    vars()[f'df_{k}'] = DataFrame(data=self.resultado_geral)
                    self.resultado_geral.clear()
                    self.resultado_final.append(vars()[f'df_{k}'])

            else:
                nome_lp_1 = list(self.sites[self.resp_squad])[0]
                primeira_url = self.sites[self.resp_squad][nome_lp_1][0]
                for k2, lp in self.sites[self.resp_squad].items():
                    self.resultado_geral[k2] = []
                    try:
                        if lp[0] == primeira_url:
                            self.navegador.get(lp[0])
                        else:
                            self.navegador.switch_to.new_window('tab')
                            self.navegador.get(lp[0])
                    except:
                        self.resultado_geral[k2] = ['LP Fora do Ar']
                        self.lista_observacoes.insert('', END, values=(self.resp_squad, k2,
                                                                       'LP Fora do Ar', 'LP Fora do Ar'))
                    else:
                        c = self.sites[self.resp_squad][k2][1]
                        n = self.sites[self.resp_squad][k2][2]
                        venci = 'Não sei'
                        try:
                            venci = self.sites[self.resp_squad][k2][3]
                        except:
                            pass
                        self.resultado_etapas.append('LP OK')
                        self.resultado_etapas.append(self.tratar_cidade(self.navegador))
                        self.resultado_etapas.append(self.abrir_snippet(self.navegador))
                        try:
                            self.navegador.switch_to.frame(self.navegador.find_element(By.ID, 'blip-chat-iframe'))
                            WebDriverWait(self.navegador, 30).until(
                                expected_conditions.presence_of_element_located(
                                    (By.XPATH,
                                     '//*[@id="messages-list"]/div[1]/div/div/div[2]/div[2]/div[2]/div[1]/div/div/div/div/div[1]/div')))
                        except:
                            self.resultado_etapas.append('CHAT TIMEOUT')
                            for cont in range(0, len(lista_auxiliar)):
                                self.resultado_geral[k2].append(self.resultado_etapas[cont])
                            if self.resultado_etapas[-1] == 'Snippet Não OK':
                                self.lista_observacoes.insert('', END, values=(self.resp_squad, k2,
                                                                               'Snippet Não OK', 'CHAT TIMEOUT'))
                            self.resultado_etapas.clear()
                            continue
                        else:
                            self.resultado_etapas.append('CHAT OK')

                        lista_auxiliar = self.interacao_chat(self.navegador, k2, c, n, venci, self.resp_squad)
                        for cont in range(0, len(lista_auxiliar)):
                            self.resultado_etapas.append(lista_auxiliar[cont])

                        self.resultado_geral[k2] = self.resultado_etapas[:]
                        self.resultado_etapas.clear()
                        lista_auxiliar.clear()

                tamanho_maximo_etapas = 0
                for operacao in self.resultado_geral.values():
                    if len(operacao) > tamanho_maximo_etapas:
                        tamanho_maximo_etapas = len(operacao)

                for operacao in self.resultado_geral.values():
                    if len(operacao) < tamanho_maximo_etapas:
                        dif = tamanho_maximo_etapas - len(operacao)
                        for cont in range(0, dif):
                            operacao.append('-')

                vars()[f'df_{self.resp_squad}'] = DataFrame(data=self.resultado_geral)
                self.resultado_geral.clear()
                self.resultado_final.append(vars()[f'df_{self.resp_squad}'])
            messagebox.showinfo(title='Status Testes', message='Testes finalizados com êxito!')
        except Exception as erro:
            messagebox.showerror(title='Erro no fluxo', message=f'Houve erro no fluxo do chat!\n\n'
                                                                f'Erro: {erro.__class__}\n\n'
                                                                f'Descrição: {erro.__context__}\n'
                                                                f'{erro.__str__()}')

    def salvar_arquivo(self):
        try:
            if self.salvar == 'Sim':
                hora = int(str(datetime.time(datetime.today()))[:2])
                if 12 > hora >= 6:
                    turno = 'Manhã'
                elif 18 > hora >= 12:
                    turno = 'Tarde'
                else:
                    turno = 'Noite'
                pasta_arquivo = self.entry_destino_arquivo.get() + '/'
                pasta_arquivo = f'{pasta_arquivo}/Testes de Fluxo {self.resp_squad if self.resp_squad != 0 else ""}' \
                                f' {date.today().day}-{date.today().month} ({turno}).xlsx'
                arquivo = ExcelWriter(pasta_arquivo, engine='xlsxwriter')
                if self.resp_squad == 0:
                    for i, resultado in enumerate(self.resultado_final):
                        nome = list(self.sites)[i]
                        self.resultado_final[i].to_excel(arquivo, sheet_name=nome, index=False)
                else:
                    self.resultado_final[0].to_excel(arquivo, sheet_name=self.resp_squad, index=False)
                arquivo.save()
            self.resultado_final.clear()
        except Exception as erro:
            messagebox.showerror(title='Erro no Salvamento', message=f'Houve erro ao salvar os testes!\n\n'
                                                                f'Erro: {erro.__class__}\n\n'
                                                                f'Descrição: {erro.__context__}\n'
                                                                f'{erro.__str__()}')

    def copiar_dados_lista(self, evento=None):
        valores = list()
        itens_selecionados = self.lista_observacoes.selection()
        if len(itens_selecionados) >=1:
            for i_item in range(0, len(itens_selecionados)):
                valores.append(self.lista_observacoes.item(itens_selecionados[i_item], 'values'))
            valores = str(valores)
            copy(valores)
            messagebox.showinfo(title='Valor Copiado',
                                message='Os itens selecionados foram copiados \npara a área de transferência com êxito!')
        else:
            messagebox.showwarning(title='Seleção inválida', message='Selecione um elemento para ser copiado.')

class Janela_principal(Funcoes):
    def __init__(self):
        # Atributos
        #Estilo
        self.estilo_1 = Style(theme='cosmo')
        self.estilo_1.configure('TButton', font='sans-serif 11')
        self.estilo_1.configure('Treeview', foreground='#3D3D3D', rowheight=25)
        self.estilo_1.map('Treeview', background=[('selected', 'green')])
        #Opções comboBox squad
        self.squads = ['Todos os Squads']
        aux = list(Funcoes.url_lps(self))
        num_squads = len(aux)
        for x in range(0, num_squads):
            self.squads.append(aux[x])
        # Define tema e cria o objeto janela
        self.root = self.estilo_1.master
        # Funções
        self.janela()
        self.frame_1()
        self.titulo()
        self.campos()
        self.botoes()
        # Mantendo janela aberta
        self.root.mainloop()

    def janela(self):
        self.root.title('BOT de Teste de Fluxo ISPs Automatizado')
        self.larg_janela = 450
        self.compr_janela = 277
        self.root.geometry(f'{self.larg_janela}x{self.compr_janela}')
        self.root.resizable(False, False)
        self.root.config(background='#257DFE')

    def frame_1(self):
        self.frame_um = Frame(self.root)
        self.frame_um.place(relx=0.02, rely=0.027, relwidth=0.96, relheight=0.9461)

    def frame_2(self):
        self.frame_dois = ttk.LabelFrame(self.root, text=' Observações ')
        self.frame_dois.place(relx=0.02, rely=0.52, relwidth=0.96, relheight=0.465)

    def frame_de_lista(self):
        # Barra de Rolagem vertical
        self.scroll_vertical = Scrollbar(self.frame_dois, orient='vertical')
        self.scroll_vertical.place(relx=0.92, rely=0.01, relwidth=0.07, relheight=0.88)
        # Barra de Rolagem horizontal
        self.scroll_horizontal = Scrollbar(self.frame_dois, orient='horizontal')
        self.scroll_horizontal.place(relx=0.01, rely=0.9, relwidth=0.9, relheight=0.08)
        #Criando o frame com o nome das colunas e linkando-o aos scrolls
        self.lista_observacoes = ttk.Treeview(self.frame_dois, height=2, columns=('squad', 'operação', 'observação', 'mensagem'),
                                              show='headings',
                                              yscrollcommand=self.scroll_vertical.set,
                                              xscrollcommand=self.scroll_horizontal.set)
        self.lista_observacoes.place(relx=0.01, rely=0.01, relwidth=0.9, relheight=0.73)
        # Linkando a barra de rolagem e a lista
        self.scroll_vertical.config(command=self.lista_observacoes.yview)
        self.scroll_horizontal.config(command=self.lista_observacoes.xview)
        #Cabeçalho das colunas
        self.lista_observacoes.heading('#1', text='Squad', anchor=W)
        self.lista_observacoes.heading('#2', text='Operação', anchor=W)
        self.lista_observacoes.heading('#3', text='Observação', anchor=W)
        self.lista_observacoes.heading('#4', text='Mensagem', anchor=W)
        #Tamanho das colunas
        self.lista_observacoes.column('#1', width=80, anchor=W)
        self.lista_observacoes.column('#2', width=80, anchor=W)
        self.lista_observacoes.column('#3', width=100, anchor=W)
        self.lista_observacoes.column('#4', width=240, anchor=W)

    def titulo(self):
        self.titulo_lb = ttk.Label(self.frame_um, text='BOT de Teste de Fluxo LP', font=('sans-serif', '18', 'bold'),
                                   foreground='#257DFE')
        self.titulo_lb.pack(pady=8)

    def campos(self):
        # Campo Squad
        self.lb_squad = ttk.Label(self.frame_um, text='Escolha o Squad:', font=('sans-serif', '13'), foreground='black')
        self.lb_squad.place(relx=0.02, rely=0.265)
        # Combobox
        self.box_squad = ttk.Combobox(
            self.frame_um, values=self.squads, font=('sans-serif', '13'),
            foreground='black', state='readonly', takefocus=False
        )
        self.box_squad.current(0)
        self.box_squad.place(relx=0.35, rely=0.24, relwidth=0.625)

        # Campo "Salvar""
        self.lb_salvar = ttk.Label(self.frame_um, text='Deseja Salvar o resultado?', font=('sans-serif', '13'),
                                   foreground='black')
        self.lb_salvar.place(relx=0.02, rely=0.45)
        # Combobox
        self.box_salvar = ttk.Combobox(
            self.frame_um, values=['Sim', 'Não'], font=('sans-serif', '13'), foreground='black', state='readonly',
            takefocus=False
        )
        self.box_salvar.current(1)
        self.box_salvar.place(relx=0.50, rely=0.425, relwidth=0.475)
        self.box_salvar.bind('<<ComboboxSelected>>', self.reacao_box_salvar)

    def botoes(self):
        self.bt_iniciar = ttk.Button(self.frame_um, text='Iniciar Testes', width=50, command=self.iniciar_testes)
        self.bt_iniciar.pack(pady=(162, 0))

    def reacao_box_salvar(self, evento=None):
        if self.box_salvar.get() == "Sim":
            self.lb_destino_arquivo = ttk.Label(self.frame_um, text='Destino do arquivo: ', font=('sans-serif', '13'),
                                                foreground='black')
            self.lb_destino_arquivo.place(relx=0.02, rely=0.625)
            # Campo de destino do arquivo
            self.entry_destino_arquivo = Entry(self.frame_um, font=('sans-serif', 9), fg='gray', state='normal')
            self.entry_destino_arquivo.place(relx=0.375, rely=0.615, relwidth=0.60, relheight=0.12)
            self.entry_destino_arquivo.insert('1',
                                            'S:/Inovação/Planejamento/3 - MIS/Gerencial/Acompanhamento das ISPS - Semanal/Testes de Fluxo')
        else:
            try:
                self.lb_destino_arquivo.destroy()
                self.entry_destino_arquivo.destroy()
            except:
                pass

Janela_principal()

Mundiale Projects/Automatização Testes Fluxo ISPs/BOT LP com interface/Interface_BOT.py


"""Boundary representation."""

# Standard Library
from typing import Optional, Tuple, List
from abc import ABC, abstractmethod

# Models
from .points import Point
from .bisectors import Bisector, PointBisector, WeightedPointBisector
from .events import Intersection, Site, WeightedSite

# Math
from decimal import Decimal

# Generaal utils
from general_utils.numbers import are_close

class Boundary(ABC):
    """Bisector that is * mapped."""

    bisector: Bisector
    sign: bool
    left_intersection: Optional[Intersection]
    right_intersection: Optional[Intersection]
    # active says if this boundary is the current added to the LList.
    active: bool
    is_to_be_deleted: bool

    def __init__(self, bisector: Bisector, sign: bool, active: bool = False) -> None:
        """Construct Boundary."""
        self.bisector = bisector
        self.sign = sign
        self.left_intersection = None
        self.right_intersection = None
        self.active = active
        self.is_to_be_deleted = False

    def get_site(self) -> Site:
        """Get the site that is highest or more to the right.

        This is the site that defines the region of the 2 boundary sibling.
        """
        return self.bisector.get_site()

    def star(self, point: Point) -> Point:
        """Map a bisector to build the region to work in."""
        return Point(point.x, point.y + self.distance_to_site(point))

    @abstractmethod
    def get_point_comparison(self, point: Point) -> Optional[Decimal]:
        """Get the y comparison of a point based on the line y coordinate of the point.

        This comparison is based on this boundary with its sign.
        Return 0 if the point is in the boundary based on l.
        Return > 0 if the point is to the right of the boundary based on l.
        Return < 0 if the point is to the left of the boundary based on l.
        """
        raise NotImplementedError

    def formula_y_without_sign(self, x: Decimal) -> List[Decimal]:
        """Return the y coordinates in all the boundary given the x coordinate.

        This is the the formula of the bisector mapped with the star map.
        This can also be viewed as the projection of x in all the boundary without
        taking care of the sign.
        """
        ys = [
            self.star(Point(x, y_bisector)).y
            for y_bisector in self.bisector.formula_y(x)
        ]
        return ys

    @abstractmethod
    def formula_y(self, x: Decimal) -> List[Decimal]:
        """Return the y coordinate given the x coordinate taking care of the sign.

        This is the the formula of the bisector mapped with the star map.
        This can also be viewed as the projection of x in the boundary taking care of
        the sign.
        """
        raise NotImplementedError

    def __str__(self):
        """Get boundary string representation."""
        if self.sign:
            sign_str = "+"
        else:
            sign_str = "-"
        return f"B*{sign_str}{self.bisector.get_sites_names()}"

    def __repr__(self):
        """Get boundary representation."""
        return self.__str__()

    def distance_to_site(self, point: Point) -> Decimal:
        """Get distance to any of the sites.

        This method is used in star.
        The distance will be taken to to the site given in get_site because the distance to any of
        the sites is the same.
        """
        site = self.get_site()
        return site.get_site_distance(point.x, point.y)

    def get_intersections(self, boundary: "Boundary") -> List[Tuple[Point, Point]]:
        """Get intersections between two boundaries.

        The return values are a list of the intersections without the star map (the
        bisectors of the boundaries intersections) and the intersection with the star map (the
        boundaries intersection).
        """
        all_intersections = []
        # bisector.get_intersections gives us the intersections in the bisectors.
        intersection_points = self.bisector.get_intersections(boundary.bisector)
        # Now we need to look that each mapped intersection point is in the boundary.
        for intersection_point in intersection_points:
            intersection_point_star = self.star(intersection_point)
            if self.is_point_in_boundary(
                intersection_point_star
            ) and boundary.is_point_in_boundary(intersection_point_star):
                all_intersections.append((intersection_point, intersection_point_star))
        return all_intersections

    @abstractmethod
    def get_side_where_point_belongs(self, point: Point) -> int:
        """Get side of the boundary where the point belongs."""
        raise NotImplementedError

    @staticmethod
    def get_boundary_sign(p: Point, q: Site, s: Site) -> bool:
        """Get the boundary sign given two sites and a point.

        This method is used when a new boundary is created.
        """
        raise NotImplementedError

class PointBoundary(Boundary):
    """Boundary of a site point."""

    bisector: PointBisector

    def __init__(self, bisector: PointBisector, sign: bool):
        """Construct Boundary of a site point."""
        super(PointBoundary, self).__init__(bisector, sign)

    def get_point_comparison(self, point: Point) -> Optional[Decimal]:
        """Get the y comparison of a point based on the line y coordinate of the point.

        This comparison is based on this boundary with its sign.
        Return 0 if the point is in the boundary based on y coordinate of the point.
        Return > 0 if the point is to the right of the boundary based on the y coordinate of the
        point.
        Return < 0 if the point is to the left of the boundary based on the y coordinate of the
        point.
        """
        p, q = self.bisector.sites
        if p.point.y == q.point.y:
            if self.sign:
                middle_point_x = self.bisector.get_middle_between_sites().x
                return point.x - middle_point_x
            else:
                # Negative Boundary of a vertical bisector is always to the left of any point.
                return Decimal(1)

        if self.is_left_to_boundary(point):
            return Decimal(-1)
        if self.is_point_in_boundary(point):
            return Decimal(0)
        return Decimal(1)

    def is_left_to_boundary(self, point: Point) -> bool:
        """Return True if the given point is to the left of the boundary."""
        ys = self.formula_y(point.x)
        if len(ys) == 0:
            return self.sign
        if self.sign:
            return ys[0] < point.y
        else:
            return ys[0] > point.y

    def formula_x(self, y: Decimal) -> List[Decimal]:
        """Return the x coordinate given the y coordinate.

        This is the the formula of the bisector mapped with the star map.
        In this case is an hiperbola.
        """
        # No blank spaces after docstring.
        def quadratic_solution_with_sign(
            a: Decimal, b: Decimal, c: Decimal
        ) -> Optional[Decimal]:
            """Return the solution of the quadratic function based on the sign of the Boundary."""
            if (b ** 2 - 4 * a * c) < 0:
                return None
            if self.sign:
                sign_value = 1
            else:
                sign_value = -1
            solution = (-b + (-sign_value) * Decimal(b ** 2 - 4 * a * c).sqrt()) / 2 * a
            return solution

        p = self.bisector.sites[0].point
        q = self.bisector.sites[1].point
        a = Decimal(-((q.x - p.x) / (q.y - p.y)))
        b = Decimal((q.x ** 2 - p.x ** 2 + q.y ** 2 - p.y ** 2) / (2 * (q.y - p.y)))
        c = Decimal(-b + y)
        d = Decimal(b - p.y)
        e = Decimal(c ** 2 - d ** 2 - p.x ** 2)
        f = Decimal(-1)
        g = Decimal(2 * (-a * (c + d) + p.x))
        x = quadratic_solution_with_sign(f, g, e)
        return [x]

    def formula_y(self, x: Decimal) -> List[Decimal]:
        """Return the y coordinate given the x coordinate, taking care of the sign.

        This is the the formula of the bisector mapped with the star map.
        This can also be viewed as the projection of x in the boundary taking care of
        the sign.
        """
        if (not self.sign and x < self.get_site().point.x) or (
            self.sign and x >= self.get_site().point.x
        ):
            return self.formula_y_without_sign(x)
        return []

    def is_point_in_boundary(self, point: Point) -> bool:
        """Check if the point is in this boundary."""
        p, q = self.bisector.sites
        if p.point.y == q.point.y:
            distance = abs(p.point.x - q.point.x)
            mid_x = min(p.point.x, q.point.x) + (distance / Decimal(2))
            return are_close(point.x, mid_x, Decimal("0.0001"),) and self.sign

        ys_in_boundary = self.formula_y(point.x)
        for y_in_boundary in ys_in_boundary:
            if are_close(y_in_boundary, point.y, Decimal("0.00001")):
                return True
        return False

    def get_side_where_point_belongs(self, point: Point) -> int:
        """Get side where point belongs."""
        return 0

    @staticmethod
    def get_boundary_sign(p: Point, q: Site, s: Site) -> bool:
        """Get Boundary sign given two sites and a point to compare."""
        same_y = q.get_event_point().y == s.get_event_point().y
        if same_y:
            return True
        else:
            if q.get_event_point().y > s.get_event_point().y:
                higher = q.get_event_point()
            else:
                higher = s.get_event_point()
        return higher.x <= p.x

class WeightedPointBoundary(Boundary):
    """Boundary of a weighted site point."""

    bisector: WeightedPointBisector

    def __init__(self, bisector: WeightedPointBisector, sign: bool):
        """Construct Boundary of a site point."""
        super(WeightedPointBoundary, self).__init__(bisector, sign)

    def is_boundary_not_x_monotone(self) -> bool:
        """Check if the boundary is concave to y."""
        sites = self.bisector.sites
        if sites[0] == self.get_site():
            max_site = sites[0]
            min_site = sites[1]
        else:
            max_site = sites[1]
            min_site = sites[0]
        if max_site.get_lowest_site_point().y < min_site.get_lowest_site_point().y:
            if max_site.point.x < min_site.point.x:
                return self.sign
            else:
                return not self.sign
        else:
            return False

    def has_vertical_asymptote(self) -> bool:
        """Check if the boundary has a vertical asymptote."""
        p, q = self.bisector.sites
        if p.weight > q.weight:
            biggest_site = p
            smallest_site = q
        else:
            biggest_site = q
            smallest_site = p
        if p.get_lowest_site_point().y == q.get_lowest_site_point().y:
            if biggest_site.point.x < smallest_site.point.x:
                return self.sign
            else:
                return not self.sign
        else:
            return False

    def formula_y(self, x: Decimal) -> List[Decimal]:
        """Return the y coordinate given the x coordinate taking care of the sign.

        This is the formula of the bisector mapped with the star map.
        """
        # It has at most 2 values.
        ys_without_sign = self.formula_y_without_sign(x)
        if len(ys_without_sign) == 0:
            return []
        to_return = []

        # Check when events are in the same y.
        p, q = self.bisector.sites
        p_event, q_event = p.get_event_point(), q.get_event_point()
        if p_event.y == q_event.y:
            if p.weight > q.weight:
                bigger, smaller = p, q
            else:
                bigger, smaller = q, p
            if (bigger.point.x > smaller.point.x and not self.sign) or (
                bigger.point.x < smaller.point.x and self.sign
            ):
                return ys_without_sign
            return []

        if self.is_boundary_not_x_monotone():
            to_return.append(max(ys_without_sign))
        if (not self.sign and x < self.get_site().point.x) or (
            self.sign and self.get_site().point.x <= x
        ):
            to_return.append(min(ys_without_sign))

        return to_return

    def is_point_in_boundary(self, point: Point) -> bool:
        """Check if the point is in this boundary."""
        p, q = self.bisector.sites
        if p.point.y == q.point.y and p.weight == q.weight:
            distance = abs(p.point.x - q.point.x)
            mid_x = min(p.point.x, q.point.x) + (distance / Decimal(2))
            return are_close(point.x, mid_x, Decimal("0.001"),) and self.sign

        ys_in_boundary = self.formula_y(point.x)
        for y_in_boundary in ys_in_boundary:
            if are_close(y_in_boundary, point.y, Decimal("0.001")):
                return True
        return False

    def get_point_comparison(self, point: Point) -> Optional[Decimal]:
        """Get the y comparison of a point based on the y coordinate of the point.

        This comparison is based on this boundary with its sign.
        Return 0 if the point is in the boundary based on y coordinate of the point.
        Return > 0 if the point is to the right of the boundary based on the y coordinate of the
        point.
        Return < 0 if the point is to the left of the boundary based on the y coordinate of the
        point.
        """
        p, q = self.bisector.sites
        same_y = p.point.y == q.point.y
        same_weight = p.weight == q.weight
        if same_y and same_weight:
            if self.sign:
                distance = abs(p.point.x - q.point.x)
                comparison = point.x - (
                    min(p.point.x, q.point.x) + (distance / Decimal(2))
                )
                return comparison
            else:
                # Negative Boundary of a vertical bisector is always to the left of any point.
                return Decimal(1)

        if self.is_left_to_boundary(point):
            return Decimal(-1)
        if self.is_point_in_boundary(point):
            return Decimal(0)
        return Decimal(1)

    def is_left_to_boundary(self, point: Point) -> bool:
        """Return True if the given point is to the left of the boundary."""
        if self.is_boundary_not_x_monotone():
            return self.is_left_when_boundary_is_not_x_monotone(point)
        elif self.has_vertical_asymptote():
            return self.is_left_when_boundary_is_stopped_to_infinity(point)
        else:
            return self.is_left_when_boundary_is_not_concave(point)

    def is_left_when_boundary_is_not_x_monotone(self, point: Point) -> bool:
        """Return True if the given point is to the left when boundary is not x monotone."""
        ys = self.formula_y(point.x)
        if len(ys) == 0:
            return not self.sign
        if len(ys) == 1:
            # Checking if the point is in the vertical tangent.
            vertical_tangents = self.bisector.get_vertical_tangents()
            # There is just one posible vertical tangent.
            if len(vertical_tangents) > 0 and are_close(
                vertical_tangents[0], point.x, Decimal("0.0001")
            ):
                return not self.sign

            if self.sign:
                return ys[0] > point.y
            else:
                return ys[0] < point.y
        if len(ys) == 2:
            if self.sign:
                return max(ys) > point.y and min(ys) < point.y
            else:
                return max(ys) < point.y or min(ys) > point.y

    def is_left_when_boundary_is_stopped_to_infinity(self, point: Point) -> bool:
        """Return True if the given point is to the left when boundary is stopped to infinity."""
        ys = self.formula_y(point.x)
        if len(ys) == 0:
            return self.get_site().point.x > point.x
        if self.sign:
            return ys[0] < point.y
        else:
            return ys[0] > point.y

    def is_left_when_boundary_is_not_concave(self, point: Point) -> bool:
        """Return True if the given point is to the left when boundary is not concave."""
        ys = self.formula_y(point.x)
        if len(ys) == 0:
            return self.sign
        if self.sign:
            return ys[0] < point.y
        else:
            return ys[0] > point.y

    def get_side_where_point_belongs(self, point: Point) -> int:
        """Get where side of the boundary where point belongs."""
        if self.is_boundary_not_x_monotone():
            ys = self.formula_y(point.x)
            if are_close(point.y, max(ys), Decimal("0.0001"),):
                return 1
        return 0

    @staticmethod
    def get_boundary_sign(p: Point, q: WeightedSite, s: WeightedSite) -> bool:
        """Get boundary sign given two sites and point to compare."""
        same_y = q.get_event_point().y == s.get_event_point().y
        if same_y:
            same_weight = q.weight == s.weight
            if same_weight:
                return True
            if q.weight > s.weight:
                higher = q.get_event_point()
            else:
                higher = s.get_event_point()
        else:
            if q.get_event_point().y > s.get_event_point().y:
                higher = q.get_event_point()
            else:
                higher = s.get_event_point()
        return higher.x <= p.x


import  re
import urllib.parse
from  coo import download
import time
import socket
# socket.getaddrinfo('127.0.0.1', 8388)
# print(socket.getaddrinfo('127.0.0.1', 8388))

def link_crawler ( seed_url , link_regex):
    crawl_queue = [seed_url]  #  liebiao ;

    seen = set(crawl_queue)
    while  crawl_queue:
        url = crawl_queue.pop()
        html = download(url)
        print(333333333,get_links(str(html)).__sizeof__())
        for link in get_links(str(html)) :
            time.sleep(0.03)
            print('-------------')
            if re.findall(link_regex ,link):
                print('++++++++++++',link)
                link = urllib.parse.urljoin( seed_url , link )
                if  link not in seen  :
                    seen.add(link)
                    crawl_queue.append(link)

    print('size' ,crawl_queue)

def get_links(html):
    # webpage_regex = re.compile('<a[^>] + href=["\'](.*?)["\']' ,re.IGNORECASE)
    print(html)
    webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
    return webpage_regex.findall(html)

link_crawler('http://example.webscraping.com/places/default' , '/(index|view)')


def lengthOfLongestSubstring(s):
        if not s:return 0
        left = 0
        lookup = set()
        n = len(s)
        max_len = 0
        cur_len = 0
        for i in range(n):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:max_len = cur_len
            lookup.add(s[i])
        return max_len
s=input()
ans=lengthOfLongestSubstring(s)
print(ans)


from baidu_index import Index
from baidu_utils import *

cookies = 'xxx'
keywords = [["天津之眼"]]
start_date = "2020-9-24"
end_date = "2020-10-25"
area = 924

index = Index(
    keywords=keywords,
    start_date=start_date,
    end_date=end_date,
    cookies=cookies,
    area=0,
)
fw = open("1.json", "w+", encoding='utf-8')
fw.write("[")
for data in index.get_index(index_name="search"):
    # print("搜索指数", end="")
    # xx = json.dumps(data)
    # print(json.loads(xx))
    fw.writelines(json.dumps(data)+",\n")
    # print(data)
fw.write("]")
fw.close()
input("暂停...")

for data in index.get_index(index_name="news"):
    print(""+data)

input("暂停...")

for data in index.get_index(index_name="feedsearch"):
    print("资讯指数", end="")
    print(data)


INF = 1 << 64

def max_flow(graph, s, t):
    n = len(graph)
    res = 0
    while True:
        # bfs
        dist = [INF] * n
        dist[s] = 0
        queue = [s]
        for x in queue:
            for y in graph[x]:
                if graph[x][y] == 0 or dist[y] < INF:
                    continue
                dist[y] = dist[x] + 1
                queue.append(y)
        if dist[t] == INF:
            break
        while True:
            # dfs
            stack = [(s, INF)]
            prev = [None] * n
            while stack:
                x, f = stack.pop()
                if x == t:
                    break
                for y in graph[x]:
                    if graph[x][y] == 0 or dist[x] >= dist[y]:
                        continue
                    stack.append((y, min(f, graph[x][y])))
                    prev[y] = x
            else:
                break
            # 経路復元 & 残余グラフ更新
            y = t
            while prev[y] is not None:
                x = prev[y]
                graph[x][y] -= f
                graph[y][x] += f
                y = x
            res += f
    return res

INF = 10 ** 10
n, w = map(int, input().split())
*a, = map(int, input().split())
graph = [{} for _ in range(n + 2)]
for i in range(n):
    graph[n][i] = a[i]
    graph[i][n] = 0
    graph[i][n + 1] = w
    graph[n + 1][i] = 0
for i in range(n):
    _, *lst, = map(int, input().split())
    for j in lst:
        graph[j - 1][i] = INF
        graph[i][j - 1] = 0
ans = sum(a) - max_flow(graph, n, n + 1)
print(ans)


from typing import Any, List, Union, Optional
import time
import gym
import torch
import copy
import numpy as np
from easydict import EasyDict
from ding.envs import BaseEnv, BaseEnvTimestep, BaseEnvInfo
from ding.envs.common.env_element import EnvElementInfo
from ding.torch_utils import to_tensor, to_ndarray, to_list
from ding.utils import ENV_REGISTRY

def disable_gym_view_window():
    from gym.envs.classic_control import rendering
    import pyglet

    def get_window(width, height, display):
        screen = display.get_screens()
        config = screen[0].get_best_config()
        context = config.create_context(None)
        return pyglet.window.Window(
            width=width, height=height, display=display, config=config, context=context, visible=False
        )

    rendering.get_window = get_window

@ENV_REGISTRY.register('cartpole')
class CartPoleEnv(BaseEnv):

    def __init__(self, cfg: dict = {}) -> None:
        self._cfg = cfg
        self._init_flag = False
        self._replay_path = None

    def reset(self) -> torch.Tensor:
        if not self._init_flag:
            self._env = gym.make('CartPole-v0')
            if self._replay_path is not None:
                self._env = gym.wrappers.Monitor(
                    self._env, self._replay_path, video_callable=lambda episode_id: True, force=True
                )
            self._init_flag = True
        if hasattr(self, '_seed') and hasattr(self, '_dynamic_seed') and self._dynamic_seed:
            np_seed = 100 * np.random.randint(1, 1000)
            self._env.seed(self._seed + np_seed)
        elif hasattr(self, '_seed'):
            self._env.seed(self._seed)
        self._final_eval_reward = 0
        obs = self._env.reset()
        obs = to_ndarray(obs).astype(np.float32)
        return obs

    def close(self) -> None:
        if self._init_flag:
            self._env.close()
        self._init_flag = False

    def seed(self, seed: int, dynamic_seed: bool = True) -> None:
        self._seed = seed
        self._dynamic_seed = dynamic_seed
        np.random.seed(self._seed)

    def step(self, action: np.ndarray) -> BaseEnvTimestep:
        assert isinstance(action, np.ndarray), type(action)
        if action.shape == (1, ):
            action = action.squeeze()  # 0-dim tensor
        obs, rew, done, info = self._env.step(action)
        self._final_eval_reward += rew
        if done:
            info['final_eval_reward'] = self._final_eval_reward
        obs = to_ndarray(obs).astype(np.float32)
        rew = to_ndarray([rew])  # wrapped to be transfered to a Tensor with shape (1,)
        return BaseEnvTimestep(obs, rew, done, info)

    def info(self) -> BaseEnvInfo:
        T = EnvElementInfo
        return BaseEnvInfo(
            agent_num=1,
            obs_space=T(
                (4, ),
                {
                    'min': [-4.8, float("-inf"), -0.42, float("-inf")],
                    'max': [4.8, float("inf"), 0.42, float("inf")],
                    'dtype': np.float32,
                },
            ),
            # [min, max)
            act_space=T(
                (1, ),
                {
                    'min': 0,
                    'max': 2,
                    'dtype': int,
                },
            ),
            rew_space=T(
                (1, ),
                {
                    'min': 0.0,
                    'max': 1.0
                },
            ),
            use_wrappers=None,
        )

    def __repr__(self) -> str:
        return "DI-engine CartPole Env"

    def enable_save_replay(self, replay_path: Optional[str] = None) -> None:
        if replay_path is None:
            replay_path = './video'
        self._replay_path = replay_path


#!/usr/bin/python3
"""Module for user reviews and ratings"""

from flask import *
from flask_login import current_user, login_required

# Import the necessary models from your application
from models.user import User
from models.recipe import Recipe
from models.comment import Comment
from models.rating import Rating

# Import the database object
from models.database import db

# Create a Flask Blueprint named 'review' for this module
review = Blueprint('review', __name__)

# Decorator to ensure that the user is logged in before adding a comment

@login_required
@review.route('/add_comment/<int:recipe_id>', methods=['POST'])
def add_comment(recipe_id):
    """Function to add a new comment to a recipe"""

    # Check if the request method is POST
    if request.method == 'POST':
        # Check if the user is authenticated
        if not current_user.is_authenticated:
            # Return an error message as a flash message and redirect to the login page
            flash('You are not logged in', 'danger')
            return redirect(url_for('auth.login'))

        # Get the comment text from the form data
        comment_text = request.form.get('feedback-user-review')

        # Check if the comment text is provided
        if not comment_text:
            # Return an error message as a flash message and redirect to the recipe view page
            flash('Comment text is required', 'success')
            return redirect(url_for('recipes.view_recipe', recipe_id=recipe_id))

        # Create a new Comment object
        comment = Comment(
            user_id=current_user.user_id,  # Associate the comment with the current user
            recipe_id=recipe_id,  # Associate the comment with the specified recipe
            comment_text=comment_text  # Set the comment text
        )

        # Add the comment to the database session
        db.session.add(comment)
        # Commit the changes to the database
        db.session.commit()

        # Redirect to the recipe view page and show a success message
        flash('Comment submitted successfully', 'success')
        return redirect(url_for('recipes.view_recipe', recipe_id=recipe_id))

    # If the request method is not POST, return an error message and redirect
    flash('Error in form', 'danger')
    return redirect(url_for('recipes.view_recipe', recipe_id=recipe_id))

# Decorator to ensure that the user is logged in before submitting a rating

@login_required
@review.route('/submit-rating/<int:recipe_id>', methods=['POST'])
def submit_rating(recipe_id):
    """Function to add or update a rating for a recipe"""

    # Check if the request method is POST
    if request.method == 'POST':
        # Check if the user is authenticated
        if not current_user.is_authenticated:
            # Return an error message as a flash message and redirect to the login page
            flash('You are not logged in', 'danger')
            return redirect(url_for('auth.login'))

        # Get the rating value from the request and convert it to an integer
        rating = int(request.form.get('rating'))

        # Check if the rating is within the valid range (1 to 5)
        if rating < 1 or rating > 5:
            flash('Invalid rating value', 'danger')
            return redirect(url_for('recipes.view_recipe', recipe_id=recipe_id))

        # Check if the user has already rated this recipe
        existing_rating = Rating.query.filter_by(
            user_id=current_user.user_id, recipe_id=recipe_id).first()

        if existing_rating:
            flash('You have already registered a rating for this recipe', 'warning')
        else:
            # Create a new Rating object and save it to the database
            new_rating = Rating(
                user_id=current_user.user_id,
                recipe_id=recipe_id,
                rating=rating
            )

            db.session.add(new_rating)
            db.session.commit()

            flash('Rating submitted successfully', 'success')

        return redirect(url_for('recipes.view_recipe', recipe_id=recipe_id))

    # If the request method is not POST, return an error message and redirect
    flash('Error in form', 'danger')
    return redirect(url_for('recipes.view_recipe', recipe_id=recipe_id))


import pandas as pd
from elasticsearch import AsyncElasticsearch
from dotenv import load_dotenv
import os

load_dotenv()
name = os.getenv("NAME")
es = AsyncElasticsearch(hosts=f"http://{name}:9200")
mapping = {"properties": {"id": {"type": "integer"}, "text": {"type": "text"}}}

class Elastic:
    async def search(query):
        resp = await es.search(
            index="documents",
            body={"query": {"match": {"text": query}}},
            size=20,
        )
        arr = [i["_source"]["id"] for i in resp["hits"]["hits"]]
        return arr

    async def delete(id):
        try:
            await es.delete_by_query(
                index="documents", body={"query": {"match": {"id": id}}}
            )
            return
        except:
            return

    async def fill():
        if not await es.indices.exists(index="documents"):
            await es.indices.create(
                index="documents", body={"mappings": mapping}
            )
            df = pd.read_csv("posts.csv")
            df = df.reset_index()
            df = df.rename(columns={"index": "id"})
            documents = df.to_dict(orient="records")
            for document in documents:
                await es.index(
                    index="documents",
                    body={"id": document["id"] + 1, "text": document["text"]},
                )


#servidor de echo: lado cliente
import rpyc

HOST = 'localhost' # maquina onde esta o servidor
PORT = 10020       # porta que o servidor esta escutando

def iniciaCliente():
	'''Conecta-se ao servidor.
	Saida: retorna a conexao criada.'''
	conn = rpyc.connect(HOST, PORT)

	print(type(conn.root)) # mostra que conn.root eh um stub de cliente
	print(conn.root.get_service_name()) # exibe o nome da classe (servico) oferecido

	return conn

def fazRequisicoes(conn):
	# le as mensagens do usuario ate ele digitar 'fim'
	while True:
		msg = input("\nO que deseja fazer?\nOpções:\n > Adicionar palavra/significado: Digite 'Add <palavra> <significado>'\n > Listar significados: Digite 'List <palavra>'\n > Deletar palavra: Digite 'Del <palavra>'\n > Fechar conexão: Digite 'Fim'\n\n")
		if msg == 'Fim': break

		# envia a mensagem do usuario para o servidor
		ret = conn.root.exposed_atendeRequisicoes(msg)

		print(ret)

	# encerra a conexao
	conn.close()

def main():
	#inicia o cliente
	conn = iniciaCliente()
	#interage com o servidor ate encerrar
	fazRequisicoes(conn)

main()


from django import forms
from .models import Task

class Input_Form(forms.ModelForm):
    class Meta:
        model = Task
        fields = [
            'title',
            'description',
            ]

        labels = {
            'title' : 'Task Name',
            'description' : 'Task Description'
        }

        input_attrs = {
            'type' : 'text',
            'placeholder' : 'Nama task',
        }

        input_attrs2 = {
            'type' : 'text',
            'placeholder' : 'Deskripsi task',
        }

        widgets = {
            'title' : forms.TextInput(attrs=input_attrs),
            'description' : forms.TextInput(attrs=input_attrs2),
        }


from __future__ import annotations

import ast
import asyncio
import time
from dataclasses import dataclass
from itertools import chain
from pathlib import Path
from typing import TYPE_CHECKING, Any, Iterator, List, Optional, cast

from robotcode.core.async_tools import check_canceled, check_canceled_sync, threaded
from robotcode.core.dataclasses import CamelSnakeMixin
from robotcode.core.logging import LoggingDescriptor
from robotcode.core.uri import Uri
from robotcode.jsonrpc2.protocol import rpc_method
from robotcode.language_server.common.lsp_types import DocumentUri, Position, Range, TextDocumentIdentifier
from robotcode.language_server.robotframework.configuration import RobotConfig
from robotcode.language_server.robotframework.utils.async_ast import AsyncVisitor

from .protocol_part import RobotLanguageServerProtocolPart

if TYPE_CHECKING:
    from robotcode.language_server.robotframework.protocol import RobotLanguageServerProtocol

@dataclass
class GetAllTestsParams(CamelSnakeMixin):
    workspace_folder: str
    paths: Optional[List[str]] = None
    suites: Optional[List[str]] = None

@dataclass
class GetTestsParams(CamelSnakeMixin):
    text_document: TextDocumentIdentifier
    base_name: Optional[str]

@dataclass
class GetTestsFromDocumentParams(CamelSnakeMixin):
    text_document: TextDocumentIdentifier

@dataclass
class TestItem(CamelSnakeMixin):
    type: str
    id: str
    label: str
    longname: str
    uri: Optional[DocumentUri] = None
    children: Optional[List[TestItem]] = None
    description: Optional[str] = None
    range: Optional[Range] = None
    tags: Optional[List[str]] = None
    error: Optional[str] = None

class FindTestCasesVisitor(AsyncVisitor):
    async def get(self, source: DocumentUri, model: ast.AST, base_name: Optional[str]) -> List[TestItem]:
        self._results: List[TestItem] = []
        self.source = source
        self.path = Uri(source).to_path().resolve()
        self.base_name = base_name
        await self.visit(model)
        return self._results

    async def visit_Section(self, node: ast.AST) -> None:  # noqa: N802
        from robot.parsing.model.blocks import TestCaseSection

        if isinstance(node, TestCaseSection):
            await self.generic_visit(node)

    async def visit_TestCase(self, node: ast.AST) -> None:  # noqa: N802
        from robot.parsing.model.blocks import TestCase
        from robot.parsing.model.statements import Tags

        test_case = cast(TestCase, node)
        longname = f"{self.base_name}.{test_case.name}" if self.base_name else test_case.name
        self._results.append(
            TestItem(
                type="test",
                id=f"{self.path};{longname};{test_case.lineno}",
                longname=longname,
                label=test_case.name,
                uri=self.source,
                range=Range(
                    start=Position(line=test_case.lineno - 1, character=test_case.col_offset),
                    end=Position(
                        line=(test_case.end_lineno if test_case.end_lineno != -1 else test_case.lineno) - 1,
                        character=test_case.end_col_offset if test_case.end_col_offset != -1 else test_case.col_offset,
                    ),
                ),
                tags=[str(tag) for tag in chain(*[tags.values for tags in test_case.body if isinstance(tags, Tags)])],
            )
        )

class DiscoveringProtocolPart(RobotLanguageServerProtocolPart):
    _logger = LoggingDescriptor()

    def __init__(self, parent: RobotLanguageServerProtocol) -> None:
        super().__init__(parent)
        self._patch()

    def _patch(self) -> None:
        from robot.api.parsing import File, get_model
        from robot.running import TestSuite
        from robot.running.builder.builders import RobotParser, TestSuiteBuilder

        from robotcode.language_server.robotframework.utils.version import get_robot_version

        def get_document_text(source: str) -> str:
            check_canceled_sync()

            if self.parent.loop:
                doc = self.parent.documents.get_sync(Uri.from_path(source).normalized())
                if doc is not None:
                    return doc.text()

            return source

        def get_source(self: Any, source: str) -> str:
            return get_document_text(source)

        RobotParser._get_source = get_source

        orig = RobotParser._build

        def my_get_model_v4(source: str, data_only: bool = False, curdir: Optional[str] = None) -> Any:
            check_canceled_sync()
            try:
                return get_model(source, data_only, curdir)
            except (SystemExit, KeyboardInterrupt):
                raise
            except BaseException as e:
                ex = e
                self._logger.critical(lambda: f"Can't parse {source}: {ex}")
                return File(source=source)

        def my_get_model_v6(
            source: str, data_only: bool = False, curdir: Optional[str] = None, lang: Any = None
        ) -> Any:
            check_canceled_sync()
            try:
                return get_model(source, data_only, curdir, lang)
            except (SystemExit, KeyboardInterrupt):
                raise
            except BaseException as e:
                ex = e
                self._logger.critical(lambda: f"Can't parse {source}: {ex}")
                return File(source=source)

        my_get_model = my_get_model_v4 if get_robot_version() < (6, 0) else my_get_model_v6

        def build(
            self: Any,
            suite: TestSuite,
            source: str,
            defaults: Any,
            model: Any = None,
            get_model: Any = my_get_model,
        ) -> TestSuite:
            check_canceled_sync()

            return orig(self, suite, source, defaults, model, get_model)

        RobotParser._build = build

        def _validate_test_counts(self: Any, suite: TestSuite, multisource: bool = False) -> None:
            # we don't need this
            pass

        TestSuiteBuilder._validate_test_counts = _validate_test_counts

    async def get_config(self, workspace_uri: str) -> Optional[RobotConfig]:
        folder = self.parent.workspace.get_workspace_folder(workspace_uri)
        if folder is None:
            return None

        return await self.parent.workspace.get_configuration(RobotConfig, folder.uri)

    @rpc_method(name="robot/discovering/getTestsFromWorkspace", param_type=GetAllTestsParams)
    @threaded()
    async def get_tests_from_workspace(
        self,
        workspace_folder: str,
        paths: Optional[List[str]] = None,
        suites: Optional[List[str]] = None,
        *args: Any,
        **kwargs: Any,
    ) -> List[TestItem]:
        from robot.output.logger import LOGGER
        from robot.running import TestCase, TestSuite
        from robot.running.builder.builders import TestSuiteBuilder

        from robotcode.language_server.robotframework.utils.version import get_robot_version

        async def generate(suite: TestSuite) -> TestItem:
            children: List[TestItem] = []

            await check_canceled()

            test: TestCase
            for test in suite.tests:
                children.append(
                    TestItem(
                        type="test",
                        id=f"{Path(test.source).resolve() if test.source is not None else ''};"
                        f"{test.longname};{test.lineno}",
                        label=test.name,
                        longname=test.longname,
                        uri=str(Uri.from_path(test.source)) if test.source else None,
                        range=Range(
                            start=Position(line=test.lineno - 1, character=0),
                            end=Position(line=test.lineno - 1, character=0),
                        ),
                        tags=list(test.tags),
                    )
                )

            for s in suite.suites:
                children.append(await generate(s))

            return TestItem(
                type="suite",
                id=f"{Path(suite.source).resolve() if suite.source is not None else ''};{suite.longname}",
                label=suite.name,
                longname=suite.longname,
                uri=str(Uri.from_path(suite.source)) if suite.source else None,
                children=children,
                range=Range(
                    start=Position(line=0, character=0),
                    end=Position(line=0, character=0),
                )
                if suite.source
                else None,
            )

        self._logger.info("Wait for workspace documents loaded...")

        await self.parent.robot_workspace.documents_loaded.wait()

        start = time.monotonic()

        self._logger.info("Start discovering tests")

        workspace_path = Uri(workspace_folder).to_path()
        canceled = False
        LOGGER._cache_only = True
        try:
            config = await self.get_config(workspace_folder)
            rpa_mode = config.get_rpa_mode() if config is not None else None
            languages = await self.parent.documents_cache.get_workspace_languages(workspace_folder)
            parsers = config.parsers if config is not None else None

            if paths is None and config is not None:
                paths = config.paths

            if paths and len(paths):

                def normalize_paths(paths: List[str]) -> Iterator[str]:
                    for path in paths:
                        p = Path(path)

                        if not p.is_absolute():
                            p = Path(workspace_path, p)

                        if p.exists():
                            yield str(p)

                def nonexisting_paths(paths: List[str]) -> Iterator[str]:
                    for path in paths:
                        p = Path(path)

                        if not p.is_absolute():
                            p = Path(workspace_path, p)

                        if not p.exists():
                            yield str(p)

                valid_paths = list(normalize_paths(paths))

                if get_robot_version() >= (6, 1):
                    builder = TestSuiteBuilder(
                        included_suites=suites if suites else None,
                        rpa=rpa_mode,
                        lang=languages,
                        parsers=parsers,
                    )
                elif get_robot_version() >= (6, 0):
                    builder = TestSuiteBuilder(
                        included_suites=suites if suites else None,
                        rpa=rpa_mode,
                        lang=languages,
                    )
                else:
                    builder = TestSuiteBuilder(included_suites=suites if suites else None, rpa=rpa_mode)

                suite: Optional[TestSuite] = builder.build(*valid_paths) if valid_paths else None
                suite_item = [await generate(suite)] if suite else []

                return [
                    TestItem(
                        type="workspace",
                        id=str(Path.cwd().resolve()),
                        label=Path.cwd().name,
                        longname=Path.cwd().name,
                        uri=str(Uri.from_path(Path.cwd())),
                        children=[
                            *suite_item,
                            *[
                                TestItem(
                                    type="error",
                                    id=f"{i};ERROR",
                                    longname="error",
                                    label=i,
                                    error=f"Parsing '{i}' failed: File or directory to does not exist.",
                                )
                                for i in nonexisting_paths(paths)
                            ],
                        ],
                    )
                ]

            if get_robot_version() >= (6, 1):
                builder = TestSuiteBuilder(
                    included_suites=suites if suites else None,
                    rpa=rpa_mode,
                    lang=languages,
                    parsers=parsers,
                )
            elif get_robot_version() >= (6, 0):
                builder = TestSuiteBuilder(included_suites=suites if suites else None, rpa=rpa_mode, lang=languages)
            else:
                builder = TestSuiteBuilder(included_suites=suites if suites else None, rpa=rpa_mode)
            return [await generate(builder.build(str(workspace_path)))]
        except (SystemExit, KeyboardInterrupt):
            raise
        except asyncio.CancelledError:
            canceled = True
            self._logger.info("Tests discovery canceled")
            raise
        except BaseException as e:
            ex = e
            self._logger.info(lambda: f"Failed to discover tests: {ex}")
            return [
                TestItem(
                    type="error",
                    id=str(Uri.from_path(Path.cwd().resolve())),
                    longname="error",
                    label=Path.cwd().name,
                    error=str(e),
                )
            ]
        finally:
            if not canceled:
                self._logger.info(lambda: f"Tests discovery took {time.monotonic() - start}s")

    @rpc_method(name="robot/discovering/getTestsFromDocument", param_type=GetTestsParams)
    @threaded()
    async def get_tests_from_document(
        self, text_document: TextDocumentIdentifier, base_name: Optional[str], *args: Any, **kwargs: Any
    ) -> List[TestItem]:
        try:
            return await FindTestCasesVisitor().get(
                text_document.uri,
                await self.parent.documents_cache.get_model(
                    await self.parent.documents.get_or_open_document(
                        Uri(text_document.uri).to_path(), language_id="robotframework"
                    )
                ),
                base_name,
            )
        except (asyncio.CancelledError, SystemExit, KeyboardInterrupt):
            raise
        except BaseException:
            return []


import os
import unittest
import tempfile

import papis.database
import papis.commands.mv

import tests
import tests.cli

class Test(tests.cli.TestWithLibrary):

    def get_docs(self):
        db = papis.database.get()
        return db.get_all_documents()

    def test_simple_update(self) -> None:
        docs = self.get_docs()
        document = docs[0]
        title = document["title"]
        new_dir = tempfile.mkdtemp()
        self.assertTrue(os.path.exists(new_dir))
        papis.commands.mv.run(document, new_dir)
        docs = papis.database.get().query_dict(dict(title=title))
        self.assertEqual(len(docs), 1)
        self.assertEqual(os.path.dirname(docs[0].get_main_folder()), new_dir)
        self.assertEqual(
            docs[0].get_main_folder(),
            os.path.join(new_dir, os.path.basename(docs[0].get_main_folder()))
        )


from limaflix.bean import usuario_bean
import limaflix.db as db
from limaflix.models.comentario import Comentario

class ComentarioController:

    def save(newComentario):
        try :
            conn = db.getConexao()
            cur = conn.cursor()
            param = (newComentario.usuario.id, newComentario.filme.id, newComentario.descricao)
            cur.execute("""
            INSERT INTO comentarios (idUsuario , idFilme, descricao) VALUES
                (?, ?, ?)
            """,param)
            conn.commit()
            conn.close()
            return True
        except Exception as ex:
            print(ex)
            return False

    def update(newComentario):
        try :
            conn = db.getConexao()
            cur = conn.cursor()
            param = (newComentario.usuario.id, newComentario.filme.id, newComentario.descricao)
            cur.execute("""
            UPDATE comentarios SET idUsuario = ?, idFilme = ?, descricao = ? WHERE id = ?
            """,param)
            conn.commit()
            conn.close()
            return True
        except Exception as ex:
            print(ex)
            return False

    def getAll() :
        conn = db.getConexao()
        cur = conn.cursor()
        cur.execute("SELECT * FROM comentarios ")
        lista = []
        for comentario in cur:
            lista.append(ComentarioController.fetchToObject(comentario=comentario))
        return lista

    def getLast() :
        conn = db.getConexao()
        cur = conn.cursor()
        cur.execute("SELECT * FROM comentarios ORDER BY id DESC LIMIT 1")
        return ComentarioController.fetchToObject(cur.fetchone())

    def getByIdFilme(idFilme) :
        conn = db.getConexao()
        cur = conn.cursor()
        param = (idFilme,)
        cur.execute("SELECT * FROM comentarios WHERE idFilme = ? ORDER BY id DESC",param)
        lista = []
        for comentario in cur:
            lista.append(ComentarioController.fetchToObject(comentario))
        return lista

    def fetchToObject(comentario):
       return None if comentario is None else Comentario(id=comentario[0], usuario=usuario_bean.UsuarioBean.getById(comentario[1]),filme=None, descricao=comentario[3])