"""This module contains retry logic for bucardo replication.

The adding and dropping of triggers in bucardo causes the potential for a
customer-facing outage due to lock contention.  The retry module allows bucardo
to attempt to get a lock, gracefully move on if it can't get one quickly
enough, and retry later.

Classes exported:
Retry: Add or remove bucardo triggers with graceful timeout and retry options.
"""
import psycopg2

from plugins import Plugin
from plugins.bucardo import Bucardo

class Retry(Plugin):
    """Add or remove bucardo triggers with graceful timeout and retry options.

    The user defines a timeout setting in the config.  If bucardo is unable to get a
    lock in that time, it will stop trying and move on.

    Methods exported:
    add_triggers: add as many triggers as possible within user-defined limits
    drop_triggers: drop as many triggers as possible within user-defined limits
    install: install dependencies for bucardo retry logic
    """

    def __init__(self, cfg):
        """Create aliases for configuration settings and instantiate Bucardo.

        In the interests of keeping lines shorter and more readable, some variables are
        assigned to config settings.

        A Bucardo class is instantiated so that its methods can be invoked as part of
        the methods of the Retry class.

        Keyword arguments:
        cfg: contents of the config file as a dictionary

        Variables exported:
        bucardo_instance: an instantiation of the Bucardo class
        cfg: a dictionary containing the config file
        primary_user: the owner of the primary database
        repl_name: an arbitrary name given by the user to the replication task
        timeout: number of milliseconds to wait for a lock before giving up
        """
        super(Retry, self).__init__(cfg)
        self.bucardo_instance = Bucardo(cfg)
        self.cfg = cfg
        self.primary_user = cfg['databases']['primary']['database_owner']
        self.repl_name = cfg['bucardo']['replication_name']
        self.timeout = cfg['retry']['timeout']

    def _check_for_syncs(self):
        """Check the bucardo database to see if a sync exists.  Return True or False."""
        query = 'SELECT * FROM bucardo.sync LIMIT 1'
        conn = psycopg2.connect(self.bucardo_conn_pg_format)
        try:
            with conn.cursor() as cur:
                cur.execute(query)
                syncs = cur.fetchone()
        finally:
            conn.close()
        if syncs:
            return True
        else:
            return False

    def _set_timeout(self, user, timeout_value):
        """Change the lock_timeout setting on the primary database.

        The lock_timeout setting will cause the query to fail if the lock cannot be
        obtained in the specified number of milliseconds.  By setting it for the user,
        we can ensure that when the bucardo command-line tool will have this setting
        when it connects.  This is only a problem for user traffic if the application
        connects as the database owner, which is already a serious security flaw, so
        this script counts on that not being the case.

        Keyword arguments:
        user -- the postgres user whose timeout value should be changed
        timeout_value -- the new timeout value (either DEFAULT or some number of milliseconds)
        """
        query = f'ALTER ROLE {user} SET lock_timeout = {timeout_value}'
        conn = psycopg2.connect(self.primary_conn_pg_format)
        try:
            with conn.cursor() as cur:
                cur.execute(query)
                conn.commit()
        finally:
            conn.close()

    def add_triggers(self):
        """Add replication triggers to tables on the primary database.

        The script updates the timeout value to whatever is in the config.

        Then it adds however many triggers it can without hitting the timeout limit,
        which applies on a per-trigger basis.

        Then it sets the timeout value back to the default.  If the user already had a
        non-default lock_timeout value, then this may cause the wrong value to be set.
        You are welcome to submit a PR in that case.
        """
        print('Adding triggers.')
        self._set_timeout(self.primary_user, self.timeout)

        # Which bucardo function to call depends on whether we just need to add
        # some triggers that timed out, or whether this is the first attempt at
        # adding them.
        sync_already_added = self._check_for_syncs()

        if sync_already_added:
            query = f"SELECT bucardo.validate_sync('{self.repl_name}', 0)"
            conn = psycopg2.connect(self.bucardo_conn_pg_format)
            try:
                with conn.cursor() as cur:
                    cur.execute(query)
                    for notice in conn.notices:
                        print(notice, end='')
            finally:
                conn.close()

            # Enable and disable triggers as needed.
            self.bucardo_instance._manage_triggers()

        else:
            self.bucardo_instance.add_triggers()

        self._set_timeout(self.primary_user, 'DEFAULT')

        print(
            'Attempted to add triggers. Check the output above for warnings about missing triggers. '
            'If you see any, just run add_triggers again. If there are no warnings, you should be good to go.'
        )

    def drop_triggers(self):
        """Drop triggers on replicated tables on the primary database.
        The script updates the timeout value to whatever is in the config.

        Then it drops however many triggers it can without hitting the timeout limit,
        which applies on a per-trigger basis.

        Then it sets the timeout value back to the default.  If the user already had a
        non-default lock_timeout value, then this may cause the wrong value to be set.
        You are welcome to submit a PR in that case.
        """
        print('Dropping triggers.')
        self._set_timeout(self.primary_user, self.timeout)
        self.bucardo_instance.drop_triggers()
        self._set_timeout(self.primary_user, 'DEFAULT')
        print(
            'Attempted to drop triggers. Check the output above for warnings about missing triggers. '
            'If you see any, just run try_drop again. If there are no warnings, you should be good to go.'
        )

    def install(self):
        """Install the dependencies for retry logic on the bucardo database.

        Strictly speaking, this function only installs one of two dependencies.  It
        loads a slightly modified copy of a bucardo function provided by the Bucardo
        project to the bucardo database.

        It does not install the Perl Try::Tiny module, which is used by the forked
        version of the function and is not installed with bucardo.  You must install
        Try::Tiny yourself.
        """
        print('Installing dependencies.')
        # Read in the definition of a SQL stored procedure.
        custom_logic_file = 'plugins/retry/custom_validate_sync.sql'
        with open(custom_logic_file, 'r') as file:
            query = file.read()

        # Load the stored procedure into bucardo, replacing the one provided by the Bucardo project.
        conn = psycopg2.connect(self.bucardo_conn_pg_format)
        try:
            with conn.cursor() as cur:
                cur.execute(query)
                conn.commit()
        finally:
            conn.close()
        print(
            'Dependencies installed, except for the Perl Try::Tiny module. '
            'Make sure that module is installed before proceeding.'
        )

    def uninstall(self):
        """Uninstall the dependencies for retry logic on the bucardo database.

        Strictly speaking, this function only uninstalls one of two dependencies.  It
        loads the original copy of a bucardo function provided by the Bucardo project
        to the bucardo database.

        It does not remove the Perl Try::Tiny module, which is used by the forked
        version of the function and is not installed with bucardo.  You must uninstall
        Try::Tiny yourself.
        """
        print('Uninstalling dependencies.')
        # Read in the definition of a SQL stored procedure.
        custom_logic_file = 'plugins/retry/original_validate_sync.sql'
        with open(custom_logic_file, 'r') as file:
            query = file.read()

        # Load the stored procedure into bucardo, replacing the modified one.
        conn = psycopg2.connect(self.bucardo_conn_pg_format)
        try:
            with conn.cursor() as cur:
                cur.execute(query)
                conn.commit()
        finally:
            conn.close()
        print(
            'Dependencies removed, except for the Perl Try::Tiny module. '
        )


import mock

from nova.network import model as network_model
from nova import test
from nova import utils
from nova.virt.vmwareapi import fake as vmwareapi_fake
from nova.virt.vmwareapi import vim_util
from nova.virt.vmwareapi import vmops

class fake_session(object):
    def __init__(self, ret=None):
        self.ret = ret

    def _get_vim(self):
        return vmwareapi_fake.FakeVim()

    def _call_method(self, module, method, *args, **kwargs):
        return self.ret

    def _wait_for_task(self, task_ref):
        return

