"""
Test suite for monitor
"""
from unittest import TestCase

import asyncio
import json
import random
import websockets

from qcodes.monitor import monitor
from qcodes.instrument.base import Parameter
from qcodes.tests.instrument_mocks import DummyInstrument

monitor.WEBSOCKET_PORT = random.randint(50000, 60000)

class TestMonitor(TestCase):
    """
    Test cases for the qcodes monitor
    """
    def test_setup_teardown(self):
        """
        Check that monitor starts up and closes correctly
        """
        m = monitor.Monitor()
        self.assertTrue(m.is_alive())
        self.assertTrue(m.loop.is_running())
        self.assertEqual(monitor.Monitor.running, m)
        m.stop()
        self.assertFalse(m.loop.is_running())
        self.assertTrue(m.loop.is_closed())
        self.assertFalse(m.is_alive())
        self.assertIsNone(monitor.Monitor.running)

    def test_monitor_replace(self):
        """
        Check that monitors get correctly replaced
        """
        m = monitor.Monitor()
        self.assertEqual(monitor.Monitor.running, m)
        m2 = monitor.Monitor()
        self.assertEqual(monitor.Monitor.running, m2)
        self.assertTrue(m.loop.is_closed())
        self.assertFalse(m.is_alive())
        self.assertTrue(m2.is_alive())
        m2.stop()

    def test_double_join(self):
        """
        Check that a double join doesn't cause a hang
        """
        m = monitor.Monitor()
        self.assertEqual(monitor.Monitor.running, m)
        m.stop()
        m.stop()

    def test_connection(self):
        """
        Test that we can connect to a monitor instance
        """
        m = monitor.Monitor()

        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        @asyncio.coroutine
        def async_test_connection():
            websocket = yield from websockets.connect(f"ws://localhost:{monitor.WEBSOCKET_PORT}")
            yield from websocket.close()
        loop.run_until_complete(async_test_connection())

        m.stop()

class TestMonitorWithInstr(TestCase):
    """
    Test monitor values from instruments
    """
    def setUp(self):
        """
        Create a dummy instrument for use in monitor tests, and hook it into
        a monitor
        """
        self.instr = DummyInstrument("MonitorDummy")
        self.param = Parameter("DummyParam",
                               unit="V",
                               get_cmd=None,
                               set_cmd=None)
        self.param(1)
        self.monitor_parameters = tuple(self.instr.parameters.values())[1:]
        self.monitor = monitor.Monitor(*self.monitor_parameters, self.param, interval=0.1)

    def tearDown(self):
        """
        Close the dummy instrument
        """
        self.monitor.stop()
        self.instr.close()

    def test_parameter(self):
        """
        Test instrument updates
        """
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)

        @asyncio.coroutine
        def async_test_monitor():
            websocket = yield from websockets.connect(f"ws://localhost:{monitor.WEBSOCKET_PORT}")

            # Recieve data from monitor
            data = yield from websocket.recv()
            data = json.loads(data)
            # Check fields
            self.assertIn("ts", data)
            self.assertIn("parameters", data)
            # Check one instrument and "No Instrument" is being sent
            self.assertEqual(len(data["parameters"]), 2)
            self.assertEqual(data["parameters"][1]["instrument"], "Unbound Parameter")
            metadata = data["parameters"][0]
            self.assertEqual(metadata["instrument"], str(self.instr))

            # Check parameter values
            old_timestamps = {}
            for local, mon in zip(self.monitor_parameters, metadata["parameters"]):
                self.assertEqual(str(local.get_latest()), mon["value"])
                self.assertEqual(local.label, mon["name"])
                old_timestamps[local.label] = float(mon["ts"])
                local(random.random())

            # Check parameter updates
            data = yield from websocket.recv()
            data = yield from websocket.recv()
            data = json.loads(data)
            metadata = data["parameters"][0]
            for local, mon in zip(self.monitor_parameters, metadata["parameters"]):
                self.assertEqual(str(local.get_latest()), mon["value"])
                self.assertEqual(local.label, mon["name"])
                self.assertGreater(float(mon["ts"]), old_timestamps[local.label])

            # Check unbound parameter
            metadata = data["parameters"][1]["parameters"]
            self.assertEqual(len(metadata), 1)
            self.assertEqual(self.param.label, metadata[0]["name"])

        loop.run_until_complete(async_test_monitor())


from typing import *

import torch
from torch import nn

from .architectures import get_conditional_deep_vae
from .stage import VaeStage, LvaeStage, BivaStage, ConditionalBivaStage
from .utils import DataCollector
from ..layers import PaddedNormedConv

