# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

#import numpy as np ## not used in this script for now
import pandas as pd
from datetime import datetime
import os
import glob
from ExecQuery import ExecQuery
#import quandl ## later imported in the function
#import zipfile ## later imported in the function

from config import get_data_config

def main():
    GetData(get_data_config)

#########################################
### The Function
#########################################
def GetData(get_data_config):
    # the conf
    data_dir = get_data_config['Quandl_partial_dir']
    api_key = get_data_config['Quandl_api_key']
    col_names = get_data_config['Quandl_col_names']
    db_name = get_data_config['mysql_database']
    table_name = get_data_config['mysql_table_name']

    raw_dir = data_dir + 'raw/'
    proc_dir = data_dir + 'proc/'

    raw_file_list = DumpBulkDataFromQuandl(raw_dir, api_key)
    print(raw_file_list)

    proc_file_dict = ProcessData(proc_dir, raw_file_list, col_names, True)
    print(proc_file_dict)

    LoadData(proc_file_dict, db_name, table_name, True)

    #historical
    #ProcessData('E:/Work/PartTime/DQ_Project/data/QuandlWiki/hist/proc/',['E:/Work/PartTime/DQ_Project/data/QuandlWiki/hist/raw/WIKI_PRICES.csv'], col_names)
    #LoadData(['E:/Work/PartTime/DQ_Project/data/QuandlWiki/hist/proc/proc_WIKI_PRICES.csv'], db_name, table_name)

#########################################
### Helper Functions
#########################################

### 1. DumpBulkDataFromQuandl ###########
def DumpBulkDataFromQuandl(raw_dir, api_key):
    # defininations
    zip_file_name = raw_dir + datetime.strftime(datetime.now(),'%Y%m%d.%H%M%S') + '.zip'

    # bulkdownload
    import quandl
    quandl.ApiConfig.api_key = api_key
    quandl.bulkdownload("WIKI", download_type="partial", filename=zip_file_name)

    # remove all the existing csv files
    to_remove_list = glob.glob(raw_dir + '*.csv')
    for f in to_remove_list:
        os.remove(f)

    # upzip and rename
    import zipfile
    zip_ref = zipfile.ZipFile(zip_file_name, 'r')
    zip_ref.extractall(raw_dir)
    zip_ref.close()

    raw_file_list = glob.glob(raw_dir + '*.csv')
    raw_file_list = [f.replace('\\','/') for f in raw_file_list]
    return raw_file_list

### 2. ProcessData ######################
def ProcessData(proc_dir, raw_file_list, col_names, keep_lastest=False):
    proc_file_dict = {}

    for raw_file_name in raw_file_list:
        #raw_file_name = raw_file_list[0] ###DEBUG
        #keep_lastest=True ###DEBUG

        # read the data
        data = pd.read_csv(raw_file_name, header=None, names = col_names)
        #data = pd.read_csv(raw_file_name) ###DEBUG, hist

        if keep_lastest:
            # only keep the data when date = date in the file name
            datex = ((raw_file_name.split('/')[-1]).split('.')[0]).split('_')[1]
            datex = datetime.strftime(datetime.strptime(datex,'%Y%m%d'), '%Y-%m-%d')
            data = data[data['date']==datex]

        # transform the format of the data
        data['date'] = pd.to_datetime(data['date']).dt.strftime('%Y/%m/%d')

        # generate the file name based on the raw file name
        proc_file_name = proc_dir + 'proc_' + raw_file_name.split('/')[-1]

        # output with nan being 'NULL'
        data.to_csv(proc_file_name, na_rep='NULL', index=False, header=None)

        proc_file_dict.update({proc_file_name:datex})

    return proc_file_dict

### 3. LoadData #########################
def LoadData(proc_file_dict, db_name, table_name, delete=False):
    for f in proc_file_dict.keys():
        if delete:
            del_query = "delete from " + table_name + " where date = '" + proc_file_dict[f] + "'; commit;"
            print(del_query)
            ExecQuery(db_name, del_query)

        load_query = """
                     LOAD DATA INFILE '""" + f.replace('/','\\\\') + """'
                     INTO TABLE """ + table_name + """
                     COLUMNS TERMINATED BY ','
                     OPTIONALLY ENCLOSED BY '"'
                     ESCAPED BY '"'
                     LINES TERMINATED BY '\\r\\n'
                     #IGNORE 1 ROWS
                     ;commit;
                     """
        print(load_query)
        ExecQuery(db_name, load_query)

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

#########################################
### Examples/Explanations
#########################################

def DumpDfDataFromQuandl(sd, ed, ticker):
    # bulkdownload
    import quandl
    quandl.ApiConfig.api_key = get_data_config['Quandl_api_key']
    df = quandl.get_table('WIKI/PRICES'
                          , qopts = {'columns': ['ticker', 'date', 'adj_close']}
                          , date={'gte': sd, 'lte': ed}
                          , ticker=ticker
                          , paginate=True)
    return df

def DumpDataFromQuandlExamples():
    import quandl

    ### Here are a few ways to dump the data from Quandl, to data frame
    # 0. load the api_key
    quandl.ApiConfig.api_key = get_data_config['Quandl_api_key']

    # 1. get_table method: can get one day or multiple days of data
    print(quandl.get_table('WIKI/PRICES', date='2018-03-28', ticker='AAPL'))

    print(quandl.get_table('WIKI/PRICES', ticker = ['AAPL', 'MSFT', 'WMT'],
                        #qopts = { 'columns': ['ticker', 'date', 'adj_close'] },
                        date = { 'gte': '2016-12-15', 'lte': '2016-12-31' },
                        paginate=True))

    # 2. get method: mostly for a time series
    print(quandl.get("WIKI/AAPL", trim_start = "2012-12-21", trim_end = "2013-01-01"))

    # 3. bulkdownload method: download all the sybmbols as of the last available date
    print(quandl.bulkdownload("WIKI", download_type="partial", filename="E:/Work/PartTime/DQ_Project/temp/WIKI.zip"))


from PyQt5.QtCore import QObject, pyqtSlot, QTimer, QTime, QModelIndex
from datetime import datetime
from models.alarm_model import AlarmModel
from views.add_alarm_view import AddAlarm
from alarm_checker import AlarmChecker
from json_storage import JsonStorage
from weather_forecaster import WeatherForecaster

class ClockController(QObject):
    def __init__(self, model, forecast):
        super().__init__()

        self._model = model
        self._forecast = forecast
        self.timer = QTimer()
        self.json_storage = JsonStorage("")
        self.load_alarms()
        self.timer.timeout.connect(self.clock)
        self.timer.start(1000)
        self.checker = AlarmChecker(self._model.alarms)
        self.weather = WeatherForecaster(self._model, self._forecast)
        print(self._model.temp)

    @pyqtSlot(int)
    def add_alarm(self):
        new_alarm = AlarmModel(self._model.name, self._model.hour, self._model.minute)
        self._model.alarms = new_alarm
        self.json_storage.save(self._model.alarms)

    @pyqtSlot(int)
    def name_changed(self, value):
        self._model.name = value

    @pyqtSlot(QTime)
    def alarm_time_changed(self, value):
        self._model.hour = value.hour()
        self._model.minute = value.minute()

    @pyqtSlot(str)
    def change_time(self, value):
        self._model.time = value

    @pyqtSlot(str)
    def change_date(self, value):
        self._model.date = value

    @pyqtSlot(QModelIndex)
    def selection_changed(self, value):
        name = self._model.alarms[value.data()].name
        ret = AddAlarm(alarm_clock=self._model.alarms[name])
        res = ret.exec()
        if ret.delete:
            self._model.alarms.pop(name)
            for item in self._model.alarm_list.findItems(name):
                self._model.alarm_list.removeRow(item.row())
            self.json_storage.save(self._model.alarms)
        if res != 0:
            self.set_alarm_model(ret.alarm)

    @pyqtSlot()
    def show_add_alarm_dialog(self):
        ret = AddAlarm()
        if ret.exec():
            self.set_alarm_model(ret.alarm)

    def load_alarms(self):
        alarm_list = self.json_storage.read()
        for alarm in alarm_list:
            self._model.alarms = alarm

    def set_alarm_model(self, alarm):
        self._model.alarms = alarm
        self.json_storage.save(self._model.alarms)

    def clock(self):
        self._model.time = datetime.now().strftime('%I:%M:%S %p')
        self._model.date = datetime.now().strftime('%m-%d-%Y')


import os
import glob2
import numpy as np
import pandas as pd
import tensorflow as tf

# /datasets/faces_emore_112x112_folders/*/*.jpg'
default_image_names_reg = "*/*.jpg"
default_image_classes_rule = lambda path: int(os.path.basename(os.path.dirname(path)))

def pre_process_folder(data_path, image_names_reg=None, image_classes_rule=None):
    while data_path.endswith("/"):
        data_path = data_path[:-1]
    if not data_path.endswith(".npz"):
        dest_pickle = os.path.join("./", os.path.basename(data_path) + "_shuffle.npz")
    else:
        dest_pickle = data_path

    if os.path.exists(dest_pickle):
        aa = np.load(dest_pickle)
        # with open(dest_pickle, "rb") as ff:
        #     aa = pickle.load(ff)
        if len(aa.keys()) == 2:
            image_names, image_classes, embeddings = aa["image_names"], aa["image_classes"], []
        else:
            # dataset with embedding values
            image_names, image_classes, embeddings = aa["image_names"], aa["image_classes"], aa["embeddings"]
    else:
        if not os.path.exists(data_path):
            return [], [], [], 0, None
        if image_names_reg is None or image_classes_rule is None:
            image_names_reg, image_classes_rule = default_image_names_reg, default_image_classes_rule
        image_names = glob2.glob(os.path.join(data_path, image_names_reg))
        image_names = np.random.permutation(image_names).tolist()
        image_classes = [image_classes_rule(ii) for ii in image_names]
        embeddings = []
        np.savez_compressed(dest_pickle, image_names=image_names, image_classes=image_classes)
        # with open(dest_pickle, "wb") as ff:
        #     pickle.dump({"image_names": image_names, "image_classes": image_classes}, ff)
    classes = np.max(image_classes) + 1
    return image_names, image_classes, embeddings, classes, dest_pickle

def tf_imread(file_path):
    img = tf.io.read_file(file_path)
    img = tf.image.decode_jpeg(img, channels=3)  # [0, 255]
    # img = tf.image.convert_image_dtype(img, tf.float32)  # [0, 1]
    img = tf.cast(img, "float32")  # [0, 255]
    return img