class VMwareVMOpsTestCase(test.NoDBTestCase):
    def setUp(self):
        super(VMwareVMOpsTestCase, self).setUp()
        subnet_4 = network_model.Subnet(cidr='192.168.0.1/24',
                                        dns=[network_model.IP('192.168.0.1')],
                                        gateway=
                                            network_model.IP('192.168.0.1'),
                                        ips=[
                                            network_model.IP('192.168.0.100')],
                                        routes=None)
        subnet_6 = network_model.Subnet(cidr='dead:beef::1/64',
                                        dns=None,
                                        gateway=
                                            network_model.IP('dead:beef::1'),
                                        ips=[network_model.IP(
                                            'dead:beef::dcad:beff:feef:0')],
                                        routes=None)
        network = network_model.Network(id=0,
                                        bridge='fa0',
                                        label='fake',
                                        subnets=[subnet_4, subnet_6],
                                        vlan=None,
                                        bridge_interface=None,
                                        injected=True)
        self.network_info = network_model.NetworkInfo([
                network_model.VIF(id=None,
                                  address='DE:AD:BE:EF:00:00',
                                  network=network,
                                  type=None,
                                  devname=None,
                                  ovs_interfaceid=None,
                                  rxtx_cap=3)
                ])
        utils.reset_is_neutron()
        self._session = fake_session()

    def test_get_machine_id_str(self):
        result = vmops.VMwareVMOps._get_machine_id_str(self.network_info)
        self.assertEqual(result,
                         'DE:AD:BE:EF:00:00;192.168.0.100;255.255.255.0;'
                         '192.168.0.1;192.168.0.255;192.168.0.1#')

    def test_is_neutron_nova(self):
        self.flags(network_api_class='nova.network.api.API')
        ops = vmops.VMwareVMOps(None, None, None)
        self.assertFalse(ops._is_neutron)

    def test_is_neutron_neutron(self):
        self.flags(network_api_class='nova.network.neutronv2.api.API')
        ops = vmops.VMwareVMOps(None, None, None)
        self.assertTrue(ops._is_neutron)

    def test_is_neutron_quantum(self):
        self.flags(network_api_class='nova.network.quantumv2.api.API')
        ops = vmops.VMwareVMOps(None, None, None)
        self.assertTrue(ops._is_neutron)

    def test_use_linked_clone_override_nf(self):
        value = vmops.VMwareVMOps.decide_linked_clone(None, False)
        self.assertFalse(value, "No overrides present but still overridden!")

    def test_use_linked_clone_override_nt(self):
        value = vmops.VMwareVMOps.decide_linked_clone(None, True)
        self.assertTrue(value, "No overrides present but still overridden!")

    def test_use_linked_clone_override_ny(self):
        value = vmops.VMwareVMOps.decide_linked_clone(None, "yes")
        self.assertTrue(value, "No overrides present but still overridden!")

    def test_use_linked_clone_override_ft(self):
        value = vmops.VMwareVMOps.decide_linked_clone(False, True)
        self.assertFalse(value,
                        "image level metadata failed to override global")

    def test_use_linked_clone_override_nt(self):
        value = vmops.VMwareVMOps.decide_linked_clone("no", True)
        self.assertFalse(value,
                        "image level metadata failed to override global")

    def test_use_linked_clone_override_yf(self):
        value = vmops.VMwareVMOps.decide_linked_clone("yes", False)
        self.assertTrue(value,
                        "image level metadata failed to override global")

    def _test_get_datacenter_ref_and_name(self, ds_ref_exists=False):
        instance_ds_ref = mock.Mock()
        instance_ds_ref.value = "ds-1"
        _vcvmops = vmops.VMwareVCVMOps(self._session, None, None)
        if ds_ref_exists:
            ds_ref = mock.Mock()
            ds_ref.value = "ds-1"
        else:
            ds_ref = None

        def fake_call_method(module, method, *args, **kwargs):
            fake_object1 = vmwareapi_fake.FakeRetrieveResult()
            fake_object1.add_object(vmwareapi_fake.Datacenter(
                ds_ref=ds_ref))
            if not ds_ref:
                # Token is set for the fake_object1, so it will continue to
                # fetch the next object.
                setattr(fake_object1, 'token', 'token-0')
                if method == "continue_to_get_objects":
                    fake_object2 = vmwareapi_fake.FakeRetrieveResult()
                    fake_object2.add_object(vmwareapi_fake.Datacenter())
                    return fake_object2

            return fake_object1

        with mock.patch.object(self._session, '_call_method',
                               side_effect=fake_call_method) as fake_call:
            dc_info = _vcvmops.get_datacenter_ref_and_name(instance_ds_ref)

            if ds_ref:
                self.assertEqual(1, len(_vcvmops._datastore_dc_mapping))
                fake_call.assert_called_once_with(vim_util, "get_objects",
                    "Datacenter", ["name", "datastore", "vmFolder"])
                self.assertEqual("ha-datacenter", dc_info.name)
            else:
                calls = [mock.call(vim_util, "get_objects", "Datacenter",
                                   ["name", "datastore", "vmFolder"]),
                         mock.call(vim_util, "continue_to_get_objects",
                                   "token-0")]
                fake_call.assert_has_calls(calls)
                self.assertIsNone(dc_info)

    def test_get_datacenter_ref_and_name(self):
        self._test_get_datacenter_ref_and_name(ds_ref_exists=True)

    def test_get_datacenter_ref_and_name_with_no_datastore(self):
        self._test_get_datacenter_ref_and_name()


'''
   File used to extract members of ICMA. From the extracted list, this file will determine whether a company is a member of ICMA
'''

# Install Relevant Libraries
# pip install openpyxl --upgrade --pre
# pip install fuzzywuzzy

# Import Libraries and ICMA
import requests
from bs4 import BeautifulSoup
from fuzzywuzzy import fuzz

url = 'https://www.icmagroup.org/sustainable-finance/membership-governance-and-working-groups/membership/'
page = requests.get(url)
soup = BeautifulSoup(page.content, "html.parser")
icma_lst = soup.find_all("td")
icma_membership_lst = []
for x in range(len(icma_lst)):
   for y in range(len(icma_lst[x])):
      curr = icma_lst[x].find_all('a')
      if len(curr) == 0:
         continue
      icma_membership_lst.append(curr[0].contents[0])

# Function to detect ICMA members

def is_member_icma(name):
   '''
   Function used to check whether a company is member of ICMA

   Parameters
   ----------
   arg1 : name
       Name of company

   Returns
   -------
   boolean
       True if a company is member of ICMA, False otherwise
   '''
   for x in icma_membership_lst:
      if fuzz.partial_ratio(x.lower(), name.lower()) >= 95:
         return True
   return False

# Output
## is_member(name)


"""
  Triggered on the Cloud event and performs the data validation.
"""
import boto3
import os
import logging
import codecs
import pandas as pd
import json

#####################################################
#  VARIABLES
#####################################################

file_name = os.path.splitext(os.path.basename(__file__))[0]

default_log_args = {
    "level": logging.DEBUG if os.environ.get("DEBUG", 0) else logging.INFO,
    "format": "%(asctime)s [%(levelname)s] %(name)s - %(message)s",
    "datefmt": "%d-%b-%y %H:%M"
}

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)

sample_records = 100
data_records = []
data_column = []
with_header = True
data_validation_flag = True
global row_count, column_count, comment
row_count =0
column_count = 0
comment = []

file_formats = ['.txt', '.csv', '.tsv']
file_names = ['prof']  # , 'inst', 'rx'
template = {
    'prof': { 79: 'prof_v3_template.csv', 74: 'prof_v2_template.csv'}
}

#####################################################
#  FUNCTIONS
#####################################################

def get_logger(name):
    logging.basicConfig(**default_log_args)
    return logging.getLogger(name)

def get_split_char(key):
    if key.lower().endswith('.tsv'):
        return '\t'
    elif key.lower().endswith('.csv'):
        return ','
    elif key.lower().endswith('.txt'):
        return '|'
    else:
        return ' '

def get_row_count_of_s3_csv(bucket_name, path):
    req = boto3.client('s3').select_object_content(
        Bucket=bucket_name,
        Key=path,
        ExpressionType="SQL",
        Expression="""SELECT count(*) FROM s3object """,
        InputSerialization={"CSV": {"FileHeaderInfo": "Use",
                                    "AllowQuotedRecordDelimiter": True}},
        OutputSerialization={"CSV": {}},
    )
    row_count = next(int(x["Records"]["Payload"]) for x in req["Payload"])
    return row_count

#####################################################
#  MAIN LAMBDA EVENT
#####################################################

def lambda_main(event: dict = None, context: dict = None):
    try:
        global row_count, column_count
        log = get_logger(f"{file_name}.{lambda_main.__name__}")
        log.info('=' * 30 + " Init " + '=' * 30)
        log.info(f"[*] event - {event}")
        log.info(f"[*] context - {context}")
        records = event.get("Records", None)

        if not records:
            log.info(f"[-] No Records found in the events - {event}")
            return None

        new_file = [{'bucket': record["s3"]["bucket"]["name"],
                      'key': record['s3']['object']['key'],
                      'size': record['s3']['object']['size']}
                     for record in records
                     if record.get("s3")]

        new_file = new_file[0]
        s3 = boto3.resource("s3")
        key = new_file['key']
        bucket = new_file['bucket']

        if any(key.lower().endswith(fmt) for fmt in file_formats):
            msg = '>>>>>>> [+] Expected File Format matched'
            comment.append(msg)
            log.info(msg)
        else:
             msg = '>>>>>>> [-] Expected File Format unmatched'
             comment.append(msg)
             log.info(msg)
             return -1

        if any(fmt in key.lower() for fmt in file_names):
            msg  = '>>>>>>> [+] Expected File Name matched'
            comment.append(msg)
            log.info(msg)
        else:
             msg = '>>>>>>> [-] Expected File Name unmatched'
             comment.append(msg)
             log.info(msg)
             return -1

        row_count = get_row_count_of_s3_csv(bucket, key)
        log.info(f'>>>>>>> [+] Row_Count = {row_count}')
        split_char = get_split_char(key)
        idx = 0
        s3_object = s3.Object(new_file['bucket'], key)
        line_stream = codecs.getreader("utf-8")
        for line in line_stream(s3_object.get()['Body']):
            # log.info(f"line is {line}")
            if idx == 0:
                data_column = [value.strip() for value in line.split(split_char)]
            else:
                data_records.append([value.strip() for value in line.split(split_char)])
            idx += 1
            if idx > sample_records:
                break

        log.info(f'>>>>>>> [+] Collected Sample records = {sample_records}')
        log.info(f'>>>>>>> Column Length - {len(data_column)}')

        # Check Sample Records has headers
        template_file = ''
        if 'prof' in key.lower():
            template_file = template['prof'].get(len(data_column), '')

        if not template_file:
            log.info('>>>>>>> [-] Template File not found.')
            return -1

        log.info(f'>>>>>>> [+] Template File found - {template_file}')
        csv_df = pd.read_csv(open(template_file))
        # print(csv_df.columns)
        # print(csv_df.head())
        # print(csv_df[['Seq', 'ColumnName']].values.tolist())
        # print('|'.join(csv_df['ColumnName'].values.tolist()))
        expected_columns = csv_df['ColumnName'].values.tolist()
        actual_columns = data_column
        log.info(f'=====>> {len(expected_columns)} == {len(actual_columns)}')
        log.info(f'=====>> {set(expected_columns) - set(actual_columns)}/{set(actual_columns) - set(expected_columns)}')
        log.info(f'=====>> type(data_records) = {type(data_records)}{len(data_records)} type(data_column)  = {type(data_column)}{len(data_column)}')

        if expected_columns == actual_columns:
            log.info('>>>>>>> [+] Header found.')
            df = pd.DataFrame(data=data_records, columns=data_column)
        else:
            log.info('>>>>>>> [-] Header is not found.')
            df = pd.DataFrame(data=data_records.append(data_column), columns=expected_columns)

        print(df.head())
        # print(df.describe())
        # print(df.columns)
        actual_columns = list(df.columns)

        # dataframe.size
        size = df.size
        # dataframe.shape
        shape = df.shape
        # printing size and shape
        log.info(">>>>> Size = {} | Shape ={} | Shape[0] x Shape[1] = {}".format(size, shape, shape[0]*shape[1]))
        column_count = shape[1]
        log.info(f'>>>>>>> Column_Count = {column_count}')

        if len(expected_columns) == column_count:
            msg = '[+] Column Count Matched'
            comment.append(msg)
            log.info(msg)
        else:
            msg = '[-] Column Count Unmatched'
            comment.append(msg)
            log.info(msg)
            return -1

        if expected_columns == actual_columns:
            msg  = '[+] Column Order & Name Matched'
            comment.append(msg)
            log.info(msg)
        else:
            msg = '[-] Column Order & Name Unmatched'
            comment.append(msg)
            log.info(msg)
            return -1
        if template_file == 'prof_v3_template.csv':
            log.info(f" >>> df['Member Sex'].isin(['M', 'F', 'U'] = {all(df['Member Sex'].isin(['M', 'F', 'U']).tolist())}")
            for col in ['Claim Paid Date', 'Payment Adjudication Date', 'Claim Submission Date', 'Member Date of Birth (DOB)', 'Member Date of Death (DOD)', 'Beginning Date of Service', 'Ending Date of Service']:
                m1 = df[col].eq('') | df[col].isna()
                m2 = pd.to_datetime(df[col], format='%m/%d/%Y', errors='coerce').isna()
                log.info(f">>>> Date Validation - {col} = {m1.eq(m2).all()}")
            return 1
    except Exception as err:
        comment.append(sr(err))
        return -1