class ConditionalDeepVae(nn.Module):
    """
    A Deep Hierarchical VAE.
    The model is a stack of N stages. Each stage features an inference and a generative path.
    Depending on the choice of the stage, multiple models can be implemented:
    - VAE: https://arxiv.org/abs/1312.6114
    - LVAE: https://arxiv.org/abs/1602.02282
    - BIVA: https://arxiv.org/abs/1902.02102
    """

    def __init__(self,
                 Stage: Any = BivaStage,
                 input_channels: Optional[int] = 3,
                 imsize: Optional[int] = 48,
                 padded_shp: Optional[Tuple] = None,
                 stages: List[List[Tuple]] = None,
                 latents: List = None,
                 nonlinearity: str = 'elu',
                 q_dropout: float = 0.5, #0.2
                 p_dropout: float = 0.5, #0.
                 features_out: Optional[int] = 3, #100
                 lambda_init: Optional[Callable] = None,
                 projection: Optional[nn.Module] = None,
                 **kwargs):

        """
        Initialize the Deep VAE model.
        :param Stage: stage constructor (VaeStage, LvaeStage, BivaStage)
        :param tensor_shp: Input tensor shape (batch_size, channels, *dimensions)
        :param padded_shp: pad input tensor to this shape
        :param stages: a list of list of tuple, each tuple describing a convolutional block (filters, stride, kernel_size)
        :param latents: a list describing the stochastic layers for each stage
        :param nonlinearity: activation function (gelu, elu, relu, tanh)
        :param q_dropout: inference dropout value
        :param p_dropout: generative dropout value
        :param features_out: optional number of output features if different from the input
        :param lambda_init: lambda function applied to the input
        :param projection: projection layer with constructor __init__(output_shape)

        :param kwargs: additional arugments passed to each stage
        """
        super().__init__()
        stages, latents = self.get_default_architecture(stages, latents)
        self.latents = latents
        self.representation_size = 4 * sum([layer['N'] for layer in self.latents]) - 2 * self.latents[-1]['N']
        self.latent_sizes = [self.representation_size // 2, self.representation_size // 2]
        self.input_channels, self.imsize, self.imlength = input_channels, imsize, imsize * imsize * input_channels
        tensor_shp = (-1, self.input_channels, self.imsize, self.imsize)
        self.input_tensor_shape = tensor_shp
        self.lambda_init = lambda_init
        self.pad = None

        # Define arg dicts
        Act = {'elu': nn.ELU, 'relu': nn.ReLU, 'tanh': nn.Tanh()}[nonlinearity]
        block_args = {'act': Act, 'q_dropout': q_dropout, 'p_dropout': p_dropout}
        delta_input_shape = {'x': (-1, 2 * self.input_channels, self.imsize, self.imsize)}
        cond_input_shape = {'x': (-1, self.input_channels, self.imsize, self.imsize)}

        # Define both model stages
        self.delta_stages = self.create_biva_model(ConditionalBivaStage, block_args, delta_input_shape, stages, latents, kwargs)
        self.cond_stages = self.create_biva_model(BivaStage, block_args, cond_input_shape, stages, latents, kwargs)

        # Output convolution
        tensor_shp = self.delta_stages[0].p_output_shape['d']
        if features_out is None:
            features_out = self.input_tensor_shape[1]
        conv_obj = nn.Conv2d if len(tensor_shp) == 4 else nn.Conv1d
        conv_out = conv_obj(tensor_shp[1], features_out, 1)
        conv_out = PaddedNormedConv(tensor_shp, conv_out, weightnorm=True)
        self.projection = nn.Sequential(Act(), conv_out)

    def create_biva_model(self, stage_class, block_args, input_shape, stages, latents, kwargs):
        stages_ = []

        for i, (conv_data, z_data) in enumerate(zip(stages, latents)):
            top = i == len(stages) - 1
            bottom = i == 0

            stage = stage_class(input_shape, conv_data, z_data, top=top, bottom=bottom, **block_args, **kwargs)
            input_shape = stage.q_output_shape
            stages_ += [stage]

        return nn.ModuleList(stages_)

    def get_default_architecture(self, stages, latents):
        if stages is None:
            stages, _ = get_conditional_deep_vae()

        if latents is None:
            _, latents = get_conditional_deep_vae()

        return stages, latents

    def infer_cond(self, x_cond, **kwargs):
        cond_posteriors = []
        cond_data = {'x': x_cond}

        for stage in self.cond_stages:
            cond_data, cond_posterior = stage.infer(cond_data, **kwargs)
            cond_posteriors += [cond_posterior]

        return cond_posteriors

    def infer(self, x_delta, x_cond, **kwargs):
        """
        Forward pass through the inference network and return the posterior of each layer order from the top to the bottom.
        :param x: input tensor
        :param kwargs: additional arguments passed to each stage
        :return: a list that contains the data for each stage
        """
        delta_posteriors = []
        delta_data = {'x': torch.cat([x_delta, x_cond], dim=1)}

        for stage in self.delta_stages:
            delta_data, delta_posterior = stage.infer(delta_data, **kwargs)
            delta_posteriors += [delta_posterior]

        cond_posteriors = self.infer_cond(x_cond, **kwargs)
        return delta_posteriors, cond_posteriors

    def generate(self, delta_posteriors, cond_posteriors, **kwargs) -> Dict[str, torch.Tensor]:
        """
        Forward pass through the generative model, compute KL and return reconstruction x_, KL and auxiliary data.
        If no posterior is provided, the prior is sampled.
        :param posteriors: a list containing the posterior for each stage
        :param kwargs: additional arguments passed to each stage
        :return: {'x_': reconstruction logits, 'kl': kl for each stage, **auxiliary}
        """
        if delta_posteriors is None:
            delta_posteriors = [None for _ in self.delta_stages]

        delta_output_data, cond_output_data = DataCollector(), DataCollector()
        x_delta, x_cond = {}, {}
        conditioning = []

        #debugging: make sure this is done right
        for posterior, delta_posterior, stage in zip(cond_posteriors[::-1], delta_posteriors[::-1], self.cond_stages[::-1]):
            x_cond, data = stage(x_cond, posterior, **kwargs)
            conditioning.append(x_cond['z'])
            cond_output_data.extend(data)

        for posterior, cond, stage in zip(delta_posteriors[::-1], conditioning, self.delta_stages[::-1]):
            x_delta, data = stage(x_delta, posterior, cond, **kwargs)
            delta_output_data.extend(data)

        # output convolution
        x_delta = self.projection(x_delta['d'])
        x_cond = self.projection(x_cond['d'])

        # sort data: [z1, z2, ..., z_L]
        delta_output_data = delta_output_data.sort()

        return {'x_': x_delta, **delta_output_data}, {'x_': x_cond, **cond_output_data}

    def forward(self, x_delta, x_cond, **kwargs):
        """
        Forward pass through the inference model, the generative model and compute KL for each stage.
        x_ = p_\theta(x|z), z \sim q_\phi(z|x)
        kl_i = log q_\phi(z_i | h) - log p_\theta(z_i | h)

        :param x: input tensor
        :param kwargs: additional arguments passed to each stage
        :return: {'x_': reconstruction logits, 'kl': kl for each stage, **auxiliary}
        """
        x_delta = x_delta.reshape(*self.input_tensor_shape)
        x_cond = x_cond.reshape(*self.input_tensor_shape)

        delta_posteriors, cond_posteriors = self.infer(x_delta, x_cond, **kwargs)

        delta_data, cond_data = self.generate(delta_posteriors, cond_posteriors, N=x_delta.size(0), **kwargs)

        return delta_data['x_'], cond_data['x_'], delta_data['kl'], cond_data['kl']

    def sample_images(self, batch_size, x_cond, **kwargs):
        """
        Sample the prior and pass through the generative model.
        x_ = p_\theta(x|z), z \sim p_\theta(z)

        :param N: number of samples (batch size)
        :param kwargs: additional arguments passed to each stage
        :return: {'x_': sample logits}
        """
        x_cond = x_cond.reshape(-1, self.imlength)
        if x_cond.shape[0] == 1:
            x_cond = x_cond.repeat(batch_size, 1)

        x_cond = x_cond.reshape(*self.input_tensor_shape)
        cond_posteriors = self.infer_cond(x_cond, **kwargs)

        delta_data, cond_data = self.generate(None, cond_posteriors, N=batch_size, **kwargs)
        samples = delta_data['x_']

        return samples

class ConditionalBIVA(ConditionalDeepVae):
    def __init__(self, **kwargs):
        kwargs.pop('Stage', None)
        super().__init__(Stage=BivaStage, **kwargs)


import sqlite3,time
import subprocess as sp

"""
Codigo fuente de la BD para interactuar con ella
"""

def create_table():
    # Conexion a sqlite3
    conn = getConexion()

    # Asigno cursor de la conexion a una variable local
    cursor = conn.cursor()

    # Defino la consulta de SQL para crear la tabla estudiantes
    query = '''
        CREATE TABLE IF NOT EXISTS student(
        id INTEGER PRIMARY KEY,
        roll INTEGER,
        name TEXT,
        phone TEXT
        );'''

    cursor.execute(query)
    #cursor.execute("-SQL QUERYS")

    # Consignar ala BD las instrucciones que se acaban de ejecutar
    conn.commit()

    # Cerrar conexion
    conn.close()

def add_student(id_,roll, name, phone):
    # Abrir la conexion
    conn = getConexion()
    # Asigna cursor de la bd a una variable local
    cursor = conn.cursor()

    # Query a ejecutar

    query = '''
        INSERT INTO student(id,roll,name,phone)
        VALUES(?,?,?,?)
        '''

    # Ejecuto la conexion en el cursor devuelto por la BD
    cursor.execute(query,(id_,roll,name,phone))

    # Consignar a la Bd la instruccion SQL ejecutada.
    conn.commit()

    # Cerrar conexion
    conn.close()

def get_students():
    # Abrir conexion a BD
    conn = getConexion()

    # Asigno el cursor
    cursor = conn.cursor()

    # Query para ejecutar
    query = '''
        SELECT id,roll, name, phone FROM student
        '''
    # Ejecutar el query
    cursor.execute(query)

    # Obtener el resultado del cursor de los registros y los
    # asigno a una variable
    all_rows = cursor.fetchall()

    # Consigno la consulta a la conexion a la BD
    conn.commit()

    # Cerrar la conexion
    conn.close()

    # Regreso el conjunto de datos devueltos por la consulta
    return all_rows

def get_student_by_id(id_):
    # Traer la conexion desde el metodo GetConexion
    conn = getConexion()

    # Asignar el cursor a una variable local
    cursor = conn.cursor()

    # Query a ejecutar
    query = '''
        SELECT id,roll, name,phone FROM student
        WHERE id = {}
        '''.format(id_)

    # Ejecutar el QUERY
    cursor.execute(query)

    # Obtener el resultado del cursor de los registros y los
    # asigno a una variable
    all_rows = cursor.fetchall()

    # Consigno la consulta a la conexion a la BD
    conn.commit()

    # Cerrar la conexion
    conn.close()

    # Regreso el conjunto de datos devueltos por la consulta
    return all_rows

def update_student(roll, name, phone):
    # Traer la conexion desde el metodo GetConexion
    conn = getConexion()

    # Asignar el cursor a una variable local
    cursor = conn.cursor()

    # Query a ejecutar
    query = '''
        UPDATE student SET name = ?, phone = ? WHERE roll = ?
        '''

    # Ejecutar el QUERY
    cursor.execute(query, (name, phone, roll))

    # Obtener el resultado del cursor de los registros y los
    # asigno a una variable
    #all_rows = cursor.fetchall()

    # Consigno la consulta a la conexion a la BD
    conn.commit()

    # Cerrar la conexion
    conn.close()

    # Regreso el conjunto de datos devueltos por la consulta
    # return all_rows

def delete_student(id__):
    # Traer la conexion desde el metodo GetConexion
    conn = getConexion()

    # Asignar el cursor a una variable local
    cursor = conn.cursor()

    # Query a ejecutar
    query = '''
        DELETE FROM student WHERE id = {}
        '''.format(id__)

    # Ejecutar el QUERY
    cursor.execute(query)

    # Obtener el resultado del cursor de los registros y los
    # asigno a una variable
    #all_rows = cursor.fetchall()

    # Consigno la consulta a la conexion a la BD
    conn.commit()

    # Cerrar la conexion
    conn.close()

    # Regreso el conjunto de datos devueltos por la consulta
    # return all_rows

def getConexion():
    conn = sqlite3.connect("testdb2.sqlite")
    return conn

def add_data(id_,roll, name, phone):
    add_student(id_,roll, name, phone)

def get_data():
    return get_students()

def show_data():
    students = get_data()
    for students in students:
        print(students)

def show_data_by_id(id_):
    students = get_student_by_id(id_)
    if not students:
        print("No hay registros para el id %r" % id_)
        time.sleep(2)
    else:
        print(students)
        time.sleep(2)

def select():
    create_table()
    sp.call('cls', shell=True)
    sel = input("1. Add\n2. Show\n3. Search\n4. Update\n5. Delete\n6. Exit\n>: ")

    if sel == '1':
        sp.call('cls', shell=True)
        id__ = int(input("Id: "))
        roll = input("Roll: ")
        name = input("Name: ")
        phone = input("Phone: ")
        add_data(id__, roll, name, phone)

        #input("\n\nPress enter to back: ")

    elif sel == '2':
        sp.call('cls', shell=True)
        show_data()
        input("\n\nPress enter to back: ")

    elif sel == '3':
        sp.call('cls', shell=True)
        id_ = int(input("Enter ID: "))
        show_data_by_id(id_)

        print("\n\nPress enter to back: ")

    elif sel == '4':
        sp.call('cls', shell=True)
        id__ = int(input("Enter ID: "))
        show_data_by_id(id__)

        print("\n")

        name = input("Name: ")
        phone = input("Phone: ")
        update_student(id__, name, phone)

        input("\n\nYour data has been updated\nPress enter to back: ")

    elif sel == '5':
        sp.call('cls', shell=True)
        id__ = int(input("Enter ID: "))
        show_data_by_id(id__)
        delete_student(id__)

        print("\n")
        input("\n\nYour data has been deleted\nPress enter to back: ")
    else:
        return 0
    return 1

while select():
    pass


#Importación de sql para establecer la conexión y excepciones.
import sqlite3
from sqlite3 import Error
#Importación de ventanas para conectar en las funciones.
from DatosAgregados import Ui_DatosAgregados
from ClaveExistente import Ui_ClaveExistente
from ClaveInexistente import Ui_ClaveInexistente
from ClaveInexistenteProveedor import Ui_ClaveInexistenteProveedor
from Alerta import Ui_Alerta
#Librería para crear nuestra aplicación.
from PyQt5 import QtCore, QtGui, QtWidgets

#Creación de la aplicación. (Menú de producto donde se introducen los datos del producto a agregar.)
class Ui_AgregarProducto(object):
    def setupUi(self, AgregarProducto):
        AgregarProducto.setObjectName("AgregarProducto")
        AgregarProducto.resize(312, 344)
        AgregarProducto.setStyleSheet("background-color: rgb(226, 230, 255);")
        self.centralwidget = QtWidgets.QWidget(AgregarProducto)
        self.centralwidget.setObjectName("centralwidget")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(0, 0, 301, 51))
        self.label_5.setObjectName("label_5")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(20, 69, 91, 21))
        self.label.setStyleSheet("border-color: rgb(0, 0, 0);\n"
"gridline-color: rgb(0, 0, 0);")
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(30, 110, 61, 16))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(20, 150, 81, 16))
        self.label_3.setObjectName("label_3")
        self.label_6 = QtWidgets.QLabel(self.centralwidget)
        self.label_6.setGeometry(QtCore.QRect(10, 190, 101, 20))
        self.label_6.setObjectName("label_6")
        self.label_7 = QtWidgets.QLabel(self.centralwidget)
        self.label_7.setGeometry(QtCore.QRect(10, 230, 101, 20))
        self.label_7.setObjectName("label_7")
        self.ClaveP = QtWidgets.QLineEdit(self.centralwidget)
        self.ClaveP.setGeometry(QtCore.QRect(130, 60, 161, 31))
        self.ClaveP.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.ClaveP.setObjectName("ClaveP")
        self.Nombre = QtWidgets.QLineEdit(self.centralwidget)
        self.Nombre.setGeometry(QtCore.QRect(130, 100, 161, 31))
        self.Nombre.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Nombre.setObjectName("Nombre")
        self.Precio = QtWidgets.QLineEdit(self.centralwidget)
        self.Precio.setGeometry(QtCore.QRect(130, 140, 161, 31))
        self.Precio.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Precio.setObjectName("Precio")
        self.Inventario = QtWidgets.QLineEdit(self.centralwidget)
        self.Inventario.setGeometry(QtCore.QRect(130, 180, 161, 31))
        self.Inventario.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Inventario.setObjectName("Inventario")
        self.Proveedor = QtWidgets.QLineEdit(self.centralwidget)
        self.Proveedor.setGeometry(QtCore.QRect(130, 220, 161, 31))
        self.Proveedor.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Proveedor.setObjectName("Proveedor")
        self.Verificar = QtWidgets.QPushButton(self.centralwidget)
        self.Verificar.setGeometry(QtCore.QRect(120, 271, 75, 23))
        self.Verificar.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Verificar.setObjectName("Verificar")
        self.Limpiar = QtWidgets.QPushButton(self.centralwidget)
        self.Limpiar.setGeometry(QtCore.QRect(20, 271, 75, 23))
        self.Limpiar.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Limpiar.setObjectName("Limpiar")
        self.Agregar = QtWidgets.QPushButton(self.centralwidget)
        self.Agregar.setGeometry(QtCore.QRect(220, 270, 75, 23))
        self.Agregar.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.Agregar.setObjectName("Agregar")
        AgregarProducto.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(AgregarProducto)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 312, 21))
        self.menubar.setObjectName("menubar")
        AgregarProducto.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(AgregarProducto)
        self.statusbar.setObjectName("statusbar")
        AgregarProducto.setStatusBar(self.statusbar)

        self.retranslateUi(AgregarProducto)
        #Boton Limpiar para limpiar todos los campos.
        self.Limpiar.clicked.connect(self.ClaveP.clear)
        self.Limpiar.clicked.connect(self.Nombre.clear)
        self.Limpiar.clicked.connect(self.Precio.clear)
        self.Limpiar.clicked.connect(self.Inventario.clear)
        self.Limpiar.clicked.connect(self.Proveedor.clear)
        QtCore.QMetaObject.connectSlotsByName(AgregarProducto)
        #Botones programados
        #Boton que permite agregar la información a la base de datos.
        self.Agregar.clicked.connect(self.LoadData)
        #Boton que permite verificar que la información cargada en la aplicación sea válida.
        self.Verificar.clicked.connect(self.VerificarDatos)

    #Función que permite verificar que la información dada por el usuario sea válida para cargar.
    def VerificarDatos(self):
        #Try para excepciones.
        try:
            #Conexión a la base de datos
            with sqlite3.connect("PIA_1845788.db") as conn:
                    #Definir nuestro cursor.
                    micursor = conn.cursor()
                    #Leer clave de producto que se introduce en nuestra ventana de Agregar Producto.
                    Clave = self.ClaveP.text()
                    #Convertir la clave a entero.Ya que en la base se tiene como Entero.
                    clave = int(Clave)
                    #Ejecutar una línea que nos permite obtener todas las claves guardadas en Producto
                    micursor.execute("SELECT Clave_Producto FROM Producto")
                    #Guardar los resultados en la variable claveP
                    claveP = micursor.fetchall()
                    #Declarar una lista donde se guardaran las claves de producto.
                    listaClaves = []
                    #Ciclo para el unpack del resultado de claveP.
                    for dato in claveP:
                        for n in dato:
                            ClaveP= int(n)
                            #Agregar cada clave a la lista de listaClaves.
                            listaClaves.append(ClaveP)
                    #Leer clave de proveedor que se introduce en nuestra ventana de Agregar Producto.
                    ClaveP = self.Proveedor.text()
                    #Convertir la clave a entero.Ya que en la base se tiene como Entero.
                    clavePro = int(ClaveP)
                    #Ejecutar una línea que nos permite obtener todas las claves guardadas en Proveedor
                    micursor.execute("SELECT Clave_Proveedor FROM Proveedor")
                    #Guardar los resultados en la variable clavePro
                    ClavePro = micursor.fetchall()
                    #Declarar una lista donde se guardaran las claves de proveedores.
                    listaClavesP = []
                    #Ciclo para el unpack del resultado de clavePro
                    for dato in ClavePro:
                        for n in dato:
                            clavepro= int(n)
                            #Agregar cada clave a la lista de listaClavesP.
                            listaClavesP.append(clavepro)
                    #ESTO ES UNA DOBLE VERIFICACIÓN YA QUE TAMBIÉN SE HACE EN LA FUNCIÓN DE AGREGAR.
                    #Si la clave que introdujo el usuario esta dentro de la lista de claves.
                    if clave in listaClaves:
                        #Se muestra una ventana donde avisa que la clave ya esta ocupada y que intente con otra.
                        self.ventana = QtWidgets.QMainWindow()
                        self.ui = Ui_ClaveExistente()
                        self.ui.setupUi(self.ventana)
                        self.ventana.show()
                    #Si la clave que introdujo el usuario en la clave proveedor NO existe muestra el siguiente mensaje.
                    elif clavePro not in listaClavesP:
                        #Ventana donde muestra que la clave de proveedor es inexistente, por lo tanto NO puede proseguir.
                        self.ventana = QtWidgets.QMainWindow()
                        self.ui = Ui_ClaveInexistenteProveedor()
                        self.ui.setupUi(self.ventana)
                        self.ventana.show()
                    #Si la clave del producto no esta dentro de la lista de claves de Productos.
                    elif clave not in listaClaves:
                        #Se muestra la ventana donde se avisa que la clave esta disponible y por lo tanto puede proseguir.
                        self.ventana = QtWidgets.QMainWindow()
                        self.ui = Ui_ClaveInexistente()
                        self.ui.setupUi(self.ventana)
                        self.ventana.show()
        #Excepcion por si ocurre un error con sqlite3.
        except Error as e:
            print(e)
        #Excepción por si no se llenan los campos necesarios.
        except:
            #Ventana que muestra el mensaje donde se piden llenar todos los campos.
            self.ventana = QtWidgets.QMainWindow()
            self.ui = Ui_Alerta()
            self.ui.setupUi(self.ventana)
            self.ventana.show()

    #Función para leer y agregar los datos a la base.
    def LoadData(self):
        try:
            #Conexión a la base de datos
            with sqlite3.connect("PIA_1845788.db") as conn:
                #Definir nuestro cursor.
                micursor = conn.cursor()
                #Leer clave de producto que se introduce en nuestra ventana de Agregar Producto.
                Clave = self.ClaveP.text()
                #Convertir la clave a entero.Ya que en la base se tiene como Entero.
                clave = int(Clave)
                #Ejecutar una línea que nos permite obtener todas las claves guardadas en Producto
                micursor.execute("SELECT Clave_Producto FROM Producto")
                #Guardar los resultados en la variable claveP
                claveP = micursor.fetchall()
                #Declarar una lista donde se guardaran las claves de producto.
                listaClaves = []
                #Ciclo para el unpack del resultado de claveP.
                for dato in claveP:
                    for n in dato:
                        ClaveP= int(n)
                        #Agregar cada clave a la lista de listaClaves.
                        listaClaves.append(ClaveP)
                #Leer clave de proveedor que se introduce en nuestra ventana de Agregar Producto.
                ClaveP = self.Proveedor.text()
                #Convertir la clave a entero.Ya que en la base se tiene como Entero.
                clavePro = int(ClaveP)
                #Ejecutar una línea que nos permite obtener todas las claves guardadas en Proveedor
                micursor.execute("SELECT Clave_Proveedor FROM Proveedor")
                #Guardar los resultados en la variable clavePro
                ClavePro = micursor.fetchall()
                #Declarar una lista donde se guardaran las claves de proveedores.
                listaClavesP = []
                #Ciclo para el unpack del resultado de clavePro
                for dato in ClavePro:
                    for n in dato:
                        clavepro= int(n)
                        #Agregar cada clave a la lista de listaClavesP.
                        listaClavesP.append(clavepro)
                #ESTO ES UNA DOBLE VERIFICACIÓN YA QUE TAMBIÉN SE HACE EN LA FUNCIÓN DE VERIFICAR.
                #Si la clave que introdujo el usuario esta dentro de la lista de claves.
                if clave in listaClaves:
                    #Se muestra una ventana donde avisa que la clave ya esta ocupada y que intente con otra.
                    self.ventana = QtWidgets.QMainWindow()
                    self.ui = Ui_ClaveExistente()
                    self.ui.setupUi(self.ventana)
                    self.ventana.show()
                #Si la clave que introdujo el usuario en la clave proveedor NO existe muestra el siguiente mensaje.
                elif clavePro not in listaClavesP:
                    #Ventana donde muestra que la clave de proveedor es inexistente, por lo tanto NO puede proseguir.
                    self.ventana = QtWidgets.QMainWindow()
                    self.ui = Ui_ClaveInexistenteProveedor()
                    self.ui.setupUi(self.ventana)
                    self.ventana.show()
                #Si la clave del producto no esta dentro de la lista de claves de Productos.
                elif clave not in listaClaves:
                    #Se lee el nombre que se introduce en la aplicación y se agrega a la variable nombre.
                    nombre = self.Nombre.text()
                    #Se lee el precio que se introduce en la aplicación y se agrega a la variable Precio.
                    Precio = self.Precio.text()
                    #Se cambia el valor a float y se guarda en la variable precio. Ya que en la base se tiene como float.
                    precio = float(Precio)
                    #Se lee el inventario que se introduce en la aplicación y se agrega a la variable Inventario.
                    Inventario = self.Inventario.text()
                    #Se cambia el valor a entero y se guarda en la variable inventario. Ya que en la base se tiene como Entero.
                    inventario = int(Inventario)
                    #Se lee la clave que se introduce en la aplicación y se agrega a la variable Proveedor.
                    Proveedor = self.Proveedor.text()
                    #Se cambia el valor a entero y se guarda en la variable proveedor. Ya que en la base se tiene como Entero.
                    proveedor = int(Proveedor)
                    #Guardar valores en un diccionario, con una clave que distinga cada uno.
                    valores = {"clave": clave, "nombre": nombre, "precio": precio, "inventario": inventario,"proveedor":proveedor}
                    #Ejecutar la linea de INSERT con las llaves del diccionario valores.
                    micursor.execute("INSERT INTO Producto VALUES(:clave,:nombre,:precio,:inventario,:proveedor)", valores)
                    #Se abre la ventana con el aviso que los datos han sido agregados exitosamente.
                    self.ventana = QtWidgets.QMainWindow()
                    self.ui = Ui_DatosAgregados()
                    self.ui.setupUi(self.ventana)
                    self.ventana.show()
        #Excepcion por si ocurre un error con sqlite3.
        except Error as e:
            print(e)
        #Excepción por si no se llenan los campos necesarios.
        except:
            #Ventana que muestra el mensaje donde se piden llenar todos los campos.
            self.ventana = QtWidgets.QMainWindow()
            self.ui = Ui_Alerta()
            self.ui.setupUi(self.ventana)
            self.ventana.show()

    #Asignación de texto a los botones y labels.
    def retranslateUi(self, AgregarProducto):
        _translate = QtCore.QCoreApplication.translate
        AgregarProducto.setWindowTitle(_translate("AgregarProducto", "MainWindow"))
        self.label_5.setText(_translate("AgregarProducto", "
NUEVO PRODUCTO
"))
        self.label.setText(_translate("AgregarProducto", "
CLAVE
"))
        self.label_2.setText(_translate("AgregarProducto", "
NOMBRE
"))
        self.label_3.setText(_translate("AgregarProducto", "
PRECIO
"))
        self.label_6.setText(_translate("AgregarProducto", "
INVENTARIO
"))
        self.label_7.setText(_translate("AgregarProducto", "
PROVEEDOR
"))
        self.Verificar.setText(_translate("AgregarProducto", "VERIFICAR"))
        self.Limpiar.setText(_translate("AgregarProducto", "LIMPIAR"))
        self.Agregar.setText(_translate("AgregarProducto", "AGREGAR"))

#Cerrar aplicación.
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    AgregarProducto = QtWidgets.QMainWindow()
    ui = Ui_AgregarProducto()
    ui.setupUi(AgregarProducto)
    AgregarProducto.show()
    sys.exit(app.exec_())


#!/usr/bin/env python2

import os
import argparse
import cv2
import rospy
import actionlib

import process_frame
import openface
import point_head
import face_recognition.msg

class HeadMover(object):
    """ head mover main class """
    _result = face_recognition.msg.HeadMoverResult()

    def __init__(self, name):
        # action server
        self._action_name = name
        self._rate = rospy.Rate(60)
        self._server = actionlib.SimpleActionServer(
            self._action_name,
            face_recognition.msg.HeadMoverAction,
            execute_cb=self.execute_cb,
            auto_start=False)
        self._server.start()

    def execute_cb(self, goal):
        """init face align lib and network"""
        args.id = goal.id
        args.align_lib = openface.AlignDlib(args.dlibFacePredictor)
        args.head_action = point_head.PointHeadClient()

        print('Start face recognition: ' + str(goal.comm))
        if goal.comm:
            if args.device == 0:
                process_frame.webcam(args)
            elif args.device == 1:
                # start rgb image call back
                args.x = 0.0
                args.y = 0.0
                ic = process_frame.image_converter(args)
                while not self._server.is_preempt_requested():
                    # face recognition
                    ret = ic.robot_process_img()

        self._server.set_succeeded(True)

        if not args.noviz:
            cv2.destroyAllWindows()

if __name__ == '__main__':
    fileDir = os.path.dirname(os.path.realpath(__file__))
    modelDir = os.path.join(fileDir, '..', 'models')
    dlibModelDir = os.path.join(modelDir, 'dlib')
    openfaceModelDir = os.path.join(modelDir, 'openface')

    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--dlibFacePredictor',
        type=str,
        help="Path to dlib's face predictor.",
        default=os.path.join(
            dlibModelDir,
            "shape_predictor_68_face_landmarks.dat"))
    parser.add_argument('--imgDim', type=int,
                        help="Default image dimension.", default=96)
    parser.add_argument(
        '--device',
        type=int,
        default=0,
        help='Capture device. 0 for webcam cam and 1 for robot cam')
    parser.add_argument('--width', type=int, default=320)
    parser.add_argument('--height', type=int, default=240)
    parser.add_argument('--threshold', type=float, default=0.5)
    parser.add_argument('--verbose', action='store_true')
    parser.add_argument('--noviz', action='store_true')
    parser.add_argument('--test', type=int, default=0)

    args = parser.parse_args()

    ######################################

    rospy.init_node('head_mover')
    server = HeadMover(rospy.get_name())
    rospy.spin()


x = 100
y = 100

print(x+y)

a = 5
print(type(a))

# Intro to Python
## Learning about Lists.

hall = 11.25
kit = 18.0
liv = 20.0
bed = 10.75
bath = 9.50

house = {"kit": 19.0, "abc":21.0} #note that this is a dictionary!
house2 = [
            ["hallway", hall],
            ["kitchen", kit],
            ["Living Room", liv],
            ["Bedroom", bed],
            ["Bathroom", bath]
            ]

print(house2)
print(house["kit"]) #and this is how you call/refer to a dictionary!

## IMPORTANT: Python lists have an index of 0.
# when calling lists (a.k.a. 'subsetting'), the last item is NOT called. ie. [inclusive:exclusive]: Example below...

print("house2[1:3]: ", house2[1:3]) #note how only 2 elements from the list are printed.
print(house2[2:]) # nothing is input after the colon. This denotes everything after
print(house2[:2]) # likewise, having no argument before the colon denotes everything prior to

#say we renovated our house as follows...
house2[0] = ["Living Room 1", liv+1]
house2[4][0] = "Living Room 2"

print(house2)

#or we demolish a room, like that weird additional living room in the middle...

del(house2[2])
print(house2)

#and then add a room...

house2 = house2 + [["Boardroom", 99.0]] #do note this is added to the back, and not the front (first)
print(house2)

#if we try to create a new house, it's important how we assign it. For instance, the following...

house3 = house2
house3[1] = ["Attic", 23.0]

print(house3)
print(house2)

#also changed house2 unintentionally. This is because in line 55, we've only created a new var house3 which POINTS to the same list.
#the following are alternatives..

house3 = list(house2) #encapsulate in a function
house3 = house2[:] #explicit slicer

house2[1] = ["kitchen", kit]
print(house2)
print(house3)

## FUNCTIONS
# example functions are max() and round(). The help function is very useful!
setattr()
help(round)
sorted()

a = [1,2,3,4]
b = [5,6,7]

c = a + b
print("+:", c)

c = a + [6]
print(type(c))
print("append:", c)

## METHODS
# Python objects have methods. For instance the list object has several methods...

a = [1,2,3,4,1,1,1,3,1,1,5,1,5,2,0]

print(a.count(1))

# in Python, EVERYTHING is an object. Maybe that's why it's called OOP

a.append(199)

print(a)

## PACKAGES
# NumPy is a good alternative to the Python list when we hope to subject arithmetic operations on it.
# This data structure is called the NumPy array.

import numpy as np

height = [1.73, 1.68, 1.71, 1.89, 1.79]
weight = [65.4, 59.2, 63.6, 88.4, 68.7]

np_height = np.array(height)
np_weight = np.array(weight)
print(np_height)
print(np_weight)

bmi = np_weight / np_height ** 2
print(bmi)

# The numpy array assumes a singular type. If it sees more than one type, it will automatically convert them based on the present types.
# this is also known as type coercion...

np_test = np.array([1.0, 'hello', 2, True])
print(np_test) # note each term is now encapsulated with apostrophe marks!

np_test2 = np.array([1, 2, True, False, 3, 12])
print(np_test2) # note here that since no string is in the list, it coerces the booleans to their integer-binary equivalents.

# Numpy subsetting...
print(bmi[1])
print(bmi > 23)
print(bmi[bmi > 23])
print(bmi[[False, False, False, True, False]])

# types of np arrays:
print(type(np_height)) # this is an nd.array, or an N-dimensional array

# now let's construct a 2-d array...
np_2d = np.array([height, weight])
print(np_2d, ':', type(np_2d)) # it's still an n-d array, but now has a new property
print('shape: ', np_2d.shape) # shapes will have rows, columns.

# You can subset an n>1 dimensional array as usual. Using less than the Nth square brackets will pull the entire row:
# To subset a specific item you'll need square brackets, [], for every N. For example:
print(np_2d[0][0])
print(np_2d[0,0]) # also works!
print(np_height[bmi<21])

print(np_2d[1,:])

# DATA VISUALIZATION with matplotlib.
import matplotlib.pyplot as plt
help(plt.scatter)

year = [1950, 1970, 1990, 2010]
pop = [2.519, 3.692, 5.263, 6.972]

plt.scatter(year, pop)
plt.show()

# other functions...

plt.xscale('log')
plt.xlabel('x-axis here')
plt.ylabel('y-axis here')
plt.title('title here')
plt.yticks([0,2,4,6,8,10], ['A', 'B', 'C', 'D', 'E']) # this is an interesting one. You can add a second list to change the numbers to string labels, maintaining the indents based on the numbers.

help(plt.hist)

# now, on to dictionaries. Let's create a sample one here:

capitals = ['berlin', 'oslo', 'ottawa', 'washington DC']
countries = ['germany', 'norway', 'canada', 'usa']

world = {countries:capitals}
print(world["berlin"])

# Adding an element to a dictionary is easy:

world["sealand"] = 'sealand'
# This data structure is very useful when using pandas. For instance, initializing a table would often require the use of dictionaries.
# Now, let's learn how to use pandas.

import pandas as pd

names = ['United States', 'Australia', 'Japan', 'India', 'Russia', 'Morocco', 'Egypt']
dr =  [True, False, False, False, True, True, True]
cpc = [809, 731, 588, 18, 200, 70, 45]


from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../user_management.db'
# Prevent flask_restful from adding annoying extra message to 404 responses
app.config['ERROR_404_HELP'] = False
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
api = Api(app)

from resources import UserResource, UserListResource, GroupResource, GroupListResource,\
    UserGroupsResource, GroupUsersResource

api.add_resource(UserResource, '/users/<int:id>')
api.add_resource(UserListResource, '/users')
api.add_resource(GroupResource, '/groups/<int:id>')
api.add_resource(GroupListResource, '/groups')
api.add_resource(UserGroupsResource, '/users/<int:id>/groups')
api.add_resource(GroupUsersResource, '/groups/<int:id>/users')


# -*- coding: utf-8 -*-
from username import USERNAME
import sys
# sys.path.insert(0, "/home/%s/work/minihand/remodet_repository/python")
import caffe
from caffe import layers as L
from caffe import params as P
from caffe.proto import caffe_pb2
from DetRelease_General import *
sys.dont_write_bytecode = True

########################################################
###############General Informaion#######################
########################################################

save_path = '/home/%s/tmp'%USERNAME
#######Body and Part Detection Data######
if train_net_id == 0:
    train_list_bdpd169 = ['/home/%s/Datasets/COCO_ori/Layout/COCO2017_CATDOG_TRAIN.txt'% USERNAME]
    root_dir_train_bdpd = ['/home/%s/Datasets/COCO_ori' % USERNAME]
    train_list_bdpd916 = ['/home/%s/Datasets/AIC_Data/Layout/train_PersonWithFaceHeadHand_V0_V0_cont1_V0_cont2_V0_cont3.txt'% USERNAME,
                       '/home/zhangming/Datasets/RemoCoco/Layout/trainval_NoPersonClean.txt',
                       '/home/zhangming/Datasets/OtherBackGround_Images/background_list.txt',
                       '/home/zhangming/Datasets/Google_BodyDet_20180817/Layout/trainval_Google_BodyDet_20180817_HWGE2_3.txt']
else:
    train_list_bdpd169 = ["/home/%s/Datasets/AIC_REMOCapture/trainval_AIC_remocap2018053008070827.txt"% USERNAME,
   "/home/%s/Datasets/RemoCoco/Layout/trainval_NoPersonClean.txt"% USERNAME,
    "/home/%s/Datasets/OtherBackGround_Images/background_list.txt"% USERNAME]

    train_list_bdpd916 = train_list_bdpd169

    root_dir_train_bdpd = ["/home/%s/Datasets/AIC_REMOCapture" % USERNAME,
                           "/home/%s/Datasets/RemoCoco" % USERNAME,
                           "/home/%s/Datasets/OtherBackGround_Images" % USERNAME]
val_list_bdpd = '/home/%s/Datasets/COCO_ori/Layout/COCO2017_CATDOG_VAL.txt' % USERNAME
root_dir_val_bdpd = '/home/%s/Datasets/COCO_ori' % USERNAME

#######Part and Minihand Detection Data######
train_list_minihand = ["/home/%s/Datasets/AIC_REMOCapture/trainval_AIC_remocap2018053008070827.txt"% USERNAME,
    "/home/%s/Datasets/RemoCoco/Layout/trainval_NoPersonClean.txt"% USERNAME,
    "/home/%s/Datasets/OtherBackGround_Images/background_list.txt"% USERNAME]
if flag_miniresizeddata:
    train_root_minihand = ["/home/%s/Datasets/AIC_REMOCapture_resized"% USERNAME,
         "/home/%s/Datasets/RemoCoco_resized"% USERNAME,
         "/home/%s/Datasets/OtherBackGround_Images_resized"% USERNAME]
else:
    train_root_minihand = ["/home/%s/Datasets/AIC_REMOCapture" % USERNAME,
                           "/home/%s/Datasets/RemoCoco" % USERNAME,
                           "/home/%s/Datasets/OtherBackGround_Images" % USERNAME]
val_list_minihand = '/home/%s/Datasets/AIC_Data/Layout/val_PersonWithFaceHeadHand_V0_V0_cont1_V0_cont2_V0_cont3.txt' % USERNAME
val_root_minihand = '/home/%s/Datasets/AIC_Data' % USERNAME
######Pose Estimation Data
root_dir_pose = '/home/%s/PoseDatasets/'%USERNAME
train_lists_pose = "/home/%s/PoseDatasets/Layout/trainval_Google20180817Coco.txt"% USERNAME
#train_lists_pose = "/home/%s/PoseDatasets/Layout/train85.txt"% USERNAME
val_lists_pose = "/home/%s/PoseDatasets/Layout/val15.txt"% USERNAME

########################################################
###############Body and Part Information#######################
########################################################

#### start of default dis_param ####################
# 'dis_param': {
#             'brightness_prob': 0.2,
#             'brightness_delta': 20,
#             'contrast_prob': 0.2,
#             'contrast_lower': 0.5,
#             'contrast_upper': 1.5,
#             'hue_prob': 0.2,
#             'hue_delta': 18,
#             'saturation_prob': 0.2,
#             'saturation_lower': 0.5,
#             'saturation_upper': 1.5,
#             'random_order_prob': 0,
#             },
#### end of default dis_param ####################
def get_unifiedTransParam(train=True,flag_169=True):
    if flag_169:
        sample_sixteennine=True
        sample_ninesixteen=False
        resized_width = 512
        resized_height = 288

    else:
        sample_sixteennine = False
        sample_ninesixteen = True
        resized_width = 288
        resized_height = 512
    if train:
        param_dic = {
                # 'bboxsample_classid':bboxsample_classid,
                'emit_coverage_thre_multiple': [1.0, 0.75, 0.5,0.25], #
                'sample_sixteennine':sample_sixteennine,
                'sample_ninesixteen':sample_ninesixteen,
                'emit_coverage_thre':0.25,
                'emit_area_check':[0.02, 0.1,0.3, 1.0],    # default is [1.0,]
                'flip_prob': 0.5,
                'for_body':for_body,
                'resized_width': resized_width,
                'resized_height': resized_height,
                'visualize': False,
                'save_dir': save_path,
                'dis_param': {
                            'brightness_prob': dist_prob,
                            'brightness_delta': brightness_delta,
                            'contrast_prob': dist_prob,
                            'contrast_lower': contrast_lower,
                            'contrast_upper': contrast_upper,
                            'hue_prob': dist_prob,
                            'hue_delta': hue_delta,
                            'saturation_prob': dist_prob,
                            'saturation_lower': saturation_lower,
                            'saturation_upper': saturation_upper,
                            'random_order_prob': 0,
                            },
                'batch_sampler': [
                {
                'max_sample': 1,
                'max_trials': 50,
                'sampler': {
                    'min_scale': min_scale[0],
                    'max_scale': max_scale[0],
                    'min_aspect_ratio':0.5, # is not used when flag_sample_sixteennine is true
                    'max_aspect_ratio':2.0, # is not used when flag_sample_sixteennine is true
                    },
                'sample_constraint': {
                    'min_object_coverage': 0.9,
                    }
                },
                {
                'max_sample': 1,
                'max_trials': 50,
                'sampler': {
                    'min_scale': min_scale[1],
                    'max_scale': max_scale[1],
                    'min_aspect_ratio': 0.98,  # is not used when flag_sample_sixteennine is true
                    'max_aspect_ratio': 1.0,  # is not used when flag_sample_sixteennine is true
                    },
                'sample_constraint': {
                    'min_object_coverage': 0.7,
                    }
                },
                {
                'max_sample': 1,
                'max_trials': 50,
                'sampler': {
                    'min_scale': min_scale[2],
                    'max_scale': max_scale[2],
                    'min_aspect_ratio': 0.98,  # is not used when flag_sample_sixteennine is true
                    'max_aspect_ratio': 1.0,  # is not used when flag_sample_sixteennine is true
                    },
                'sample_constraint': {
                    'min_object_coverage': 0.5,
                    }
                },
                {
                'max_sample': 1,
                'max_trials': 50,
                'sampler': {
                    'min_scale': min_scale[3],
                    'max_scale': max_scale[3],
                    'min_aspect_ratio': 0.98,  # is not used when flag_sample_sixteennine is true
                    'max_aspect_ratio': 1.0,  # is not used when flag_sample_sixteennine is true
                    },
                'sample_constraint': {
                    'min_object_coverage': 0.3,
                    }
                }
            ]
        }
        return param_dic
    else:
        return {
                'sample_sixteennine':sample_sixteennine,
                'sample_ninesixteen':sample_ninesixteen,
                'resized_width': resized_width,
                'resized_height': resized_height,
                'visualize': False,
                'save_dir': save_path,
        }

def get_unified_data_param(train=True,batchsize=1,id_val=0,flag_169=False):
    if flag_169:
        train_list = train_list_bdpd169
    else:
        train_list = train_list_bdpd916
    if train:
        if isinstance(train_list,list):
            return {
                'xml_list_multiple': train_list,
                'xml_root_multiple': root_dir_train_bdpd,
                'shuffle': True,
                'rand_skip': 500,
                'batch_size': batchsize,
                'mean_value': [104, 117, 123],
                'add_parts': True,
                'base_bindex':base_bindex
            }
        else:
            return {
                'xml_list': train_list,
                'xml_root': root_dir_train_bdpd,
                'shuffle': True,
                'rand_skip': 500,
                'batch_size': batchsize,
                'mean_value': [104, 117, 123],
                'add_parts': True,
                'base_bindex': base_bindex
            }
    else:
        if isinstance(val_list_bdpd, list):
            return {
                'xml_list': val_list_bdpd[id_val],
                'xml_root': root_dir_val_bdpd[id_val],
                'shuffle': True,
                'rand_skip': 1,
                'batch_size': 1,
                'mean_value': [104, 117, 123],
                'add_parts': True,
                'base_bindex': base_bindex
            }
        else:
            return {
                'xml_list': val_list_bdpd,
                'xml_root': root_dir_val_bdpd,
                'shuffle': True,
                'rand_skip': 1,
                'batch_size': 1,
                'mean_value': [104, 117, 123],
                'add_parts': True,
                'base_bindex': base_bindex
            }

def get_DAPDataLayer(net, train=True, batchsize=1,id_val=0,data_name = "data",label_name = "label",flag_169=True):
    if train:
        unifiedDataParam = get_unified_data_param(train=train, batchsize=batchsize,flag_169=flag_169)
    else:
        unifiedDataParam = get_unified_data_param(train=train, batchsize=batchsize, id_val=id_val,flag_169=flag_169)
    if train:
        kwargs = {
            'include': dict(phase=caffe_pb2.Phase.Value('TRAIN')),
            }
        unifiedTransParam=get_unifiedTransParam(train=True,flag_169=flag_169)
    else:
        kwargs = {
            'include': dict(phase=caffe_pb2.Phase.Value('TEST')),
            }
        unifiedTransParam=get_unifiedTransParam(train=False,flag_169=flag_169)
    net[data_name], net[label_name] = L.BBoxData(name=data_name, unified_data_param=unifiedDataParam, unified_data_transform_param=unifiedTransParam, ntop=2, **kwargs)
    return net

#######################################################
###############Minihand InFormation############################
########################################################
# List

def get_MinihandTransParam(train=True,flag_169=True):
    if flag_169:
        sample_sixteennine=True
        sample_ninesixteen=False
        resized_width = 512
        resized_height = 288

    else:
        sample_sixteennine = False
        sample_ninesixteen = True
        resized_width = 288
        resized_height = 512
    if train:
        return {
            'do_flip': True,
            'flip_prob': 0.5,
            'resized_width': resized_width,
            'resized_height': resized_height,
            'save': False,
            'save_path': save_path,
            'cov_limits': [0.3, 0.5, 0.7, 0.9],
            'dis_param': {
                'brightness_prob': dist_prob,
                'brightness_delta': brightness_delta,
                'contrast_prob': dist_prob,
                'contrast_lower': contrast_lower,
                'contrast_upper': contrast_upper,
                'hue_prob': dist_prob,
                'hue_delta': hue_delta,
                'saturation_prob': dist_prob,
                'saturation_lower': saturation_lower,
                'saturation_upper': saturation_upper,
                'random_order_prob': 0,
            },
            'flag_eqhist':flag_eqhist,
            'sample_sixteennine':sample_sixteennine,
            'sample_ninesixteen':sample_ninesixteen
        }
    else:
        return {
            'do_flip': False,
            'resized_width': resized_width,
            'resized_height': resized_height,
            'save': False,
            'save_path': save_path,
            'flag_eqhist': flag_eqhist
        }

def get_MinihandDataParam(train=True):
    if train:
        return {
            'xml_list_multiple': train_list_minihand,
            'xml_root_multiple': train_root_minihand,
            'shuffle': True,
            'rand_skip': 500,
            'batch_size': batch_size,
            'mean_value': [104,117,123],
        }
    else:
        return {
            'xml_list': val_list_minihand,
            'xml_root': val_root_minihand,
            'shuffle': False,
            'rand_skip': 1,
            'batch_size': 1,
            'mean_value': [104,117,123],
        }

def get_MinihandDataLayer(net, train=True,data_name = "data",label_name = "label",flag_169=True):
    data_param = get_MinihandDataParam(train=train)
    if train:
        kwargs = {
            'include': dict(phase=caffe_pb2.Phase.Value('TRAIN')),
            }
        trans_param = get_MinihandTransParam(train=True,flag_169=flag_169)
    else:
        kwargs = {
            'include': dict(phase=caffe_pb2.Phase.Value('TEST')),
            }
        trans_param = get_MinihandTransParam(train=False,flag_169=flag_169)
    net[data_name], net[label_name] = L.MinihandData(name=data_name, minihand_data_param=data_param, minihand_transform_param=trans_param, ntop=2, **kwargs)
    return net
#######################################################
###############Pose InFormation############################
########################################################

# if use trainval
use_trainval = False
# if use color_distortion
use_distorted = True
crop_using_resize = False
scale_max = 1.1
pose_stride = 8
def get_poseDataParam(train=True, batch_size=1):
    if train:
        xml_list = train_lists_pose
        shuffle = True
        rand_skip = 1000
        batch_size_real = batch_size_pose
        out_kps = False
    else:
        xml_list = val_lists_pose
        shuffle = False
        rand_skip = 0
        batch_size_real = 1
        out_kps = True
    return {
        'xml_list': xml_list,
        'xml_root': root_dir_pose,
        'shuffle': shuffle,
        'rand_skip': rand_skip,
        'batch_size': batch_size_real,
        'out_kps': out_kps,
    }

def get_poseDataTransParam(train = True):
    if pose_img_w == 368:
        resized_width = 384
        resized_height = 384
    else:
        resized_width = pose_img_w
        resized_height = pose_img_h
    if use_distorted and train:
        return {
            'mirror': True if train else False,
            'stride': pose_stride,
            'max_rotate_degree': 40,
            'visualize': False,
            'crop_using_resize': crop_using_resize,
            'crop_size_x': pose_img_w,
            'crop_size_y': pose_img_h,
            'scale_prob': 1.0,
            'scale_min': 0.5,
            'scale_max': scale_max,
            'target_dist': 0.6,
            'center_perterb_max': 40,
            'sigma': 7,
            'transform_body_joint': True,
            'mode': 5,
            'save_dir': '%stemp/visual/' % root_dir_pose,
            'root_dir': root_dir_pose,
            'resized_width': resized_width,
            'resized_height': resized_height,
            'dis_param': {
                # brightness
                'brightness_prob': 0.5,
                'brightness_delta': 18,
                # contrast
                'contrast_prob': 0.5,
                'contrast_lower': 0.7,
                'contrast_upper': 1.3,
                # hue
                'hue_prob': 0.5,
                'hue_delta': 18,
                # sat
                'saturation_prob': 0.5,
                'saturation_lower': 0.7,
                'saturation_upper': 1.3,
                # random swap the channels
                'random_order_prob': 0,
            },
            # if True -> (x-128)/256 or False -> x - mean_value[c], default is True
            'normalize': False,
            'mean_value': [104,117,123],
        }
    else:
        return {
            'mirror': True if train else False,
            'stride': pose_stride,
            'max_rotate_degree': 40,
            'visualize': False,
            'crop_using_resize': crop_using_resize,
            'crop_size_x': pose_img_w,
            'crop_size_y': pose_img_h,
            'scale_prob': 1.0,
            'scale_min': 0.5,
            'scale_max': scale_max,
            'target_dist': 0.6,
            'center_perterb_max': 40,
            'sigma': 7,
            'transform_body_joint': True,
            'mode': 5,
            'save_dir': '%stemp/visual/' % root_dir_pose,
            'root_dir': root_dir_pose,
            'resized_width': resized_width,
            'resized_height': resized_height,
            # if True -> (x-128)/256 or False -> x - mean_value[c], default is True
            'normalize': False,
            'mean_value': [104,117,123],
        }

def get_poseDataLayer(net, train=True, batch_size=1,data_name = "data",label_name = "label"):
    if train:
        kwargs = {
            'include': dict(phase=caffe_pb2.Phase.Value('TRAIN')),
            'pose_data_transform_param': get_poseDataTransParam(train=train),
            }
        posedata_kwargs = get_poseDataParam(train=train, batch_size=batch_size)
    else:
        kwargs = {
            'include': dict(phase=caffe_pb2.Phase.Value('TEST')),
            'pose_data_transform_param': get_poseDataTransParam(train=train),
            }
        posedata_kwargs = get_poseDataParam(train=train, batch_size=batch_size)
    net[data_name], net[label_name] = L.PoseData(name=data_name, pose_data_param=posedata_kwargs, \
                                     ntop=2, **kwargs)
    return net


from os import write
import requests as r
import datetime as dt
import csv
from PIL import Image
from IPython.display import display
from urllib.parse import quote

from requests.sessions import dispatch_hook

url = 'https://api.covid19api.com/dayone/country/brazil'
response = r.get(url)

raw_data = response.json()
final_data = []

for line in raw_data:
    final_data.append([line['Confirmed'], line['Deaths'], line['Recovered'], line['Active'], line['Date']])

final_data.insert(0,['Confirmados', 'Obitos', 'Recuperados', 'Ativos', 'Data'])

CONFIRMADOS = 0
OBITOS = 1
RECUPERADOS = 2
ATIVOS = 3
DATA = 4

for i in range(1, len(final_data)):
    final_data[i][DATA] = final_data[i][DATA][:10]

with open('brasil-covid-projeto.csv', 'w', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerows(final_data)

for i in range(1, len(final_data)):
    final_data[i][DATA] = dt.datetime.strptime(final_data[i][DATA], "%Y-%m-%d")

def get_datasets(y, labels):
    if type(y[0]) == list:
        datasets = []
        for i in range(len(y)):
            datasets.append({
                'label': labels[i],
                'data': y[i]
            })
        return datasets
    else:
        return [
            {
                'label': labels[0],
                'data': y
            }
        ]

def set_title(title=''):
    if title != '':
        display = 'true'
    else:
        display = 'false'
    return {
        'title': title,
        'display': display
    }

def create_chart(x, y, labels, kind='bar', title=''):
    datasets = get_datasets(y, labels)
    options = set_title(title)

    chart = {
        'type': kind,
        'data': {
            'labels': x,
            'datasets': datasets
        },
        'options': options
    }

    return chart

def get_api_chart(chart):
    url_base = 'https://quickcharts.io/charts'
    resp = r.get(f'{url_base}?c={str(chart)}')
    return resp.content

def save_image(path, content):
    with open(path, 'wb') as image:
        image.write(content)

def display_image(path):
    img_pil = Image.open(path)
    display(img_pil)

def get_api_qrcode(link):
    text = quote(link) #parse de link para url
    url_base = 'https://quickchart.io/qr'
    resp = r.get(f'{url_base}?text={text}')
    return resp.content

y_data_1 = []
y_data_2 = []
y_data_3 = []
x = []

for obs in final_data[1::30]:
    y_data_1.append(obs[CONFIRMADOS])
    y_data_2.append(obs[RECUPERADOS])
    x.append(obs[DATA].strftime('%d/%m/%Y'))

labels = ['Confirmados', 'Recuperados']

#cria json de dados para gerar o grafico
chart = create_chart(x, [y_data_1, y_data_2], labels, title='Gráfico Covid (CONFIRMADOS, RECUPERADOS)')

#retorna grafico da api
chart_content = get_api_chart(chart)
print(chart_content)

#salva imagem no diretorio
#save_image('meu-primeio-grafico.png', chart_content)

#mostra imagem
#display_image('meu-primeiro-grafico.png')


"""
Custom halite bot by ABaucom

This bot will use general path planning and swarm tactics to play

Key points
- Use A* planning for all path routes
- Centralized swarm processing (make decisions as a group)
- For first pass, just try to find optimal distribution of ships to take over planets fastest
    - Assume no enemies for now and worry about enemy-based strategies later

Better strategy
- Each ship has a number of actions it can take: divide, fortify, attack, defend, conquer
    - Divide will send the ship to the closest unocupied planet, will superceed another ship 'dividing' to that planet if it is closer (need to be careful of looping here) - also need a flag for sending multiple ships to planets
    - Foritfy will send the ship to the closest planet we own.
    - Attack will send ships to attack enemies on other planets (aim maybe for weakest enemy on closest planet)
    - Defend will attack enemies in flight
    - Conquer will aim to destroy entire planets by crashing ships into them
- What action to take is determined by some higher level probabalistic process (i.e. NN or game logic)
    -Look at a few global game parameters and then a subset of local entities to choose action
- Once an action is chosen, there is a small probability that this action will be abandoned or if there is a significant change in the game state
- Three tierd approach
    - Strategist looks at game state and determines what percentage of fleet should do which actions
    - Swarm master assigns actions to ships and helps determine best ship for each action
    - Ships carry out actions and communicate with swarm master regarding suitability for action

More better-er stategy
- Keep processing more centralized for assigning ships - use more efficient distance and prioirty queue
- write A* pathfinding module, include ability to change obstacle types (planets and ships)
- Stick with basic probabilty to choose fortify vs diversify tactics, but make sure bots don't keep flipping back and forth
- Dont worry about planet destruction for now, focus on getting solid, extensible foundation that can capture planets and attack enemies
- Maybe try targetting specific strategic planets
"""

import hlt
import logging
import time
from enum import Enum
import random

class ActionType(Enum):
    DIVIDE = 0
    FORTIFY = 1
    ATTACK = 2
    DEFEND = 3
    CONQUER = 4
    EVADE = 5

def get_weakest_ship(ship_list):

    weakest_ship = []
    lowest_health = 10000000
    for ship in ship_list:
        if ship.health < lowest_health:
            weakest_ship = ship
            lowest_health = ship.health
    return weakest_ship

class ActionShip:

    def __init__(self, ship, default_action=ActionType.DIVIDE):
        self.ship = ship
        self.action = default_action
        self.is_action_set = False

    def get_id(self):
        return self.ship.id

    def set_action(self, action):
        self.action = action
        self.is_action_set = True
        logging.info(str(self.ship.id)+": setting action to "+str(action))

    def do_action(self, game_map):

        if self.action == ActionType.DIVIDE:
            cmd = self.do_divide_action(game_map)
        elif self.action == ActionType.FORTIFY:
            cmd = self.do_fortify_action(game_map)
        elif self.action == ActionType.ATTACK:
            cmd = self.do_attack_action(game_map)
        elif self.action == ActionType.DEFEND:
            cmd = self.do_defend_action(game_map)
        elif self.action == ActionType.CONQUER:
            cmd = self.do_conquer_action(game_map)
        else:
            logging.warning("Invalid ActionType")
            cmd = ''

        return cmd

    def do_divide_action(self, game_map):
        logging.info("Ship "+str(self.get_id()) + " doing action DIVIDE")
        closest_free_planet = self.find_closest_planet(game_map, planet_status='free')
        if closest_free_planet:
            return self.navigate_then_dock(game_map, closest_free_planet)
        else:
            return ''

    def do_fortify_action(self, game_map):
        logging.info("Ship "+str(self.get_id()) + " doing action FORTIFY")
        closest_owned_planet = self.find_closest_planet(game_map, planet_status='mine')
        if closest_owned_planet:
            return self.navigate_then_dock(game_map, closest_owned_planet)
        else:
            return ''
        pass

    def do_attack_action(self, game_map):
        logging.info("Ship "+str(self.get_id()) + " doing action ATTACK")
        closest_enemy_planet = self.find_closest_planet(game_map, planet_status='enemy')
        if closest_enemy_planet:
            weakest_ship = get_weakest_ship(closest_enemy_planet.all_docked_ships())
        else:
            return ''
        if weakest_ship:
            return self.basic_navigation(game_map,weakest_ship,ignore_mode='ships')
        else:
            return ''

    def do_defend_action(self, game_map):
        logging.info("Ship "+str(self.get_id()) + " doing action DEFEND")
        closest_enemy_ship = self.find_closest_enemy_ship(game_map)
        if closest_enemy_ship:
            if self.ship.calculate_distance_between(closest_enemy_ship) < 20:
                return self.basic_navigation(game_map,closest_enemy_ship,ignore_mode='ships')
            else:
                return self.basic_navigation(game_map,closest_enemy_ship,ignore_mode='none')

    def do_conquer_action(self, game_map):
        logging.info("Ship "+str(self.get_id()) + " doing action CONQUER")
        closest_enemy_planet = self.find_closest_planet(game_map, planet_status='enemy')
        if closest_enemy_planet:
            return self.basic_navigation(game_map,closest_enemy_planet,ignore_mode='planets')
        else:
            return ''

    def basic_navigation(self, game_map, destination,ignore_mode='none'):
        if ignore_mode == 'none':
            nav_cmd = self.ship.navigate(
                    self.ship.closest_point_to(destination),
                    game_map,
                    speed=int(hlt.constants.MAX_SPEED))
        elif ignore_mode == 'ships':
            nav_cmd = self.ship.navigate(
                    self.ship.closest_point_to(destination),
                    game_map,
                    speed=int(hlt.constants.MAX_SPEED),
                    ignore_ships=True)
        elif ignore_mode == 'planets':
            nav_cmd = self.ship.navigate(
                    destination,
                    game_map,
                    speed=int(hlt.constants.MAX_SPEED),
                    ignore_planets=True)
        elif ignore_mode == 'all':
            nav_cmd = self.ship.navigate(
                    destination,
                    game_map,
                    speed=int(hlt.constants.MAX_SPEED),
                    avoid_obstacles=False)
        else:
            logging.warning("Invalid ignore_mode set for basic_navigation")
            nav_cmd = ''

        if nav_cmd:
            return nav_cmd
        else:
            return ''

    def navigate_then_dock(self, game_map, planet):
        if self.ship.can_dock(planet):
            logging.info(str(self.ship.id)+": Docking!")
            return self.ship.dock(planet)
        else:
            return self.basic_navigation(game_map,planet)

    @staticmethod
    def is_planet_suitable(game_map, planet, planet_status, ignore_list=set()):

        if planet.is_owned():
            if planet_status == 'free':
                return False
            else:
                if planet.owner == game_map.get_me() and (planet_status == 'enemy' or planet.is_full()):
                    return False
                if planet.owner != game_map.get_me() and planet_status == 'mine':
                    return False

        if planet in ignore_list:
            return False

        return True

    def find_closest_planet(self, game_map, planet_status='free'):

        # For each planet in the game (only non-destroyed planets are included)
        best_planet = []
        min_dist = 1000000
        for planet in game_map.all_planets():

            if not self.is_planet_suitable(game_map, planet, planet_status):
                continue

            # find distance to planet
            dist = self.ship.calculate_distance_between(planet)
            if dist < min_dist:
                min_dist = dist
                best_planet = planet

        #only update list if we get a valid planet
        if not best_planet:
            return []
        else:
            return best_planet

    def find_closest_enemy_ship(self, game_map):

        # For each enemy ship
        best_ship = []
        min_dist = 1000000
        for player in game_map.all_players():
            if player == game_map.get_me():
                continue

            for enemy_ship in player.all_ships():
                # find distance to ship
                dist = self.ship.calculate_distance_between(enemy_ship)
                if dist < min_dist:
                    min_dist = dist
                    best_ship = enemy_ship

        #only update list if we get a valid planet
        if not best_ship:
            return []
        else:
            return best_ship

class SwarmMaster:

    DIVIDE_PROB = 0.7
    ATTACK_PROB = 0.7

    def __init__(self):
        logging.info("Starting Swarm Master")
        self.planets_being_explored = []
        self.active_ship_list = []

    def update_ship_list(self, game_map):

        #first check to see if any of my ships have docked or been destroyed
        my_ship_ids = [ship.id for ship in game_map.get_me().all_ships()]
        logging.info("All ship ids: "+str(my_ship_ids))
        #for actionShip in self.active_ship_list:
            #if actionShip.ship.docking_status != hlt.entity.Ship.DockingStatus.UNDOCKED or actionShip.get_id() not in my_ship_ids:
                #self.active_ship_list.remove(actionShip)

        #next, figure out if there are any new ships to add to the active list
        active_ship_ids = [actionShip.get_id() for actionShip in self.active_ship_list]
        logging.info("Active ship ids: "+str(active_ship_ids))
        for ship in game_map.get_me().all_ships():
            if ship.docking_status == hlt.entity.Ship.DockingStatus.UNDOCKED and not ship.id in active_ship_ids:
                self.active_ship_list.append(ActionShip(ship))

    def set_ship_action(self, actionShip):
        if random.random() < self.DIVIDE_PROB:
            actionShip.set_action(ActionType.DIVIDE)
        else:
            actionShip.set_action(ActionType.FORTIFY)

    def set_ship_offensive_action(self, actionShip):
        if random.random() < self.ATTACK_PROB:
            actionShip.set_action(ActionType.ATTACK)
        else:
            actionShip.set_action(ActionType.DEFEND)

    def update_swarm(self, game_map, turn_count, turn_time):

        logging.info("Updating swarm")
        command_queue = []
        self.planets_being_explored = []
        self.update_ship_list(game_map)

        for actionShip in self.active_ship_list:

            #if we are getting close to time limit, break early
            if time.time() - turn_time > 1.75:
                logging.warning("Breaking from turn "+str(turn_count)+" early due to time limit!")
                break

            #set action if it isn't set already
            if not actionShip.is_action_set:
                self.set_ship_offensive_action(actionShip)

            cmd = actionShip.do_action(game_map)

            #if the set action doesn't work, then try offensive action
            if not cmd:
                self.set_ship_offensive_action(actionShip)
                cmd = actionShip.do_action(game_map)

            command_queue.append(cmd)

        return command_queue

class GameMaster:
    def __init__(self):

        #start up game process
        self.game = hlt.Game("BaucomBot")
        logging.info("Starting Game Master")

        #init game master
        self.turn_counter = 0
        self.turn_timer = time.time()

        #init swarm master
        self.swarm = SwarmMaster()

    def one_turn(self):

        self.turn_counter += 1
        self.turn_timer = time.time()
        logging.info("Starting Turn: " + str(self.turn_counter))

        commands = self.swarm.update_swarm(self.game.update_map(), self.turn_counter, self.turn_timer)
        if not commands:
            commands = ''
        self.game.send_command_queue(commands)
        logging.info("Commands: "+str(commands))
        logging.info("Ending Turn: "+str(self.turn_counter) + ", Elapsed time: " +str(time.time() - self.turn_timer))

if __name__ == "__main__":
    gm = GameMaster()
    while True:
        gm.one_turn()


from bottle import (
    route, run, template, request, redirect
)
import bottle
import string
import os
from scraputils import get_news
from db import News, session
from bayes import NaiveBayesClassifier

@route("/news")
def news_list():
    s = session()
    rows = s.query(News).filter(News.label == None).all()
    return template("news_template", rows=rows)

@route("/add_label/")
def add_label():
    s = session()
    news = s.query(News).filter(News.id == request.query.id).one()
    news.label = request.query.label
    s.commit()
    redirect("/news")

@route("/update")
def update_news():
    s = session()
    news_list = get_news("https://news.ycombinator.com/newest", n_pages=5)
    news_list_bd = s.query(News).all()
    if len(news_list_bd) > 0:
        for new_news in news_list:
            f = False
            for old_news_bd in news_list_bd:
                if new_news['author'] == old_news_bd.author and new_news['title'] == old_news_bd.title:
                    f = True
                    break
            if not f:
                s.add(News(**new_news))

    else:
        for new_news in news_list:
            s.add(News(**new_news))
    s.commit()
    redirect("/news")

@route("/classify")
def classify_news():
    s = session()
    labeled_news = s.query(News).filter(News.label != None).all()
    x_train = [clean(news.title) for news in labeled_news]
    y_train = [news.label for news in labeled_news]
    classifier.fit(x_train, y_train)

    rows = s.query(News).filter(News.label == None).all()
    good, maybe, never = [], [], []
    for row in rows:
        prediction = classifier.predict(clean(row.title))
        if prediction == 'good':
            good.append(row)
        elif prediction == 'maybe':
            maybe.append(row)
        else:
            never.append(row)

    return template('news_recommendations', good=good, maybe=maybe, never=never)

def clean(s):
    translator = str.maketrans("", "", string.punctuation)
    return s.translate(translator).lower()

if __name__ == "__main__":
    abs_app_dir_path = os.path.dirname(os.path.realpath(__file__))
    abs_views_path = os.path.join(abs_app_dir_path, 'templates')
    bottle.TEMPLATE_PATH.insert(0, abs_views_path)
    classifier = NaiveBayesClassifier()
    run(host="localhost", port=8080)


# -*- encoding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools.float_utils import float_round

from datetime import datetime
import base64
from lxml import etree
import requests
import re

#from import XMLSigner

import logging

class AccountInvoice(models.Model):
    _inherit = "account.invoice"

    pdf_fel = fields.Char('PDF FEL', copy=False)

    def invoice_validate(self):
        for factura in self:
            if factura.journal_id.usuario_fel and factura.requiere_certificacion():

                if factura.error_pre_validacion():
                    return

                dte = factura.dte_documento()
                logging.warn(dte)
                xmls = etree.tostring(dte, encoding="UTF-8")
                # xmls = xmls.decode("utf-8").replace("&", "&").encode("utf-8")
                xmls_base64 = base64.b64encode(xmls)
                logging.warn(xmls)

                headers = { "Content-Type": "application/json" }
                data = {
                    "llave": factura.journal_id.token_firma_fel,
                    "archivo": xmls_base64.decode("utf-8"),
                    "codigo": factura.company_id.vat.replace('-',''),
                    "alias": factura.journal_id.usuario_fel,
                }
                r = requests.post('https://signer-emisores.feel.com.gt/sign_solicitud_firmas/firma_xml', json=data, headers=headers)
                logging.warn(r.text)
                firma_json = r.json()
                if firma_json["resultado"]:

                    headers = {
                        "USUARIO": factura.journal_id.usuario_fel,
                        "LLAVE": factura.journal_id.clave_fel,
                        "IDENTIFICADOR": factura.journal_id.code+str(factura.id),
                        "Content-Type": "application/json",
                    }
                    data = {
                        "nit_emisor": factura.company_id.vat.replace('-',''),
                        "correo_copia": factura.company_id.email,
                        "xml_dte": firma_json["archivo"]
                    }
                    r = requests.post("https://certificador.feel.com.gt/fel/certificacion/v2/dte/", json=data, headers=headers)
                    logging.warn(r.json())
                    certificacion_json = r.json()
                    if certificacion_json["resultado"]:
                        factura.firma_fel = certificacion_json["uuid"]
                        factura.name = str(certificacion_json["serie"])+"-"+str(certificacion_json["numero"])
                        factura.serie_fel = certificacion_json["serie"]
                        factura.numero_fel = certificacion_json["numero"]
                        factura.documento_xml_fel = xmls_base64
                        factura.resultado_xml_fel = certificacion_json["xml_certificado"]
                        factura.pdf_fel = "https://report.feel.com.gt/ingfacereport/ingfacereport_documento?uuid="+certificacion_json["uuid"]
                    else:
                        factura.error_certificador(str(certificacion_json["descripcion_errores"]))
                        return

                else:
                    factura.error_certificador(r.text)
                    return

                return super(AccountInvoice, self).invoice_validate()

            else:
                return super(AccountInvoice, self).invoice_validate()

    def action_cancel(self):
        result = super(AccountInvoice, self).action_cancel()
        if result:
            for factura in self:
                if factura.journal_id.usuario_fel and factura.requiere_certificacion():
                    dte = factura.dte_anulacion()
                    xmls = etree.tostring(dte, encoding="UTF-8")
                    # xmls = xmls.decode("utf-8").replace("&", "&").encode("utf-8")
                    xmls_base64 = base64.b64encode(xmls)
                    logging.warn(xmls)

                    headers = { "Content-Type": "application/json" }
                    data = {
                        "llave": factura.journal_id.token_firma_fel,
                        "archivo": xmls_base64.decode("utf-8"),
                        "codigo": factura.company_id.vat.replace('-',''),
                        "alias": factura.journal_id.usuario_fel,
                        "es_anulacion": "S",
                    }
                    r = requests.post('https://signer-emisores.feel.com.gt/sign_solicitud_firmas/firma_xml', json=data, headers=headers)
                    logging.warn(r.text)
                    firma_json = r.json()
                    if firma_json["resultado"]:

                        headers = {
                            "USUARIO": factura.journal_id.usuario_fel,
                            "LLAVE": factura.journal_id.clave_fel,
                            "IDENTIFICADOR": factura.journal_id.code+str(factura.id),
                            "Content-Type": "application/json",
                        }
                        data = {
                            "nit_emisor": factura.company_id.vat.replace('-',''),
                            "correo_copia": factura.company_id.email,
                            "xml_dte": firma_json["archivo"]
                        }
                        r = requests.post("https://certificador.feel.com.gt/fel/anulacion/v2/dte/", json=data, headers=headers)
                        logging.warn(r.text)
                        certificacion_json = r.json()
                        if not certificacion_json["resultado"]:
                            raise UserError(str(certificacion_json["descripcion_errores"]))

                    else:
                        raise UserError(r.text)

class AccountJournal(models.Model):
    _inherit = "account.journal"

    usuario_fel = fields.Char('Usuario FEL', copy=False)
    clave_fel = fields.Char('Clave FEL', copy=False)
    token_firma_fel = fields.Char('Token Firma FEL', copy=False)


# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
=============
TAP plus
=============

"""
import requests

from astroquery.utils.tap.core import TapPlus
from astroquery.utils.tap.model.job import Job

__all__ = ['TapPlusNavo']

VERSION = "1.0.1"
TAP_CLIENT_ID = "aqtappy-" + VERSION

class TapPlusNavo(TapPlus):
    """TAP plus class
    Provides TAP and TAP+ capabilities

    Notes
    -----------------
    To override some parts of the utils/tap library in order for it to
    work around the autostart issue.
    """

    def __init__(self, url=None, host=None, server_context=None,
                 tap_context=None, port=80, sslport=443,
                 default_protocol_is_https=False, connhandler=None,
                 agent=None, verbose=False):
        """

        Parameters
        ----------
        url : str, mandatory if no host is specified, default None
            TAP URL
        host : str, optional, default None
            host name
        server_context : str, optional, default None
            server context
        tap_context : str, optional, default None
            tap context
        port : int, optional, default '80'
            HTTP port
        sslport : int, optional, default '443'
            HTTPS port
        default_protocol_is_https : bool, optional, default False
            Specifies whether the default protocol to be used is HTTPS
        connhandler connection handler object, optional, default None
            HTTP(s) connection hander (creator). If no handler is provided, a
            new one is created.
        agent : User-Agent string, optional, default None
        verbose : bool, optional, default 'False'
            flag to display information about the process
        """

        super(TapPlusNavo, self).__init__(url, host, server_context,
                                          tap_context, port, sslport,
                                          default_protocol_is_https,
                                          connhandler, verbose)

        # Hack to set the User-Agent on TAP requests.
        if agent is not None:
            ch = self._Tap__connHandler
            self.set_header_agent(ch._TapConn__postHeaders, agent)
            self.set_header_agent(ch._TapConn__getHeaders, agent)

    def set_header_agent(self, header, agent):
        if header is not None:
            header.update({
                'User-Agent': agent
            })

    def _Tap__launchJob(self, query, outputFormat,
                        context, verbose, name=None):
        """

        Notes
        -----------------
        Get rid of PHASE:RUN in args and if async job send PHASE:RUN to
        async/phase in order to get the job to run
        """
        args = {
            "REQUEST": "doQuery",
            "LANG": "ADQL",
            "FORMAT": str(outputFormat),
            "tapclient": str(TAP_CLIENT_ID),
            "QUERY": str(query)}
        data = self._Tap__connHandler.url_encode(args)
        response = self._Tap__connHandler.execute_post(context, data)
        if verbose:
            print(response.status, response.reason)
            print(response.getheaders())
        if 'async' in context:
            location = self._Tap__connHandler.find_header(
                response.getheaders(),
                "location")
            jobid = self._Tap__getJobId(location)
            runresponse = self.__runAsyncQuery(jobid, verbose)
            return runresponse
        return response

    def __runAsyncQuery(self, jobid, verbose):
        """
        Notes
        ------------------
        This was added in order to run the job after it was created
        """
        if verbose:
            print(f'Running async query for job: {jobid}')
        args = {
            "PHASE": "RUN"}
        data = self._Tap__connHandler.url_encode(args)
        response = self._Tap__connHandler.execute_post('async/'+jobid+'/phase',
                                                       data)
        if verbose:
            print(response.status, response.reason)
            print(response.getheaders())
        return response

    def launch_job(self, query, name=None, output_file=None,
                   output_format="votable", verbose=False,
                   dump_to_file=False, upload_resource=None,
                   upload_table_name=None):
        """Launches a synchronous job

        Parameters
        ----------
        query : str, mandatory
            query to be executed
        output_file : str, optional, default None
            file name where the results are saved if dumpToFile is True.
            If this parameter is not provided, the jobid is used instead
        output_format : str, optional, default 'votable'
            results format
        verbose : bool, optional, default 'False'
            flag to display information about the process
        dump_to_file : bool, optional, default 'False'
            if True, the results are saved in a file instead of using memory
        upload_resource: str, optional, default None
            resource to be uploaded to UPLOAD_SCHEMA
        upload_table_name: str, required if uploadResource is provided, default None
            resource temporary table name associated to the uploaded resource

        Returns
        -------
        A Job object
        """
        # Do not limit these queries. query = taputils.set_top_in_query(query, 2000)
        if verbose:
            print("Launched sync query: '"+str(query)+"'")
        if upload_resource is not None:
            if upload_table_name is None:
                raise ValueError("Table name is required when a resource is uploaded")
            response = self._Tap__launchJobMultipart(
                query, upload_resource, upload_table_name,
                output_format, "sync", verbose, name)
        else:
            response = self._Tap__launchJob(query,
                                            output_format,
                                            "sync",
                                            verbose,
                                            name)
        # handle redirection
        if response.status == 303:
            # redirection
            if verbose:
                print("Redirection found")
            location = self._Tap__connHandler.find_header(
                response.getheaders(),
                "location")
            if location is None:
                raise requests.exceptions.HTTPError("No location found after redirection was received (303)")
            if verbose:
                print("Redirect to %s", location)
            subcontext = self._Tap__extract_sync_subcontext(location)
            response = self._Tap__connHandler.execute_get(subcontext)
        job = Job(async_job=False, query=query, connhandler=self._Tap__connHandler)
        isError = self._Tap__connHandler.check_launch_response_status(
            response, verbose, 200)
        suitableOutputFile = self._Tap__getSuitableOutputFile(
            False, output_file, response.getheaders(), isError,
            output_format)
        job.outputFile = suitableOutputFile
        job.parameters['format'] = output_format
        job.set_response_status(response.status, response.reason)
        if isError:
            job.set_failed(True)
            if dump_to_file:
                self._Tap__connHandler.dump_to_file(suitableOutputFile, response)
            raise requests.exceptions.HTTPError(response.reason)
        else:
            pass
        return job, response


from django.conf import settings
from django.contrib import admin
from django.utils.html import format_html

from ..models.Post import Post
from ..models.SourceType import SourceType

@admin.register(Post)
class AdminPost(admin.ModelAdmin):
    list_display = [
        'title',
        'product_url',
        'created_at',
        'updated_at',
        'post_type',
        'source_type',
        'source_url'
    ]
    list_filter = [
        'post_type',
        'source_type'
    ]
    readonly_fields = [
        'created_at',
        'updated_at'
    ]

    def product_url(self, obj):
        return format_html(
            '{1}',
            obj.product.id,
            obj.product
        )

    product_url.short_description = "Product"

    def source_url(self, obj):
        if obj.source_type == SourceType.YOUTUBE:
            return format_html(
                '{0}',
                obj.url
            )
        elif obj.source_type == SourceType.UPLOAD:
            return format_html(
                '{1}',
                settings.MEDIA_URL,
                obj.file
            )

    source_url.short_description = "URL"