def random_process_image(img, img_shape=(112, 112), random_status=2, random_crop=None):
    if random_status >= 0:
        img = tf.image.random_flip_left_right(img)
    if random_status >= 1:
        # 25.5 == 255 * 0.1
        img = tf.image.random_brightness(img, 25.5 * random_status)
    if random_status >= 2:
        img = tf.image.random_contrast(img, 1 - 0.1 * random_status, 1 + 0.1 * random_status)
        img = tf.image.random_saturation(img, 1 - 0.1 * random_status, 1 + 0.1 * random_status)
    if random_status >= 3 and random_crop is not None:
        img = tf.image.random_crop(img, random_crop)
        img = tf.image.resize(img, img_shape)

    if random_status >= 1:
        img = tf.clip_by_value(img, 0.0, 255.0)
    return img

def prepare_dataset(
    data_path,
    image_names_reg=None,
    image_classes_rule=None,
    batch_size=128,
    img_shape=(112, 112),
    random_status=2,
    random_crop=None,
    cache=False,
    shuffle_buffer_size=None,
    is_train=True,
):
    image_names, image_classes, embeddings, classes, _ = pre_process_folder(data_path, image_names_reg, image_classes_rule)
    if len(image_names) == 0:
        return None
    print(">>>> Image length: %d, Image class length: %d, classes: %d" % (len(image_names), len(image_classes), classes))

    if len(embeddings) == 0:
        ds = tf.data.Dataset.from_tensor_slices((image_names, image_classes))
        process_func = lambda imm, label: (tf_imread(imm), tf.one_hot(label, depth=classes, dtype=tf.int32))
    else:
        # dataset with embedding values
        print(">>>> embeddings: %s. This takes some time..." % (np.shape(embeddings),))
        ds = tf.data.Dataset.from_tensor_slices((image_names, image_classes, embeddings))
        process_func = lambda imm, label, emb: (tf_imread(imm), (tf.one_hot(label, depth=classes, dtype=tf.int32), emb))

    AUTOTUNE = tf.data.experimental.AUTOTUNE
    ds = ds.shuffle(buffer_size=len(image_names))
    ds = ds.map(process_func, num_parallel_calls=AUTOTUNE)

    if is_train and random_status >= 0:
        random_process_func = lambda xx, yy: (random_process_image(xx, img_shape, random_status, random_crop), yy)
        ds = ds.map(random_process_func, num_parallel_calls=AUTOTUNE)

    ds = ds.batch(batch_size)  # Use batch --> map has slightly effect on dataset reading time, but harm the randomness
    ds = ds.map(lambda xx, yy: ((xx - 127.5) * 0.0078125, yy))
    ds = ds.prefetch(buffer_size=AUTOTUNE)
    return ds