def lambda_handler(event: dict = None, context: dict = None):

    log = get_logger(f"{file_name}.{lambda_handler.__name__}")
    if lambda_main(event, context):
        kwargs = {"row_count": row_count,
            "column_count": column_count,
            "data_validation_flag": True,
            "comment":  '|'.join(comment)}
    else:
        log.info('Data validation failed')
        kwargs = {"row_count": row_count,
            "column_count": column_count,
            "data_validation_flag": False,
            "comment":  '|'.join(comment)}
    log.info(f'{kwargs}')

    _records  = event['Records'][0]
    _records['row_count'] = kwargs['row_count']
    _records['column_count'] = kwargs['column_count']
    _records['data_validation_flag'] = kwargs['data_validation_flag']
    _records['comment'] =  kwargs['comment']

    lambda_client = boto3.client('lambda')

    lambda_client.invoke(FunctionName='File-Meta-Data-Catcher',
                         InvocationType='Event',
                         Payload=json.dumps(event))
    log.info('=' * 30 + " Exit " + '=' * 30)


import boto3
from datetime import date, datetime

client = boto3.client('stepfunctions')

# https://stackoverflow.com/questions/11875770/how-to-overcome-datetime-datetime-not-json-serializable
def json_serial(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))

def get_executions(stateMachineArn, maxResults=1):
    results = {}
    for state in ['RUNNING', 'SUCCEEDED', 'FAILED', 'TIMED_OUT', 'ABORTED']:
        results.update({
            state: client.list_executions(
                stateMachineArn=stateMachineArn,
                statusFilter=state,
                maxResults=maxResults
            )
        })
    return results

def get_timestamp(results, status):
    ts = datetime(2017, 1, 1, 0, 0, 0)
    if len(results[status]["executions"]) > 0:
        try:
            ts = results[status]["executions"][0]['stopDate']
        except Exception as e:
            ts = datetime.now()
    return ts.isoformat()

def get_status(stateMachineArn):
    results = get_executions(stateMachineArn)
    statuses = {
        'RUNNING': get_timestamp(results, 'RUNNING'),
        'SUCCEEDED': get_timestamp(results, 'SUCCEEDED'),
        'FAILED': get_timestamp(results, 'FAILED'),
        'TIMED_OUT': get_timestamp(results, 'TIMED_OUT'),
        'ABORTED': get_timestamp(results, 'ABORTED')
    }
    return {
        'stateMachineArn': stateMachineArn,
        'status': max(statuses, key=statuses.get)
    }


# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name：     LIBSVM_test
   Description :
   Author :       cqh
   date：          2021/4/19
-------------------------------------------------
   Change Activity:
                   2021/4/19:
-------------------------------------------------
"""
__author__ = 'cqh'

# %%

from libsvm.svmutil import *
from libsvm.svm import *
from sklearn import svm
from sklearn.metrics import accuracy_score

#%%

y, x = svm_read_problem('./train.txt')
yt, xt = svm_read_problem('./test.txt')
y, x
# %%
problem = svm_problem(y, x)
model = svm_train(problem)
p_label, p_acc, p_val = svm_predict(yt, xt, model)
svm_save_model('svm_model', model)

# %%

# 转化为sklearn能用的数据库

TrainingSet = []
TestingSet = []

for i in x:
    TrainingSet.append(list(i.values()))

for j in xt:
    TestingSet.append(list(j.values()))

clf = svm.SVC(kernel='rbf')
clf.fit(TrainingSet, y)

predict_y = clf.predict(TestingSet)
accuracy_score(predict_y, yt)


import csv
import folium
import geopandas
import pandas as pd
from folium.plugins import FastMarkerCluster

def load_csv(csv_file):
    content = []
    with open(csv_file) as f:
        reader = csv.DictReader(f)
        for row in reader:
            content.append(row)
    return content

def create_map(csv_file, output_html):
    mood_content = load_csv(csv_file)
    mood_location = {}
    for item in mood_content:
        if item["location"] not in mood_location:
            mood_location[item["location"]] = {"Positive": 0, "Negative": 0}
        mood_location[item["location"]][item["mood"]] += 1
    my_map = folium.Map()
    world = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
    country_names = []
    moods = []
    for country in mood_location:
        mood = mood_location[country]['Positive'] / (
                mood_location[country]['Positive'] + mood_location[country]['Negative'])
        moods.append(mood)
        country_names.append(country)

    data_to_plot = pd.DataFrame({'Country': country_names, 'Mood': moods})

    folium.Choropleth(
        geo_data=world,
        name='choropleth',
        data=data_to_plot,
        columns=['Country', 'Mood'],
        key_on='feature.properties.name',
        fill_color='YlGn',
        fill_opacity=0.7,
        line_opacity=0.2,
        legend_name='Mood'
    ).add_to(my_map)
    cluster_data = []
    for row in mood_content:
        if row["latitude"] != "":
            cluster_data.append([float(row["latitude"]), float(row["longitude"])])
    FastMarkerCluster(cluster_data).add_to(my_map)

    folium.LayerControl().add_to(my_map)
    my_map.save(output_html)

if __name__ == "__main__":
    create_map("tweet_mood_java.csv", "mood_java.html")
    create_map("tweet_mood_python.csv", "mood_python.html")


# Built-in Library
from re import I
from typing import Sequence, Dict
import time
# External Imports.
import dm_env
from dm_env import specs
from torch.utils.tensorboard import SummaryWriter
from torch.distributions import distribution
from torch.distributions.categorical import Categorical
from torch.nn.modules import dropout
import tree

import numpy as np

import torch
import torch.nn as nn
import torch.nn.functional as F

# Internal Imports.
from algorithms import base
import algorithms.utils.sequence as sequence
from algorithms.vit import ViT

use_cuda = torch.cuda.is_available()
device = torch.device('cuda' if use_cuda else 'cpu')
print('we will use ', device)

writer = SummaryWriter('logs')

class A2C(base.Agent):
    """A simple TensorFlow-based feedforward actor-critic implementation."""

    def __init__(
            self,
            obs_spec: specs.Array,
            action_spec: specs.Array,
            max_sequence_length: int,
            network: 'PolicyValueNet',
            learning_rate: float,
            discount: float,
    ):
        """A simple actor-critic agent."""

        self._discount = discount

        # Internalise network and optimizer.
        self._network = network
        self._optimizer = torch.optim.Adam(
            network.parameters(), lr=learning_rate)

        # Create windowed buffer for learning from trajectories.
        self._buffer = sequence.Buffer(
            obs_spec, action_spec, max_sequence_length)

    def __compute_returns(self, final_value, rewards, discounts):
        value = final_value
        returns = []
        for step in reversed(range(len(rewards))):
            value = rewards[step] + self._discount * value * discounts[step]
            returns.insert(0, value)
        return torch.tensor(returns)

    def _step(self, trajectory: sequence.Trajectory, step: int):
        """Do a batch of SGD on the actor + critic loss."""
        stime = time.time()
        observations, actions, costs, discounts = trajectory

        # calculate values by the value network.
        observations = observations[:-1]
        _, values = self._network(observations)
        values = torch.squeeze(values)

        # compute loss.
        advantage = costs - values
        print("costs shape:", costs.shape, "costs", costs, "values", values)
        actor_loss = costs.mean()
        critic_loss = advantage.pow(2).mean()
        loss = (actor_loss + 0.05 * critic_loss).pow(0.1)
        # print("actor_loss ", actor_loss, "critic_loss", critic_loss, "loss", loss)

        # log to tensor board event.
        writer.add_scalar('Multi-Step_Loss', loss.item())
        print('Multi-Step loss is:', loss.item())

        # update parameter.
        self._network.train()
        #TODO(thekips): test.
        for p in self._network._policy_head.parameters():
            p.requires_grad = False
        self._optimizer.zero_grad()
        loss.backward()
        nn.utils.clip_grad_norm_(self._network.parameters(), 0.5)

        self._optimizer.step()
        print("Time of step use %ds" % (time.time() - stime))

    def select_action(self, timestep: dm_env.TimeStep) -> base.Action:
        """Selects actions according to the latest softmax policy."""
        # combine the agent's location with obj's location respectively.
        observation = torch.tensor(timestep.observation)
        # print('observation shape is', observation.shape)

        policies, _ = self._network(observation)
        return policies

    def update(
        self,
        timestep: dm_env.TimeStep,
        action: base.Action,
        new_timestep: dm_env.TimeStep,
        step: int,
    ):
        """Receives a transition and performs a learning update."""

        self._buffer.append(timestep, action, new_timestep)

        # When the batch is full, do a step of SGD.
        if self._buffer.full() or new_timestep.last():
            trajectory = self._buffer.drain()
            trajectory = tree.map_structure(torch.tensor, trajectory)
            self._step(trajectory, step)

class PolicyValueNet(nn.Module):
    def __init__(
        self,
        image_size,
        patch_size,
        hidden_size: int,
    ):
        super(PolicyValueNet, self).__init__()
        print('Vit init.')
        self._vit = ViT(image_size=image_size, patch_size=patch_size, num_classes=hidden_size,
                       dim=1024, depth=6, heads=16, mlp_dim=2048, dropout=0.1, emb_dropout=0.1)
        self._policy_head = nn.Linear(hidden_size, 2)
        self._value_head = nn.Linear(hidden_size, 1)

        print('Vit end init.')
        # self._fc_layer = nn.Sequential()
        # for i in range(len(hidden_sizes) - 1):
        #     self._fc_layer.add_module(
        #         'fc'+str(i), nn.Linear(hidden_sizes[i], hidden_sizes[i+1]))
        #     self._fc_layer.add_module('relu'+str(i), nn.ReLU())

    def forward(self, x: torch.Tensor):
        x = x / 255 # take value in x into [0, 1] as float.
        if len(x.shape) == 3:
            x = torch.unsqueeze(x, 0)
        # (thekips):When use pytorch<=1.3.0, you should use x.float() to avoid scalar type error.
        x = self._vit(x.float())   # x.shape turn from image_size to hidden_size.
        # x = einops.rearrange(x, 'i j k l -> i (j k l)')

        policies = self._policy_head(x)
        value = self._value_head(x)

        return policies.squeeze().tolist(), value


import torch
import torch.nn as nn
from .date2vec import Date2Vec

class Model(nn.Module):
    def __init__(self, user_len, item_len, d_model=6):
        super(Model, self).__init__()
        self.userID_embeddings = nn.Embedding(user_len, d_model)
        self.itemID_embeddings = nn.Embedding(item_len + 1, d_model)  # if not +1, index out of range in Embedding()!!
        self.date2vec = Date2Vec(k=32, act='sin')  # (N, 6) -> (N, dim_date)
        self.transformer = nn.Transformer(
            d_model=d_model,  # default is 512
            nhead=3,  # default is 4
            num_encoder_layers=6,
            num_decoder_layers=6,
            dim_feedforward=2048,
            dropout=0.1,
            activation='relu',
            custom_encoder=None,
            custom_decoder=None,
            layer_norm_eps=1e-05,
            batch_first=True,
            device=None,
            dtype=None
        )  # (N, T, E) -> (N, T, E)
        self.linear = nn.Linear(d_model, 1)  # (N, T, E) -> (N, T, 1)

    def forward(self, u, d, i, tgt_mask, tgt_key_padding_mask):
        """
        :param u: {Tensor: (N,)}, user indexes
        :param d: {Tensor: (N, 6)}, date
        :param i: {Tensor: (N, T)}, item indexes (target sentence)
        """
        # prepare src
        u = self.userID_embeddings(u)  # (N, dim_user)
        d = self.date2vec(d.float())  # (N, dim_date)
        ud = torch.transpose(torch.stack([u, d]), 1, 0)  # (N, S, E)
        # prepare tgt
        i = self.itemID_embeddings(i)  # (N, T, E)
        # calculate out
        out = self.transformer(src=ud, tgt=i, tgt_mask=tgt_mask, tgt_key_padding_mask=tgt_key_padding_mask)  # (N, T, E)
        out = self.linear(out)  # (N, T, 1)
        return out

    def get_tgt_mask(self, size) -> torch.tensor:
        # Generates a squeare matrix where the each row allows one word more to be seen
        mask = torch.tril(torch.ones(size, size) == 1)  # Lower triangular matrix
        mask = mask.float()
        mask = mask.masked_fill(mask == 0, float('-inf'))  # Convert zeros to -inf
        mask = mask.masked_fill(mask == 1, float(0.0))  # Convert ones to 0

        # EX for size=5:
        # [[0., -inf, -inf, -inf, -inf],
        #  [0.,   0., -inf, -inf, -inf],
        #  [0.,   0.,   0., -inf, -inf],
        #  [0.,   0.,   0.,   0., -inf],
        #  [0.,   0.,   0.,   0.,   0.]]

        return mask

    def create_pad_mask(self, matrix: torch.tensor, pad_token: int) -> torch.tensor:
        # If matrix = [1,2,3,0,0,0] where pad_token=0, the result mask is
        # [False, False, False, True, True, True]
        return (matrix == pad_token)


import netCDF4 as nc
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
import math
from numba import njit
from numba.experimental import jitclass
from time import time
import functools

#from joblib import Parallel, delayed
#import multiprocessing
from multiprocessing import Pool

class nctools:
    @staticmethod
    def walk(top):
        yield top, top.groups, top.__dict__, top.variables
        if top.groups:
            for v in top.groups.values():
                for children in nctools.walk(v):
                    yield children

    @staticmethod
    def ncdispl(file_path):
        with nc.Dataset(file_path) as dataset:
            print(dataset.data_model)

            for root, groups, atributs, variables in nctools.walk(dataset):

                tabs=""
                for t in root.path.split("/"):
                    tabs += "\t"

                print(tabs,root.path)

                if atributs:
                    print(tabs,"\tAtributs")
                    for k,v in atributs.items():
                        print(tabs,"\t\t","{}:\t{}".format(k,v))
                    print()

                if groups:
                    print(tabs,"\tGroups (Sumary)")
                    for g in groups.values():
                        print(tabs,"\t\t",g.path)
                    print()

                if variables:
                    print(tabs,"\tVariables")
                    for k,v in variables.items():

                        print(tabs,"\t\t",k)

                        #print(tabs,"\t\t\tSize:",len(v))
                        #print(tabs,"\t\t\tDatatype:",v.datatype)

                        print(tabs,"\t\t\t\tSize:      \t",len(v),end="")
                        for i,d in enumerate(v.dimensions):
                            if i > 0:
                                r = root
                                while True:
                                    try:
                                        print("x{}".format(r.dimensions[d].size),end="")
                                        break
                                    except:
                                        if r.parent:
                                            r = r.parent
                                        else:
                                            raise RuntimeError("ERROR: Could not find dimension for {}!".format(d))
                        print()

                        print(tabs,"\t\t\t\tDimensions:\t",end="")
                        for i,d in enumerate(v.dimensions):
                            if i > 0: print(end=",")

                            r = root
                            while not d in r.dimensions.keys():
                                if r.parent:
                                    r = r.parent
                                else:
                                    raise RuntimeError("ERROR: Could not find dimension for {}!".format(d))

                            print("", r.path + "/" + d, end="")

                        print()

                        print(tabs,"\t\t\t\tDatatype:  \t",v.datatype)
                    print()

class XFCTools:

    @staticmethod
    @njit
    def sum_beams(ping,
                  reflectivity_count_ping,
                  reflectivity_count_ping_max):

        #print(pingNr)
        pingstack = np.zeros(reflectivity_count_ping_max)
        pingstack.fill(float(np.nan))
        for bnr in range(len(ping)):
            beam = ping[bnr][:reflectivity_count_ping[bnr]]

            #add all samples of the beam to the pingstack
            for snr, s in enumerate(beam):
                if np.isnan(pingstack[snr]):
                    pingstack[snr] = 10 ** (s / 5)
                else:
                    pingstack[snr] += 10 ** (s / 5)

        return pingstack

    @staticmethod
    @njit
    def fill_ping_with_data(ping,pingNr,sample_amplitude,reflectivity_offset,reflectivity_count):
        for bnr in range(len(reflectivity_count[pingNr])):
            ping[bnr][:reflectivity_count[pingNr][bnr]] = sample_amplitude[reflectivity_offset[pingNr][bnr]:
                                                                           reflectivity_offset[pingNr][bnr] + reflectivity_count[pingNr][bnr]]

    @staticmethod
    @njit
    def to_db(rangestack):

        for bnr in range(len(rangestack)):
            for snr in range(len(rangestack[bnr])):
                rangestack[bnr][snr] = 10 * math.log10(rangestack[bnr][snr])

        return rangestack

#@jitclass(spec)
class XFCPingReader(object):
    def __init__(self,file_path):
        with nc.Dataset(file_path) as dataset:
            self.reflectivity_count  = np.array(dataset['/sounder/water_column/rx_info/reflectivity_count'][:])
            self.reflectivity_offset = np.array(dataset['/sounder/water_column/rx_info/reflectivity_offset'][:])
            self.sample_amplitude    = np.array(dataset['/sounder/water_column/rx_info/sample_amplitude'][:])
            # self.reflectivity_count  = dataset['/sounder/water_column/rx_info/reflectivity_count'][:]
            # self.reflectivity_offset = dataset['/sounder/water_column/rx_info/reflectivity_offset'][:]
            # self.sample_amplitude    = dataset['/sounder/water_column/rx_info/sample_amplitude'][:]

            self.numOfPings = int(dataset["/sounder"].dimensions["swath_dim"].size)
            self.numOfBeams = int(dataset["/sounder/water_column"].dimensions["beam_dim"].size)

    def get_ping(self,pingNr):

        max_samples = max(self.reflectivity_count[pingNr])
        max_beams = len(self.reflectivity_count[pingNr])
        ping = np.zeros((max_beams, max_samples))
        ping.fill(float(np.nan))

        XFCTools.fill_ping_with_data(ping, pingNr,
                                          self.sample_amplitude,self.reflectivity_offset,self.reflectivity_count)

        return ping

if __name__ == "__main__":
    time_start = time()

    base_path = "/home/ssd/data/xsf/"
    filename = "0100_20180707_142144.xsf"
    rangestack_name="rangestack.np"

    file_path = base_path + filename

    num_cores = 7

    if True:
        nctools.ncdispl(file_path)

    if False:
        plt.figure()
        with nc.Dataset(file_path) as dataset:
            depth    = dataset['/sounder/bathy/rx_info/depth']

            plt.imshow(depth)

    if False:
        plt.figure()

        xfcreader = XFCPingReader(file_path)

        pingNr = 500

        ping = xfcreader.get_ping(pingNr)

        plt.imshow(ping.transpose())

    if True:
        plt.figure()

        xfcreader = XFCPingReader(file_path)

        max_samples = max([max(samples) for samples in xfcreader.reflectivity_count])
        max_pings   = xfcreader.numOfPings

        rangestack = np.zeros((max_pings, max_samples))
        rangestack.fill(float(np.nan))

        def get_stacked_ping(pingNr : int):
            reflectivity_count_ping = xfcreader.reflectivity_count[pingNr]

            ping = xfcreader.get_ping(pingNr)

            return pingNr, XFCTools.sum_beams(ping, reflectivity_count_ping, max(reflectivity_count_ping))

        multiprocessing = False
        if not multiprocessing:
            for pingNr in tqdm(range(max_pings)):
                _,pingstack = get_stacked_ping(pingNr)
                rangestack[pingNr][:len(pingstack)] = pingstack

        if multiprocessing:
            with Pool(num_cores) as pool:
                for pnr,pingstack in tqdm(pool.imap(get_stacked_ping,range(max_pings))):
                    rangestack[pnr][:len(pingstack)] = pingstack

        rangestack = XFCTools.to_db(rangestack)

        rangestack.dump(base_path + "/" + rangestack_name)
        plt.imshow(rangestack.transpose())

    if False:
        plt.figure()

        rangestack = np.load(base_path + "/" + rangestack_name)
        plt.imshow(rangestack.transpose())

    print("Time: {}s".format(round(time()-time_start)),3)
    plt.show()


import os
import yaml
import collections

def deep_update(d, u):
    for k, v in u.items():
        if not isinstance(d, collections.abc.Mapping):
            d = {}
        if isinstance(v, collections.abc.Mapping):
            d[k] = deep_update(d.get(k, {}), v)
        else:
            d[k] = v
    return d

def load_config() -> dict:
    env = os.getenv('ENVIRONMENT')
    mod = os.getenv('MODEL')

    if not env:
        raise ValueError('Missing environment: {}'.format(env))
    if env.endswith('-io'):
        env = env[:-3]
    if env not in ['development', 'development_production', 'alpha', 'beta', 'production', ]:
        raise ValueError('Invalid environment: {}'.format(env))
    # app.logger.info('STARTING: env={}'.format(env))
    stage = 'production' if env == 'production' else 'staging'

    if not mod:
        raise ValueError('Missing model: {}'.format(mod))
    if mod not in ['J-Engine', 'W-Engine']:
        raise ValueError('Invalid model: {}'.format(mod))
    # app.logger.info('STARTING: mod={}'.format(mod))

    with open('config/default.yaml', 'r') as f:
        config = yaml.load(f, Loader=yaml.SafeLoader)

    with open('config/{}.yaml'.format(env), 'r') as f:
        config_env = yaml.load(f, Loader=yaml.SafeLoader)

    if config_env:
        config = deep_update(config, config_env)

    config['env'] = env
    config['mod'] = mod
    config['stage'] = stage

    return config

config = load_config()


# encoding: utf-8
"""
@author:  liaoxingyu
@contact: sherlockliao01@gmail.com
"""
import copy
import logging
from collections import OrderedDict

import numpy as np
import torch
import torch.nn.functional as F
from sklearn import metrics

from fastreid.utils import comm
from fastreid.utils.compute_dist import build_dist
from .evaluator import DatasetEvaluator
from .query_expansion import aqe
from .rank import evaluate_rank
from .roc import evaluate_roc

logger = logging.getLogger(__name__)

class ReidEvaluator(DatasetEvaluator):
    def __init__(self, cfg, num_query, output_dir=None):
        self.cfg = cfg
        self._num_query = num_query
        self._output_dir = output_dir

        self.features = []
        self.pids = []
        self.camids = []

    def reset(self):
        self.features = []
        self.pids = []
        self.camids = []

    def process(self, inputs, outputs):
        self.pids.extend(inputs["targets"])
        self.camids.extend(inputs["camids"])
        self.features.append(outputs.cpu())

    def evaluate(self):
        if comm.get_world_size() > 1:
            comm.synchronize()
            features = comm.gather(self.features)
            features = sum(features, [])

            pids = comm.gather(self.pids)
            pids = sum(pids, [])

            camids = comm.gather(self.camids)
            camids = sum(camids, [])

            # fmt: off
            if not comm.is_main_process(): return {}
            # fmt: on
        else:
            features = self.features
            pids = self.pids
            camids = self.camids

        features = torch.cat(features, dim=0)
        # query feature, person ids and camera ids
        query_features = features[:self._num_query]
        query_pids = np.asarray(pids[:self._num_query])
        query_camids = np.asarray(camids[:self._num_query])

        # gallery features, person ids and camera ids
        gallery_features = features[self._num_query:]
        gallery_pids = np.asarray(pids[self._num_query:])
        gallery_camids = np.asarray(camids[self._num_query:])

        self._results = OrderedDict()

        if self.cfg.TEST.AQE.ENABLED:
            logger.info("Test with AQE setting")
            qe_time = self.cfg.TEST.AQE.QE_TIME
            qe_k = self.cfg.TEST.AQE.QE_K
            alpha = self.cfg.TEST.AQE.ALPHA
            query_features, gallery_features = aqe(query_features, gallery_features, qe_time, qe_k, alpha)

        dist = build_dist(query_features, gallery_features, self.cfg.TEST.METRIC)

        if self.cfg.TEST.RERANK.ENABLED:
            logger.info("Test with rerank setting")
            k1 = self.cfg.TEST.RERANK.K1
            k2 = self.cfg.TEST.RERANK.K2
            lambda_value = self.cfg.TEST.RERANK.LAMBDA

            if self.cfg.TEST.METRIC == "cosine":
                query_features = F.normalize(query_features, dim=1)
                gallery_features = F.normalize(gallery_features, dim=1)

            rerank_dist = build_dist(query_features, gallery_features, metric="jaccard", k1=k1, k2=k2)
            dist = rerank_dist * (1 - lambda_value) + dist * lambda_value

        cmc, all_AP, all_INP = evaluate_rank(dist, query_pids, gallery_pids, query_camids, gallery_camids)

        mAP = np.mean(all_AP)
        mINP = np.mean(all_INP)
        for r in [1, 5, 10]:
            self._results['Rank-{}'.format(r)] = cmc[r - 1] * 100
        self._results['mAP'] = mAP * 100
        self._results['mINP'] = mINP * 100
        self._results["metric"] = (mAP + cmc[0]) / 2 * 100

        if self.cfg.TEST.ROC_ENABLED:
            scores, labels = evaluate_roc(dist, query_pids, gallery_pids, query_camids, gallery_camids)
            fprs, tprs, thres = metrics.roc_curve(labels, scores)

            for fpr in [1e-4, 1e-3, 1e-2]:
                ind = np.argmin(np.abs(fprs - fpr))
                self._results["TPR@FPR={:.0e}".format(fpr)] = tprs[ind]

        return copy.deepcopy(self._results)


import sqlite3

def valida(limite_inferior, limite_superior):
    """
   -> Verificar se tem coerencia nos dados inseridos
    :param limite_inferior: Valor de medição minímo do conversor
    :param limite_superior: Valor de medição maxímo do conversor
    """
    while True:
        if limite_inferior > limite_superior:
            print('Limites inválidos, digite novamente')
            limite_inferior = float(input('Digite o limite inferior'))
            limite_superior = float(input('Digite o limite superior'))
        else:
            break
    return limite_inferior, limite_superior

def escala(limite_inferior, limite_superior):
    """
    ->Validar os dados e descobrir a escala total
    :param limite_inferior: Valor minímo do conversor
    :param limite_superior: Valor maxímo do conversor
    :return: retorna a escala total do conversor e quanto vale  1 bits convertido
    """
    total = abs(limite_superior - limite_inferior)
    return total

def equivalente(escala_total,tipo_conversor):
    """
    ->Descobrir o valor equivalente de um único bit
    :param tipo_conversor: Tipo do conversor
    :param escala_total: Escala total do conversor
    :return: Retorna o valor equivalente a um bit
    """
    if tipo_conversor == 1 or tipo_conversor == 2:
        valor_1_bit = escala_total / 32768
        return valor_1_bit
    elif tipo_conversor == 3:
        valor_1_bit = escala_total / 26214
        #valor_1_bit = escala_total / 65535/2
        return valor_1_bit

def conversão(limite_inferior, valor_1_bit, valor_medido, tipo_conversor):
    """
    ->Converter valores medidos
    :param tipo_conversor: O tipo de conversor utilizado, tensão ou corrente(0-20mA / 4-20mA)
    :param limite_inferior: Valor minímo do conversor
    :param valor_1_bit: Valor equivalente a um bits do conversor
    :param valor_medido: Valor vindo do conversor
    :return: Valor já convertido
    """
    if tipo_conversor == 1 or tipo_conversor == 2:
        valor_convertido = valor_medido * valor_1_bit
        valor_real = limite_inferior + valor_convertido
    elif tipo_conversor == 3:
        if valor_medido <= 6553:
            return 'Conversor desconectado'
        elif valor_medido > 6553:
            valor_certo = (valor_medido - 6553)  # Faz a diferença e calcular o valor correspondente real
            valor_convertido = valor_certo * valor_1_bit
            valor_real = limite_inferior + valor_convertido
    return valor_real

def valor_real():
    return valor_real

def conversor(tipo_conversor):
    """
    -> Tipo de conversor que o usuario diz que vai usar
    :param tipo_conversor:
    :return: (número de identificação, tipo de sensor)
    """
    while True:
        if tipo_conversor == 1:
            return 1, 'Sensor tipo tensão'
            break
        elif tipo_conversor == 2:
            return 2, 'Sensor tipo corrente (0-20mA)'
            break
        elif tipo_conversor == 3:
            return 3, 'Sensor tipo corrente (4-20mA)'
            break
        else:
            print('Dado invalido, favor inserir uma das opções abaixo')
            tipo_conversor = int(input('''Digite o número correspondete ao sensor utilizado
            [1] Tensão
            [2] Corrente (0-20mA)
            [3] Corrente (4-20mA)
            Sensor corresponde ao número: '''))

# BACKUP DO BANCO DE DADOS
    # -> FAZER VERIFICAÇÃO DE NOME VÁLIDO
def backup(self):
    file_name = input('Digite o nome do arquivo de backup: ')
    file_name = file_name + '.sql'
    with io.open(file_name, 'w') as f:
        for linha in self.conn.iterdump():
            f.write('%f\n' % linha)
    # VERIFICAR SE DEU CERTO
    print('Backup realizado com sucesso!')
    print('Salvo como: %s' % file_name)

def arquivo():
    """
    -> Pedir para salvar no mesmo arquivo ou criar um novo
    :param teste: Resposta do usuario
    :return: retorna o nome do novo banco de dados
    """
    # CRIA UM NOVO ARQUIVO .db
    # CONFIGURA O SQLITE
    conn = sqlite3.connect('datalogger.db')
    cursor = conn.cursor()

    while True:
        novo = str(input('Deseja criar uma nova tabela? [S/N]: '))

        if novo in 'Ss':
            nome_tabela = str(input('Digite o nome da tabela: '))
            dados = nome_tabela
            continuar = input('Alerta: caso exista uma tabela com esse mesmo nome, a anterior sera apagada. Continuar? [S/N]: ')

            if continuar in 'Ss':
                cursor.execute("DROP TABLE IF EXISTS "+dados)
                cursor.execute("CREATE TABLE "+dados+"(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,"
                               "dia TINYINT, mes TINYINT, ano SMALLINT, hora TINYINT,"
                               "minuto TINYINT, segundo TINYINT, dado FLOAT)")
                break
            else:
                break

        elif novo in 'Nn':
            print('Alerta: caso a tabela não exista o programa resultará em erro')
            nome_tabela = str(input('Digite o nome da tabela: '))
            dados = nome_tabela
            break

        else:
            print('Resposta Inválida!')

    return nome_tabela


from django.urls import path

from .views import IndexView, CreateVinhoView, UpdateVinhoView, DeleteVinhoView, DetailsVinhoView

urlpatterns = [
    path('', IndexView.as_view(), name='index'),
    path('add/', CreateVinhoView.as_view(), name='add_vinho'),
    path('<int:pk>/update/', UpdateVinhoView.as_view(), name='upd_vinho'),
    path('<int:pk>/delete/', DeleteVinhoView.as_view(), name='del_vinho'),
    path('<int:pk>/details/', DetailsVinhoView.as_view(), name='det_vinho'),
]


# type: ignore
from datetime import datetime

import pandas
import pytest
from pathier import Pathier

import databased

root = Pathier(__file__).parent
dbpath = root / "dummy" / "db.db"

def test_is_this_thing_on():
    dbpath.unlink(missing_ok=True)
    db = databased.DataBased(dbpath)
    assert db

def test__databased__create_table():
    with databased.DataBased(dbpath) as db:
        cols = ["name text", "favorite_int int", "date_added timestamp"]
        db.create_table("dummy", cols)
        db.create_table("dummy2", cols)

def test__databased___get_dict():
    ...

def test__databased___get_conditions():
    ...

def test__databased__get_table_names():
    with databased.DataBased(dbpath) as db:
        tables = db.get_table_names()
        assert "dummy" in tables
        assert "dummy2" in tables

def test__databased__get_column_names():
    with databased.DataBased(dbpath) as db:
        tables = db.get_table_names()
        for table in tables:
            cols = db.get_column_names(table)
            assert all(col in cols for col in ["name", "favorite_int", "date_added"])

def test__databased__add_row():
    with databased.DataBased(dbpath) as db:
        for row in [
            ("John Smith", 31, datetime.now()),
            ("Amy Gonzalez", 276, datetime.now()),
            ("Bobby Tables", 627, datetime.now()),
            ("Mark Smith", 31, datetime.now()),
        ]:
            db.add_row("dummy", row)
        for row in [
            ("John Smith", 111, datetime.now()),
            ("Deshawn Sanders", 99, datetime.now()),
            ("Marsha Wallander", 31, datetime.now()),
            ("Jan Smith", 87, datetime.now()),
        ]:
            db.add_row("dummy2", row)

def test__databased__count():
    with databased.DataBased(dbpath) as db:
        assert db.count("dummy") == 4
        assert db.count("dummy2", [("name", "Deshawn Sanders")]) == 1

def test__databased__get_rows():
    with databased.DataBased(dbpath) as db:
        rows = db.get_rows("dummy")
        assert len(rows) == 4
        assert all(col in rows[0] for col in ["name", "favorite_int", "date_added"])
        row = rows[0]
        assert type(row["name"]) == str
        assert type(row["favorite_int"]) == int
        assert type(row["date_added"]) == datetime
        assert row["name"] == "John Smith"
        assert row["favorite_int"] == 31
        assert row["date_added"] < datetime.now()
        rows = db.get_rows("dummy2", columns_to_return=["name"])
        assert len(rows[0]) == 1
        rows = db.get_rows("dummy2", columns_to_return=["name"], values_only=True)
        assert type(rows[0]) == tuple
        assert rows[0][0] == "John Smith"
        assert len(db.get_rows("dummy2", limit=1)) == 1
        assert (
            db.get_rows("dummy2", order_by="favorite_int")[0]["name"]
            == "Marsha Wallander"
        )
        df = db.get_rows("dummy2", return_as_dataframe=True)
        assert type(df) == pandas.DataFrame
        cols = db.get_column_names("dummy2")
        assert len(df.columns) == len(cols)
        for i in range(len(cols)):
            assert df.columns[i] == cols[i]
        rows = db.get_rows("dummy2", values_only=True)
        for row, df_row in zip(rows, df.values):
            for item1, item2 in zip(row, df_row):
                assert item1 == item2

def test__databased_query():
    with databased.DataBased(dbpath) as db:
        rows = db.query("select name from dummy2 where name like 'Deshawn Sanders';")
        assert len(rows) == 1
        assert rows[0][0] == "Deshawn Sanders"

def test__databased__find():
    ...

def test__databased__update():
    with databased.DataBased(dbpath) as db:
        assert db.update("dummy", "favorite_int", 12345, {"favorite_int": 31}) == 2
        assert db.update("dummy2", "favorite_int", 1, {"name": "Jan Smith"}) == 1

def test__databased__delete():
    with databased.DataBased(dbpath, connection_timeout=30.13) as db:
        assert db.delete("dummy", {"name": "Smith"}, False) == 2
        assert db.delete("dummy2", {"name": "Jan Smith"}) == 1

def test__databased__drop_table():
    ...

def test__databased__add_column():
    ...

def test__databased__data_to_string():
    ...

def test__cleanup():
    for path in dbpath.parent.iterdir():
        path.unlink()


"""create known entities

