import graphene
from django.db import IntegrityError, transaction
from graphql_jwt.decorators import login_required

from backend.graphql.exceptions import ValidationError
from backend.trip.graphql.types import TripType, ExpenseType
from backend.trip.graphql.inputs import CreateTripInput, UpdateTripInput, CreateOrUpdateTripCategoryInput, CreateExpenseInput, UpdateExpenseInput
from backend.trip.models import Trip, TripUser, TripCategory, Expense
from backend.core.models import Currency
from backend.trip.constants import TripUserRoles
from backend.core.services import get_countries, get_currency
from backend.trip.services import get_trip, get_expense_in_trip, get_category_in_trip
from backend.trip.permissions import UserIsInTripPermission
from backend.graphql.mutations import BaseMutation
from backend.graphql.decorators import permission_classes

class CreateTrip(BaseMutation):
    trip = graphene.Field(TripType)

    class Arguments:
        input = CreateTripInput(required=True)

    class Meta:
        description = 'Create trip'

    @login_required
    def perform_mutation(cls, info, input):
        base_currency = get_currency(input['base_currency'], 'base_currency')
        countries = get_countries(input['countries'])

        with transaction.atomic():
            trip = Trip(
                title=input['title'],
                budget=input['budget'],
                start_date=input['start_date'],
                end_date=input['end_date'],
                base_currency=base_currency,
            )
            trip.save()

            trip.countries.add(*countries)

            TripUser.objects.create(
                user=info.context.user,
                trip=trip,
                role=TripUserRoles.DEFAULT
            )
        return CreateTrip(trip=trip)

class UpdateTrip(BaseMutation):
    trip = graphene.Field(TripType)

    class Arguments:
        id = graphene.ID(required=True)
        input = UpdateTripInput(required=True)

    class Meta:
        description = 'Update trip'
        editable_fields = (
            'title',
            'budget',
            'start_date',
            'end_date',
            'countries',
        )

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, id, input):
        countries = None
        if 'countries' in input:
            countries = get_countries(input['countries'])

        with transaction.atomic():
            trip = Trip.objects.get(id=id)
            for key, value in input.items():
                if key in UpdateTrip._meta.editable_fields and key is not 'countries':
                    setattr(trip, key, value)
            trip.save()

            if 'countries' in UpdateTrip._meta.editable_fields and countries:
                trip.countries.set(countries)
        return UpdateTrip(trip=trip)

class DeleteTrip(BaseMutation):
    id = graphene.ID()

    class Arguments:
        id = graphene.ID(required=True)

    class Meta:
        description = 'Delete trip'

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, id):
        trip = get_trip(id)

        with transaction.atomic():
            trip.delete()

        return DeleteTrip(id=id)

class CreateOrUpdateTripCategory(BaseMutation):
    trip = graphene.Field(TripType)

    class Arguments:
        trip_id = graphene.ID(required=True)
        categories = graphene.List(CreateOrUpdateTripCategoryInput, required=True)

    class Meta:
        description = 'Create or update trip category'
        editable_fields = (
            'id',
            'name',
            'color',
        )

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, trip_id, categories):
        trip = get_trip(trip_id)

        with transaction.atomic():
            for category in categories:
                category_generated = {'id': None, 'name': None, 'color': None}

                for key, value in category.items():
                    if key in CreateOrUpdateTripCategory._meta.editable_fields:
                        category_generated[key] = value

                if category_generated.get('id'):
                    # Check if the id field exists. If exists, validate that this category belongs to the trip
                    get_category_in_trip(category_generated['id'], trip.id)
                    category_generated['trip'] = trip
                else:
                    category_generated['trip'] = trip

                TripCategory.objects.update_or_create(
                    id=category_generated['id'],
                    defaults=category_generated
                )
            trip.refresh_from_db()

        return CreateOrUpdateTripCategory(trip=trip)

class DeleteTripCategory(BaseMutation):
    id = graphene.ID()

    class Arguments:
        category_id= graphene.ID(required=True)
        trip_id = graphene.ID(required=True)

    class Meta:
        description = 'Delete category trip'

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, category_id, trip_id):
        category = get_category_in_trip(category_id, trip_id)

        with transaction.atomic():
            category.delete()

        return DeleteTripCategory(id=category_id)

class CreateExpense(BaseMutation):
    expense = graphene.Field(ExpenseType)

    class Arguments:
        input = CreateExpenseInput(required=True)

    class Meta:
        description = 'Create expense'

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, input):
        currency = get_currency(input['currency'])
        trip = get_trip(input['trip'])
        category = get_category_in_trip(input['category'], input['trip'])

        with transaction.atomic():
            expense = Expense(
                title = input['title'],
                amount = input['amount'],
                date = input['date'],
                created_by = info.context.user,
                currency = currency,
                category = category,
                trip = trip,
            )
            expense.save()
        return CreateExpense(expense=expense)

class UpdateExpense(BaseMutation):
    expense = graphene.Field(ExpenseType)

    class Arguments:
        expense_id = graphene.ID(required=True)
        trip_id = graphene.ID(required=True)
        input = UpdateExpenseInput(required=True)

    class Meta:
        description = 'Update expense'
        editable_fields = (
            'title',
            'amount',
            'date',
            'category',
        )

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, expense_id, trip_id, input):
        expense = get_expense_in_trip(expense_id, trip_id)
        category = get_category_in_trip(input['category'], trip_id)

        with transaction.atomic():
            expense = Expense.objects.get(id=expense_id)
            for key, value in input.items():
                if key in UpdateExpense._meta.editable_fields:
                    if key is 'category':
                        setattr(expense, key, category)
                    else:
                        setattr(expense, key, value)
            expense.save()

        return UpdateExpense(expense=expense)

class DeleteExpense(BaseMutation):
    id = graphene.ID()

    class Arguments:
        expense_id= graphene.ID(required=True)
        trip_id = graphene.ID(required=True)

    class Meta:
        description = 'Delete expense'

    @login_required
    @permission_classes([UserIsInTripPermission,])
    def perform_mutation(cls, info, expense_id, trip_id):
        expense = get_expense_in_trip(expense_id, trip_id)

        with transaction.atomic():
            expense.delete()

        return DeleteExpense(id=expense_id)


# -*- coding: utf-8 -*-
"""TF 2.0 Fast-SCNN.ipynb
"""

# !pip install tensorflow-gpu==2.0.0-alpha0

import tensorflow as tf
import os
import random
import re
from PIL import Image
from dataset import data_gen
from matplotlib import pyplot as plt
import utils

#from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import TensorBoard

from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.callbacks import CSVLogger
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Adam
from metrics.miou import MeanIoU
from keras import backend as K

import tensorflow.keras.backend.tensorflow_backend as ktf

"""
def get_session(gpu_fraction=0.333):
    gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_fraction,
                                allow_growth=True)
    return tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

ktf.set_session(get_session())
"""

flags = tf.compat.v1.app.flags
FLAGS = flags.FLAGS

flags.DEFINE_integer('batch_size', 8, 'The number of images in each batch during training.')

flags.DEFINE_string('procdata_dir', None, 'Where to write the event logs.')

flags.DEFINE_integer('no_of_epochs', None, 'The number of steps used for training.')

## num_classes needs to be reviewed
flags.DEFINE_integer('num_classes', 32, 'The number of classes in the dataset.')

NO_OF_TRAINING_IMAGES = len(os.listdir(FLAGS.procdata_dir + '/train_images/images'))
NO_OF_VAL_IMAGES = len(os.listdir(FLAGS.procdata_dir + '/val_images/images'))

logdir=FLAGS.procdata_dir + '/../export/tensorboard_logs'
tensorboard = TensorBoard(log_dir=logdir, histogram_freq=1,
    write_graph=True, write_images=False)

# Initialize mIoU metric
miou_metric = MeanIoU(FLAGS.num_classes)