class Triplet_dataset:
    def __init__(
        self,
        data_path,
        image_names_reg=None,
        image_classes_rule=None,
        batch_size=48,
        image_per_class=4,
        img_shape=(112, 112, 3),
        random_status=3,
        random_crop=None,
    ):
        self.AUTOTUNE = tf.data.experimental.AUTOTUNE
        image_names, image_classes, _, classes, _ = pre_process_folder(data_path, image_names_reg, image_classes_rule)
        image_dataframe = pd.DataFrame({"image_names": image_names, "image_classes": image_classes})
        image_dataframe = image_dataframe.groupby("image_classes").apply(lambda xx: xx.image_names.values)
        aa = image_dataframe.map(len)
        self.image_dataframe = image_dataframe[aa > image_per_class]
        self.split_func = lambda xx: np.array(
            np.split(np.random.permutation(xx)[: len(xx) // image_per_class * image_per_class], len(xx) // image_per_class)
        )
        self.image_per_class = image_per_class
        self.batch_size = batch_size
        self.img_shape = img_shape[:2]
        self.channels = img_shape[2] if len(img_shape) > 2 else 3
        print("The final train_dataset batch will be %s" % ([batch_size * image_per_class, *self.img_shape, self.channels]))

        get_label = lambda xx: tf.one_hot(
            tf.cast(tf.strings.to_number(tf.strings.split(xx, os.path.sep)[-2]), tf.int32), depth=classes, dtype=tf.int32
        )
        self.process_path = lambda img_name: (
            random_process_image(tf_imread(img_name), self.img_shape, random_status, random_crop),
            get_label(img_name),
        )
        # image_data = self.image_data_shuffle()
        # self.steps_per_epoch = np.ceil(image_data.shape[0] / self.batch_size)

        train_dataset = tf.data.Dataset.from_generator(
            self.image_data_shuffle_gen, output_types=tf.string, output_shapes=(image_per_class,)
        )
        # train_dataset = train_dataset.shuffle(total)
        train_dataset = train_dataset.batch(self.batch_size)
        if "-dev" in tf.__version__ or int(tf.__version__.split(".")[1]) > 2:
            # tf-nightly or tf >= 2.3.0
            train_dataset = train_dataset.map(self.process_batch_path_2, num_parallel_calls=self.AUTOTUNE)
        else:
            train_dataset = train_dataset.map(self.process_batch_path_1, num_parallel_calls=self.AUTOTUNE)
        train_dataset = train_dataset.map(lambda xx, yy: ((xx - 127.5) * 0.0078125, yy))
        self.train_dataset = train_dataset.prefetch(buffer_size=self.AUTOTUNE)
        self.classes = classes

    def image_data_shuffle_gen(self):
        tf.print("Shuffle image data...")
        shuffle_dataset = self.image_dataframe.map(self.split_func)
        image_data = np.random.permutation(np.vstack(shuffle_dataset.values))
        return (ii for ii in image_data)

    def process_batch_path_1(self, image_name_batch):
        image_names = tf.reshape(image_name_batch, [-1])
        images, labels = tf.map_fn(self.process_path, image_names, dtype=(tf.float32, tf.int32))
        return images, labels

    def process_batch_path_2(self, image_name_batch):
        image_names = tf.reshape(image_name_batch, [-1])
        images, labels = tf.map_fn(self.process_path, image_names, fn_output_signature=(tf.float32, tf.int32))
        return images, labels


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

"""
Simple Python API client for NSoT REST API.

The easiest way to get a client is to call ``get_api_client()`` with no
arguments. This will read the user's ``~/.pynsotrc`` file and pass the values
to the client constructor::

    >>> from pynsot.client import get_api_client
    >>> api = get_api_client()
    >>> api
    AuthTokenClient(url=http://localhost:8990/api)>
"""

__author__ = 'Jathan McCollum'
__maintainer__ = 'Jathan McCollum'
__email__ = 'jathan@dropbox.com'
__copyright__ = 'Copyright (c) 2015 Dropbox, Inc.'

import getpass
import json
import logging
import os

from .vendor import click
from .vendor.requests.auth import AuthBase
from .vendor import slumber
from .vendor.slumber.exceptions import HttpClientError

from . import dotfile

# Logger
log = logging.getLogger(__name__)

# Header used for passthrough authentication.
AUTH_HEADER = 'X-NSoT-Email'

__all__ = (
    'ClientError', 'LoginFailed', 'BaseClient', 'EmailHeaderAuthentication',
    'EmailHeaderClient', 'AuthTokenAuthentication', 'AuthTokenClient',
    'get_auth_client_info', 'get_api_client'
)

class ClientError(HttpClientError):
    """Generic client error."""

class LoginFailed(ClientError):
    """Raised when login fails for some reason."""

class BaseClient(slumber.API):
    """
    Magic REST API client for NSoT.
    """
    def __init__(self, base_url=None, **kwargs):
        auth = kwargs.pop('auth', None)  # Ditch default auth
        self.default_site = kwargs.pop('default_site', None)  # Default site_id

        # Override the auth method if we have defined .get_auth()
        if auth is None:
            # Set these as object attributes so that they can be mutated in the
            # subclass .get_auth() method
            self._kwargs = kwargs
            auth = self.get_auth(base_url)

        kwargs['auth'] = auth
        kwargs['append_slash'] = True  # Append slashes!
        super(BaseClient, self).__init__(base_url, **kwargs)

    def get_auth(self, base_url=None):
        """
        Subclasses should references kwargs from ``self._kwargs``.

        :param base_url:
            Base API URL
        """
        raise NotImplementedError('SUBCLASS ME OR SOMETHING!')

    def error(self, exc):
        """
        Take errors and make them human-readable.

        :param exc:
            Exception instance
        """
        log.debug('Processing error: %r' % (exc,))
        # If it's a HTTP response, format the JSON
        try:
            try:
                err = exc.response.json()['error']
            except ValueError:
                # This is probably a JSON decoding error
                msg = exc.message
            else:
                msg = '%s %s' % (err['code'], err['message'])
        except AttributeError:
            msg = str(exc)
        raise ClientError(msg)

    def get_resource(self, resource_name):
        """
        Return a single resource object.

        :param resource_name:
            Name of resource
        """
        return getattr(self, resource_name)

    def __repr__(self):
        cls_name = self.__class__.__name__
        return '<%s(url=%s)>' % (cls_name, self._store['base_url'])

class EmailHeaderAuthentication(AuthBase):
    """Special authentication that sets the email auth header."""
    def __init__(self, email=None, auth_header=AUTH_HEADER):
        if email is None:
            raise LoginFailed('You must provide an email!')
        self.email = email
        self.auth_header = auth_header

    def __call__(self, r):
        """Set the auth header."""
        r.headers[self.auth_header] = self.email
        return r

class EmailHeaderClient(BaseClient):
    """Default client using email auth header method."""
    @classmethod
    def get_user(cls):
        """Get the local username, or if root, the sudo username."""
        user = getpass.getuser()
        if user == 'root':
            user = os.getenv('SUDO_USER')
        return user

    def get_auth(self, base_url):
        kwargs = self._kwargs
        email = kwargs.pop('email', None)
        default_domain = kwargs.pop('default_domain', 'localhost')

        if email is None and default_domain:
            log.debug('No email provided; Using default_domain: %r',
                      default_domain)
            user = self.get_user()
            email = '%s@%s' % (user, default_domain)
            log.debug('Using email: %r', email)

        auth_header = kwargs.pop('auth_header', AUTH_HEADER)
        return EmailHeaderAuthentication(email, auth_header)

class AuthTokenAuthentication(AuthBase):
    """
    Special authentication that utilizes auth_tokens.

    Adds header for "Authorization: ApiToken {email}:{auth_token}"
    """
    def __init__(self, email=None, auth_token=None):
        self.email = email
        self.auth_token = auth_token

    def __call__(self, r):
        header = 'AuthToken %s:%s' % (self.email, self.auth_token)
        r.headers['Authorization'] = header
        return r

class AuthTokenClient(BaseClient):
    """Client that uses auth_token method."""
    def get_token(self, base_url, email, secret_key):
        """
        Currently ghetto: Hit the API to get an auth_token.

        :param base_url:
            API URL

        :param email:
            User's email

        :param secret_key:
            User's secret_key
        """
        data = {'email': email, 'secret_key': secret_key}
        debug_data = data.copy()  # For debug display
        debug_data['secret_key'] = 'X' * 8

        log.debug('Getting token for user data: %r' % (debug_data,))
        try:
            url = base_url + '/authenticate/'
            headers = {'content-type': 'application/json'}
            r = slumber.requests.post(url, data=json.dumps(data),
                                      headers=headers)
        except Exception as err:
            log.debug('Got error: %s' % (err,))
            self.error(err)

        if r.ok:
            log.debug('Got response: %r' % (r,))
            return r.json()['data']['auth_token']
        else:
            msg = 'Failed to fetch auth_token from %s' % base_url
            err = HttpClientError(msg, response=r, content=r.content)
            self.error(err)

    def get_auth(self, base_url):
        kwargs = self._kwargs
        email = kwargs.pop('email', None)
        secret_key = kwargs.pop('secret_key', None)
        auth_token = self.get_token(base_url, email, secret_key)
        auth = AuthTokenAuthentication(email, auth_token)
        return auth
Client = AuthTokenClient  # Default client is auth_token

# Mapping to our two (2) hard-coded auth methods and their required arguments.
AUTH_CLIENTS = {
    'auth_header': (EmailHeaderClient, ('email', 'default_domain', 'default_site')),
    'auth_token': (AuthTokenClient, ('email', 'secret_key', 'default_site')),
}

def get_auth_client_info(auth_method):
    """
    Return the proper Client class and required args.

    :param auth_method:
        Auth method used by the client
    """
    return AUTH_CLIENTS[auth_method]

def get_api_client(auth_method=None, url=None, extra_args=None):
    """
    Safely create an API client so that users don't see tracebacks.

    Any arguments taht aren't explicitly passed will be replaced by the
    contents of the user's dotfile.

    :param auth_method:
        Auth method used by the client

    :param url:
        API URL
    """
    if extra_args is None:
        extra_args = {}

    # Read the dotfile
    try:
        log.debug('Reading dotfile.')
        client_args = dotfile.Dotfile().read()
    except dotfile.DotfileError as err:
        raise click.UsageError(err.message)

    # Merge the extra_args w/ the client_args from the config
    client_args.update(extra_args)

    # Minimum required arguments that we don't want getting passed to the client
    if auth_method is None:
        auth_method = client_args.pop('auth_method')
    if url is None:
        url = client_args.pop('url')

    # Validate the auth_method
    log.debug('Validating auth_method: %s', auth_method)
    try:
        client_class, arg_names = get_auth_client_info(auth_method)
    except KeyError:
        raise click.UsageError('Invalid auth_method: %s' % (auth_method,))

    try:
        api_client = client_class(url, **client_args)
    except ClientError as err:
        msg = str(err)
        if 'Connection refused' in msg:
            msg = 'Could not connect to server: %s' % (url,)
        raise click.UsageError(msg)
    return api_client


import glob, io, os, sys

from PyPDF2 import PdfFileReader, PdfFileMerger

def merge_pdfs(links, output):
    print(f'Merging to {output}')
    merger = PdfFileMerger()
    for link in links:
            with open(link, 'rb') as file:
                merger.append(
                    PdfFileReader(
                        file
                    )
                )

    merger.write(output)

links = list()

def add_files(uri):
    if os.path.isdir(uri):
        for base, dirs, files in os.walk(uri):

            for file in files:
                add_files(os.path.join(base, file))

            for dir in dirs:
                add_files(os.path.join(base, dir))
    elif os.path.splitext(uri)[1].lower() == '.pdf':
        links.append(uri)

def merge_from_file(uri):
    print(f'Merging from file {uri}')
    with open(uri) as file:
        for line in file:
            for g in glob.iglob(os.path.join(os.path.dirname(uri), line)):
                # print(os.path.join('.', os.path.relpath(os.path.join(os.path.dirname(uri), g))))
                add_files(os.path.join('.', os.path.relpath(g)))

    merge_pdfs(links, uri + '.pdf')

for arg in sys.argv:
    merge_from_file(arg)


import numpy as np
from os import listdir
from Example_RF_classifier import load_data
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
__author__ = "Ulysse Cote-Allard<ulysse.cote-allard.1@ulaval.ca> and David St-Onge<david.st-onge@polymtl.ca>"
__copyright__ = "Copyright 2007, MIST Lab"
__credits__ = ["David St-Onge", "Ulysse Cote-Allard", "Kyrre Glette", "Benoit Gosselin", "Giovanni Beltrame"]
__license__ = "MIT"
__version__ = "1.0"
__maintainer__ = "David St-Onge"
__email__ = "david.st-onge@polymtl.ca"
__status__ = "Production"

if __name__ == '__main__':
    """
    Main function utilized to build the training dataset and the performance of each participant and then training and using the classifier
    """
    dataLoader = load_data.DataLoader()
    # Get the list of participants from the true labels folder
    list_participants = listdir("../true_labels_informations/")

    accuracy_RF_array = []
    accuracy_CNN_array = []
    number_gestures_array = []

    accuracy_calculated_RF = []

    array_participants_id = []

    examples_imu_training_datasets = []
    examples_emg_training_datasets = []
    labels_training_datasets = []
    examples_imu_test_datasets = []
    examples_emg_test_datasets = []
    labels_test_datasets = []
    for participant in list_participants:
        identification_participant = participant.split(".")[0]
        information_labels = np.load("../true_labels_informations/" + participant, encoding="bytes")
        dataset_delay, labels_intervals, number_gestures, true_labels = information_labels
        number_gestures_array.append(number_gestures[0])
        print(identification_participant)
        array_participants_id.append(identification_participant)

        # Comment between here

        test_data_emg, test_data_imu_1, test_data_imu_2, labels_test, accuracy_RF = dataLoader.read_performance_data("../" +
                                                                                identification_participant,
                                                                                path_labels=labels_intervals,
                                                                                dataset_delay=dataset_delay[0])

        np.savez("../formated_datasets/" + identification_participant + "_accuracy_RF.npz", accuracy_RF=[accuracy_RF])
        examples_emg, examples_imu_1, examples_imu_2, labels = dataLoader.read_training(
            "../" + identification_participant,
            number_of_classes=number_gestures[0])

        np.savez("../formated_datasets/" + identification_participant + "_train_rf_features.npz", examples_emg=examples_emg,
                 examples_imu_1=examples_imu_1, examples_imu_2=examples_imu_2, labels=labels)

        np.savez("../formated_datasets/" + identification_participant + "_test_rf_features.npz", test_data_emg=test_data_emg,
                 test_data_imu_1=test_data_imu_1, test_data_imu_2=test_data_imu_2, labels_test=labels_test)

        # And here to stop building the datasets from scratch

        npzfile = np.load("../formated_datasets/" + identification_participant + "_accuracy_RF.npz", encoding="bytes")
        accuracy_RF_live_performance = npzfile['accuracy_RF'][0]

        npzfile = np.load("../formated_datasets/" + identification_participant + "_train_rf_features.npz", encoding="bytes")
        emg_train, examples_imu_1_pre_training, examples_imu_2_pre_training, labels_pre_training = npzfile['examples_emg'],\
                                                                                npzfile['examples_imu_1'],\
                                                                                npzfile['examples_imu_2'], npzfile['labels']

        npzfile = np.load("../formated_datasets/" + identification_participant + "_test_rf_features.npz", encoding="bytes")
        emg_test, test_data_imu_1, test_data_imu_2, labels_test = npzfile['test_data_emg'], npzfile['test_data_imu_1'], npzfile['test_data_imu_2'],\
                                                                  npzfile['labels_test']

        rf = RandomForestClassifier(n_estimators=500, max_features='log2', random_state=np.random.RandomState(42))
        rf.fit(np.concatenate((emg_train, examples_imu_1_pre_training, examples_imu_2_pre_training), axis=1), labels_pre_training)
        predictions = rf.predict(np.concatenate((emg_test, test_data_imu_1, test_data_imu_2), axis=1))

        accuracy_RF = accuracy_score(labels_test, predictions)

        print("ACCURACY RF LIVE PERFORMANCE: ", accuracy_RF_live_performance)
        print("ACCURACY RF CALCULATED: ", accuracy_RF)
        print("CONFUSION MATRIX: \n", confusion_matrix(labels_test, predictions))
        print("  ")
        print(npzfile.files)
        accuracy_calculated_RF.append(accuracy_RF)

    print("ACCURACY RF FROM ALL DATASETS:", accuracy_calculated_RF)
    print("participant ID: ", array_participants_id)


import requests
import json

class Douban():
    def __init__(self):
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Mobile Safari/537.36",
            "Referer": "https://m.douban.com/tv/american"}

        self.url = "https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_american_hot/items?os=android&for_mobile=1&start=0&count=18&loc_id=108288&_=1529481198406"

    def send_url(self):#发送请求,获取相应
        response = requests.post(url=self.url,headers=self.headers)
        return response.content.decode()
    def get_content(self,send_dict):#接受数据,处理数据
        dict_ret=json.loads(send_dict)
        json_ret =dict_ret["subject_collection_items"]
        return json_ret
    def save_content(self,content):#保存数据
        with open('douban.txt', 'w', encoding='utf-8') as f:
            json.dump(content, f, ensure_ascii=False, indent=1)
    def run(self):#运行
        send_dict=self.send_url()
        html=self.get_content(send_dict)
        content=self.save_content(html)

if __name__ == '__main__':
    douban = Douban()
    douban.run()


from scipy import io
import numpy as np
import os

matFile_path = 'data' + os.path.sep + 'mnist-original.mat'
initialData = io.loadmat(matFile_path)

data = initialData['data'].transpose([1,0])
data = data.reshape([-1,1,28,28])
label = initialData['label'].transpose([1,0])

data_save_path = 'data'

if not(os.path.exists(data_save_path)):
	os.makedirs(data_save_path)

np.save(data_save_path + os.path.sep + 'mnist',data)
np.save(data_save_path + os.path.sep + 'mnist_label',label)


from django.urls import path

from . import views

urlpatterns = [
    path('', views.LandingPage, name='LandingPage'),
    path('prestations', views.Prestations, name='Prestations'),
    path('portfolio', views.Portfolio, name='Portfolio'),
    path('contact', views.Contact, name='Contact'),
    path('license', views.License, name='License'),
    path('home', views.Home, name='Home'),
]


#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2002 Bruce J. DeGrasse
# Copyright (C) 2000-2007 Donald N. Allingham
# Copyright (C) 2007-2009 Brian G. Matherly
# Copyright (C) 2007      Robert Cawley  <rjc@cawley.id.au>
# Copyright (C) 2008-2009 James Friedmann <jfriedmannj@gmail.com>
# Copyright (C) 2009      Benny Malengier <benny.malengier@gramps-project.org>
# Copyright (C) 2010      Jakim Friant
# Copyright (C) 2010      Vlada Peri\u0107
# Copyright (C) 2011      Matt Keenan <matt.keenan@gmail.com>
# Copyright (C) 2011      Tim G L Lyons
# Copyright (C) 2013      Paul Franklin
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

"""Reports/Text Reports/Detailed Descendant Report"""

#------------------------------------------------------------------------
#
# standard python modules
#
#------------------------------------------------------------------------
from functools import partial

#------------------------------------------------------------------------
#
# GRAMPS modules
#
#------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gen.errors import ReportError
from gramps.gen.lib import FamilyRelType, Person, NoteType
from gramps.gen.plug.menu import (BooleanOption, NumberOption, PersonOption,
                           EnumeratedListOption)
from gramps.gen.plug.docgen import (IndexMark, FontStyle, ParagraphStyle,
                             FONT_SANS_SERIF, FONT_SERIF,
                             INDEX_TYPE_TOC, PARA_ALIGN_CENTER)
from gramps.gen.plug.report import (Report, Bibliography)
from gramps.gen.plug.report import endnotes
from gramps.gen.plug.report import utils as ReportUtils
from gramps.gen.plug.report import MenuReportOptions
from gramps.gen.plug.report import stdoptions
from gramps.plugins.lib.libnarrate import Narrator

#------------------------------------------------------------------------
#
# Constants
#
#------------------------------------------------------------------------
EMPTY_ENTRY = "_____________"
HENRY = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

#------------------------------------------------------------------------
#
#
#
#------------------------------------------------------------------------
class DetDescendantReport(Report):

    def __init__(self, database, options, user):
        """
        Create the DetDescendantReport object that produces the report.

        The arguments are:

        database        - the GRAMPS database instance
        options         - instance of the Options class for this report
        user            - a gen.user.User() instance

        This report needs the following parameters (class variables)
        that come in the options class.

        gen           - Maximum number of generations to include.
        pagebgg       - Whether to include page breaks between generations.
        pageben       - Whether to include page break before End Notes.
        fulldates     - Whether to use full dates instead of just year.
        listc         - Whether to list children.
        incnotes      - Whether to include notes.
        usecall       - Whether to use the call name as the first name.
        repplace      - Whether to replace missing Places with ___________.
        repdate       - Whether to replace missing Dates with ___________.
        computeage    - Whether to compute age.
        omitda        - Whether to omit duplicate ancestors (e.g. when distant cousins marry).
        verbose       - Whether to use complete sentences.
        numbering     - The descendancy numbering system to be utilized.
        desref        - Whether to add descendant references in child list.
        incphotos     - Whether to include images.
        incnames      - Whether to include other names.
        incevents     - Whether to include events.
        incaddresses  - Whether to include addresses.
        incsrcnotes   - Whether to include source notes in the Endnotes section. Only works if Include sources is selected.
        incmates      - Whether to include information about spouses
        incattrs      - Whether to include attributes
        incpaths      - Whether to include the path of descendancy from the start-person to each descendant.
        incssign      - Whether to include a sign ('+') before the descendant number in the child-list to indicate a child has succession.
        pid           - The Gramps ID of the center person for the report.
        name_format   - Preferred format to display names
        incmateref    - Whether to print mate information or reference
        """
        Report.__init__(self, database, options, user)

        self.map = {}
        self._user = user

        menu = options.menu
        get_option_by_name = menu.get_option_by_name
        get_value = lambda name: get_option_by_name(name).get_value()
        self.max_generations = get_value('gen')
        self.pgbrk         = get_value('pagebbg')
        self.pgbrkenotes   = get_value('pageben')
        self.fulldate      = get_value('fulldates')
        use_fulldate     = self.fulldate
        self.listchildren  = get_value('listc')
        self.inc_notes     = get_value('incnotes')
        use_call           = get_value('usecall')
        blankplace         = get_value('repplace')
        blankdate          = get_value('repdate')
        self.calcageflag   = get_value('computeage')
        self.dubperson     = get_value('omitda')
        self.verbose       = get_value('verbose')
        self.numbering     = get_value('numbering')
        self.childref      = get_value('desref')
        self.addimages     = get_value('incphotos')
        self.inc_names     = get_value('incnames')
        self.inc_events    = get_value('incevents')
        self.inc_addr      = get_value('incaddresses')
        self.inc_sources   = get_value('incsources')
        self.inc_srcnotes  = get_value('incsrcnotes')
        self.inc_mates     = get_value('incmates')
        self.inc_attrs     = get_value('incattrs')
        self.inc_paths     = get_value('incpaths')
        self.inc_ssign     = get_value('incssign')
        self.inc_materef   = get_value('incmateref')
        pid                = get_value('pid')
        self.center_person = database.get_person_from_gramps_id(pid)
        if (self.center_person == None) :
            raise ReportError(_("Person %s is not in the Database") % pid )

        self.gen_handles = {}
        self.prev_gen_handles = {}
        self.gen_keys = []
        self.dnumber = {}
        self.dmates = {}

        if blankdate:
            empty_date = EMPTY_ENTRY
        else:
            empty_date = ""

        if blankplace:
            empty_place = EMPTY_ENTRY
        else:
            empty_place = ""

        self._locale = self.set_locale(get_value('trans'))

        name_format = menu.get_option_by_name("name_format").get_value()
        if name_format != 0:
            self._name_display.set_default_format(name_format)

        self.__narrator = Narrator(self.database, self.verbose,
                                   use_call, use_fulldate,
                                   empty_date, empty_place,
                                   nlocale=self._locale,
                                   get_endnote_numbers=self.endnotes)

        self.bibli = Bibliography(Bibliography.MODE_DATE|Bibliography.MODE_PAGE)

    def apply_henry_filter(self,person_handle, index, pid, cur_gen=1):
        if (not person_handle) or (cur_gen > self.max_generations):
            return
        self.dnumber[person_handle] = pid
        self.map[index] = person_handle

        if len(self.gen_keys) < cur_gen:
            self.gen_keys.append([index])
        else:
            self.gen_keys[cur_gen-1].append(index)

        person = self.database.get_person_from_handle(person_handle)
        index = 0
        for family_handle in person.get_family_handle_list():
            family = self.database.get_family_from_handle(family_handle)
            for child_ref in family.get_child_ref_list():
                ix = max(self.map)
                self.apply_henry_filter(child_ref.ref, ix+1,
                                  pid+HENRY[index], cur_gen+1)
                index += 1

    # Filter for d'Aboville numbering
    def apply_daboville_filter(self,person_handle, index, pid, cur_gen=1):
        if (not person_handle) or (cur_gen > self.max_generations):
            return
        self.dnumber[person_handle] = pid
        self.map[index] = person_handle

        if len(self.gen_keys) < cur_gen:
            self.gen_keys.append([index])
        else:
            self.gen_keys[cur_gen-1].append(index)

        person = self.database.get_person_from_handle(person_handle)
        index = 1
        for family_handle in person.get_family_handle_list():
            family = self.database.get_family_from_handle(family_handle)
            for child_ref in family.get_child_ref_list():
                ix = max(self.map)
                self.apply_daboville_filter(child_ref.ref, ix+1,
                                  pid+"."+str(index), cur_gen+1)
                index += 1

    # Filter for Record-style (Modified Register) numbering
    def apply_mod_reg_filter_aux(self, person_handle, index, cur_gen=1):
        if (not person_handle) or (cur_gen > self.max_generations):
            return
        self.map[index] = person_handle

        if len(self.gen_keys) < cur_gen:
            self.gen_keys.append([index])
        else:
            self.gen_keys[cur_gen-1].append(index)

        person = self.database.get_person_from_handle(person_handle)

        for family_handle in person.get_family_handle_list():
            family = self.database.get_family_from_handle(family_handle)
            for child_ref in family.get_child_ref_list():
                ix = max(self.map)
                self.apply_mod_reg_filter_aux(child_ref.ref, ix+1, cur_gen+1)

    def apply_mod_reg_filter(self, person_handle):
        self.apply_mod_reg_filter_aux(person_handle, 1, 1)
        mod_reg_number = 1
        for generation in range(len(self.gen_keys)):
            for key in self.gen_keys[generation]:
                person_handle = self.map[key]
                if person_handle not in self.dnumber:
                    self.dnumber[person_handle] = mod_reg_number
                    mod_reg_number += 1

    def write_report(self):
        """
        This function is called by the report system and writes the report.
        """
        if self.numbering == "Henry":
            self.apply_henry_filter(self.center_person.get_handle(), 1, "1")
        elif self.numbering == "d'Aboville":
            self.apply_daboville_filter(self.center_person.get_handle(), 1, "1")
        elif self.numbering == "Record (Modified Register)":
            self.apply_mod_reg_filter(self.center_person.get_handle())
        else:
            raise AttributeError("no such numbering: '%s'" % self.numbering)

        name = self._name_display.display_name(self.center_person.get_primary_name())

        self.doc.start_paragraph("DDR-Title")

        # feature request 2356: avoid genitive form
        title = self._("Descendant Report for %(person_name)s") % {
                    'person_name' : name }
        mark = IndexMark(title, INDEX_TYPE_TOC, 1)
        self.doc.write_text(title, mark)
        self.doc.end_paragraph()

        generation = 0

        self.numbers_printed = list()
        for generation in range(len(self.gen_keys)):
            if self.pgbrk and generation > 0:
                self.doc.page_break()
            self.doc.start_paragraph("DDR-Generation")
            text = self._("Generation %d") % (generation+1)
            mark = IndexMark(text, INDEX_TYPE_TOC, 2)
            self.doc.write_text(text, mark)
            self.doc.end_paragraph()
            if self.childref:
                self.prev_gen_handles = self.gen_handles.copy()
                self.gen_handles.clear()

            for key in self.gen_keys[generation]:
                person_handle = self.map[key]
                self.gen_handles[person_handle] = key
                self.write_person(key)

        if self.inc_sources:
            if self.pgbrkenotes:
                self.doc.page_break()
            # it ignores language set for Note type (use locale)
            endnotes.write_endnotes(self.bibli, self.database, self.doc,
                                    printnotes=self.inc_srcnotes,
                                    elocale=self._locale)

    def write_path(self, person):
        path = []
        while True:
            #person changes in the loop
            family_handle = person.get_main_parents_family_handle()
            if family_handle:
                family = self.database.get_family_from_handle(family_handle)
                mother_handle = family.get_mother_handle()
                father_handle = family.get_father_handle()
                if mother_handle and mother_handle in self.dnumber:
                    person = self.database.get_person_from_handle(mother_handle)
                    person_name = \
                        self._name_display.display_name(person.get_primary_name())
                    path.append(person_name)
                elif father_handle and father_handle in self.dnumber:
                    person = self.database.get_person_from_handle(father_handle)
                    person_name = \
                        self._name_display.display_name(person.get_primary_name())
                    path.append(person_name)
                else:
                    break
            else:
                break

        index = len(path)

        if index:
            self.doc.write_text("(")

        for name in path:
            if index == 1:
                self.doc.write_text(name + "-" + str(index) + ") ")
            else:
                # translators: needed for Arabic, ignore otherwise
                self.doc.write_text(name + "-" + str(index) + self._("; "))
            index -= 1

    def write_person(self, key):
        """Output birth, death, parentage, marriage and notes information """

        person_handle = self.map[key]
        person = self.database.get_person_from_handle(person_handle)

        val = self.dnumber[person_handle]

        if val in self.numbers_printed:
            return
        else:
            self.numbers_printed.append(val)

        self.doc.start_paragraph("DDR-First-Entry","%s." % val)

        name = self._name_display.display_formal(person)
        mark = ReportUtils.get_person_mark(self.database, person)

        self.doc.start_bold()
        self.doc.write_text(name, mark)
        if name[-1:] == '.':
            self.doc.write_text_citation("%s " % self.endnotes(person))
        else:
            self.doc.write_text_citation("%s. " % self.endnotes(person))
        self.doc.end_bold()

        if self.inc_paths:
            self.write_path(person)

        if self.dubperson:
            # Check for duplicate record (result of distant cousins marrying)
            for dkey in sorted(self.map):
                if dkey >= key:
                    break
                if self.map[key] == self.map[dkey]:
                    self.doc.write_text(self._(
                        "%(name)s is the same person as [%(id_str)s].") % {
                            'name' :'',
                            'id_str': self.dnumber[self.map[dkey]],
                            }
                        )
                    self.doc.end_paragraph()
                    return

        self.doc.end_paragraph()

        self.write_person_info(person)

        if (self.inc_mates or self.listchildren or self.inc_notes or
            self.inc_events or self.inc_attrs):
            for family_handle in person.get_family_handle_list():
                family = self.database.get_family_from_handle(family_handle)
                if self.inc_mates:
                    self.__write_mate(person, family)
                if self.listchildren:
                    self.__write_children(family)
                if self.inc_notes:
                    self.__write_family_notes(family)
                first = True
                if self.inc_events:
                    first = self.__write_family_events(family)
                if self.inc_attrs:
                    self.__write_family_attrs(family, first)

    def write_event(self, event_ref):
        text = ""
        event = self.database.get_event_from_handle(event_ref.ref)

        if self.fulldate:
            date = self._get_date(event.get_date_object())
        else:
            date = event.get_date_object().get_year()

        ph = event.get_place_handle()
        if ph:
            place = self.database.get_place_from_handle(ph).get_title()
        else:
            place = ''

        self.doc.start_paragraph('DDR-MoreDetails')
        event_name = self._get_type(event.get_type())
        if date and place:
            text +=  self._('%(date)s, %(place)s') % {
                       'date' : date, 'place' : place }
        elif date:
            text += self._('%(date)s') % {'date' : date}
        elif place:
            text += self._('%(place)s') % { 'place' : place }

        if event.get_description():
            if text:
                text += ". "
            text += event.get_description()

        text += self.endnotes(event)

        if text:
            text += ". "

        text = self._('%(event_name)s: %(event_text)s') % {
                 'event_name' : self._(event_name),
                 'event_text' : text }

        self.doc.write_text_citation(text)

        if self.inc_attrs:
            text = ""
            attr_list = event.get_attribute_list()
            attr_list.extend(event_ref.get_attribute_list())
            for attr in attr_list:
                if text:
                    # translators: needed for Arabic, ignore otherwise
                    text += self._("; ")
                attrName = self._get_type(attr.get_type())
                text += self._("%(type)s: %(value)s%(endnotes)s") % {
                    'type'     : self._(attrName),
                    'value'    : attr.get_value(),
                    'endnotes' : self.endnotes(attr) }
            text = " " + text
            self.doc.write_text_citation(text)

        self.doc.end_paragraph()

        if self.inc_notes:
            # if the event or event reference has a note attached to it,
            # get the text and format it correctly
            notelist = event.get_note_list()
            notelist.extend(event_ref.get_note_list())
            for notehandle in notelist:
                note = self.database.get_note_from_handle(notehandle)
                self.doc.write_styled_note(note.get_styledtext(),
                        note.get_format(),"DDR-MoreDetails",
                        contains_html= note.get_type() == NoteType.HTML_CODE)

    def __write_parents(self, person):
        family_handle = person.get_main_parents_family_handle()
        if family_handle:
            family = self.database.get_family_from_handle(family_handle)
            mother_handle = family.get_mother_handle()
            father_handle = family.get_father_handle()
            if mother_handle:
                mother = self.database.get_person_from_handle(mother_handle)
                mother_name = \
                    self._name_display.display_name(mother.get_primary_name())
                mother_mark = ReportUtils.get_person_mark(self.database, mother)
            else:
                mother_name = ""
                mother_mark = ""
            if father_handle:
                father = self.database.get_person_from_handle(father_handle)
                father_name = \
                    self._name_display.display_name(father.get_primary_name())
                father_mark = ReportUtils.get_person_mark(self.database, father)
            else:
                father_name = ""
                father_mark = ""
            text = self.__narrator.get_child_string(father_name, mother_name)
            if text:
                self.doc.write_text(text)
                if father_mark:
                    self.doc.write_text("", father_mark)
                if mother_mark:
                    self.doc.write_text("", mother_mark)

    def write_marriage(self, person):
        """
        Output marriage sentence.
        """
        is_first = True
        for family_handle in person.get_family_handle_list():
            family = self.database.get_family_from_handle(family_handle)
            spouse_handle = ReportUtils.find_spouse(person, family)
            spouse = self.database.get_person_from_handle(spouse_handle)
            if spouse:
                name = self._name_display.display_formal(spouse)
            else:
                name = ""
            text = ""
            spouse_mark = ReportUtils.get_person_mark(self.database, spouse)

            text = self.__narrator.get_married_string(family, is_first, self._name_display)

            if text:
                self.doc.write_text_citation(text, spouse_mark)
                is_first = False

    def __write_mate(self, person, family):
        """
        Write information about the person's spouse/mate.
        """
        if person.get_gender() == Person.MALE:
            mate_handle = family.get_mother_handle()
        else:
            mate_handle = family.get_father_handle()

        if mate_handle:
            mate = self.database.get_person_from_handle(mate_handle)

            self.doc.start_paragraph("DDR-MoreHeader")
            name = self._name_display.display_formal(mate)
            mark = ReportUtils.get_person_mark(self.database, mate)
            if family.get_relationship() == FamilyRelType.MARRIED:
                self.doc.write_text(self._("Spouse: %s") % name, mark)
            else:
                self.doc.write_text(self._("Relationship with: %s") % name, mark)
            if name[-1:] != '.':
                self.doc.write_text(".")
            self.doc.write_text_citation(self.endnotes(mate))
            self.doc.end_paragraph()

            if not self.inc_materef:
                # Don't want to just print reference
                self.write_person_info(mate)
            else:
                # Check to see if we've married a cousin
                if mate_handle in self.dnumber:
                    self.doc.start_paragraph('DDR-MoreDetails')
                    self.doc.write_text_citation(
                        self._("Ref: %(number)s. %(name)s") %
                        {'number': self.dnumber[mate_handle], 'name': name})
                    self.doc.end_paragraph()
                else:
                    self.dmates[mate_handle] = person.get_handle()
                    self.write_person_info(mate)

    def __get_mate_names(self, family):
        mother_handle = family.get_mother_handle()
        if mother_handle:
            mother = self.database.get_person_from_handle(mother_handle)
            mother_name = self._name_display.display(mother)
        else:
            mother_name = self._("unknown")

        father_handle = family.get_father_handle()
        if father_handle:
            father = self.database.get_person_from_handle(father_handle)
            father_name = self._name_display.display(father)
        else:
            father_name = self._("unknown")

        return mother_name, father_name

    def __write_children(self, family):
        """
        List the children for the given family.
        """
        if not family.get_child_ref_list():
            return

        mother_name, father_name = self.__get_mate_names(family)

        self.doc.start_paragraph("DDR-ChildTitle")
        self.doc.write_text(
                        self._("Children of %(mother_name)s and %(father_name)s") %
                            {'father_name': father_name,
                             'mother_name': mother_name
                             } )
        self.doc.end_paragraph()

        cnt = 1
        for child_ref in family.get_child_ref_list():
            child_handle = child_ref.ref
            child = self.database.get_person_from_handle(child_handle)
            child_name = self._name_display.display(child)
            child_mark = ReportUtils.get_person_mark(self.database, child)

            if self.childref and self.prev_gen_handles.get(child_handle):
                value = str(self.prev_gen_handles.get(child_handle))
                child_name += " [%s]" % value

            if self.inc_ssign:
                prefix = " "
                for family_handle in child.get_family_handle_list():
                    family = self.database.get_family_from_handle(family_handle)
                    if family.get_child_ref_list():
                        prefix = "+ "
                        break
            else:
                prefix = ""

            if child_handle in self.dnumber:
                self.doc.start_paragraph("DDR-ChildList",
                        prefix
                        + str(self.dnumber[child_handle])
                        + " "
                        + ReportUtils.roman(cnt).lower()
                        + ".")
            else:
                self.doc.start_paragraph("DDR-ChildList",
                              prefix + ReportUtils.roman(cnt).lower() + ".")
            cnt += 1

            self.doc.write_text("%s. " % child_name, child_mark)
            self.__narrator.set_subject(child)
            self.doc.write_text_citation(self.__narrator.get_born_string() or
                                         self.__narrator.get_christened_string() or
                                         self.__narrator.get_baptised_string())
            self.doc.write_text_citation(self.__narrator.get_died_string() or
                                         self.__narrator.get_buried_string())
            self.doc.end_paragraph()

    def __write_family_notes(self, family):
        """
        Write the notes for the given family.
        """
        notelist = family.get_note_list()
        if len(notelist) > 0:
            mother_name, father_name = self.__get_mate_names(family)

            self.doc.start_paragraph("DDR-NoteHeader")
            self.doc.write_text(
                self._('Notes for %(mother_name)s and %(father_name)s:') % {
                'mother_name' : mother_name,
                'father_name' : father_name })
            self.doc.end_paragraph()
            for notehandle in notelist:
                note = self.database.get_note_from_handle(notehandle)
                self.doc.write_styled_note(note.get_styledtext(),
                                           note.get_format(),"DDR-Entry")

    def __write_family_events(self, family):
        """
        List the events for the given family.
        """
        if not family.get_event_ref_list():
            return

        mother_name, father_name = self.__get_mate_names(family)

        first = 1
        for event_ref in family.get_event_ref_list():
            if first:
                self.doc.start_paragraph('DDR-MoreHeader')
                self.doc.write_text(
                    self._('More about %(mother_name)s and %(father_name)s:') % {
                    'mother_name' : mother_name,
                    'father_name' : father_name })
                self.doc.end_paragraph()
                first = 0
            self.write_event(event_ref)
            return first

    def __write_family_attrs(self, family, first):
        """
        List the attributes for the given family.
        """
        attrs = family.get_attribute_list()

        if first and attrs:
            mother_name, father_name = self.__get_mate_names(family)

            self.doc.start_paragraph('DDR-MoreHeader')
            self.doc.write_text(
                self._('More about %(mother_name)s and %(father_name)s:') % {
                'mother_name' : mother_name,
                'father_name' : father_name })
            self.doc.end_paragraph()

        for attr in attrs:
            self.doc.start_paragraph('DDR-MoreDetails')
            attrName = self._get_type(attr.get_type())
            text = self._("%(type)s: %(value)s%(endnotes)s") % {
                'type'     : self._(attrName),
                'value'    : attr.get_value(),
                'endnotes' : self.endnotes(attr) }
            self.doc.write_text_citation( text )
            self.doc.end_paragraph()

            if self.inc_notes:
                # if the attr or attr reference has a note attached to it,
                # get the text and format it correctly
                notelist = attr.get_note_list()
                for notehandle in notelist:
                    note = self.database.get_note_from_handle(notehandle)
                    self.doc.write_styled_note(note.get_styledtext(),
                                               note.get_format(),"DDR-MoreDetails")

    def write_person_info(self, person):
        name = self._name_display.display_formal(person)
        self.__narrator.set_subject(person)

        plist = person.get_media_list()
        if self.addimages and len(plist) > 0:
            photo = plist[0]
            ReportUtils.insert_image(self.database, self.doc, photo, self._user)

        self.doc.start_paragraph("DDR-Entry")

        if not self.verbose:
            self.__write_parents(person)

        text = self.__narrator.get_born_string()
        if text:
            self.doc.write_text_citation(text)

        text = self.__narrator.get_baptised_string()
        if text:
            self.doc.write_text_citation(text)

        text = self.__narrator.get_christened_string()
        if text:
            self.doc.write_text_citation(text)

        text = self.__narrator.get_died_string(self.calcageflag)
        if text:
            self.doc.write_text_citation(text)

        text = self.__narrator.get_buried_string()
        if text:
            self.doc.write_text_citation(text)

        if self.verbose:
            self.__write_parents(person)
        self.write_marriage(person)
        self.doc.end_paragraph()

        notelist = person.get_note_list()
        if len(notelist) > 0 and self.inc_notes:
            self.doc.start_paragraph("DDR-NoteHeader")
            # feature request 2356: avoid genitive form
            self.doc.write_text(self._("Notes for %s") % name)
            self.doc.end_paragraph()
            for notehandle in notelist:
                note = self.database.get_note_from_handle(notehandle)
                self.doc.write_styled_note(note.get_styledtext(),
                        note.get_format(),"DDR-Entry",
                        contains_html= note.get_type() == NoteType.HTML_CODE)

        first = True
        if self.inc_names:
            for alt_name in person.get_alternate_names():
                if first:
                    self.doc.start_paragraph('DDR-MoreHeader')
                    self.doc.write_text(self._('More about %(person_name)s:') % {
                        'person_name' : name })
                    self.doc.end_paragraph()
                    first = False
                self.doc.start_paragraph('DDR-MoreDetails')
                atype = self._get_type(alt_name.get_type())
                aname = alt_name.get_regular_name()
                self.doc.write_text_citation(self._('%(name_kind)s: %(name)s%(endnotes)s') % {
                    'name_kind' : self._(atype),
                    'name' : aname,
                    'endnotes' : self.endnotes(alt_name),
                    })
                self.doc.end_paragraph()

        if self.inc_events:
            for event_ref in person.get_primary_event_ref_list():
                if first:
                    self.doc.start_paragraph('DDR-MoreHeader')
                    self.doc.write_text(self._('More about %(person_name)s:') % {
                        'person_name' : self._name_display.display(person) })
                    self.doc.end_paragraph()
                    first = 0

                self.write_event(event_ref)

        if self.inc_addr:
            for addr in person.get_address_list():
                if first:
                    self.doc.start_paragraph('DDR-MoreHeader')
                    self.doc.write_text(self._('More about %(person_name)s:') % {
                        'person_name' : name })
                    self.doc.end_paragraph()
                    first = False
                self.doc.start_paragraph('DDR-MoreDetails')

                text = ReportUtils.get_address_str(addr)

                if self.fulldate:
                    date = self._get_date(addr.get_date_object())
                else:
                    date = addr.get_date_object().get_year()

                self.doc.write_text(self._('Address: '))
                if date:
                    # translators: needed for Arabic, ignore otherwise
                    self.doc.write_text(self._('%s, ') % date )
                self.doc.write_text( text )
                self.doc.write_text_citation( self.endnotes(addr) )
                self.doc.end_paragraph()

        if self.inc_attrs:
            attrs = person.get_attribute_list()
            if first and attrs:
                self.doc.start_paragraph('DDR-MoreHeader')
                self.doc.write_text(self._('More about %(person_name)s:') % {
                    'person_name' : name })
                self.doc.end_paragraph()
                first = False

            for attr in attrs:
                self.doc.start_paragraph('DDR-MoreDetails')
                attrName = self._get_type(attr.get_type())
                text = self._("%(type)s: %(value)s%(endnotes)s") % {
                    'type'     : self._(attrName),
                    'value'    : attr.get_value(),
                    'endnotes' : self.endnotes(attr) }
                self.doc.write_text_citation( text )
                self.doc.end_paragraph()

    def endnotes(self, obj):
        if not obj or not self.inc_sources:
            return ""

        txt = endnotes.cite_source(self.bibli, self.database, obj)
        if txt:
            txt = '<super>' + txt + '</super>'
        return txt

#------------------------------------------------------------------------
#
# DetDescendantOptions
#
#------------------------------------------------------------------------
class DetDescendantOptions(MenuReportOptions):

    """
    Defines options and provides handling interface.
    """

    def __init__(self, name, dbase):
        MenuReportOptions.__init__(self, name, dbase)

    def add_menu_options(self, menu):
        """
        Add options to the menu for the detailed descendant report.
        """

        # Report Options
        category = _("Report Options")
        add_option = partial(menu.add_option, category)

        pid = PersonOption(_("Center Person"))
        pid.set_help(_("The center person for the report"))
        add_option("pid", pid)

        stdoptions.add_name_format_option(menu, category)

        numbering = EnumeratedListOption(_("Numbering system"), "Henry")
        numbering.set_items([
                ("Henry",      _("Henry numbering")),
                ("d'Aboville", _("d'Aboville numbering")),
                ("Record (Modified Register)",
                               _("Record (Modified Register) numbering"))])
        numbering.set_help(_("The numbering system to be used"))
        add_option("numbering", numbering)

        generations = NumberOption(_("Generations"), 10, 1, 100)
        generations.set_help(
            _("The number of generations to include in the report")
            )
        add_option("gen", generations)

        pagebbg = BooleanOption(_("Page break between generations"), False)
        pagebbg.set_help(
                     _("Whether to start a new page after each generation."))
        add_option("pagebbg", pagebbg)

        pageben = BooleanOption(_("Page break before end notes"),False)
        pageben.set_help(
                     _("Whether to start a new page before the end notes."))
        add_option("pageben", pageben)

        stdoptions.add_localization_option(menu, category)

        # Content

        add_option = partial(menu.add_option, _("Content"))

        usecall = BooleanOption(_("Use callname for common name"), False)
        usecall.set_help(_("Whether to use the call name as the first name."))
        add_option("usecall", usecall)

        fulldates = BooleanOption(_("Use full dates instead of only the year"),
                                  True)
        fulldates.set_help(_("Whether to use full dates instead of just year."))
        add_option("fulldates", fulldates)

        listc = BooleanOption(_("List children"), True)
        listc.set_help(_("Whether to list children."))
        add_option("listc", listc)

        computeage = BooleanOption(_("Compute death age"),True)
        computeage.set_help(_("Whether to compute a person's age at death."))
        add_option("computeage", computeage)

        omitda = BooleanOption(_("Omit duplicate ancestors"), True)
        omitda.set_help(_("Whether to omit duplicate ancestors."))
        add_option("omitda", omitda)

        verbose = BooleanOption(_("Use complete sentences"), True)
        verbose.set_help(
                 _("Whether to use complete sentences or succinct language."))
        add_option("verbose", verbose)

        desref = BooleanOption(_("Add descendant reference in child list"),
                               True)
        desref.set_help(
                    _("Whether to add descendant references in child list."))
        add_option("desref", desref)

        category_name = _("Include")
        add_option = partial(menu.add_option, _("Include"))

        incnotes = BooleanOption(_("Include notes"), True)
        incnotes.set_help(_("Whether to include notes."))
        add_option("incnotes", incnotes)

        incattrs = BooleanOption(_("Include attributes"), False)
        incattrs.set_help(_("Whether to include attributes."))
        add_option("incattrs", incattrs)

        incphotos = BooleanOption(_("Include Photo/Images from Gallery"), False)
        incphotos.set_help(_("Whether to include images."))
        add_option("incphotos", incphotos)

        incnames = BooleanOption(_("Include alternative names"), False)
        incnames.set_help(_("Whether to include other names."))
        add_option("incnames", incnames)

        incevents = BooleanOption(_("Include events"), False)
        incevents.set_help(_("Whether to include events."))
        add_option("incevents", incevents)

        incaddresses = BooleanOption(_("Include addresses"), False)
        incaddresses.set_help(_("Whether to include addresses."))
        add_option("incaddresses", incaddresses)

        incsources = BooleanOption(_("Include sources"), False)
        incsources.set_help(_("Whether to include source references."))
        add_option("incsources", incsources)

        incsrcnotes = BooleanOption(_("Include sources notes"), False)
        incsrcnotes.set_help(_("Whether to include source notes in the "
            "Endnotes section. Only works if Include sources is selected."))
        add_option("incsrcnotes", incsrcnotes)

        incmates = BooleanOption(_("Include spouses"), False)
        incmates.set_help(_("Whether to include detailed spouse information."))
        add_option("incmates", incmates)

        incmateref = BooleanOption(_("Include spouse reference"), False)
        incmateref.set_help(_("Whether to include reference to spouse."))
        add_option("incmateref", incmateref)

        incssign = BooleanOption(_("Include sign of succession ('+')"
                                   " in child-list"), True)
        incssign.set_help(_("Whether to include a sign ('+') before the"
                            " descendant number in the child-list to indicate"
                            " a child has succession."))
        add_option("incssign", incssign)

        incpaths = BooleanOption(_("Include path to start-person"), False)
        incpaths.set_help(_("Whether to include the path of descendancy "
                            "from the start-person to each descendant."))
        add_option("incpaths", incpaths)

        # Missing information

        add_option = partial(menu.add_option, _("Missing information"))

        repplace = BooleanOption(_("Replace missing places with ______"), False)
        repplace.set_help(_("Whether to replace missing Places with blanks."))
        add_option("repplace", repplace)

        repdate = BooleanOption(_("Replace missing dates with ______"), False)
        repdate.set_help(_("Whether to replace missing Dates with blanks."))
        add_option("repdate", repdate)

    def make_default_style(self, default_style):
        """Make the default output style for the Detailed Ancestral Report"""
        font = FontStyle()
        font.set(face=FONT_SANS_SERIF, size=16, bold=1)
        para = ParagraphStyle()
        para.set_font(font)
        para.set_header_level(1)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_alignment(PARA_ALIGN_CENTER)
        para.set_description(_('The style used for the title of the page.'))
        default_style.add_paragraph_style("DDR-Title", para)

        font = FontStyle()
        font.set(face=FONT_SANS_SERIF, size=14, italic=1)
        para = ParagraphStyle()
        para.set_font(font)
        para.set_header_level(2)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_description(_('The style used for the generation header.'))
        default_style.add_paragraph_style("DDR-Generation", para)

        font = FontStyle()
        font.set(face=FONT_SANS_SERIF, size=10, italic=0, bold=1)
        para = ParagraphStyle()
        para.set_font(font)
        para.set_left_margin(1.5)   # in centimeters
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_description(_('The style used for the children list title.'))
        default_style.add_paragraph_style("DDR-ChildTitle", para)

        font = FontStyle()
        font.set(size=10)
        para = ParagraphStyle()
        para.set_font(font)
        para.set(first_indent=-0.75, lmargin=2.25)
        para.set_top_margin(0.125)
        para.set_bottom_margin(0.125)
        para.set_description(_('The style used for the children list.'))
        default_style.add_paragraph_style("DDR-ChildList", para)

        font = FontStyle()
        font.set(face=FONT_SANS_SERIF, size=10, italic=0, bold=1)
        para = ParagraphStyle()
        para.set_font(font)
        para.set(first_indent=0.0, lmargin=1.5)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        default_style.add_paragraph_style("DDR-NoteHeader", para)

        para = ParagraphStyle()
        para.set(lmargin=1.5)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_description(_('The basic style used for the text display.'))
        default_style.add_paragraph_style("DDR-Entry", para)

        para = ParagraphStyle()
        para.set(first_indent=-1.5, lmargin=1.5)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_description(_('The style used for the first personal entry.'))
        default_style.add_paragraph_style("DDR-First-Entry", para)

        font = FontStyle()
        font.set(size=10, face=FONT_SANS_SERIF, bold=1)
        para = ParagraphStyle()
        para.set_font(font)
        para.set(first_indent=0.0, lmargin=1.5)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_description(_('The style used for the More About header and '
            'for headers of mates.'))
        default_style.add_paragraph_style("DDR-MoreHeader", para)

        font = FontStyle()
        font.set(face=FONT_SERIF, size=10)
        para = ParagraphStyle()
        para.set_font(font)
        para.set(first_indent=0.0, lmargin=1.5)
        para.set_top_margin(0.25)
        para.set_bottom_margin(0.25)
        para.set_description(_('The style used for additional detail data.'))
        default_style.add_paragraph_style("DDR-MoreDetails", para)

        endnotes.add_endnote_styles(default_style)


import random
import torch
import torch.nn as nn
import torch.nn.parallel
from miscc.config import cfg
from torch.autograd import Variable
import torch.nn.functional as F
from torchvision import models
import torch.utils.model_zoo as model_zoo

class Encoder(nn.Module):
    def __init__(self):
        super(Encoder, self).__init__()

        self.hid_dim = cfg.CHARLSTM.DIMENSION
        self.n_layers = 1

        self.word_embeds = nn.Embedding(cfg.CHAR.VOCABSIZE, cfg.CHARVEC.DIMENSION)

        self.pokemon_embed = nn.Linear(cfg.POKEMON.SIZE, cfg.POKEMON.DIMENSION)

        self.rnn = nn.LSTM(cfg.CHARVEC.DIMENSION + cfg.POKEMON.DIMENSION, cfg.CHARLSTM.DIMENSION, 1, dropout=cfg.CHARLSTM.DROPOUT)

        self.dropout = nn.Dropout(cfg.CHARLSTM.DROPOUT)

    def forward(self, sentence, embedding):
        embeds = self.word_embeds(Variable(sentence))
        concated_emb = torch.cat((embeds, self.pokemon_embed(embedding).repeat(len(sentence), 1, 1)), dim=2)
        lstm_out, (hn, cn) = self.rnn(concated_emb)
        return hn, cn

class Decoder(nn.Module):
    def __init__(self):
        super(Decoder, self).__init__()

        self.output_dim = cfg.CHAR.VOCABSIZE
        self.hid_dim = cfg.CHARLSTM.DIMENSION
        self.n_layers = 1

        self.word_embeds = nn.Embedding(cfg.CHAR.VOCABSIZE + 1, cfg.CHARVEC.DIMENSION)

        self.pokemon_embed = nn.Linear(cfg.POKEMON.SIZE, cfg.POKEMON.DIMENSION)

        self.rnn = nn.LSTM(cfg.CHARVEC.DIMENSION + cfg.POKEMON.DIMENSION, cfg.CHARLSTM.DIMENSION, 1, dropout=cfg.CHARLSTM.DROPOUT)

        self.fc_out = nn.Linear(cfg.CHARLSTM.DIMENSION, cfg.CHAR.VOCABSIZE + cfg.POKEMON.SIZE)

        self.dropout = nn.Dropout(cfg.CHARLSTM.DROPOUT)

    def forward(self, sentence, embedding, hidden, cell):
        sentence = sentence.unsqueeze(0)
        embeds = self.word_embeds(Variable(sentence))
        concated_emb = torch.cat((embeds, self.pokemon_embed(embedding).unsqueeze(0)), dim=2)
        output, (hidden, cell) = self.rnn(concated_emb, (hidden, cell))
        prediction = self.fc_out(output.squeeze(0))
        output_word = prediction[:, :cfg.CHAR.VOCABSIZE]
        output_emb = prediction[:, cfg.CHAR.VOCABSIZE:]

        return output_word, output_emb, hidden, cell

class Seq2Seq(nn.Module):
    def __init__(self, encoder, decoder, device):
        super(Seq2Seq, self).__init__()

        self.encoder = encoder
        self.decoder = decoder
        self.device = device

        assert encoder.module.hid_dim == decoder.module.hid_dim, \
            "Hidden dimensions of encoder and decoder must be equal!"
        assert encoder.module.n_layers == decoder.module.n_layers, \
            "Encoder and decoder must have equal number of layers!"

    def forward(self, pokemon_words, pokemon_emb, teacher_forcing_ratio=0.5):
        # src = [src len, batch size]
        # src = [src len, batch size]
        # teacher_forcing_ratio is probability to use teacher forcing
        # e.g. if teacher_forcing_ratio is 0.75 we use ground-truth inputs 75% of the time

        batch_size = pokemon_words.shape[1]
        src_len = pokemon_words.shape[0]
        src_vocab_size = self.decoder.module.output_dim

        # tensor to store decoder outputs
        outputs = torch.zeros(src_len, batch_size, src_vocab_size).to(self.device)

        # last hidden state of the encoder is used as the initial hidden state of the decoder
        hidden, cell = self.encoder(pokemon_words, pokemon_emb)

        # first input to the decoder is the <sos> tokens
        input = torch.tensor([cfg.CHAR.VOCABSIZE]).repeat(cfg.TRAIN.BATCH_SIZE)
        input_pokemon_emb = torch.zeros(cfg.TRAIN.BATCH_SIZE, cfg.POKEMON.SIZE)
        for t in range(src_len):
            # insert input token embedding, previous hidden and previous cell states
            # receive output tensor (predictions) and new hidden and cell states
            output_word, output_emb, hidden, cell = self.decoder(input, input_pokemon_emb, hidden, cell)

            # place predictions in a tensor holding predictions for each token
            outputs[t] = output_word

            # decide if we are going to use teacher forcing or not
            teacher_force = random.random() < teacher_forcing_ratio

            # get the highest predicted token from our predictions
            top1 = torch.argmax(output_word, dim=1)

            # if teacher forcing, use actual next token as next input
            # if not, use predicted token
            if teacher_force:
                input = pokemon_words[t]
                input_pokemon_emb = pokemon_emb
            else:
                input = top1
                input_pokemon_emb = output_emb

        return outputs, output_emb


#! /usr/bin/env python3

import os
import signal
from subprocess import call
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as AppIndicator

APPINDICATOR_ID = "screenrotator"
orientation = "right"

def main():
    global indicator
    script_path = os.path.dirname(os.path.realpath(__file__))
    icon_path = script_path + '/icon.svg'
    indicator = AppIndicator.Indicator.new(APPINDICATOR_ID, icon_path, AppIndicator.IndicatorCategory.SYSTEM_SERVICES)
    indicator.set_label("Horizontal", "Horizontal")
    indicator.set_status(AppIndicator.IndicatorStatus.ACTIVE)
    indicator.set_menu(build_menu())
    Gtk.main()

def build_menu():
    menu = Gtk.Menu()
    #rotate
    item_rotate = Gtk.MenuItem(label='Rotar pantalla')
    item_rotate.connect('activate', rotate_screen)
    menu.append(item_rotate)
    #seperator
    seperator = Gtk.SeparatorMenuItem()
    menu.append(seperator)
    #quit
    item_quit = Gtk.MenuItem(label='Cerrar')
    item_quit.connect('activate', quit)
    menu.append(item_quit)
    menu.show_all()
    return menu

def rotate_screen(source):
    global orientation
    if orientation == "right":
        indicator.set_label("Vertical", "Horizontal")
        direction = "normal"
    elif orientation == "normal":
        indicator.set_label("Horizontal", "Horizontal")
        direction ="right"
    call(["xrandr", "-o", direction])
    orientation = direction

if __name__ == "__main__":
    #make sure the screen is in "right" orientation when the script starts
    call(["xrandr", "-o", orientation])
    #keyboard interrupt handler
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    main()


import mxnet as mx

class Quantization_int8(mx.operator.CustomOp):
    def __init__(self, quant_mode, is_weight, is_weight_perchannel, delay_quant, ema_decay):
        self.quant_mode = quant_mode
        self.is_weight = is_weight
        self.is_weight_perchannel = is_weight_perchannel
        self.delay_quant = delay_quant
        self.ema_decay = ema_decay
        self.QUANT_LEVEL = 127
        self.init = True
    def forward(self, is_train, req, in_data, out_data, aux):
        if is_train and self.delay_quant > 0:
            self.assign(out_data[0], req[0], in_data[0])
            self.delay_quant -= 1
            return
        if self.is_weight:
            data = mx.nd.abs(in_data[0])
            if self.is_weight_perchannel:
                target_shape = (data.shape[0],) + (1,) * len(data.shape[1:])
                reduce_axis = tuple([i for i in range(len(data.shape))])
                maxs = mx.nd.max(data, axis=reduce_axis[1:])
                quant_unit = maxs / self.QUANT_LEVEL
                quant_unit = quant_unit.reshape(target_shape).broadcast_like(in_data[0])
            else:
                maxs = mx.nd.max(data)
                quant_unit = maxs / self.QUANT_LEVEL
            self.assign(out_data[0], req[0], mx.nd.round(in_data[0] / quant_unit) * quant_unit)
            # save weight maxs
            if is_train:
                aux[0][:] = maxs
        else:
            if is_train:
                data = mx.nd.abs(in_data[0])
                maxs = mx.nd.max(data)
                # udpate acativation maxs
                aux[0][:] = aux[0] * self.ema_decay + maxs * (1 - self.ema_decay)

            quant_unit = aux[0] / self.QUANT_LEVEL
            self.assign(out_data[0], req[0], mx.nd.round(in_data[0] / quant_unit) * quant_unit)
    def backward(self, req, out_grad, in_data, out_data, in_grad, aux):
        self.assign(in_grad[0], req[0], out_grad[0])

@mx.operator.register("Quantization_int8_V2")
class QuantizationInt8Prop(mx.operator.CustomOpProp):
    def __init__(self, quant_mode, is_weight, is_weight_perchannel=False, delay_quant=0, ema_decay=0.99):
        self.quant_mode = str(quant_mode)
        self.delay_quant = int(delay_quant)
        self.ema_decay = float(ema_decay)
        self.is_weight = eval(is_weight)
        self.is_weight_perchannel = eval(is_weight_perchannel)
        super(QuantizationInt8Prop, self).__init__(True)
    def list_arguments(self):
        return ['data']
    def list_outputs(self):
        return ['output']
    def list_auxiliary_states(self):
        return ["minmax"]
    def infer_shape(self, in_shape):
        shape = in_shape[0]
        if self.is_weight_perchannel and self.is_weight:
            aux_shape = [shape[0]]
        else:
            aux_shape = [1]
        return [shape], [shape], [aux_shape]
    def infer_type(self, in_type):
        return in_type, in_type, in_type

    def create_operator(self, ctx, shapes, dtypes):
        return Quantization_int8(self.quant_mode, self.is_weight,
                                 self.is_weight_perchannel,
                                 self.delay_quant, self.ema_decay)

def get_sym_output_channel(name, sym, data_shape=(1, 3, 224, 224)):
    _, out_shapes, _ = sym.infer_shape(data=data_shape)
    assert len(out_shapes) == 1, 'the output of sym is not equal to 1'
    # print('sym:{}:{}'.format(name, sym))
    return out_shapes[0][1]

def quant_conv(name, data, num_filter, kernel, stride, pad=(0,0), no_bias=True, dilate=(1,1), num_group=1,
               quant_mod='minmax', delay_quant=0, is_weight_perchannel=False):
    if is_weight_perchannel:
        assert quant_mod == "minmax", "currenet weight perchannel only support minmax node with weight"

    input_channel = get_sym_output_channel(name, data)
    weight = mx.sym.Variable(name=name + "_weight", shape=(num_filter, input_channel // num_group, kernel[0], kernel[1]),
                             dtype="float32")
    weight_q = mx.sym.Custom(data=weight, name = name + "_weight_quant", quant_mode=quant_mod, is_weight=True,
                             is_weight_perchannel = is_weight_perchannel, ema_decay=0.99, delay_quant=delay_quant,
                             op_type="Quantization_int8_V2")
    data_q = mx.sym.Custom(data=data, name = name + "_data_quant", quant_mode=quant_mod, is_weight=False,
                             is_weight_perchannel = False, ema_decay=0.99, delay_quant=delay_quant,
                             op_type="Quantization_int8_V2")
    conv = mx.symbol.Convolution(
        name=name,
        data=data_q,
        num_filter=num_filter,
        kernel=kernel,
        num_group=num_group,
        stride=stride,
        pad=pad,
        no_bias=no_bias,
        dilate=dilate,
        weight=weight_q
    )
    return conv

def quant_fc(name, data, num_hidden, quant_mod='minmax', delay_quant=0, is_weight_perchannel=False):
    if is_weight_perchannel:
        assert quant_mod == "minmax", "currenet weight perchannel only support minmax node with weight"
    input_channel = get_sym_output_channel(name, data)
    fc_weight = mx.sym.Variable(name=name +"_weight", shape=(num_hidden, input_channel), dtype="float32")
    fc_q = mx.sym.Custom(fc_weight, name= name + "_weight_quant", is_weight=True, ema_decay=0.99,
                         delay_quant=delay_quant, quant_mode = quant_mod, is_weight_perchannel=is_weight_perchannel,
                         op_type="Quantization_int8_V2")
    fc_data_q = mx.sym.Custom(data=data, name= name + "_data_quant", is_weight=False, ema_decay=0.99,
                              delay_quant=delay_quant, quant_mode = quant_mod, is_weight_perchannel=False,
                              op_type="Quantization_int8_V2")
    fc = mx.symbol.FullyConnected(data=fc_data_q, num_hidden=num_hidden, name='fc', weight=fc_q)
    return fc


### imports
import sys, os, time
import logging
import numpy as np
import h5py
from matplotlib import pyplot as plt
from analysis.lib.tools import toolbox

class M2Analysis:

    plot_format = 'png'

    def __init__(self, folder, **kw):
        #print 'analyzing in', folder
        self.folder = folder
        self.load_hdf5data(**kw)

    def load_hdf5data(self, **kw):
        self.h5filepath = toolbox.measurement_filename(self.folder)
        h5mode=kw.pop('hdf5_mode', 'r')
        self.f = h5py.File(self.h5filepath,h5mode)
        for k in self.f.keys():
            if type(self.f[k])==h5py.Group and k in os.path.split(self.h5filepath)[1]: # PH added this check because sometimes additional files added to hdf5 file (06/16)
                self.name = k
                self.g = self.f[self.name]
                break

        self.measurementstring = os.path.split(self.folder)[1]
        self.timestamp = os.path.split(os.path.split(self.folder)[0])[1] \
                + '/' + self.measurementstring[:6]
        self.measurementstring = self.measurementstring[7:]
        self.default_plot_title = self.timestamp+'\n'+self.measurementstring

    def finish(self):
        self.f.close()

    def adwingrp(self, name=''):

        if name != '':
            adwingrpname = name
        else:
            if len(self.g.keys()) == 1:
                adwingrpname = self.g.keys()[0]
            else:
                logging.error("More than one measurement. Please give a name")
                return False
        return self.g[adwingrpname]

    def analysis_h5data(self, name='analysis'):
        if not os.path.exists(os.path.join(self.folder, name+'.hdf5')):
            mode = 'w'
        else:
            mode = 'r+'

        return h5py.File(os.path.join(self.folder, name+'.hdf5'), mode)

    def default_fig(self, **kw):
        figsize = kw.pop('figsize', (4,4))

        return plt.figure(figsize=figsize, **kw)

    def default_ax(self, fig=None, *arg, **kw):
        if fig == None:
            fig = self.default_fig(*arg, **kw)

        ax = fig.add_subplot(111)
        ax.set_title(self.timestamp+'\n'+self.measurementstring)

        return ax

    def save_fig_incremental_filename(self,fig,savename):
            i=1
            sfn=os.path.join(self.folder, savename+'-{}.png'.format(i))
            while(os.path.exists(sfn)):
                sfn=os.path.splitext(sfn)[0][:-2]+'-{}.png'.format(i)
                i=i+1
            fig.savefig(sfn,format='png')


import argparse
import codecs
import logging
from collections import Counter

import epihan
import panphon
import unicodecsv as csv

logging.basicConfig(level=logging.WARNING)

def normpunc(epi, s):
    def norm(c):
        if c in dict(epi.punc):
            return epi.normalize_punc(c)
        else:
            return c
    return ''.join(map(norm, s))

def add_record_gen(epi, ft, orth):
    space = Counter()
    orth = normpunc(epi, orth)
    trans = epi.transliterate(orth)
    while trans:
        pref = ft.longest_one_seg_prefix(trans)
        if pref != '':
            space[pref] += 1
            trans = trans[len(pref):]
        else:
            if trans[0] in epi.puncnorm_vals:
                space[trans[0]] += 1
            else:
                space[trans[0]] += 1
            trans = trans[1:]
    return space

def add_file(epi, ft, fn):
    space = Counter()
    with codecs.open(fn, 'r', 'utf-8') as f:
        for line in f:
            fields = line.split(u'\t')
            if len(fields) > 0:
                orth = fields[0]
                space.update(add_record_gen(epi, ft, orth))
    logging.debug(u'Length of counter:\t{}'.format(len(space)))
    return space

def print_space(output, space):
    pairs = enumerate(sorted(filter(lambda x: x, space.keys())))
    with open(output, 'wb') as f:
        writer = csv.writer(f, encoding='utf-8')
        for i, char in pairs:
            writer.writerow((i, char))

def main(infiles, output):
    epi = epihan.Epihan('cedict', 'pinyin-to-ipa')
    ft = panphon.FeatureTable()
    space = Counter()
    for fn in infiles:
        logging.debug(u'Scanning:\t{}'.format(fn).encode('utf-8'))
        space.update(add_file(epi, ft, fn))
    print_space(output, space)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output', help='Output file.')
    parser.add_argument('infiles', nargs='+', help='CONLL files serving as basis for segment space.')
    args = parser.parse_args()
    main(args.infiles, args.output)


import sys
from cx_Freeze import setup, Executable

# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    name="XcalxS",
    version="0.1.0",
    description="RPN Calculator",
    options={
        "build_exe": {
            "include_msvcr": False,
            "optimize": 2,
            "packages": [],
            "includes": ['atexit', 'solver_tab', 'solver_lex'],
            "excludes": ["email", 'PySide.QtNetwork'],
            "bin_path_includes": [],
            "bin_path_excludes": [],
            "bin_includes": [],
            "bin_excludes": ['imageformats/*.dll'],
            "include_files": [],
            },
        },
    executables=[
        Executable("xcalcs.py", base=base),
        Executable("console.py", base=base)
        ],
    )