Revision ID: cab84848600b
Revises: 0445df8a3cbd
Create Date: 2020-04-28 19:01:11.337078+00:00

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "cab84848600b"
down_revision = "0445df8a3cbd"
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "known_entities",
        sa.Column("entity_id", sa.String(length=100), nullable=False),
        sa.Column("entity_type", sa.String(length=100), nullable=False),
        sa.Column("ihs_last_seen_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("enverus_last_seen_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("fracfocus_last_seen_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column(
            "created_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("now()"),
            nullable=True,
        ),
        sa.Column(
            "updated_at",
            sa.DateTime(timezone=True),
            server_default=sa.text("now()"),
            nullable=True,
        ),
        sa.PrimaryKeyConstraint(
            "entity_id", "entity_type", name=op.f("pk_known_entities")
        ),
    )
    op.create_index(
        "ix_known_entities_all",
        "known_entities",
        [
            "entity_type",
            "entity_id",
            "ihs_last_seen_at",
            "enverus_last_seen_at",
            "fracfocus_last_seen_at",
        ],
        unique=False,
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index("ix_known_entities_all", table_name="known_entities")
    op.drop_table("known_entities")
    # ### end Alembic commands ###


import json

import click

from app.convertor import convert_to_troposphere

@click.command()
@click.argument('input', type=click.File('r'))
@click.argument('output', type=click.File('w'))
def convert(input, output):
    """
    This script takes a cloudformation template file and converts it to
    troposphere.
    """

    data = json.loads(input.read())
    result = convert_to_troposphere(data)

    output.write(result)
    output.flush()

if __name__ == '__main__':
    convert()


from typing import Optional, Dict, Union
import os
import os.path as osp

import pickle

import numpy as np

import torch
import torch.nn as nn

from .lbs import (lbs, blend_shapes)

from .vertex_ids import vertex_ids as VERTEX_IDS
from .utils import (
    Struct, to_np, to_tensor, Tensor, Array,
    SMPLOutput)
from .vertex_joint_selector import VertexJointSelector

class SMPL(nn.Module):
    NUM_JOINTS = 23
    NUM_BODY_JOINTS = 23
    SHAPE_SPACE_DIM = 300

    def __init__(
        self, model_path: str,
        data_struct: Optional[Struct] = None,
        create_betas: bool = True,
        betas: Optional[Tensor] = None,
        num_betas: int = 10,
        create_global_orient: bool = True,
        global_orient: Optional[Tensor] = None,
        create_body_pose: bool = True,
        body_pose: Optional[Tensor] = None,
        create_transl: bool = True,
        transl: Optional[Tensor] = None,
        dtype=torch.float32,
        batch_size: int = 1,
        joint_mapper=None,
        gender: str = 'neutral',
        vertex_ids: Dict[str, int] = None,
        v_template: Optional[Union[Tensor, Array]] = None,
        **kwargs
    ) -> None:
        ''' SMPL model constructor

            Parameters
            ----------
            model_path: str
                The path to the folder or to the file where the model
                parameters are stored
            data_struct: Strct
                A struct object. If given, then the parameters of the model are
                read from the object. Otherwise, the model tries to read the
                parameters from the given `model_path`. (default = None)
            create_global_orient: bool, optional
                Flag for creating a member variable for the global orientation
                of the body. (default = True)
            global_orient: torch.tensor, optional, Bx3
                The default value for the global orientation variable.
                (default = None)
            create_body_pose: bool, optional
                Flag for creating a member variable for the pose of the body.
                (default = True)
            body_pose: torch.tensor, optional, Bx(Body Joints * 3)
                The default value for the body pose variable.
                (default = None)
            num_betas: int, optional
                Number of shape components to use
                (default = 10).
            create_betas: bool, optional
                Flag for creating a member variable for the shape space
                (default = True).
            betas: torch.tensor, optional, Bx10
                The default value for the shape member variable.
                (default = None)
            create_transl: bool, optional
                Flag for creating a member variable for the translation
                of the body. (default = True)
            transl: torch.tensor, optional, Bx3
                The default value for the transl variable.
                (default = None)
            dtype: torch.dtype, optional
                The data type for the created variables
            batch_size: int, optional
                The batch size used for creating the member variables
            joint_mapper: object, optional
                An object that re-maps the joints. Useful if one wants to
                re-order the SMPL joints to some other convention (e.g. MSCOCO)
                (default = None)
            gender: str, optional
                Which gender to load
            vertex_ids: dict, optional
                A dictionary containing the indices of the extra vertices that
                will be selected
        '''

        self.gender = gender

        if data_struct is None:
            if osp.isdir(model_path):
                model_fn = 'SMPL_{}.{ext}'.format(gender.upper(), ext='pkl')
                smpl_path = os.path.join(model_path, model_fn)
            else:
                smpl_path = model_path
            assert osp.exists(smpl_path), 'Path {} does not exist!'.format(
                smpl_path)

            with open(smpl_path, 'rb') as smpl_file:
                data_struct = Struct(**pickle.load(smpl_file,
                                                   encoding='latin1'))

        super(SMPL, self).__init__()
        self.batch_size = batch_size
        shapedirs = data_struct.shapedirs
        if (shapedirs.shape[-1] < self.SHAPE_SPACE_DIM):
            print(f'WARNING: You are using a {self.name()} model, with only'
                  ' 10 shape coefficients.')
            num_betas = min(num_betas, 10)
        else:
            num_betas = min(num_betas, self.SHAPE_SPACE_DIM)

        self._num_betas = num_betas
        shapedirs = shapedirs[:, :, :num_betas]
        # The shape components
        self.register_buffer(
            'shapedirs',
            to_tensor(to_np(shapedirs), dtype=dtype))

        if vertex_ids is None:
            # SMPL and SMPL-H share the same topology, so any extra joints can
            # be drawn from the same place
            vertex_ids = VERTEX_IDS['smplh']

        self.dtype = dtype

        self.joint_mapper = joint_mapper

        self.vertex_joint_selector = VertexJointSelector(
            vertex_ids=vertex_ids, **kwargs)

        self.faces = data_struct.f
        self.register_buffer('faces_tensor',
                             to_tensor(to_np(self.faces, dtype=np.int64),
                                       dtype=torch.long))

        if create_betas:
            if betas is None:
                default_betas = torch.zeros(
                    [batch_size, self.num_betas], dtype=dtype)
            else:
                if torch.is_tensor(betas):
                    default_betas = betas.clone().detach()
                else:
                    default_betas = torch.tensor(betas, dtype=dtype)

            self.register_parameter(
                'betas', nn.Parameter(default_betas, requires_grad=True))

        # The tensor that contains the global rotation of the model
        # It is separated from the pose of the joints in case we wish to
        # optimize only over one of them
        if create_global_orient:
            if global_orient is None:
                default_global_orient = torch.zeros(
                    [batch_size, 3], dtype=dtype)
            else:
                if torch.is_tensor(global_orient):
                    default_global_orient = global_orient.clone().detach()
                else:
                    default_global_orient = torch.tensor(
                        global_orient, dtype=dtype)

            global_orient = nn.Parameter(default_global_orient,
                                         requires_grad=True)
            self.register_parameter('global_orient', global_orient)

        if create_body_pose:
            if body_pose is None:
                default_body_pose = torch.zeros(
                    [batch_size, self.NUM_BODY_JOINTS * 3], dtype=dtype)
            else:
                if torch.is_tensor(body_pose):
                    default_body_pose = body_pose.clone().detach()
                else:
                    default_body_pose = torch.tensor(body_pose,
                                                     dtype=dtype)
            self.register_parameter(
                'body_pose',
                nn.Parameter(default_body_pose, requires_grad=True))

        if create_transl:
            if transl is None:
                default_transl = torch.zeros([batch_size, 3],
                                             dtype=dtype,
                                             requires_grad=True)
            else:
                default_transl = torch.tensor(transl, dtype=dtype)
            self.register_parameter(
                'transl', nn.Parameter(default_transl, requires_grad=True))

        if v_template is None:
            v_template = data_struct.v_template
        if not torch.is_tensor(v_template):
            v_template = to_tensor(to_np(v_template), dtype=dtype)
        # The vertices of the template model
        self.register_buffer('v_template', v_template)

        j_regressor = to_tensor(to_np(
            data_struct.J_regressor), dtype=dtype)
        self.register_buffer('J_regressor', j_regressor)

        # Pose blend shape basis: 6890 x 3 x 207, reshaped to 6890*3 x 207
        num_pose_basis = data_struct.posedirs.shape[-1]
        # 207 x 20670
        posedirs = np.reshape(data_struct.posedirs, [-1, num_pose_basis]).T
        self.register_buffer('posedirs',
                             to_tensor(to_np(posedirs), dtype=dtype))

        # indices of parents for each joints
        parents = to_tensor(to_np(data_struct.kintree_table[0])).long()
        parents[0] = -1
        self.register_buffer('parents', parents)

        lbs_weights = to_tensor(to_np(data_struct.weights), dtype=dtype)
        self.register_buffer('lbs_weights', lbs_weights)

    @property
    def num_betas(self):
        return self._num_betas

    @property
    def num_expression_coeffs(self):
        return 0

    def create_mean_pose(self, data_struct) -> Tensor:
        pass

    def name(self) -> str:
        return 'SMPL'

    @torch.no_grad()
    def reset_params(self, **params_dict) -> None:
        for param_name, param in self.named_parameters():
            if param_name in params_dict:
                param[:] = torch.tensor(params_dict[param_name])
            else:
                param.fill_(0)

    def get_num_verts(self) -> int:
        return self.v_template.shape[0]

    def get_num_faces(self) -> int:
        return self.faces.shape[0]

    def extra_repr(self) -> str:
        msg = [
            f'Gender: {self.gender.upper()}',
            f'Number of joints: {self.J_regressor.shape[0]}',
            f'Betas: {self.num_betas}',
        ]
        return '\n'.join(msg)

    def forward_shape(
        self,
        betas: Optional[Tensor] = None,
    ) -> SMPLOutput:
        betas = betas if betas is not None else self.betas
        v_shaped = self.v_template + blend_shapes(betas, self.shapedirs)
        return SMPLOutput(vertices=v_shaped, betas=betas, v_shaped=v_shaped)

    def forward(
        self,
        betas: Optional[Tensor] = None,
        body_pose: Optional[Tensor] = None,
        global_orient: Optional[Tensor] = None,
        transl: Optional[Tensor] = None,
        return_verts=True,
        return_full_pose: bool = False,
        pose2rot: bool = True,
        **kwargs
    ) -> SMPLOutput:
        ''' Forward pass for the SMPL model

            Parameters
            ----------
            global_orient: torch.tensor, optional, shape Bx3
                If given, ignore the member variable and use it as the global
                rotation of the body. Useful if someone wishes to predicts this
                with an external model. (default=None)
            betas: torch.tensor, optional, shape BxN_b
                If given, ignore the member variable `betas` and use it
                instead. For example, it can used if shape parameters
                `betas` are predicted from some external model.
                (default=None)
            body_pose: torch.tensor, optional, shape Bx(J*3)
                If given, ignore the member variable `body_pose` and use it
                instead. For example, it can used if someone predicts the
                pose of the body joints are predicted from some external model.
                It should be a tensor that contains joint rotations in
                axis-angle format. (default=None)
            transl: torch.tensor, optional, shape Bx3
                If given, ignore the member variable `transl` and use it
                instead. For example, it can used if the translation
                `transl` is predicted from some external model.
                (default=None)
            return_verts: bool, optional
                Return the vertices. (default=True)
            return_full_pose: bool, optional
                Returns the full axis-angle pose vector (default=False)

            Returns
            -------
        '''
        # If no shape and pose parameters are passed along, then use the
        # ones from the module
        batch_size = max([v.shape[0] if v is not None else 0 for v in [betas, body_pose, global_orient, transl]])
        global_orient = global_orient if global_orient is not None else self.global_orient.expand(batch_size, -1)
        body_pose = body_pose if body_pose is not None else self.body_pose.expand(batch_size, -1)
        betas = betas if betas is not None else self.betas.expand(batch_size, -1)

        apply_trans = transl is not None or hasattr(self, 'transl')
        if transl is None and hasattr(self, 'transl'):
            transl = self.transl

        full_pose = torch.cat([global_orient, body_pose], dim=1)
        vertices, joints, A, T, shape_offsets, pose_offsets = lbs(
            betas, full_pose, self.v_template, self.shapedirs, self.posedirs,
            self.J_regressor, self.parents, self.lbs_weights, pose2rot=pose2rot)

        joints = self.vertex_joint_selector(vertices, joints)
        # Map the joints to the current dataset
        if self.joint_mapper is not None:
            joints = self.joint_mapper(joints)

        if apply_trans:
            joints = joints + transl.unsqueeze(dim=1)
            vertices = vertices + transl.unsqueeze(dim=1)
            # clone because we are modifying them in-place
            A = A.clone()
            A[..., :3, 3] += transl.unsqueeze(dim=1)
            T = T.clone()
            T[..., :3, 3] += transl.unsqueeze(dim=1)

        output = SMPLOutput(vertices=vertices if return_verts else None,
                            global_orient=global_orient,
                            body_pose=body_pose,
                            joints=joints,
                            betas=betas,
                            full_pose=full_pose if return_full_pose else None,
                            A=A,
                            T=T,
                            shape_offsets=shape_offsets,
                            pose_offsets=pose_offsets)
        return output


from rest_framework import viewsets
from goal.serializers import (
    GoalSerializer,
    GoalTypeSerializer,
    GoalManagerSerializer,
)

from goal.models import (
    Goal,
    GoalType,
    GoalManager,
)

class GoalViewSet(viewsets.ModelViewSet):
    """
    retrieve:
        Return a goal instance.

    list:
        Return all goals, ordered by most recently joined.

    create:
        Create a new goal.

    delete:
        Remove an existing goal.

    partial_update:
        Update one or more fields on an existing goal.

    update:
        Update a goal.
    """

    serializer_class = GoalSerializer
    queryset = Goal.objects.all()

class GoalTypeViewSet(viewsets.ModelViewSet):
    """
    retrieve:
        Return a goal type instance.

    list:
        Return all goals type, ordered by most recently joined.

    create:
        Create a new goal type.

    delete:
        Remove an existing goal type.

    partial_update:
        Update one or more fields on an existing goal type.

    update:
        Update a goal type.
    """

    serializer_class = GoalTypeSerializer
    queryset = GoalType.objects.all()

class GoalManagerViewSet(viewsets.ModelViewSet):
    """
    retrieve:
        Return a goal manager instance.

    list:
        Return all goals manager, ordered by most recently joined.

    create:
        Create a new goal manager.

    delete:
        Remove an existing goal manager.

    partial_update:
        Update one or more fields on an existing goal manager.

    update:
        Update a goal manager.
    """

    serializer_class = GoalManagerSerializer
    queryset = GoalManager.objects.all()


from flask import Flask, Response, request, jsonify, redirect, url_for, render_template, session, abort
import os
import pymongo
import json
from datetime import datetime
import time
import sys

# from people_counter import get_frame
# from people_counter import VideoCamera

seconds = time.time()

client = pymongo.MongoClient('localhost', 27017)
db = client['db1']

state = db['state']
db_log = db['db_log']

app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017"
app.config['SECRET_KEY'] = 'secret!'

# Sanity Check
@app.route("/ping")
def ping():
    app.logger.info("Responded ping with pong")
    return "Pong"

@app.route("/")
def index():
    return render_template('index.html')
# def gen(camera):
#     while True:
#         #get camera frame
#         frame = camera.get_frame()
#         yield (b'--frame\r\n'
#                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

# @app.route('/video_feed')
# def video_feed():
#     return Response(gen(VideoCamera()),
#                     mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route("/api/log/<int:door>/<int:is_entry>")
def log_event(door, is_entry):
    def entry(x): return x == 1
    # db_log.insert_one({'door': door, 'is_entry': entry(
    #     is_entry), 'time': datetime.now().timestamp()})
    new_state = update_counters(door, entry(is_entry))
    return jsonify({'status': 'saved', 'state': new_state})

@app.route("/api/log")
def log_all():
    all_log = list(db_log.find())
    for x in all_log:
        del x['_id']
    return jsonify(all_log)

@app.route("/reset")
def reset_all():
    db_log.remove({})
    state.remove({})
    return jsonify({'logs': db_log.count(), 'state': state.count() })

def update_log():
    current = state.find_one({'index': 1})
    del current['_id']
    current['time'] = time.time()
    current['hour'] = datetime.now().hour
    current['minute'] = datetime.now().minute
    current['second'] = datetime.now().second
    current['ts'] = datetime.now().strftime("%c")
    db_log.insert_one(current)

def update_counters(door, is_entry):
    current = state.find_one()
    if current is None:  # Check if document empty
        current_state = {'index': 1, 'door1_entries': 0, 'door2_entries': 0,
                         'door1_exits': 0, 'door2_exits': 0, 'people_count': 0}
        state.insert_one(current_state)
        update_log()
        print(state.find_one())

    if(door == 1):
        if is_entry:
            state.update_one(
                {'index': 1}, {'$inc': {'door1_entries': 1, 'people_count': 1}})
            update_log()
        else:
            state.update_one(
                {'index': 1}, {'$inc': {'door1_exits': 1,'people_count': -1}})
            update_log()
    elif(door == 2):
        if is_entry:
            state.update_one(
                {'index': 1}, {'$inc': {'door2_entries': 1, 'people_count': 1}})
            update_log()
        else:
            state.update_one(
                {'index': 1}, {'$inc': {'door2_exits': 1,'people_count': -1}})
            update_log()
    else:
        raise ValueError("Invalid Door Number")
    ret_val = state.find_one()
    del ret_val['_id']
    return ret_val

# @app.route("/upload/temperature/<float:temp>/<float:hum>")
# def temp_upload(temp,hum):
#     tmp.update_one({'time':datetime.now().hour},{'$set': {'temperature': temp, 'humidity': hum}}, upsert=False)
#     return jsonify({'status': 'saved'})

# @app.route("/get/temperature/current")
# def temp_get_current():
#     data = tmp.find_one({'time':datetime.now().hour })
#     return str(data['temperature'])

# @app.route("/upload/water_level/<float:level>/")
# def level_upload(level):
#     levels.update_one({'time':datetime.now().hour},{'$set': {'level': level}}, upsert=False)
#     return jsonify({'status': 'saved'})

if __name__ == "__main__":
    Flask.run(app, host='0.0.0.0', port=5000, debug=True)