""" Plots """
class PlotLosses(tf.keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.i = 0
        self.x = []
        self.losses = []
        self.val_losses = []

        self.fig = plt.figure()

        self.logs = []

    def on_epoch_end(self, epoch, logs={}):

        self.logs.append(logs)
        self.x.append(self.i)
        self.losses.append(logs.get('loss'))
        self.val_losses.append(logs.get('val_loss'))
        self.i += 1

        clear_output(wait=True)
        plt.plot(self.x, self.losses, label="loss")
        plt.plot(self.x, self.val_losses, label="val_loss")
        plt.legend()
        plt.show();

plot_losses = PlotLosses()

""" plots """
"""
# Model Architecture

"""

"""## Step 1: Learning to DownSample"""

# Input Layer
#[1242, 378]
nb_classes = 34
input_size_height = 512
input_size_width = 512
input_layer = tf.keras.layers.Input(shape=(input_size_height, input_size_width, 3), name = 'input_layer')
#input_layer = tf.keras.layers.Input(shape=(2048, 1024, 3), name = 'input_layer')

lds_layer = utils.conv_block(input_layer, 'conv', 32, (3, 3), strides = (2, 2))
lds_layer = utils.conv_block(lds_layer, 'ds', 48, (3, 3), strides = (2, 2))
lds_layer = utils.conv_block(lds_layer, 'ds', 64, (3, 3), strides = (2, 2))

"""## Step 2: Global Feature Extractor

"""

"""#### Assembling all the methods"""

gfe_layer = utils.bottleneck_block(lds_layer, 64, (3, 3), t=6, strides=2, n=3)
gfe_layer = utils.bottleneck_block(gfe_layer, 96, (3, 3), t=6, strides=2, n=3)
gfe_layer = utils.bottleneck_block(gfe_layer, 128, (3, 3), t=6, strides=1, n=3)
gfe_layer = utils.pyramid_pooling_block(gfe_layer, [2,4,6,8])

"""## Step 3: Feature Fusion"""

ff_layer1 = utils.conv_block(lds_layer, 'conv', 128, (1,1), padding='same', strides= (1,1), relu=False)

ff_layer2 = tf.keras.layers.UpSampling2D((4, 4))(gfe_layer)
ff_layer2 = tf.keras.layers.DepthwiseConv2D(128, strides=(1, 1), depth_multiplier=1, padding='same')(ff_layer2)
ff_layer2 = tf.keras.layers.BatchNormalization()(ff_layer2)
ff_layer2 = tf.keras.activations.relu(ff_layer2)
ff_layer2 = tf.keras.layers.Conv2D(128, 1, 1, padding='same', activation=None)(ff_layer2)

#ff_layer2 = tf.keras.layers.Lambda(lambda ff_layer2: tf.image.resize(ff_layer2, (w,h)))(ff_layer2)

ff_final = tf.keras.layers.add([ff_layer1, ff_layer2])
ff_final = tf.keras.layers.BatchNormalization()(ff_final)
ff_final = tf.keras.activations.relu(ff_final)

"""## Step 4: Classifier"""

classifier = tf.keras.layers.SeparableConv2D(128, (3, 3), padding='same', strides = (1, 1), name = 'DSConv1_classifier')(ff_final)
classifier = tf.keras.layers.BatchNormalization()(classifier)
classifier = tf.keras.activations.relu(classifier)

classifier = tf.keras.layers.SeparableConv2D(128, (3, 3), padding='same', strides = (1, 1), name = 'DSConv2_classifier')(classifier)
classifier = tf.keras.layers.BatchNormalization()(classifier)
classifier = tf.keras.activations.relu(classifier)

classifier = utils.conv_block(classifier, 'conv', nb_classes, (1, 1), strides=(1, 1), padding='same', relu=True)

classifier = tf.keras.layers.Dropout(0.3)(classifier)

classifier = tf.keras.layers.UpSampling2D((8, 8))(classifier)
classifier = tf.keras.activations.softmax(classifier)

### Model End ###

"""## DATA GEN"""
zipped_train = data_gen._get_pairs_from_paths(PROC_DATA = FLAGS.procdata_dir, gen='train')
zipped_val = data_gen._get_pairs_from_paths(PROC_DATA = FLAGS.procdata_dir, gen='val')

##TODO
# data_gen.image_segmentation_generator_1 doesn't work with do_argument=False

train_data_gen = data_gen.image_segmentation_generator_1(zipped=zipped_train, target_size = (input_size_width, input_size_height), batch_size=FLAGS.batch_size, do_augment=True)
val_data_gen = data_gen.image_segmentation_generator_1(zipped=zipped_val, target_size = (input_size_width, input_size_height), batch_size=FLAGS.batch_size, do_augment=True)

weights_path = FLAGS.procdata_dir + '../export/weights'
checkpoint = ModelCheckpoint(weights_path, monitor='METRI C_TO_MONITOR',
                             verbose=1, save_best_only=True, mode='max')
csv_logger = CSVLogger('./log.out', append=True, separator=';')
earlystopping = EarlyStopping(monitor = 'METRIC_TO_MONITOR', verbose = 1,
                              min_delta = 0.01, patience = 3, mode = 'max')

callbacks_list = [checkpoint, csv_logger, earlystopping, tensorboard, plot_losses]
"""## Model Compilation"""

fast_scnn = tf.keras.Model(inputs = input_layer , outputs = classifier, name = 'Fast_SCNN')
optimizer = tf.keras.optimizers.SGD(momentum=0.9, lr=0.045)
fast_scnn.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy', miou_metric.mean_iou])

# TODO
print("\n\n")
print(train_data_gen)
print("\n\n")

results = fast_scnn.fit_generator(generator = train_data_gen, epochs=FLAGS.no_of_epochs,
                          steps_per_epoch = (NO_OF_TRAINING_IMAGES//FLAGS.batch_size),
                          validation_data=val_data_gen,
                          validation_steps=(NO_OF_VAL_IMAGES//FLAGS.batch_size),
                          callbacks=callbacks_list,
                          use_multiprocessing=False,
                          shuffle=True,
                          initial_epoch=0)


from pyelicit import elicit
from collections import namedtuple

def Struct(**kwargs):
    return namedtuple('Struct', ' '.join(kwargs.keys()))(**kwargs)

el = elicit.Elicit(Struct(apiurl='https://elicit.compute.dtu.dk',send_opt=dict(verify=True),debug=True))
client = el.client

user_id = 919
study_definition_id = 394
experiment_result_id = 711
study_result_id = 711
page_size = 10

el.find_trial_results(study_result_id=study_result_id, experiment_id=experiment_result_id, page_size=page_size)


__author__ = "Ash-Ishh.."
__version__ = "1.0.0"
__email__ = "mr.akc@outlook.com"

from functools import partial
import operator
import re

from datedetect.exceptions import InvalidArguments

def get_regex(_type, delimiter, _format):
    """
    This function returns regex of given date format.
    :param _type:
    :param delimiter: string
    :param _format: string
    :return: regex string
    """
    attributes = _format.split(delimiter) if delimiter else [_format]
    regex = []
    for attribute in attributes:
        try:
            regex.append(regex_patterns.get(_type)[attribute])
        except KeyError as _:
            regex.append(attribute)
    final_regex = regex_patterns.get(_type).get(delimiter, "").join(regex)
    return final_regex

regex_patterns = {
    "date": {
        "%d": r"(?:0[1-9]|1[0-9]|2[0-9]|3[0-1])(?!\d)",
        "%m": r"(?:0[1-9]|1[0-2])(?!\d)",
        "%b": r"(?:[a-z]{3})",
        "%B": r"(?:may|[a-z]{4,9})",
        "%Y": r"(?<!\d)\d{4}(?!\d)",
        "%y": r"(?<!\d)\d{2}(?!\d)",
        "%-d": r"(?:(?<!\d)[1-9]|1[0-9]|2[0-9]|3[0-1])(?!\d)",
        "%-m": r"(?:(?<!\d)[1-9]|1[0-2])(?!\d)",
        "/": r"\W"
    },
    "time": {
        "%H": r"(?:(?<!\d)0[0-9]|1[0-9]|2[0-3](?!\d))",
        "%I": r"(?:(?<!\d)0[0-9]|1[0-2](?!\d))",
        "%M": r"(?:(?<!\d)0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9](?!\d))",
        "%S": r"(?:(?<!\d)0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9](?!\d))",
        "%f": r"(?<!\d)\d{6}(?!\d)",
        "%-H": r"(?:(?<!\d)1[0-9]|2[0-3]|[0-9](?!\d))",
        "%-M": r"(?:(?<!\d)1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9](?!\d))",
        "%-S": r"(?:(?<!\d)1[0-9]2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9](?!\d))",
        "/": r"(?:\.|:)",
    },
    "timezone": {
        "%z": r"(?:\+|\-)\d+:\d+",
    },
    "am_pm": {
        "%p": "(?:am|pm)",
    }
}

get_date_regex = partial(get_regex, "date", "/")
date_regex = {
    "%d/%m/%Y": get_date_regex("%d/%m/%Y"),
    "%m/%d/%Y": get_date_regex("%m/%d/%Y"),
    "%Y/%m/%d": get_date_regex("%Y/%m/%d"),
    "%b/%d/%Y": get_date_regex("%b/%d/%Y"),
    "%d/%b/%Y": get_date_regex("%d/%b/%Y"),
    "%d/%B/%Y": get_date_regex("%d/%B/%Y"),
    "%-d/%b/%Y": get_date_regex("%-d/%b/%Y"),
    "%-d/%-m/%Y": get_date_regex("%-d/%-m/%Y"),
    "%-m/%-d/%Y": get_date_regex("%-m/%-d/%Y"),
    "%Y/%-m/%-d": get_date_regex("%Y/%-m/%-d"),
    "%b/%-d/%Y": get_date_regex("%b/%-d/%Y"),
    "%B/%d//%Y": get_date_regex("%B/%d//%Y"),

    "%d/%m/%y": get_date_regex("%d/%m/%y"),
    "%m/%d/%y": get_date_regex("%m/%d/%y"),
    "%d/%b/%y": get_date_regex("%d/%b/%y"),
    "%d/%B/%y": get_date_regex("%d/%B/%y"),
    "%-d/%b/%y": get_date_regex("%-d/%b/%y"),
    "%-d/%-m/%y": get_date_regex("%-d/%-m/%y"),
    "%-m/%-d/%y": get_date_regex("%-m/%-d/%y"),
    "%b/%-d/%y": get_date_regex("%b/%-d/%y"),

    "%Y/%m": get_date_regex("%Y/%m"),
    "%b/%Y": get_date_regex("%b/%Y"),
    "%B/%Y": get_date_regex("%b/%Y"),

    "%Y": get_date_regex("%Y")
}

get_time_regex = partial(get_regex, "time", "/")
time_regex = {
    "%H/%M/%S/%f": get_time_regex("%H/%M/%S/%f"),
    "%-H/%-M/%-S/%f": get_time_regex("%-H/%-M/%-S/%f"),
    "%I/%M/%S/%f": get_time_regex("%I/%M/%S/%f"),
    "%H/%M:%S": get_time_regex("%H/%M/%S"),
    "%-H/%-M/%-S": get_time_regex("%-H/%-M/%-S"),
    "%I/%M:%S": get_time_regex("%I/%M/%S"),
    "%H/%M": get_time_regex("%H/%M"),
    "%-H/%-M": get_time_regex("%-H/%-M"),
    "%I/%M": get_time_regex("%I/%M")
}

get_am_pm_regex = partial(get_regex, "am_pm", None)
am_pm_regex = {
    "%p": get_am_pm_regex("%p")
}

get_timezone_regex = partial(get_regex, "timezone", None)
timezone_regex = {
    "%z": get_timezone_regex("%z"),
}

mapping = {
    "%d": "dd",
    "%-d": "d",
    "%m": "MM",
    "%-m": "M",
    "%b": "MMM",
    "%B": "MMMM",
    "%y": "yy",
    "%Y": "yyyy",
    "%H": "HH",
    "%-H": "H",
    "%M": "mm",
    "%-M": "m",
    "%f": "ffffff",
    "%S": "ss",
    "%-S": "s",
    "%z": "zzz",
    "%I": "h",
    "%p": "a"
}
display_name_regex = re.compile("|".join(map(re.escape, mapping.keys())))

def get_possible_formats(datetime, regex_mapping):
    """
    This function iterates through given mapping of possible regex and
    returns list of possible formats along with the matched string
    :param datetime:
    :param regex_mapping:
    :return: possible_formats, matched_string (tuple (list, str))
    """
    possible_formats = []
    matched_string = ""
    matched_string_len = 0
    for _format, regex in regex_mapping.items():
        regex = re.compile(regex)
        results = regex.findall(datetime)
        if results:
            possible_match = results[0]

            if len(possible_match) > matched_string_len:
                possible_formats = []
                matched_string = possible_match
                matched_string_len = len(matched_string)

            if len(possible_match) == matched_string_len:
                possible_formats.append(_format)

    return possible_formats, matched_string

def update_formats(formats, delimiters):
    """
    This function replaces generic format detected to user given
    string format
    Example:
        input: ['%d/%m/%Y %H/%M/%S/%f'] ['-','-','-',':',':','.']
        output: ['%d-%m-%Y %H:%M:%S.%f']
    Args:
        formats (list)
        delimiters (list)
    Output:
        formats (list)
    """
    for i, _format in enumerate(formats):
        for delimiter in delimiters:
            formats[i] = formats[i].replace("/", delimiter, 1)
    return formats

def update_date_formats(date_formats, detected, placeholder):
    """
    This function updated date placeholder with detected formats with proper delimiter.
    :param date_formats:
    :param detected:
    :param placeholder:
    :return:
    """
    date_delimiters = re.findall(r"\W", detected)
    date_formats = update_formats(date_formats, date_delimiters)
    date_updated_formats = [placeholder.replace("{DATE}", date_format) for date_format in date_formats]
    return date_updated_formats

def update_time_formats(time_formats, detected, placeholder):
    """
    This function updates time placeholder with detected formats with proper delimiter.
    :param time_formats:
    :param detected:
    :param placeholder:
    :return:
    """
    if time_formats:
        time_formats = [time_formats[0]]
    time_delimiters = re.findall(r"\W", detected)
    time_formats = update_formats(time_formats, time_delimiters)
    updated_time_formats = [placeholder.replace("{TIME}", time_format) for time_format in time_formats]
    return updated_time_formats

def update_am_pm_formats(am_pm_formats, _, placeholder):
    """
    This function replaces Am Pm placeholder
    :param am_pm_formats:
    :param _:
    :param placeholder:
    :return:
    """
    updated_am_pm_formats = [placeholder.replace("{AM_PM}", am_pm_format) for am_pm_format in am_pm_formats]
    return updated_am_pm_formats

def update_timezone_formats(timezone_formats, _, placeholder):
    """
    This function replaces Timezone placeholder with detected timezone
    :param timezone_formats:
    :param _:
    :param placeholder:
    :return:
    """
    updated_timezone_formats = [placeholder.replace("{TIMEZONE}", timezone_format) for timezone_format in
                                timezone_formats]
    return updated_timezone_formats

def stitch_formats(_, placeholder, data):
    """
    The possible formats are located in chunks
    this function stiches them as per given input string with proper delimiters
    :param _:
    :param placeholder:
    :param data:
    :return:
    """
    date = data.get("date")
    date_detected = date.get("detected")
    date_formats = date.get("formats")
    updated_date_formats = update_date_formats(date_formats, date_detected, placeholder)

    # TODO: check if placeholder pattern in updated format if not return if yes process
    final_formats = updated_date_formats

    time = data.get("time")
    time_detected = time.get("detected")
    time_formats = time.get("formats")

    updated_time_formats = []
    if time_detected:
        for date_format in updated_date_formats:
            updated_time_formats.extend(update_time_formats(time_formats, time_detected, date_format))
        final_formats = updated_time_formats

    am_pm = data.get("am_pm")
    am_pm_detected = am_pm.get("detected")
    am_pm_formats = am_pm.get("formats")
    updated_am_pm_formats = []
    if am_pm_detected:
        for time_format in updated_time_formats:
            updated_am_pm_formats.extend(update_am_pm_formats(am_pm_formats, am_pm_detected, time_format))
        final_formats = updated_am_pm_formats

    timezone = data.get("timezone")
    timezone_detected = timezone.get("detected")
    timezone_formats = timezone.get("formats")
    updated_timezone_formats = []
    if timezone_detected:
        for am_pm_format in updated_time_formats:
            updated_timezone_formats.extend(update_timezone_formats(timezone_formats, timezone_detected, am_pm_format))
        final_formats = updated_timezone_formats

    return final_formats

def get_display_name(_format, _mapping, display_name_regex):
    """
    This function returns display name of python format strings
    e.g: %I -> H, %H -> HH
    :param _format:
    :param _mapping:
    :param display_name_regex:
    :return:
    """
    return display_name_regex.sub(lambda match: _mapping[match.group(0)], _format)

def get_possible_datetime_format_codes(datetime):
    """
    This function returns list of possible python date format codes of given string with common delimiter /.
    :param datetime: string
    :return:
    """
    datetime = datetime.lower()
    datetime_original = datetime
    timezone_formats, timezone = get_possible_formats(datetime, timezone_regex)
    datetime = datetime.replace(timezone, "{TIMEZONE}") if timezone else datetime
    time_formats, time = get_possible_formats(datetime, time_regex)
    datetime = datetime.replace(time, "{TIME}") if time else datetime
    am_pm_formats, am_pm = get_possible_formats(datetime, am_pm_regex)
    datetime = datetime.replace(am_pm, "{AM_PM}") if am_pm else datetime
    date_formats, date = get_possible_formats(datetime, date_regex)
    datetime = datetime.replace(date, "{DATE}") if date else datetime

    stitch_payload = {
        "date": {
            "detected": date,
            "formats": date_formats,
        },
        "time": {
            "detected": time,
            "formats": time_formats,
        },
        "am_pm": {
            "detected": am_pm,
            "formats": am_pm_formats,
        },
        "timezone": {
            "detected": timezone,
            "formats": timezone_formats,
        },
    }
    stitched_formats = stitch_formats(datetime_original, datetime, stitch_payload)
    return stitched_formats

def get_possible_datetimes_format_codes(datetimes, verbose):
    """
    Get possible datetimes formats takes sample list of strings
    and matches with supported regex of dates and returns matched cases
    at the output user will get dictionary with possible formats as keys
    and its count as value

    Args:
        datetimes (list)
        verbose
    Output:
        possible_formats_count (dict)
        verbose (bool)
    """
    possible_formats_count = {}
    for datetime in datetimes:
        possible_formats = get_possible_datetime_format_codes(datetime)
        for possible_format in possible_formats:
            if possible_format not in possible_formats_count:
                possible_formats_count[possible_format] = 1
            else:
                possible_formats_count[possible_format] += 1

    if not verbose:
        max_count = max(set(list(possible_formats_count.values()))) if possible_formats_count else 0
        possible_formats = [_format for _format, count in possible_formats_count.items() if count == max_count]
        return possible_formats

    possible_formats_list = list(possible_formats_count.items())
    possible_formats_list.sort(key=operator.itemgetter(1), reverse=True)
    sorted_possible_formats = []
    for _format, count in possible_formats_list:
        sorted_possible_formats.append({
            "format": _format,
            "display_name": get_display_name(_format, mapping, display_name_regex),
            "count": count,
        })
    return sorted_possible_formats

def get_format_codes(user_input, verbose=False):
    if isinstance(user_input, list):
        datetimes = user_input
    elif isinstance(user_input, str):
        datetimes = [user_input]
    else:
        raise InvalidArguments("Please provide string or list as input.")
    result = get_possible_datetimes_format_codes(datetimes, verbose)
    return result

if __name__ == "__main__":
    test = get_format_codes(['2012-12-18'], verbose=True)
    print(test)


"""empty message

Revision ID: 4e4710949dd
Revises: 3bc88a29a22
Create Date: 2015-10-13 10:55:27.441589

"""

# revision identifiers, used by Alembic.
revision = '4e4710949dd'
down_revision = '3bc88a29a22'

from alembic import op
import sqlalchemy as sa

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('chart_block_defaults')
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.create_table('chart_block_defaults',
    sa.Column('id', sa.INTEGER(), nullable=False),
    sa.Column('title', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
    sa.Column('caption', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
    sa.Column('slug', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
    sa.Column('dataset', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
    sa.Column('content', sa.TEXT(), autoincrement=False, nullable=True),
    sa.PrimaryKeyConstraint('id', name='chart_block_defaults_pkey')
    )
    ### end Alembic commands ###


from django.shortcuts import render
from rest_framework.decorators import api_view
import os
import json
from bson import ObjectId, datetime
from django.http import JsonResponse, HttpResponse
from django.http import FileResponse
import datetime
from datetime import date
from collections import OrderedDict

import logging
import boto3
import io
import base64
import tempfile

from .env_secrets import aws_env

#CONSTANTS
BUCKET_DIR = aws_env['bucket_dir']
AWS_ACCESS_KEY = aws_env['aws_access_key']
AWS_SECRET_KEY = aws_env['aws_secret_key']
AWS_BUCKET_NAME = aws_env['aws_bucket_name']

class JSONEncoder(json.JSONEncoder):

    def default(self, o):
        if isinstance(o, ObjectId) or isinstance(o, (datetime.date, datetime.datetime)):
            return str(o)
        return json.JSONEncoder.default(self, o)

# Create your views here.
@api_view(['POST'])
def get_filename(request):
    try:
        print("Enter Try++++++++++++++++++", request)
        file_name = request.POST["file_name"]
        print("File_name++++++++++++++", file_name)
        os.system("bash get_files/search_script.sh "+ file_name)

        file_path = 'get_files/'+file_name
        print(file_path)
        file_result = FileResponse(open(file_path, 'rb'))
        print(type(file_result))
        json_result = {"FILE_NAME": file_name}
        # json_result = JSONEncoder().encode({"FILE_NAME": file_name})
        print("JSON",json_result)
        # return JsonResponse(json_result, safe=False)
        return file_result

    except Exception as error:
        print("error in get filename string",error)
        # LOGGER.exception(error)

@api_view(['POST'])
def upload_file(request):
    try:
        # logging.debug("Enter GET FILE FUNCTION")
        print("Enter GET FILE FUNCTION")
        fileToUpload = request.FILES.get('file')
        cloudFilename = BUCKET_DIR + fileToUpload.name

        # logging.info(cloudFilename)
        print('cloudFilename: ',cloudFilename)

        s3_client = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY,aws_secret_access_key=AWS_SECRET_KEY)
        s3_client.upload_fileobj(fileToUpload, AWS_BUCKET_NAME, cloudFilename)
        print("Upload done: ", fileToUpload.name)

        # session = boto3.session.Session(aws_access_key_id=AWS_ACCESS_KEY,
        #                                 aws_secret_access_key=AWS_SECRET_KEY)
        # s3 = session.resource('s3')
        # s3.Bucket(AWS_BUCKET_NAME).put_object(Key=cloudFilename, Body=fileToUpload)
        json_result = {"cloudFilename": cloudFilename}
        return JsonResponse(json_result, safe=False)

    except Exception as error:
        logging.error(error)

@api_view(['POST'])
def download_file(request):
    try:
        print("ENTER DOWNLOAD FILE FUNCTION")
        file_name = request.POST['file_name']
        cloudFilename = BUCKET_DIR + file_name

        print('cloudFilename: ', cloudFilename)

        s3_client = boto3.client('s3', aws_access_key_id=AWS_ACCESS_KEY, aws_secret_access_key=AWS_SECRET_KEY)

        # tmp = tempfile.NamedTemporaryFile()
        # with open(tmp.name, 'wb') as file_obj:
        #     s3_client.download_fileobj(AWS_BUCKET_NAME, cloudFilename, file_obj)

        tmp = tempfile.NamedTemporaryFile(mode='w', delete=False)
        with open(tmp.name, 'wb') as file_obj:
            s3_client.download_fileobj(AWS_BUCKET_NAME, cloudFilename, file_obj)

        print("file_obj: ",  file_obj)
        print("TYPE OF file_obj: ", type(file_obj))

        tmp.close()
        os.remove(tmp.name)

        # file_base64 = base64.b64encode(file_stream)

        json_result = {file_name: str(file_obj)}
        return JsonResponse(json_result, safe=False)

        # return HttpResponse(str(file_stream), 'image/jpeg')

    except Exception as error:
        logging.error(error)


import pymysql

from server.auth import DB_AUTH

def connection():
    return pymysql.connect(**DB_AUTH)

def fetch_user_by_id(id):
    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    query = '''
        SELECT id, user_id, name, email, avatar, tokens
          FROM cafe.users
         WHERE id = %(id)s
    '''
    params = {'id': id}
    cursor.execute(query, params)
    results = cursor.fetchall()
    if results:
        user = results[0]
    else:
        user = None
    conn.close()
    return user

def fetch_user(user_id):
    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    query = '''
        SELECT id, user_id, name, email, avatar, tokens
          FROM cafe.users
         WHERE user_id = %(user_id)s
    '''
    params = {'user_id': user_id}
    cursor.execute(query, params)
    results = cursor.fetchall()
    if results:
        user = results[0]
    else:
        user = None
    conn.close()
    return user

def set_user(user):
    conn = connection()
    cursor = conn.cursor()
    query = '''
        INSERT IGNORE cafe.users (user_id, name, email, avatar, tokens)
               VALUES (%(user_id)s, %(name)s, %(email)s, %(avatar)s, %(tokens)s)
    '''
    cursor.execute(query, user.db_dict())
    conn.commit()
    id = fetch_user(user.user_id)['id']
    conn.close()
    return id

def fetch_foods():
    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    query = '''
        SELECT food.id, baker.name as baker, baker.id as baker_id,
               food.image_url
          FROM cafe.foods food
     LEFT JOIN cafe.bakers baker
            ON food.baker_id = baker.id
    '''
    cursor.execute(query)
    foods = list(cursor.fetchall())
    conn.close()
    return foods

def fetch_voted_foods(user):
    query_1 = '''
        SELECT food.id
          FROM cafe.votes vote
     LEFT JOIN cafe.foods food
            ON vote.winner_baker_id = food.baker_id
         WHERE vote.user_id = %(user_id)s
    '''
    query_2 = '''
        SELECT food.id
          FROM cafe.votes vote
     LEFT JOIN cafe.foods food
            ON vote.loser_baker_id = food.baker_id
         WHERE vote.user_id = %(user_id)s
    '''
    params = {'user_id': user.id}
    conn = connection()
    cursor = conn.cursor()
    cursor.execute(query_1, params)
    voted_foods_1 = {x for (x,) in cursor.fetchall()}
    cursor.execute(query_2, params)
    voted_foods_2 = {x for (x,) in cursor.fetchall()}
    conn.close()
    return voted_foods_1.union(voted_foods_2)

def fetch_selected_foods(user):
    conn = connection()
    cursor = conn.cursor()
    query = '''
        SELECT food_id
          FROM cafe.selected_foods
         WHERE is_selected = 1
           AND user_id = %(user_id)s
    '''
    params = {'user_id': user.id}
    cursor.execute(query, params)
    selected_foods = {x for (x,) in cursor.fetchall()}
    conn.close()
    return selected_foods

def set_selected_foods(user_id, foods):
    conn = connection()
    cursor = conn.cursor()
    query = '''
         INSERT INTO cafe.selected_foods (user_id, food_id, is_selected)
              VALUES (%(user_id)s, %(food_id)s, %(is_selected)s)
    ON DUPLICATE KEY UPDATE is_selected=VALUES(is_selected)
    '''
    def _param(user, food, is_selected):
        return {
            'user_id': user,
            'food_id': food,
            'is_selected': is_selected,
        }
    params = [_param(user_id, food['id'], food['selected']) for food in foods]
    for param in params:
        cursor.execute(query, param)
    conn.commit()
    conn.close()

def fetch_categories():
    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    query = '''
        SELECT id, name, superlative
          FROM cafe.categories
    '''
    cursor.execute(query)
    categories = list(cursor.fetchall())
    conn.close()
    return categories

def fetch_votes(user):
    query = '''
        SELECT category_id, winner_baker_id, loser_baker_id
          FROM cafe.votes
         WHERE user_id = %(user_id)s
    '''
    params = {'user_id': user.id}
    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute(query, params)
    votes = list(cursor.fetchall())
    conn.close()
    return votes

def set_votes(user, category, winner, loser):
    query = '''
        INSERT INTO cafe.votes (user_id, category_id, winner_baker_id,
                    loser_baker_id)
             VALUES (%(user_id)s, %(category_id)s, %(winner_id)s, %(loser_id)s)
    '''
    params = {
        'user_id': user.id,
        'category_id': category['id'],
        'winner_id': winner['baker_id'],
        'loser_id': loser['baker_id'],
    }
    conn = connection()
    cursor = conn.cursor()
    cursor.execute(query, params)
    conn.commit()
    conn.close()

def fetch_winnings():
    query = '''
        SELECT category.name as category, w_baker.name as winner,
               l_baker.name as loser
          FROM cafe.votes vote
     LEFT JOIN cafe.bakers w_baker
            ON vote.winner_baker_id = w_baker.id
     LEFT JOIN cafe.bakers l_baker
            ON vote.loser_baker_id = l_baker.id
     LEFT JOIN cafe.categories category
            ON vote.category_id = category.id
    '''
    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute(query)
    winnings = cursor.fetchall()
    conn.close()
    return winnings

def fetch_baker(user):
    query = '''
        SELECT baker.id, baker.name
          FROM cafe.foods food
     LEFT JOIN cafe.bakers baker
            ON food.baker_id = baker.id
         WHERE image_url LIKE %(image_url)s
    '''
    params = {'image_url': '%/{}.%'.format(user.id)}

    conn = connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute(query, params)
    results = cursor.fetchall()
    conn.close()

    if results:
        baker = results[0]
    else:
        baker = None
    return baker

def set_baker(user, baker_name, food_image_url):
    maybe_baker = fetch_baker(user)
    query_1 = '''
        INSERT IGNORE cafe.bakers (name)
               VALUES (%(baker_name)s)
    '''
    params_1 = {'baker_name': baker_name}

    query_2 = '''
        SELECT MAX(id)
          FROM cafe.bakers
    '''

    query_3 = '''
        INSERT IGNORE cafe.foods (baker_id, image_url)
               VALUES (%(baker_id)s, %(image_url)s)
    '''

    conn = connection()
    cursor = conn.cursor()
    if not maybe_baker:
        cursor.execute(query_1, params_1)
        conn.commit()

        cursor.execute(query_2)
        baker_id = cursor.fetchall()[0][0]
    else:
        baker_id = maybe_baker['id']

    params_3 = {'baker_id': baker_id, 'image_url': food_image_url}
    cursor.execute(query_3, params_3)
    conn.commit()

    conn.close()

def fetch_baker_photo(user):
    query = '''
        SELECT food.image_url
          FROM cafe.foods food
         WHERE image_url LIKE %(image_url)s
    '''
    params = {'image_url': '%s.' % user.id}

    conn = connection()
    cursor = conn.cursor()
    cursor.execute(query, params)
    results = cursor.fetchall()
    conn.close()

    if results:
        image_url = results[0]
    else:
        image_url = None
    return image_url


#################################################################################################
# Visual object tracking in panoramic video
# Master thesis at Brno University of Technology - Faculty of Information Technology
# Author:       Vít Ambrož (xambro15@stud.fit.vutbr.cz)
# Supervisor:   Doc. Ing. Martin Čadík, Ph.D.
# Module:       tracker_360_default.py
# Description:  Default tracking using DaSiamRPN tracker
#################################################################################################
# --------------------------------------------------------
# DaSiamRPN (https://github.com/foolwood/DaSiamRPN)
# Licensed under The MIT License
# Written by Qiang Wang (wangqiang2015 at ia.ac.cn)
# --------------------------------------------------------

import sys
import cv2
import torch
import numpy as np
from os.path import realpath, dirname, join

from net import SiamRPNBIG
from run_SiamRPN import SiamRPN_init, SiamRPN_track
from utils import get_axis_aligned_bbox, cxy_wh_2_rect, rect_2_cxy_wh

# custom modules to improve equirectangular tracking
from boundingbox import BoundingBox
from parser import Parser

class Tracker360Default:
    """Default tracking using DaSiamRPN tracker"""
    def __init__(self, video_path: str, groundtruth_path: str = None, save_result_path: str = None):
        self.video_path = video_path
        self.groundtruth_path = groundtruth_path
        if save_result_path:
            self.save_result_path = save_result_path
        else:
            self.save_result_path = "tmp-result-DaSiamRPN.txt"

        self.net = None

        self.video = None
        self.video_width = None
        self.video_height = None
        self.frame = None
        self.tracker = None
        self.bbox = None
        self.gt_bounding_boxes = []
        self.result_bounding_boxes = []

        # enable parsing/creating methods
        self.parser = Parser()

        # constants for sizes and positions of opencv circles, rectangles and texts
        self.RECTANGLE_BORDER_PX = 3
        self.FONT_SCALE = 0.75
        self.FONT_WEIGHT = 1
        self.TEXT_ROW1_POS = (30,30)
        self.TEXT_ROW2_POS = (30,60)
        self.TEXT_ROW3_POS = (30,90)
        self.TEXT_ROW4_POS = (30,120)

        self.WINDOW_NAME = "Tracker-DaSiamRPN"

    def _drawBoundingBox(self, videoWidth, point1, point2, boundingBox, color, thickness):
        """Method for drawing rectangle according to points"""
        if (boundingBox.is_on_border()):
            # draw two rectangles around the region of interest
            rightBorderPoint = (videoWidth - 1, point2[1])
            cv2.rectangle(self.frame, point1, rightBorderPoint, color, thickness)

            leftBorderPoint = (0, point1[1])
            cv2.rectangle(self.frame, leftBorderPoint, point2, color, thickness)
        else:
            # draw a rectangle around the region of interest
            cv2.rectangle(self.frame, point1, point2, color, thickness)

    def _checkBoundsOfPoint(self, point):
        """Checks if given point is in interval [0,self.width] and [0,self.height] with x overflow"""
        # horizontal could overflow in equirectangular
        x = point[0]
        y = point[1]
        if x < 0:
            x = self.video_width + x - 1
        elif x > self.video_width - 1:
            x = x - self.video_width - 1

        # vertical
        if y < 0:
            y = 0
        elif y > self.video_height - 1:
            y = self.video_height - 1

        point = (x,y)
        return point

    def _saveResults(self):
        """Method for saving result bounding boxes to .txt file"""
        # creating string result data
        resultData = self.parser.createAnnotations(self.result_bounding_boxes)
        # saving file on drive
        self.parser.saveDataToFile(self.save_result_path, resultData)
        print("File '" + self.save_result_path + "' has been successfully created with total " + str(len(self.result_bounding_boxes)) + " computed frames.")

    def run_video_default(self):
        """Method for start DaSiamRPN tracking without any modifications"""
        ########## 1) Video Checking ##########
        # Read video
        self.video = cv2.VideoCapture(self.video_path)
        # Exit if video not opened.
        if not self.video.isOpened():
            print("Could not open video")
            print(help)
            sys.exit(-1)

        # Read first frame.
        ok, self.frame = self.video.read()
        if not ok:
            print("Error - Could not read a video file")
            sys.exit(-1)

        # save video width/height to global variables
        self.video_width = int(self.video.get(cv2.CAP_PROP_FRAME_WIDTH))
        self.video_height = int(self.video.get(cv2.CAP_PROP_FRAME_HEIGHT))

        ########## 2) Load pretrained model ##########
        # load net
        print("Loading pretrained model SiamRPNBIG.model...")
        self.net = SiamRPNBIG()
        self.net.load_state_dict(torch.load(join(realpath(dirname(__file__)), 'SiamRPNBIG.model')))
        self.net.eval().cuda()

        ########## 3) Setup opencv2 window ##########
        # resize window (lets define max width is 1600px)
        if self.video_width < 1600:
            cv2.namedWindow(self.WINDOW_NAME)
        else:
            cv2.namedWindow(self.WINDOW_NAME, cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
            whRatio = self.video_width / self.video_height
            if whRatio == 2:
                # pure equirectangular 2:1
                cv2.resizeWindow(self.WINDOW_NAME, 1600, 800)
            else:
                # default 16:9
                cv2.resizeWindow(self.WINDOW_NAME, 1600, 900)

            scaleFactor = self.video_width / 1600
            self.RECTANGLE_BORDER_PX = int(self.RECTANGLE_BORDER_PX * scaleFactor)
            self.FONT_SCALE = self.FONT_SCALE * scaleFactor
            self.FONT_WEIGHT = int(self.FONT_WEIGHT * scaleFactor) + 1
            self.TEXT_ROW1_POS = (int(self.TEXT_ROW1_POS[0] * scaleFactor), int(self.TEXT_ROW1_POS[1] * scaleFactor))
            self.TEXT_ROW2_POS = (int(self.TEXT_ROW2_POS[0] * scaleFactor), int(self.TEXT_ROW2_POS[1] * scaleFactor))
            self.TEXT_ROW3_POS = (int(self.TEXT_ROW3_POS[0] * scaleFactor), int(self.TEXT_ROW3_POS[1] * scaleFactor))
            self.TEXT_ROW4_POS = (int(self.TEXT_ROW4_POS[0] * scaleFactor), int(self.TEXT_ROW4_POS[1] * scaleFactor))

        # use copy of frame to be shown in window
        frame_disp = self.frame.copy()

        ########## 4) Initialation of bounding box ##########
        # Set up initial bounding box
        self.bbox = None
        self.result_bounding_boxes = []
        self.gt_bounding_boxes = []
        if self.groundtruth_path:
            # use first bounding box from given groundtruth
            self.gt_bounding_boxes = self.parser.parseGivenDataFile(self.groundtruth_path, self.video_width)

            if len(self.gt_bounding_boxes) > 0:
                bb1 = self.gt_bounding_boxes[0]
                if bb1.is_annotated:
                    self.bbox = (bb1.get_point1_x(), bb1.get_point1_y(), bb1.get_width(), bb1.get_height())
                    self.result_bounding_boxes.append(bb1)
                else:
                    print("Error - Invalid first frame annotation from file: '" + self.groundtruth_path + "'")
                    sys.exit(-1)
        else:
            # using opencv2 select ROI
            cv2.putText(frame_disp, 'Select target ROI and press ENTER', self.TEXT_ROW1_POS, cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE, (0, 200, 250), self.FONT_WEIGHT)

            x, y, w, h = cv2.selectROI(self.WINDOW_NAME, frame_disp, False)
            self.bbox = [x, y, w, h]

            # save it to result list
            p1 = (int(self.bbox[0]), int(self.bbox[1]))
            p2 = (int(self.bbox[0] + self.bbox[2]), int(self.bbox[1] + self.bbox[3]))
            # new instance of bounding box
            bb1 = BoundingBox(p1, p2, self.video_width)
            bb1.is_annotated = True
            self.result_bounding_boxes.append(bb1)

        if not(self.bbox) or self.bbox == (0,0,0,0):
            print("Error - Invalid first frame annotation")
            sys.exit(-1)

        ########## 5) Tracking process ##########
        # prints just basic guide and info
        print("--------------------------------------------------------------------")
        print("DaSiamRPN default tracking process has started...")
        print("Tracker  : DaSiamRPN")
        print("Frame #1 : " + str(self.bbox))
        print("Press 'Esc' or 'Q' key to exit")
        print("--------------------------------------------------------------------")

        # initialize tracker with first frame and bounding box
        ([cx, cy], [w, h]) = rect_2_cxy_wh(self.bbox)
        target_pos, target_sz = np.array([int(cx), int(cy)]), np.array([int(w), int(h)])
        state = SiamRPN_init(self.frame, target_pos, target_sz, self.net)

        # display first frame
        cv2.imshow(self.WINDOW_NAME, frame_disp)

        # if you want to have the FPS according to the video then uncomment this code
        # fps = cap.get(cv2.CAP_PROP_FPS)
        videoFPS = 30
        # calculate the interval between frame
        interval = int(1000/videoFPS)

        while True:
            # Read a new frame
            ok, self.frame = self.video.read()
            if not ok:
                break

            # Start timer
            timer = cv2.getTickCount()

            # Get tracked bbox
            state = SiamRPN_track(state, self.frame)  # track
            res = cxy_wh_2_rect(state['target_pos'], state['target_sz'])
            res = [int(l) for l in res]
            self.bbox = res

            # Calculate Frames per second (FPS)
            fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer)

            # draw bounding box
            if res[0] and res[1] and res[2] and res[3]:
                # Tracking success
                p1 = (res[0], res[1])
                p2 = (res[0] + res[2], res[1] + res[3])

                p1 = self._checkBoundsOfPoint(p1)
                p2 = self._checkBoundsOfPoint(p2)

                # new instance of bounding box
                bb = BoundingBox(p1, p2, self.video_width)
                bb.is_annotated = True
                self.result_bounding_boxes.append(bb)

                # draw bounding box to original frame
                self._drawBoundingBox(self.video_width, p1, p2, bb, (0, 255, 0), self.RECTANGLE_BORDER_PX)
            else:
                # tracking failure
                cv2.putText(self.frame, "Tracking failure detected", self.TEXT_ROW4_POS, cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE, (0, 0, 255), self.FONT_WEIGHT)

                # new instance of bounding box
                bb = BoundingBox(None, None, self.video_width)
                bb.is_annotated = False
                self.result_bounding_boxes.append(bb)

            # Display tracker type on frame
            cv2.putText(self.frame, "DaSiamRPN Tracker", self.TEXT_ROW1_POS, cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE, (0, 200, 250), self.FONT_WEIGHT)
            # Display FPS on frame
            cv2.putText(self.frame, "Video   FPS : " + str(videoFPS), self.TEXT_ROW2_POS, cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE, (0, 250, 0), self.FONT_WEIGHT)
            cv2.putText(self.frame, "Tracker FPS : " + str(int(fps)), self.TEXT_ROW3_POS, cv2.FONT_HERSHEY_SIMPLEX, self.FONT_SCALE, (0, 250, 0), self.FONT_WEIGHT)
            # Display result
            cv2.imshow(self.WINDOW_NAME, self.frame)

            # waitKey time computing
            # time in ms
            time = int(1000 * (cv2.getTickCount() - timer) / cv2.getTickFrequency())

            waitMiliseconds = 1
            if (time >= interval):
                waitMiliseconds = 1
            else:
                waitMiliseconds = interval - time

            k = cv2.waitKey(waitMiliseconds) & 0xff
            # Exit if 'Esc' or 'q' key is pressed
            if k == 27 or k == ord("q"):
                break

        # always save tracker result
        self._saveResults()

        self.video.release()
        cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
import xlrd
import string
import nltk
from nltk.stem import WordNetLemmatizer
from nltk.stem.porter import PorterStemmer
from nltk.corpus import wordnet
from nltk.corpus import stopwords
#import genism
from gensim import corpora, models
from gensim.models import CoherenceModel
import sys, errno
import xlsxwriter

dictionary = corpora.Dictionary.load("D:\\aproject\\dictionary1.dic")
#print( dictionary)
corpus = corpora.MmCorpus("D:\\aproject\\corpus1.m")
#print(len(corpus))
# 使用 gensim 来创建 LDA 模型对象
Lda = models.ldamodel.LdaModel
# 在 DT 矩阵上运行和训练 LDA 模型# iterations=50
Perplexity_list=[]
coherence_list=[]
#Passes=[300]
Iterations=[25]
for j in range(20,30):
    print('num_topics:',j)
    for it in Iterations:
        print('num_iter:',it)
        ldamodel = Lda(corpus, num_topics=j, id2word = dictionary,passes=300,alpha='auto',eta='auto',iterations=25, random_state=123,minimum_probability=0.0)
        #print(ldamodel.print_topics(num_topics=12, num_words=30))
        for i in  ldamodel.show_topics(num_topics=j):
            print (i[0], i[1])
        #, random_state=1  , num_words=10
        print('-----------------')

        file='D:\\aproject\\audience_text_classifier\\text_classifier_'+str(j)+'_i'+str(it)+'_v1.xlsx'
        workbook= xlsxwriter.Workbook(file)
        worksheet= workbook.add_worksheet(u'sheet1')
        for i in range(0,len(brand)):
            index1=0
            index2=0
            index1=brand0.index(brand[i])
            index2=i+360
            classifier1=ldamodel[corpus[index1]]
            ll1=[]
            for a,b in classifier1:
                ll1.append((b,a))
            ll1.sort(reverse=True)

            classifier2=ldamodel[corpus[index2]]
            ll2=[]
            for a,b in classifier2:
                ll2.append((b,a))
            ll2.sort(reverse=True)

            worksheet.write(i,0,brand[i])
            index3=0
            for a,b in ll1:
                if(index3<3):
                    if(a>0):
                        worksheet.write(i,index3+1,b)
                index3+=1

            worksheet.write(i,4,influencer[i])
            index4=0
            for a,b in ll2:
                if(index4<3):
                    if(a>0):
                        worksheet.write(i,index4+5,b)
                    else:
                        worksheet.write(i,index4+5,-1)
                index4+=1
        workbook.close()
        print('----------save-------')

        # Compute Perplexity
        print('\nPerplexity: ', ldamodel.log_perplexity(corpus))
        Perplexity_list.append(ldamodel.log_perplexity(corpus))
        # a measure of how good the model is. lower the better.
        # Compute Coherence Score
        coherence_model_lda = CoherenceModel(model=ldamodel,corpus=corpus,dictionary=dictionary, coherence='u_mass')
        try:
            coherence_lda = coherence_model_lda.get_coherence()
        except IOError as e:
            if e.errno == errno.EPIPE:
                print('err')
        print('\nCoherence Score: ', coherence_lda)
        coherence_list.append(coherence_lda)
        '''
        file2='D:\\aproject\\text_classifier\\text_classifier_vector.xlsx'
        workbook2= xlsxwriter.Workbook(file2)
        worksheet2= workbook2.add_worksheet(u'sheet1')
        for kk in range(0,len(corpus)):
            index_k=0
            if(kk<360):
                worksheet2.write(kk,0,brand0[kk])
            else:
                worksheet2.write(kk,0,influencer[kk-360])
            for a,b in ldamodel[corpus[kk]]:

                worksheet2.write(kk,1+index_k*2,a)
                worksheet2.write(kk,2+index_k*2,b)
                index_k+=1

        workbook2.close()
        '''
print(Perplexity_list)
print(coherence_list)


#!/usr/bin/env python
# coding: utf-8

# # Mapping using Python
#
# Here we use geotext library to extract places names from the sentence.
#
# ## Installation of geotext modules

# In[1]:

get_ipython().system('pip install geotext')

# ### Example to use GeoText module

# In[2]:

from geotext import GeoText

places = GeoText("I was in Chennai on that day and next day i went to Erode")
places.cities

# ## Example to Exract place names from a website
#
# * here we going to extract place names from the caption of the picture on the site , "https://www.gutenberg.org/files/64316/64316-h/64316-h.htm"
#
# * also we used the method of previous web scraping method using BeautifulSoup module
#
#
# ![](../images/map2.png)

# In[3]:

import urllib.request,sys,time
from bs4 import BeautifulSoup
import requests
import pandas as pd
from geotext import GeoText

# In[13]:

url="https://www.gutenberg.org/files/64316/64316-h/64316-h.htm"

# In[266]:

page=requests.get(url)

soup=BeautifulSoup(page.text,'html.parser')
frame=[]
resultframe=[]
links=soup.find_all('div',attrs={'class':'ills'})
#links=soup.find_all('li',attrs={'class':'o-listicle__item'})
#print(links)
filename="caption.csv"
f=open(filename,"w", encoding = 'utf-8')
headers="Link,Caption\n"
f.write(headers)
u='https://www.gutenberg.org/files/64316/64316-h/'
for i in links:
    k=i.find_all('div',attrs={'class':'figcenter'})
    for j in k:
        l=j.find_all('a')
        Link = u+l[1].find('img')['src'].strip()          #Extract Link of all the images
        cap=j.find('p',attrs={'class':'caption'}).text.strip()  #Extract caption of all the images

        a=cap.replace(' ',',').title()

        result = GeoText(a,'US').cities

        if(result!=[]):
            frame.append((Link,str(result[0])))
            f.write(Link+","+str(result[0])+"\n")   #stored only the link and caption that contains city names
    resultframe.extend(frame)
f.close()

# ### Result of the above Code

# In[14]:

data=pd.DataFrame(resultframe, columns=['Link','Caption'])
print(data)

# ### Installing arcgis to map the places

# In[214]:

get_ipython().system('pip install arcgis')

# ## Code to find latitude and longitude
# here we find the latitude and longitude of the places that extract in the caption of the images. and we mark the point on the map using simple loop condition.

# In[16]:

from arcgis.gis import GIS
from arcgis.geometry import Point
from arcgis.geocoding import geocode, reverse_geocode

my_gis = GIS()
# m = my_gis.map()

m = my_gis.map("US", zoomlevel=4)

# function to find the latitude and longitude
def place_names(get_places):
    i=get_places
    geocoded=geocode(i)[0]['location']
    return geocoded

for i in data['Caption']:

    geocoded=place_names(i)
    lat=geocoded['y']
    longi=geocoded['x']
    print(lat,longi)

    location = {
     'Y': lat,                 # `Y` is latitude
     'X':  longi,               # `X` is longitude
     'spatialReference': {
         'wkid':4326
     }
    }
    unknown_pt = Point(location)
    address = reverse_geocode(location=unknown_pt)
    print(address)  #matching address found from the latitude and longitude

    m.draw(address)

# ### Result Map of the above code

# In[17]:

m

# ![](../images/resmap1.png)

# ## Example to Find the address of the Given latitude and longitude

# In[19]:

from arcgis.geometry import Point
location = {
     'Y': 39.86347000000006,                 # `Y` is latitude
     'X':  -105.05000999999999,               # `X` is longitude
     'spatialReference': {
         'wkid':4326
     }
}
unknown_pt = Point(location)
address = reverse_geocode(location=unknown_pt)
address

# ### Draw a map for above address

# In[21]:

m = my_gis.map("USA", zoomlevel=5)
m.draw(address)
m

# ![](../images/resmap2.png)

# ## map can be save as html file

# In[22]:

file_path = r"C:\Users\Mohanapriya\city_map.html"
m.export_to_html(file_path)

# In[333]:

import webbrowser
webbrowser.open_new('http://127.0.0.1:2000/')


import numpy as np
import cv2

canavas = np.zeros((300,300,3),dtype="uint8")

for i in range(0,300,5):
    cv2.rectangle(canavas,(i,i-5),(i,i+5),(0,0,255),-1)

#måla upp en grön cirkel i mitten
cv2.circle(canavas,(canavas.shape[0]//2,canavas.shape[1]//2),canavas.shape[1]//8,(0,255,0),-1)

cv2.imshow("Bilden",canavas)
cv2.waitKey(0)


from django import forms
from django.utils.translation import gettext_lazy as _

from .models import Label

class FormLabel(forms.ModelForm):
    class Meta:
        model = Label
        fields = ("name",)

    label_place = _("Имя")

    def __init__(self, *args, **kwargs):
        super(FormLabel, self).__init__(*args, **kwargs)
        self.fields["name"].label = self.label_place

    def clean_name(self):
        name = self.cleaned_data["name"]
        if Label.objects.filter(name=name):
            raise forms.ValidationError(
                _("Метка с таким названием уже сущуствует")
            )
        return name


import torch
from PIL import Image
from io import BytesIO
import streamlit as st
from model import EasyVQAEarlyFusion
from transformers import AutoTokenizer, AutoFeatureExtractor, AutoModel
import warnings
warnings.filterwarnings("ignore")

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

idx2label = {0:'circle',
 1:'green',
 2:'red',
 3:'gray',
 4:'yes',
 5:'teal',
 6:'black',
 7:'rectangle',
 8:'yellow',
 9:'triangle',
 10:'brown',
 11:'blue',
 12:'no'}

@st.cache(allow_output_mutation=True, show_spinner=False)
def load_language_model():
    tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
    text_encoder = AutoModel.from_pretrained("bert-base-uncased")
    text_encoder.to(device)
    for p in text_encoder.parameters():
        p.requires_grad = False

    return tokenizer, text_encoder

@st.cache(allow_output_mutation=True, show_spinner=False)
def load_vision_model():
    image_processor = AutoFeatureExtractor.from_pretrained("google/vit-base-patch16-224-in21k")
    image_encoder = AutoModel.from_pretrained("google/vit-base-patch16-224-in21k")
    image_encoder.to(device)
    for p in image_encoder.parameters():
        p.requires_grad = False

    return image_processor, image_encoder

@st.cache(allow_output_mutation=True, show_spinner=False)
def load_model():
    model = EasyVQAEarlyFusion()
    model.load_state_dict(torch.load('./weights/final.model', map_location=device))
    model.to(device)
    return model

def process_text(question, tokenizer, text_encoder):
    text_inputs = tokenizer(question, return_tensors="pt")
    text_inputs = text_inputs.to(device)
    text_outputs = text_encoder(**text_inputs)
    text_embedding = text_outputs.pooler_output
    text_embedding = text_embedding.view(-1)
    text_embedding = text_embedding.detach()

    return text_embedding.view(1, -1)

def process_image(image, image_processor, image_encoder):
    image_inputs = image_processor(image, return_tensors="pt")
    image_inputs = image_inputs.to(device)
    image_outputs = image_encoder(**image_inputs)
    image_embedding = image_outputs.pooler_output
    image_embedding = image_embedding.view(-1)
    image_embedding = image_embedding.detach()

    return image_embedding.view(1, -1)

def predict(input, model):
    model.eval()
    with torch.no_grad():
        output = model(**input)

    probs = round(torch.max(output.softmax(dim=1), dim=-1)[0].detach().cpu().numpy()[0]*100, 4)
    output = output.argmax(-1)
    logit = output.detach().cpu().numpy()
    label = idx2label[logit[0]]

    return label, probs

if __name__=="__main__":

    st.title("Visual Question-Answering with Early Fusion Transformers on EasyVQA Dataset")
    with st.spinner('Models are being loaded.This could take some seconds...'):
        model=load_model()
        tokenizer, text_encoder = load_language_model()
        image_processor, image_encoder = load_vision_model()
    btn = None
    image_embedding = None
    text_embedding = None
    image = st.file_uploader("Upload an Image", type=['jpeg', 'jpg', 'png'], accept_multiple_files=False)

    if image:
        image_bytes = image.getvalue()
        img = Image.open(BytesIO(image_bytes)).convert("RGB")
        image_embedding = process_image(img, image_processor=image_processor, image_encoder=image_encoder)

        st.image(img, caption="Uploaded Image")

        question = st.text_input('Enter input question: (Play with questions to see some funny results)', '')
        if question:
            text_embedding = process_text(question, tokenizer=tokenizer, text_encoder=text_encoder)
            btn = st.button("Answer")
    if btn:
        if image_embedding is not None and text_embedding is not None:
            with st.spinner("Running Prediction..."):
                input = {"image_emb":image_embedding, "text_emb":text_embedding}
                label, prob = predict(input, model)

            st.text(f"Answer: {label}\nConfidence: {prob}")


# encoding: utf-8

import time
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException,NoSuchElementException

class Testcase1():
    '''写一个测试类，未继承unittest'''
    def testcase1(self):
            print('用例1，点击左边的按钮，弹出alert，点击接受')
            driver=webdriver.Chrome()
            driver.get('http://127.0.0.1:5000/')
            try:
                driver.find_element_by_xpath('//*[@id="testid"]').click()
            except NoSuchElementException as e:
                print(e)
            time.sleep(2)
            text=driver.switch_to.alert.text
            print(text)
            driver.switch_to.alert.accept()
    def testcase2(self):
        print('用例2，点击登录网站进入练习页面')
        username='15902127953'
        driver=webdriver.Chrome()
        driver.get('http://127.0.0.1:5000/')
        driver.find_element_by_xpath('/html/body/a').click()
        driver.find_element_by_xpath('/html/body/form/p[1]/input').send_keys(username)
        driver.find_element_by_xpath('/html/body/form/p[2]/input').send_keys('123456')
        driver.find_element_by_xpath('/html/body/form/p[3]/button').click()
        print('case2')

Testcase1().testcase1()
Testcase1().testcase2()


"""Functions for importing data."""
import os
import csv
from typing import Dict, Tuple
import pandas as pd

from . import exceptions

def data_path(filename: str) -> str:
    """Get full path to a file in the data folder.

    Args:
        filename (str): The data file's name.

    Returns:
        path (str): The full path to the file.
    """
    return os.path.join(os.path.dirname(__file__), "data", filename)

def test_data_file(short_name: str) -> None:
    """Raise exception if data file unavailable.

    Args:
        short_name (str): file name.

    Raises:
        exceptions.DataFileMissingOrUnreadable

    Returns:
        None
    """
    path = data_path(short_name)
    if not os.path.isfile(path):
        raise exceptions.DataFileMissingOrUnreadable(short_name)

def read_csv_to_dict(short_name: str) -> Dict[str, str]:
    """Load csv into memory.

    Args:
        short_name (str): file name.

    Returns:
        Dict[str, str]: A dictionary of first column -> second column
    """
    path = data_path(short_name)
    test_data_file(short_name)
    with open(path, "r", encoding="utf-8-sig") as file:
        csv_reader = csv.reader(file, delimiter=",")
        mapping = {rows[0]: rows[1] for rows in csv_reader}
    return mapping

def read_nicknames_file(
    short_name: str
) -> Tuple[Dict[str, str], Dict[str, str]]:
    """Read a nicknames csv file into two dictionaries.

    The file is in the format:
        official,short,*other_nicknames

    Args:
        short_name (str): [description]

    Returns:
        A tuple of dictionaries (Tuple[Dict[str, str], Dict[str, str]]):
            nicknames_to_official
            official_to_short_name
    """
    nicknames_to_official: Dict[str, str] = {}
    official_to_short_name: Dict[str, str] = {}
    path = data_path(short_name)
    test_data_file(short_name)
    with open(path, "r", encoding="utf-8-sig") as file:
        csv_reader = csv.reader(file, delimiter=",")
        for row in csv_reader:
            official = row[0].strip()
            short = row[1].strip()
            nicknames_to_official[short.lower()] = official
            nicknames_to_official[official.lower()] = official
            official_to_short_name[official.lower()] = short
            for nickname in row[2:]:
                nicknames_to_official[nickname.lower()] = official
    # Green Party, with its different chapters, needs to be set by hand
    nicknames_to_official["green party"] = "Green Party"
    return nicknames_to_official, official_to_short_name

def read_csv_to_dataframe(
    short_name: str,
    separator: str = ","
) -> "pd.DataFrame":
    """Load csv into pandas dataframe.

    Args:
        short_name (str): Name of data file.
        separator (str, optional): Separator used in the file. Defaults to ",".

    Returns:
        data: dataframe
    """
    path = data_path(short_name)
    test_data_file(short_name)
    dataframe = pd.read_csv(path, sep=separator)
    return dataframe

PARTY_NICKNAMES, PARTY_SHORTNAMES = read_nicknames_file("party_nicknames.csv")
"""Official names from the nicknames we have on record."""

PARTY_COLORS = read_csv_to_dict("party_colors.csv")
"""Web color names for the parties."""

"""MIT License

Copyright (c) 2021 Stonehaven

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#-:-:-:-:-:-:-::-:-:#
#     SIP Torch     #
#-:-:-:-:-:-:-::-:-:#

# Author: 0xInfection
# This module requires SIPTorch
# https://github.com/0xInfection/SIPTorch

import logging

def permuteCase(inp: str):
    '''
    Generate maximum permutations by changing case
    '''
    log = logging.getLogger('permuteCase')
    if not inp:
        log.error('Nothing available for parsing')
        return
    n = len(inp)
    mx = 1 << n
    inp = inp.lower()
    maxperm = list()
    for i in range(mx):
        combination = [k for k in inp]
        for j in range(n):
            if ((i >> j) & 1) == 1:
                combination[j] = inp[j].upper()
        temp = ''
        for i in combination:
            temp += i
        maxperm.append(temp)
    return maxperm


import time
from django.core.exceptions import ObjectDoesNotExist
import os
import datetime
import json
from pprint import pprint
import logging
import urllib

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404, redirect
from django.http import Http404
from django.contrib.auth.models import User
from django.contrib import auth
from django.core import exceptions
from django.template.loader import get_template
from django.template import Context, Template
from django.core.cache import cache
from django.views.decorators.cache import cache_page
from django.contrib.auth.decorators import login_required

from django.conf import settings

import mainapp.models as models
import mainapp.forms as forms
import mainapp.tools as tools
import mainapp.tools.sendmail as sendmail
import mainapp.tools.mailchimp as mailchimp
from mainapp.views.photopager import *
from mainapp.tools import photoflow
from mainapp import bgjobs
from mainapp import adminvalues

log = logging.getLogger(__name__)

CACHE_TIME = 60 * 15  # 15 Minutes

@cache_page(CACHE_TIME)
def home(request):
    # Create a flow manager
    flow = photoflow.FlowManager()

    # Calculate the number of photos for the initial blocks
    blocks_initial = adminvalues.PHOTOFLOW_BLOCKS_INITIAL.get_int()
    photo_count = sum(flow.get_items_per_block(n) for n in xrange(blocks_initial))

    # Get the photos for the current page
    pager = ThumbnailPager(Filters(featured_only=True))
    pager.load_page(limit=photo_count)

    # Build the flow-html and render to response
    flow_html = flow.get_html(pager.photos)
    return render(request, 'index.html', {'page': pager, "flow_html": flow_html })

@cache_page(CACHE_TIME)
def sitemap(request):
    sets = models.Set.objects.filter(published=True).order_by("-id")
    tags = models.Tag.objects.all().order_by("-id")
    locations = models.Location .objects.all().order_by("-id")
    photos = models.Photo.objects.filter(published=True).order_by("-id")
    return render(request, 'sitemap.xml', {'photos': photos, "sets": sets, "locations": locations, "tags": tags})

@cache_page(CACHE_TIME)
def photo(request, photo_slug):
    try:
        photo = models.Photo.objects.get(slug=photo_slug)
    except ObjectDoesNotExist:
        # Check if its an old slug and we should redirect
        slug_deprecated = get_object_or_404(models.PhotoSlugHistory, slug=photo_slug)
        return redirect("/photo/%s/" % slug_deprecated.photo.slug, permanent=True)

    tag_slug = request.GET.get("tag")
    set_slug = request.GET.get("set")
    location_slug = request.GET.get("location")

    # Get next and previous photo, based on current browsing
    q_next = models.Photo.objects.filter(order_id__gt=photo.order_id, published=True).order_by("order_id")
    q_prev = models.Photo.objects.filter(order_id__lt=photo.order_id, published=True).order_by("-order_id")
    linkvars = ""
    if tag_slug:
        tag = get_object_or_404(models.Tag, slug=tag_slug)
        tags = [tag]
        tags += tag.get_descendants()
        q_next = q_next.filter(tags__in=tags)
        q_prev = q_prev.filter(tags__in=tags)
        linkvars = "tag=%s" % tag_slug
    elif location_slug:
        location = get_object_or_404(models.Location, slug=location_slug)
        locations = [location]
        locations += location.get_descendants()
        q_next = q_next.filter(location__in=locations)
        q_prev = q_prev.filter(location__in=locations)
        linkvars = "location=%s" % location_slug
    elif set_slug:
        cur_set = get_object_or_404(models.Set, slug=set_slug)
        q_next = q_next.filter(sets=cur_set)
        q_prev = q_prev.filter(sets=cur_set)
        linkvars = "set=%s" % set_slug

    next = q_next[0] if q_next.count() else None
    prev = q_prev[0] if q_prev.count() else None
    return render(request, 'mainapp/photo.html', {'photo': photo, "linkvars": linkvars, "next": next, "prev": prev})

def logout(request):
    auth.logout(request)
    return HttpResponseRedirect("/")

@cache_page(CACHE_TIME)
def tags_list(request):
    """ Show a list of tags """
    class CountAwareTagTree(object):
        """ Tree based on one root node with model counts """
        tag = None
        model_count = 0
        children = []

        callback = None
        rootlist = None

        def __init__(self, tag, callback=None, rootlist=[]):
            self.tag = tag
            self.callback = callback

            self.count()

            self.rootlist = rootlist or []
            self.rootlist.append(self)

            # Build children tags
            for tag in self.tag.get_children():
                awareTag = CountAwareTagTree(tag, callback=self._signal_count, rootlist=self.rootlist)

        def count(self):
            count = models.Photo.objects.filter(tags__in=[self.tag]).count()
            self._signal_count(count)

        def _signal_count(self, v):
            """Pass the model-count increase through all parents"""
            self.model_count += v
            if self.callback:
                self.callback(v)

    tags = []
    root_tags = models.Tag.get_root_nodes()
    for tag in root_tags:
        tags.append(CountAwareTagTree(tag))

    photo_count = models.Photo.objects.all().count()
    tag_count = models.Tag.objects.all().count()

    return render(request, 'mainapp/tags.html', {'tags': tags, "photo_count": photo_count, "tag_count": tag_count})

@cache_page(CACHE_TIME)
def locations_list(request):
    """ Show a list of locations """
    class CountAwareLocationTree(object):
        """ Tree based on one root node with model counts """
        location = None
        model_count = 0
        children = []

        callback = None
        rootlist = None

        def __init__(self, location, callback=None, rootlist=[]):
            self.location = location
            self.callback = callback

            self.count()

            self.rootlist = rootlist or []
            self.rootlist.append(self)

            # Build children tags
            for location in self.location.get_children():
                awareTag = CountAwareLocationTree(location, callback=self._signal_count, rootlist=self.rootlist)

        def count(self):
            count = models.Photo.objects.filter(location=self.location).count()
            self._signal_count(count)

        def _signal_count(self, v):
            """Pass the model-count increase through all parents"""
            self.model_count += v
            if self.callback:
                self.callback(v)

    locations = []
    root_locations = models.Location.get_root_nodes()
    for location in root_locations:
        tree = CountAwareLocationTree(location)
        locations.append(tree)

    photo_count = models.Photo.objects.all().count()
    location_count = models.Location.objects.all().count()

    return render(request, 'mainapp/locations.html', {'locations': locations, "photo_count": photo_count, "location_count": location_count})

@cache_page(CACHE_TIME)
def sets_list(request):
    """ Show a sets of tags """
    sets = models.Set.objects.filter(published=True)
    photo_count = models.Photo.objects.all().count()
    sets_count = models.Set.objects.all().count()
    return render(request, 'mainapp/sets.html', {'sets': sets, "photo_count": photo_count, "sets_count": sets_count})

@cache_page(CACHE_TIME)
def tag_photos(request, tag_slug):
    """ Show photos with a specific tag """
    tag = get_object_or_404(models.Tag, slug=tag_slug)
    page = ThumbnailPager(Filters(tags=[tag_slug])).load_page(adminvalues.PHOTOGRID_ITEMS_INITIAL.get_int())
    return render(request, 'mainapp/tag_photos.html', {'tag': tag, 'page': page})

@cache_page(CACHE_TIME)
def location_photos(request, location_slug):
    """ Show photos with a specific tag """
    location = get_object_or_404(models.Location, slug=location_slug)
    page = ThumbnailPager(Filters(location=location_slug)).load_page(adminvalues.PHOTOGRID_ITEMS_INITIAL.get_int())
    return render(request, 'mainapp/location_photos.html', {'location': location, 'page': page})

@cache_page(CACHE_TIME)
def set_photos(request, set_slug):
    """ Show photos in a set """
    set = get_object_or_404(models.Set, slug=set_slug)
    page = ThumbnailPager(Filters(sets=[set_slug])).load_page(adminvalues.PHOTOGRID_ITEMS_INITIAL.get_int())
    return render(request, 'mainapp/set_photos.html', {'set': set, 'page': page})

@cache_page(CACHE_TIME)
def ajax_photo_more(request):
    is_flow_mode = request.REQUEST.get("type") == "flow"
    if is_flow_mode:
        blocks_initial = adminvalues.PHOTOFLOW_BLOCKS_INITIAL.get_int()
        blocks_perpage = adminvalues.PHOTOFLOW_BLOCKS_PERPAGE.get_int()

        ajax_page_count = int(request.REQUEST.get("page"))  # 0-indexed
        cur_block = blocks_initial + (ajax_page_count * blocks_perpage)  # 0-indexed

        # Count the photos for the currently requested blocks
        flow = photoflow.FlowManager()
        photo_count = sum(flow.get_items_per_block(n) for n in xrange(cur_block, cur_block+blocks_perpage))

        pager = ThumbnailPager.from_request(request)
        pager.load_page(limit=photo_count)
        ret = {
            "html": flow.get_html(pager.photos, block_offset=cur_block),
            "has_more": pager.has_more,
            "last_hash": pager.last_hash,
        }

    else:
        pager = ThumbnailPager.from_request(request)
        pager.load_page(limit=adminvalues.PHOTOGRID_ITEMS_INITIAL.get_int())

        ret = {
            "photos": [],
            "has_more": pager.has_more,
            "last_hash": pager.last_hash,
        }

        griditem_template = get_template('mainapp/photogrid_item.html')
        for photo in pager.photos:
            ret["photos"].append(griditem_template.render(Context({ "photo": photo })))

    return HttpResponse(json.dumps(ret))

def ajax_contact(request):
    if request.method == 'POST':
        form = forms.ContactForm(request.POST)
        if form.is_valid():
            # All validation rules pass
            photo = None
            photo_ref = request.POST.get("photo_ref")
            if photo_ref:
                photo = models.Photo.objects.get(hash=photo_ref)

            # Prepare email
            email_template = get_template('mainapp/email/contact.html')
            msg = email_template.render(Context({
                    "form": form.cleaned_data,
                    "photo": photo
            }))

            # Send the email in the background
            bgjobs.SendMail("chris@metachris.org", "Photoblog Contact", msg).start()

            # Add an artificial delay for the user to get the feeling something is happening
            time.sleep(1)

            # If requested, subscribe to newsletter
            if request.POST.get("add_to_list") != "false":
                email = form.cleaned_data["email"]
                mailchimp.mailchimp_subscribe(email)

            # Return success
            return HttpResponse('1')
        else:
            return HttpResponse(str(form.errors))
    else:
        return HttpResponse("wrong turn?")

def get_handout(request, handout_hash=None):
    """Handout URL"""
    if not handout_hash:
        return render(request, 'mainapp/handout_search.html')

    SESSION_KEY_HAS_SUBSCRIBED = "has_subscribed_to_handout_%s" % handout_hash
    contact_subscribed = request.session.get(SESSION_KEY_HAS_SUBSCRIBED)

    # Users can force-remove the info that they already have subscribed
    if request.GET.get("n") == "1":
        contact_subscribed = request.session[SESSION_KEY_HAS_SUBSCRIBED] = None
        log.debug("Handout: Force-removed session key %s" % SESSION_KEY_HAS_SUBSCRIBED)

    # Handle new subscription
    if request.method == 'POST':
        # Extract data
        name = request.POST.get("name")
        email = request.POST.get("email")
        phone = request.POST.get("phone")
        msg = request.POST.get("message")
        add_to_list = request.POST.get("add_to_list") == "on"  # boolean: True or False

        # Poor mans validation
        if not name or (not email and not phone) or (email and (not "." in email or not "@" in email)):
            return render(request, 'mainapp/handout_notyetonline.html', {"id": handout_hash,
                    "error": "Please add your name and email/phone.", "name": name, "email": email,
                    "phone": phone, "msg": msg, "add_to_list": add_to_list
            })
        log.debug("Handout: contact validation passed (%s)" % name)

        # Sanitize phone number
        phone = phone.strip().replace(" ", "").replace("-", "").replace("/", "")

        # Create Handout Contact
        handout_contact = models.HandoutContact(
            name=name, email=email, tel=phone, subscribed_to_mail_list=add_to_list, hash=models.Handout._mk_hash()
        )
        handout_contact.save()

        # Create Handout if not exists, else add contact
        try:
            handout = models.Handout.objects.get(hash=handout_hash)
        except ObjectDoesNotExist:
            handout = models.Handout(hash=handout_hash)
            handout.save()
        handout.contacts.add(handout_contact)

        # All done. Now save the contact to session, send email, etc.
        log.debug("Handout: added contact %s to handout %s" % (handout_contact, handout))
        contact_subscribed = request.session[SESSION_KEY_HAS_SUBSCRIBED] = handout_contact

        # Prepare email
        email_template = get_template('mainapp/email/contact_handout.html')
        msg = email_template.render(Context({
            "id": handout_hash, "name": name, "email": email, "phone": phone,
            "msg": msg, "add_to_list": add_to_list
        }))

        # Send Email
        bgjobs.SendMail("chris@metachris.org", "Photoblog Handout Contact", msg).start()

        # If requested, subscribe to newsletter
        if add_to_list and email:
            mailchimp.mailchimp_subscribe(email)

    # See if the handout is already  published
    try:
        handout = models.Handout.objects.get(hash=handout_hash, is_published=True)
        handout.views += 1
        handout.save()
        return render(request, 'mainapp/handout.html', {"id": handout_hash,
                "contact": contact_subscribed, "handout": handout})

    except exceptions.ObjectDoesNotExist:
        return render(request, 'mainapp/handout_notyetonline.html', {"id": handout_hash, "contact": contact_subscribed})

@login_required
def view_flow(request):
    """Show initial flow page"""
    # Allow overwriting layout-ids for testing with eg. '/flow/?l=0,3'
    _layout_ids = request.GET.get("l")
    layout_ids = [int(id) for id in _layout_ids.split(",")] if _layout_ids else None

    # Create a flow manager
    flow = photoflow.FlowManager(layout_ids=layout_ids, is_test_layouts=True)

    # Calculate the number of photos for the initial blocks
    photo_count = sum(flow.get_items_per_block(n) for n in xrange(adminvalues.PHOTOFLOW_BLOCKS_INITIAL.get_int()))

    # Get the current page from the pager
    pager = ThumbnailPager(Filters(featured_only=True))
    pager.load_page(limit=photo_count)

    # Get the flow html and render to response
    flow_html = flow.get_html(pager.photos)
    return render(request, 'mainapp/flow.html', {'page': pager, "flow_html": flow_html })

def view_test(request):
    """Show initial flow page"""
    # Allow overwriting layout-ids for testing with eg. '/flow/?l=0,3'
    def l(s):
        log.info("[view_test] %s" % s)

    l(request)
    return HttpResponse("test")

@cache_page(CACHE_TIME)
def view_test_cached(request):
    def l(s):
        log.info("[view_test_cached] %s" % s)

    l(request)
    return HttpResponse("test_cached")

def i18n_setlang(request):
    return render(request, 'i18n_setlang.html')


#!/usr/bin/env python
#encoding: utf-8

import os
import logging
import traceback
import time
import datetime
import threading
import copy
import re

try:
    import gconf
except BaseException:
    import sys
    sys.path.insert(0, '..')
    import gconf

from cmdutils import exec_cmd
from fmonitor import folder_monitor
from fileutils import get_all_files

INTERVAL_CALLBACK = 60

_logger = logging.getLogger('root.utils.crontab')

_lock = threading.Lock()
_script_path_dir = os.path.join(gconf.PROCESS_PATH, 'scripts')

_commands = []

def _execute_cmd(cmd, cwd):
    return exec_cmd(cmd, True, cwd=cwd)[0]

def _validate_time_sequence(time_sequence):
    for _seq in time_sequence:
        if re.match("^([*]|[\d]{1,2}([,-][\d]{1,2})*|[*][/][\d]{1,2})$", _seq) is None:
            return False
    return True

def _read_configs():
    global _commands

    _cmds = []
    _paths = get_all_files(_script_path_dir, filter=lambda x:os.path.basename(x)=='crontab')

    for _path in _paths:
        _cwd = os.path.dirname(_path)
        with open(_path, 'rb') as _handler:
            for _line in _handler:
                _line = _line.strip()
                if _line == '' or _line.startswith('#'):
                    continue

                _sp = _line.split()

                if len(_sp) < 6:
                    _logger.error('crontab file config error, path:%s, line:%s', _path, _line)
                    continue

                if not _validate_time_sequence(_sp[:5]):
                    _logger.error('crontab file config error, path:%s, line:%s', _path, _line)
                    continue

                _cmds.append({'time_sequence': _sp[:5], 'cmd': _sp[5:], 'cwd': _cwd})

    if _lock.acquire():
        try:
            _commands = _cmds
        finally:
            _lock.release()

    return _cmds

def _judge_time(current_time_sequence, time_sequence):
    for _i in xrange(5):
        if time_sequence[_i] == '*':
            continue
        elif str(time_sequence[_i]).startswith('*/'):
            if int(current_time_sequence[_i]) % int(str(time_sequence[_i])[2:]) != 0:
                return False
        else:
            _nodes = str(time_sequence[_i]).split(',')
            _rt = False
            for _node in _nodes:
                if _node.find('-') != -1:
                    _min, _max = _node.split('-')[:2]
                    if int(current_time_sequence[_i]) >= int(_min) and int(current_time_sequence[_i]) <= int(_max):
                        _rt = True
                        break
                else:
                    if int(_node) == int(current_time_sequence[_i]):
                        _rt = True
                        break
            if not _rt:
                return False

    return True

def _judge_execute_commands(current_time, commands):
    _current_datetime = datetime.datetime.fromtimestamp(current_time)
    _current_time_sequence = [_current_datetime.minute, _current_datetime.hour, _current_datetime.day, _current_datetime.month, (_current_datetime.weekday()) + 1 % 7]
    for _command in commands:
        _time_sequence = _command.get('time_sequence')
        if _judge_time(_current_time_sequence, _time_sequence):
            _cmd = _command.get('cmd')
            _cwd = _command.get('cwd')
            _code = _execute_cmd(_cmd, _cwd)
            _logger.debug('execute cmd: %s at dir:%s, result:%s', _cmd, _cwd, _code)

def run():
    _logger.debug('judge exec commands')

    _execute_commands = []
    if _lock.acquire():
        try:
            _execute_commands = copy.deepcopy(_commands)
        finally:
            _lock.release()

    _judge_execute_commands(time.time(), _execute_commands)

folder_monitor(_script_path_dir, _read_configs, sleeptime=5, content=True, filter=lambda x:os.path.basename(x)=='crontab')

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s %(name)s %(levelname)s:%(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        )
    from runserver import Callback, run_as_server
    run_as_server(Callback(callback=run, interval=INTERVAL_CALLBACK))


import numpy as np
import matplotlib.pyplot as plt
import os

from math import log

from models.document import CACMDocumentCollection

if __name__ == '__main__':

    if 'cacm.collection' in os.listdir(os.path.join('Data', 'Collection')):
        document_collection = CACMDocumentCollection()
        document_collection.load_from_file(os.path.join('Data', 'Collection', 'cacm.collection'))
    else:
        document_collection = CACMDocumentCollection(
            source_data_filepath=os.path.join('Data', 'CACM', 'cacm.all'),
            stop_list_filepath=os.path.join('Data', 'CACM', 'common_words'),
            load_on_creation=True,
        )

    vocabulary = document_collection.vocabulary
    token_number = document_collection.token_number
    vocabulary_size = document_collection.vocabulary_size

    frequence = np.array(list(vocabulary.values()))
    frequence.sort()
    frequence = frequence[::-1]
    rank = np.array(list(range(1, len(frequence) + 1)))

    half_document_collection = document_collection
    half_document_collection.collection = {
        key: value
        for key, value
        in list(document_collection.items())[:len(document_collection) // 2]
    }
    half_document_collection.generate_vocabulary()

    half_vocabulary = half_document_collection.vocabulary
    half_token_number = half_document_collection.token_number
    half_vocabulary_size = half_document_collection.vocabulary_size

    b_Heap = (
        log(vocabulary_size / half_vocabulary_size) /
        log(token_number / half_token_number)
    )
    k_Heap = (
        (vocabulary_size - half_vocabulary_size) /
        (token_number ** b_Heap - half_token_number ** b_Heap)
    )

    vocabulary_size_1_million = k_Heap * (1000000) ** b_Heap

    print('Question 1:')
    print('CACM contains {} tokens.'.format(token_number))
    print('Question 2:')
    print('CACM has a vocabulary size of {}.'.format(vocabulary_size))
    print('Question 3:')
    print('Half of CACM contains {} tokens.'.format(half_token_number))
    print('Half of CACM has a vocabulary size of {}.'.format(
        half_vocabulary_size
    ))
    print('We can deduce Heap law parameter k = {}, b = {}.'.format(
        k_Heap,
        b_Heap,
    ))
    print('Question 4:')
    print(
        'If CACM has 1 million tokens, its vocabulary size '
        'would be around {}.'.format(vocabulary_size_1_million)
    )

    plt.subplot(2, 1, 2)
    plt.plot(np.log(frequence), np.log(rank))
    plt.ylabel('Log(f)')
    plt.xlabel('Log(r)')

    plt.subplot(2, 1, 1)
    plt.title('Question 5')
    plt.plot(frequence, rank)
    plt.ylabel('Frequence (f)')
    plt.xlabel('Rank (r)')

    plt.show()