import os.path
import tempfile
import shutil
import screed

from spacegraphcats import catlas
import search.index_contigs_by_kmer
import search.extract_nodes_by_query
import search.characterize_catlas_regions
import search.extract_unassembled_nodes
import search.catlas_info
import sourmash_lib

class TempDirectory(object):
    def __init__(self):
        self.tempdir = tempfile.mkdtemp(prefix='sgc_test')

    def __enter__(self):
        return self.tempdir

    def __exit__(self, exc_type, exc_value, traceback):
        try:
            shutil.rmtree(self.tempdir, ignore_errors=True)
        except OSError:
            pass

        if exc_type:
            return False

def relative_filename(filename):
    thisdir = os.path.dirname(__file__)
    pkgdir = os.path.join(thisdir, '..')
    newpath = os.path.join(pkgdir, filename)
    return os.path.abspath(newpath)

class Args(object):
    pass

def test_dory():
    with TempDirectory() as location:
        import search.bcalm_to_gxt

        # make the output directory
        try:
            os.mkdir('dory_k21_r1')
        except FileExistsError:
            pass

        # convert the bcalm file to gxt
        args = ['-k', '-21', '-P',
                relative_filename('dory/bcalm.dory.k21.unitigs.fa'),
                'dory_k21_r1/cdbg.gxt',
                'dory_k21_r1/contigs.fa.gz']

        search.bcalm_to_gxt.main(args)

        # build catlas

        args = Args()
        args.no_checkpoint = True
        args.level = 0
        args.radius = 1
        args.project = 'dory_k21_r1'

        catlas.main(args)

        # make k-mer search index
        args = '-k 21 dory_k21_r1'.split()
        search.index_contigs_by_kmer.main(args)

        # do search!!
        search.extract_nodes_by_query

        args='dory_k21_r1 dory_k21_r1_search_oh0 --query data/dory-head.fa -k 21 --overhead=0.0'.split()

        try:
            search.extract_nodes_by_query.main(args)
        except SystemExit as e:
            assert e.code == 0, str(e)

        # check output!
        output_path = 'dory_k21_r1_search_oh0/'
        assert os.path.exists(output_path + 'command.txt')
        assert os.path.exists(output_path + 'dory-head.fa.frontier.txt.gz')
        assert os.path.exists(output_path + 'dory-head.fa.cdbg_ids.txt.gz')
        assert os.path.exists(output_path + 'dory-head.fa.response.txt')
        assert os.path.exists(output_path + 'dory-head.fa.contigs.sig')
        assert os.path.exists(output_path + 'results.csv')

        with open(output_path + 'results.csv') as fp:
            lines = fp.readlines()
            assert len(lines) == 2

            last_line = lines[-1].strip()
            assert last_line == 'data/dory-head.fa,1.0,1.0,1671,2,21,1631,1.0,0.0,0.0'

        # run characterize_catlas_regions
        args = 'dory_k21_r1 dory_k1_r1.vec'.split()
        search.characterize_catlas_regions.main(args)

        # run extract_unassembled_regions
        args = 'dory_k21_r1 data/dory-head.fa dory.regions -k 21'.split()
        search.extract_unassembled_nodes.main(args)

        # run catlas info
        search.catlas_info.main(['dory_k21_r1'])


from collections import OrderedDict
from decimal import Decimal
from django.conf import settings
from django.contrib.auth.models import User
from django.db import connection, transaction
from django.db.models import F, Q
from django.utils import timezone

from crowdsourcing import models
import constants
from crowdsourcing.emails import send_notifications_email
from crowdsourcing.models import TaskWorker, PayPalPayoutLog
from crowdsourcing.redis import RedisProvider
from crowdsourcing.utils import PayPalBackend
from csp.celery import app as celery_app

@celery_app.task
def expire_tasks():
    cursor = connection.cursor()
    # noinspection SqlResolve
    query = '''
            WITH taskworkers AS (
                SELECT
                  tw.id,
                  p.id project_id
                FROM crowdsourcing_taskworker tw
                INNER JOIN crowdsourcing_task t ON  tw.task_id = t.id
                INNER JOIN crowdsourcing_project p ON t.project_id = p.id
                WHERE p.timeout IS NOT NULL AND tw.created_at + p.timeout < NOW()
                AND tw.status=%(in_progress)s)
                UPDATE crowdsourcing_taskworker tw_up SET status=%(expired)s
            FROM taskworkers
            WHERE taskworkers.id=tw_up.id
            RETURNING tw_up.id, tw_up.worker_id
        '''
    cursor.execute(query, {'in_progress': TaskWorker.STATUS_IN_PROGRESS, 'expired': TaskWorker.STATUS_EXPIRED})
    workers = cursor.fetchall()
    worker_list = []
    task_workers = []
    for w in workers:
        worker_list.append(w[1])
        task_workers.append({'id': w[0]})
    refund_task.delay(task_workers)
    update_worker_cache.delay(worker_list, constants.TASK_EXPIRED)
    return 'SUCCESS'

@celery_app.task
def update_worker_cache(workers, operation, key=None, value=None):
    provider = RedisProvider()

    for worker in workers:
        name = provider.build_key('worker', worker)
        if operation == constants.TASK_ACCEPTED:
            provider.hincrby(name, 'in_progress', 1)
        elif operation == constants.TASK_SUBMITTED:
            provider.hincrby(name, 'in_progress', -1)
            provider.hincrby(name, 'submitted', 1)
        elif operation == constants.TASK_REJECTED:
            provider.hincrby(name, 'submitted', -1)
            provider.hincrby(name, 'rejected', 1)
        elif operation == constants.TASK_RETURNED:
            provider.hincrby(name, 'submitted', -1)
            provider.hincrby(name, 'returned', 1)
        elif operation == constants.TASK_APPROVED:
            provider.hincrby(name, 'submitted', -1)
            provider.hincrby(name, 'approved', 1)
        elif operation in [constants.TASK_EXPIRED, constants.TASK_SKIPPED]:
            provider.hincrby(name, 'in_progress', -1)
        elif operation == constants.ACTION_GROUPADD:
            provider.set_add(name + ':worker_groups', value)
        elif operation == constants.ACTION_UPDATE_PROFILE:
            provider.set_hash(name, key, value)

    return 'SUCCESS'

@celery_app.task
def email_notifications():
    users = User.objects.all()
    url = '%s/%s/' % (settings.SITE_HOST, 'messages')
    users_notified = []

    for user in users:
        email_notification, created = models.EmailNotification.objects.get_or_create(recipient=user)

        if created:
            # unread messages
            message_recipients = models.MessageRecipient.objects.filter(
                status__lt=models.MessageRecipient.STATUS_READ,
                recipient=user
            ).exclude(message__sender=user)

        else:
            # unread messages since last notification
            message_recipients = models.MessageRecipient.objects.filter(
                status__lt=models.MessageRecipient.STATUS_READ,
                created_at__gt=email_notification.updated_at,
                recipient=user
            ).exclude(message__sender=user)

        message_recipients = message_recipients.order_by('-created_at') \
            .select_related('message', 'recipient', 'message__sender') \
            .values('created_at', 'message__body', 'recipient__username', 'message__sender__username')

        result = OrderedDict()

        # group messages by sender
        for message_recipient in message_recipients:
            if message_recipient['message__sender__username'] in result:
                result[message_recipient['message__sender__username']].append(message_recipient)
            else:
                result[message_recipient['message__sender__username']] = [message_recipient]

        messages = [{'sender': k, 'messages': v} for k, v in result.items()]

        if len(messages) > 0:
            # send email
            send_notifications_email(email=user.email, url=url, messages=messages)

            users_notified.append(user)

    # update the last time user was notified
    models.EmailNotification.objects.filter(recipient__in=users_notified).update(updated_at=timezone.now())

    return 'SUCCESS'

@celery_app.task(bind=True)
def create_tasks(self, tasks):
    try:
        with transaction.atomic():
            task_obj = []
            x = 0
            for task in tasks:
                x += 1
                t = models.Task(data=task['data'], project_id=task['project_id'],
                                row_number=x)
                task_obj.append(t)
            models.Task.objects.bulk_create(task_obj)
            models.Task.objects.filter(project_id=tasks[0]['project_id']).update(group_id=F('id'))
    except Exception as e:
        self.retry(countdown=4, exc=e, max_retries=2)

    return 'SUCCESS'

@celery_app.task(bind=True)
def create_tasks_for_project(self, project_id, file_deleted):
    project = models.Project.objects.filter(pk=project_id).first()
    if project is None:
        return 'NOOP'
    previous_rev = models.Project.objects.prefetch_related('batch_files', 'tasks').filter(~Q(id=project.id),
                                                                                group_id=project.group_id) \
        .order_by('-id').first()

    previous_batch_file = previous_rev.batch_files.first() if previous_rev else None
    models.Task.objects.filter(project=project).delete()
    if file_deleted:
        models.Task.objects.filter(project=project).delete()
        task_data = {
            "project_id": project_id,
            "data": {}
        }
        task = models.Task.objects.create(**task_data)
        if previous_batch_file is None:
            task.group_id = previous_rev.tasks.all().first().group_id
        else:
            task.group_id = task.id
        task.save()
        return 'SUCCESS'
    try:
        with transaction.atomic():
            data = project.batch_files.first().parse_csv()
            task_obj = []
            x = 0
            previous_tasks = previous_rev.tasks.all().order_by('row_number') if previous_batch_file else []
            previous_count = len(previous_tasks)
            for row in data:
                x += 1
                t = models.Task(data=row, project_id=int(project_id), row_number=x)
                if previous_batch_file is not None and x <= previous_count:
                    if len(set(row.items()) ^ set(previous_tasks[x - 1].data.items())) == 0:
                        t.group_id = previous_tasks[x - 1].group_id
                task_obj.append(t)
            models.Task.objects.bulk_create(task_obj)
            models.Task.objects.filter(project_id=project_id, group_id__isnull=True) \
                .update(group_id=F('id'))
    except Exception as e:
        self.retry(countdown=4, exc=e, max_retries=2)

    return 'SUCCESS'

@celery_app.task
def pay_workers():
    workers = User.objects.all()
    total = 0

    for worker in workers:
        tasks = TaskWorker.objects.values('task__project__price', 'id').filter(worker=worker,
                                                                               status=TaskWorker.STATUS_ACCEPTED,
                                                                               is_paid=False)
        total = sum(tasks.values_list('task__project__price', flat=True))
        if total > 0 and worker.profile.paypal_email is not None and single_payout(total, worker):
            tasks.update(is_paid=True)

    return {"total": total}

def single_payout(amount, user):
    backend = PayPalBackend()

    payout = backend.paypalrestsdk.Payout({
        "sender_batch_header": {
            "sender_batch_id": "batch_worker_id__" + str(user.id) + '_week__' + str(timezone.now().isocalendar()[1]),
            "email_subject": "Daemo Payment"
        },
        "items": [
            {
                "recipient_type": "EMAIL",
                "amount": {
                    "value": amount,
                    "currency": "USD"
                },
                "receiver": user.profile.paypal_email,
                "note": "Your Daemo payment.",
                "sender_item_id": "item_1"
            }
        ]
    })
    payout_log = PayPalPayoutLog()
    payout_log.worker = user
    if payout.create(sync_mode=True):
        payout_log.is_valid = payout.batch_header.transaction_status == 'SUCCESS'
        payout_log.save()
        return payout_log.is_valid
    else:
        payout_log.is_valid = False
        payout_log.response = payout.error
        payout_log.save()
        return False

@celery_app.task
def post_approve(task_id, num_workers):
    task = models.Task.objects.prefetch_related('project').get(pk=task_id)
    latest_revision = models.Project.objects.filter(~Q(status=models.Project.STATUS_DRAFT),
                                                    group_id=task.project.group_id) \
        .order_by('-id').first()
    latest_revision.amount_due -= Decimal(num_workers * task.project.price)
    latest_revision.save()
    return 'SUCCESS'

def create_transaction(sender_id, recipient_id, amount, reference):
    transaction_data = {
        'sender_id': sender_id,
        'recipient_id': recipient_id,
        'amount': amount,
        'method': 'daemo',
        'sender_type': models.Transaction.TYPE_SYSTEM,
        'reference': 'P#' + str(reference)
    }
    with transaction.atomic():
        daemo_transaction = models.Transaction.objects.create(**transaction_data)
        daemo_transaction.recipient.balance += Decimal(daemo_transaction.amount)
        daemo_transaction.recipient.save()
        if daemo_transaction.sender.type not in [models.FinancialAccount.TYPE_WORKER,
                                                 models.FinancialAccount.TYPE_REQUESTER]:
            daemo_transaction.sender.balance -= Decimal(daemo_transaction.amount)
            daemo_transaction.sender.save()
    return 'SUCCESS'

@celery_app.task
def refund_task(task_worker_in):
    task_worker_ids = [tw['id'] for tw in task_worker_in]
    system_account = models.FinancialAccount.objects.get(is_system=True,
                                                         type=models.FinancialAccount.TYPE_ESCROW).id
    task_workers = models.TaskWorker.objects.prefetch_related('task', 'task__project').filter(
        id__in=task_worker_ids)
    amount = 0
    for task_worker in task_workers:

        latest_revision = models.Project.objects.filter(~Q(status=models.Project.STATUS_DRAFT),
                                                        group_id=task_worker.task.project.group_id) \
            .order_by('-id').first()
        is_running = latest_revision.deadline is None or latest_revision.deadline > timezone.now()
        if task_worker.task.project_id == latest_revision.id:
            amount = 0
        elif task_worker.task.exclude_at is not None:
            amount = task_worker.task.project.price
        elif is_running and latest_revision.price >= task_worker.task.project.price:
            amount = 0
        elif is_running and latest_revision.price < task_worker.task.project.price:
            amount = task_worker.task.project.price - latest_revision.price
        else:
            amount = latest_revision.price
        if amount > 0:
            requester_account = models.FinancialAccount.objects.get(owner_id=task_worker.task.project.owner_id,
                                                                    type=models.FinancialAccount.TYPE_REQUESTER,
                                                                    is_system=False).id
            create_transaction(sender_id=system_account, recipient_id=requester_account, amount=amount,
                               reference=task_worker.id)
            latest_revision.amount_due -= Decimal(amount)
            latest_revision.save()
    return 'SUCCESS'


from __future__ import print_function
import time

from simpleflow import (
    activity,
    Workflow,
    futures,
)

@activity.with_attributes(task_list='quickstart', version='example',
                          start_to_close_timeout=60, heartbeat_timeout=15,
                          raises_on_failure=True)
def sleep(seconds):
    print("will sleep {}s".format(seconds))
    time.sleep(seconds)
    print("good sleep")
    # return a complex object so we can visually test the json-ified version of
    # it is displayed in "simpleflow activity.rerun" ; unfortunately hard to
    # include in a unit or integration test...
    return {"result": "slept {}s".format(seconds)}

class SleepWorkflow(Workflow):
    name = 'basic'
    version = 'example'
    task_list = 'example'

    def run(self, seconds):
        x = self.submit(sleep, seconds)
        futures.wait(x)


from collections import defaultdict
from sys import stdin
import queue, math

class Graph():
	""" A weightless and oriented graph """

	def __init__(self, n):
		""" Initializes the graph as a dicitonary with list """
		self.graph = defaultdict(list)
		self.n = n

	def __str__(self):
		""" Return the graph in a printable form """
		ans = ""
		for i, v in sorted(self.graph.items()):
			ans += str(i) + ": "
			for aux in v:
				ans += str(aux) + " "
			ans += "\n"

		return ans

	def add(self, a, b):
		""" Add 'b' in 'a' """
		self.graph[a].append(b)

	def sort_vertex(self):
		""" Sort each vertex """
		for i in self.graph.keys():
			self.graph[i] = sorted(self.graph[i])

	def bfs(self, s, end):
		""" Do a BFS search starting at 's' and going to 'end' """

		# Initializes the lists
		color = ["white"] * self.n
		distance = [math.inf] * self.n
		paths = [ [] for _ in range(self.n) ]
		color[s] = "gray"
		distance[s] = 0
		paths[s] = None

		# Put the starting in the queue
		q = queue.Queue()
		q.put(s)

		# While the queue is not empty
		while not q.empty():
			# Remove from queue
			u = q.get()

			# If it found the end
			if u == end:
				# If the end is not the first
				if paths[u] != None:
					# Put the end in the path and return it
					paths[u].append(u)
					return paths[u]
				# end == begin, return it
				else:
					return [end]

			# For every vertex in U
			for v in self.graph[u]:
				# If it's hasn't been visited
				if color[v] == "white":
					color[v] = "gray" 				# Not finished
					distance[v] = distance[u] + 1	# Calculates the distance
					# Add it's parent's path
					paths[v] = paths[u] + [u] if paths[u] != None else [u]
					# Put it in the queue
					q.put(v)

			# Finished been visited
			color[u] = "black"

		# If it get here, it dind't found a path from start to end
		return None

if __name__ == "__main__":

	# Read the number of vertex and egds
	n, v = list(map(int, input().split()))

	# Create the graph
	graph = Graph(n)

	# Read the graph
	for _ in range(v):
		a, b = list(map(int, input().split()))
		graph.add(a, b)

	graph.sort_vertex()

	# Read until end of file
	for line in stdin:
		a, b = list(map(int, line.split()))

		# Do a bfs
		p = graph.bfs(a, b)

		# If it found a answer, print it
		if p != None:
			for x in p:
				print(x, end=" ")

		# If it dind't found, just print a \n
		print()


from .                   import views
from django.conf.urls    import url
from django.contrib.auth import views as auth_views

app_name = 'accounts'

urlpatterns = [
	url(r'^$',
		views.dashboard,
		name = 'dashboard'),
	url(r'^login/$',
		auth_views.login,
		{'template_name': 'accounts/login.html', 'extra_context':{'title':'Login', 'current': 4}},
        name = 'login'),
	url(r'^logout/$',
		auth_views.logout,
		{'next_page': 'core:index'},
		name = 'logout'),
	url(r'^signup/$',
		views.register,
		name = 'register'),
]


import time
from django.test import TestCase
from stepicstudio.video_recorders.camera_recorder import ServerCameraRecorder
import os

from stepicstudio.operations_statuses.statuses import ExecutionStatus

os.environ['DJANGO_SETTINGS_MODULE'] = 'STEPIC_STUDIO.settings'

"""Functional tests.
Needs delays between starts to free up video device.
"""

class TestCameraRecorder(TestCase):
    def setUp(self):
        self.output_file = 'test_record.TS'
        self.path = 'C:\\Development\\Tests'

    def test_should_successfully_start_and_stop_record(self):
        time.sleep(2)
        cam_recorder = ServerCameraRecorder()
        start_result = cam_recorder.start_recording(self.path, self.output_file)
        self.assertTrue(cam_recorder.is_active())
        self.assertTrue(start_result.status is ExecutionStatus.SUCCESS)
        time.sleep(5)
        stop_result = cam_recorder.stop_recording()
        self.assertTrue(stop_result.status is ExecutionStatus.SUCCESS)
        self.assertFalse(cam_recorder.is_active())

    def test_should_fail_on_start_when_record_is_active(self):
        time.sleep(2)
        cam_recorder = ServerCameraRecorder()
        start_result = cam_recorder.start_recording(self.path, self.output_file)
        self.assertTrue(cam_recorder.is_active())
        self.assertTrue(start_result.status is ExecutionStatus.SUCCESS)

        time.sleep(2)
        start_result = cam_recorder.start_recording(self.path, self.output_file)
        self.assertTrue(start_result.status is ExecutionStatus.FATAL_ERROR)

        time.sleep(2)
        stop_result = cam_recorder.stop_recording()
        self.assertTrue(stop_result.status is ExecutionStatus.SUCCESS)
        self.assertFalse(cam_recorder.is_active())

    def test_should_fail_on_stop_non_existing_record(self):
        cam_recorder = ServerCameraRecorder()

        stop_result = cam_recorder.stop_recording()

        self.assertTrue(stop_result.status is ExecutionStatus.FATAL_ERROR)


from jinja2 import Template

from folium.elements import JSCSSMixin
from folium.features import GeoJson
from folium.map import Layer

class TimeSliderChoropleth(JSCSSMixin, Layer):
    """
    Creates a TimeSliderChoropleth plugin to append into a map with Map.add_child.

    Parameters
    ----------
    data: str
        geojson string
    styledict: dict
        A dictionary where the keys are the geojson feature ids and the values are
        dicts of `{time: style_options_dict}`
    name : string, default None
        The name of the Layer, as it will appear in LayerControls.
    overlay : bool, default False
        Adds the layer as an optional overlay (True) or the base layer (False).
    control : bool, default True
        Whether the Layer will be included in LayerControls.
    show: bool, default True
        Whether the layer will be shown on opening (only for overlays).
    init_timestamp: int, default 0
        Initial time-stamp index on the slider. Must be in the range
        `[-L, L-1]`, where `L` is the maximum number of time stamps in
        `styledict`. For example, use `-1` to initialize the slider to the
        latest timestamp.
    """

    _template = Template(
        """
        {% macro script(this, kwargs) %}
            var timestamps = {{ this.timestamps|tojson }};
            var styledict = {{ this.styledict|tojson }};
            var current_timestamp = timestamps[{{ this.init_timestamp }}];
            // insert time slider
            d3.select("body").insert("p", ":first-child").append("input")
                .attr("type", "range")
                .attr("width", "100px")
                .attr("min", 0)
                .attr("max", timestamps.length - 1)
                .attr("value", {{ this.init_timestamp }})
                .attr("id", "slider")
                .attr("step", "1")
                .style('align', 'center');

            // insert time slider output BEFORE time slider (text on top of slider)
            d3.select("body").insert("p", ":first-child").append("output")
                .attr("width", "100")
                .attr("id", "slider-value")
                .style('font-size', '18px')
                .style('text-align', 'center')
                .style('font-weight', '500%');

            var datestring = new Date(parseInt(current_timestamp)*1000).toDateString();
            d3.select("output#slider-value").text(datestring);

            fill_map = function(){
                for (var feature_id in styledict){
                    let style = styledict[feature_id]//[current_timestamp];
                    var fillColor = 'white';
                    var opacity = 0;
                    if (current_timestamp in style){
                        fillColor = style[current_timestamp]['color'];
                        opacity = style[current_timestamp]['opacity'];
                        d3.selectAll('#feature-'+feature_id
                        ).attr('fill', fillColor)
                        .style('fill-opacity', opacity);
                    }
                }
            }

            d3.select("#slider").on("input", function() {
                current_timestamp = timestamps[this.value];
                var datestring = new Date(parseInt(current_timestamp)*1000).toDateString();
                d3.select("output#slider-value").text(datestring);
                fill_map();
            });

            {% if this.highlight %}
                {{this.get_name()}}_onEachFeature = function onEachFeature(feature, layer) {
                    layer.on({
                        mouseout: function(e) {
                        if (current_timestamp in styledict[e.target.feature.id]){
                            var opacity = styledict[e.target.feature.id][current_timestamp]['opacity'];
                            d3.selectAll('#feature-'+e.target.feature.id).style('fill-opacity', opacity);
                        }
                    },
                        mouseover: function(e) {
                        if (current_timestamp in styledict[e.target.feature.id]){
                            d3.selectAll('#feature-'+e.target.feature.id).style('fill-opacity', 1);
                        }
                    },
                        click: function(e) {
                            {{this._parent.get_name()}}.fitBounds(e.target.getBounds());
                    }
                    });
                };
            {% endif %}

            var {{ this.get_name() }} = L.geoJson(
                    {{ this.data|tojson }}
            ).addTo({{ this._parent.get_name() }});

            {{ this.get_name() }}.setStyle(function(feature) {
                if (feature.properties.style !== undefined){
                    return feature.properties.style;
                }
                else{
                    return "";
                }
            });

            function onOverlayAdd(e) {
                {{ this.get_name() }}.eachLayer(function (layer) {
                    layer._path.id = 'feature-' + layer.feature.id;
                });

                d3.selectAll('path')
                .attr('stroke', 'white')
                .attr('stroke-width', 0.8)
                .attr('stroke-dasharray', '5,5')
                .attr('fill-opacity', 0);

                fill_map();
            }
            {{ this._parent.get_name() }}.on('overlayadd', onOverlayAdd);

            onOverlayAdd(); // fill map as layer is loaded
        {% endmacro %}
        """
    )

    default_js = [("d3v4", "https://d3js.org/d3.v4.min.js")]

    def __init__(
        self,
        data,
        styledict,
        name=None,
        overlay=True,
        control=True,
        show=True,
        init_timestamp=0,
    ):
        super().__init__(name=name, overlay=overlay, control=control, show=show)
        self.data = GeoJson.process_data(GeoJson({}), data)

        if not isinstance(styledict, dict):
            raise ValueError(
                f"styledict must be a dictionary, got {styledict!r}"
            )  # noqa
        for val in styledict.values():
            if not isinstance(val, dict):
                raise ValueError(
                    f"Each item in styledict must be a dictionary, got {val!r}"
                )  # noqa

        # Make set of timestamps.
        timestamps = set()
        for feature in styledict.values():
            timestamps.update(set(feature.keys()))
        try:
            timestamps = sorted(timestamps, key=int)
        except (TypeError, ValueError):
            timestamps = sorted(timestamps)

        self.timestamps = timestamps
        self.styledict = styledict
        assert (
            -len(timestamps) <= init_timestamp < len(timestamps)
        ), "init_timestamp must be in the range [-{}, {}) but got {}".format(
            len(timestamps), len(timestamps), init_timestamp
        )
        if init_timestamp < 0:
            init_timestamp = len(timestamps) + init_timestamp
        self.init_timestamp = init_timestamp


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QLineEdit, QLabel, QFileDialog , QMessageBox
import sys
import csv
import pandas
#import pandas as pd
#from pandasModel import pandasModel

class Ui_Mainwindow(object):

    def updatebatchUM(self):
        try:
            dialog = QFileDialog.getOpenFileName()
            path = dialog[0]
            print(path)
            self.label.setText("Commands for\nUnmarking :")
            self.textEdit_2.clear()
            # with open (path) as fileread:
            #    fileread1 = fileread.readlines()
            #    print(fileread1)
            dfs = pandas.read_csv(path)
            df = pandas.DataFrame(dfs)
            #self.textEdit.setText(str(df))
            # cel = df.loc['1' , 'Cluster']

            str  = []
            str1 = []
            str2 = []
            temp = ""
            commaseperatedtenants = ""
            commaseperatedtenants1 = ""
            tenants = ""
            tenants1 = ""
            temp2 = ""
            clus = ""
            for i, item in df.iterrows():

                if item["Cluster"] not in temp:
                    temp = temp + item["Cluster"]
                    commaseperatedtenants = commaseperatedtenants +"\\\\reddog\Builds\\branches\git_azure_compute_master_latest\\retail-amd64\services\controller\FcShell\scripts\MarkTenantsAsOptedOutFromHEUpdate.ps1  -clusterName" + item["Cluster"] + "-commaSeperatedTenantNames" +item["TenantName"] + "\n"

                    # print(commaseperatedtenants)

                else:
                    clus = clus + item["Cluster"] + " "
                    line = clus.split()

                    commaseperatedtenants1 = commaseperatedtenants1 + "\"" + item["TenantName"] + "\"" + ","

                if item["Cluster"] not in clus:
                    tenants = tenants + "\"" + item["Cluster"] + "\"" + ","

                else:
                    tenants1 = tenants1 + "\"" + item["Cluster"] + "\"" + ","
            print("\\\\reddog\Builds\\branches\git_azure_compute_master_latest\\retail-amd64\services\controller\FcShell\scripts\MarkTenantsAsOptedOutFromHEUpdate.ps1  -clusterName" + tenants + commaseperatedtenants1 )
            print("\\\\reddog\Builds\\branches\git_azure_compute_master_latest\\retail-amd64\services\controller\FcShell\scripts\MarkTenantsAsOptedOutFromHEUpdate.ps1  -clusterName" + tenants1 + commaseperatedtenants1)

        except (FileNotFoundError, KeyError) as error:
            print (error)

            self.textEdit.setText("No File Selected or Wrong file selected")

                    # for l in str:
                    #     try:
                    #         str.remove(l)
                    #     except ValueError:
                    #         pass
                    # str1 = str1.append(c)
                    #
                    # if c not in str1:
                    #     str2 st
                    #
                    # clus = str.insert(c)
                    # str1 = str1 + clus
                    #
                    # for t in item["TenantName"]:
                    #     tena.remove
                    #
                    #     if c in str1:
                    #
                    #         str2 = str2 + tena
                    #         print( str)
                    #     else:
                    #         print(str + tena)

            #
            #     tenants = item["Cluster"]
            #     x = tenants.splitlines()
            #     for s in x:
            #
            #         if s not in str:
            #             str.append(s)
            #         else:
            #             str2.append(s)
            # print(str)
            # print(str2)

                # tenants = item["TenantName"]
                # tenants.splitlines()
                #
                # for s in tenants:
                #     if s not in str:
                #         str = str + s
                #         print(str)
                #
                #     else:
                #         str2 = str2 + s
                #         print(str2)

    def updatebatch(self):
        pass

    def withoutjit(self):

        try:
            dialog = QFileDialog.getOpenFileName()
            path = dialog[0]
            print(path)
            self.label.setText("Commands \nWithout JIT :")
            self.textEdit_2.clear()

            # with open (path) as fileread:
            #    fileread1 = fileread.readlines()
            #    print(fileread1)

            dfs = pandas.read_csv(path)
            df = pandas.DataFrame(dfs)
            self.textEdit.setText(str(df))
            # cel = df.loc['1' , 'Cluster']
            commands = ""

            for i, item in df.iterrows():
                cell = "\\\\reddog\Builds\\branches\git_azure_compute_master_latest\\retail-amd64\Services\Controller\FcShell\scripts\BatchingUpdateForAllNodesOfTenantWhoSkippedHEUpdateWithoutJITAccess.ps1" " -clusterName " +item["Cluster"] +" -tenantName " +item["TenantName"]
                # print(cel)
                # dfs = df.values.tolist()
                # print(dfs)
                # self.textEdit.setText(str(dfs))
                # i=df.drop_duplicates()

                commands = commands + cell + "\n"
                self.textEdit.setText(str(commands))
                # print(ff)

        except (FileNotFoundError, KeyError ) as error:

            self.textEdit.setText("No File Selected or Wrong file selected")

    def withjit(self):

        try:
            dialog = QFileDialog.getOpenFileName()
            path = dialog[0]
            print(path)
            self.label.setText("Commands \nWith JIT :")
            self.textEdit_2.clear()

            # with open (path) as fileread:
            #    fileread1 = fileread.readlines()
            #    print(fileread1)
            #box = QMessageBox()
            #box.setWindowTitle("incident details")
            #box.setText("Enter incident ID :")
            #x=box.exec()

            text ,incident_id = QtWidgets.QInputDialog.getText(Mainwindow, 'Incident details', 'Enter incident ID :')
            if text and incident_id:
                incident_id = text

            dfs = pandas.read_csv(path)
            df = pandas.DataFrame(dfs)
            self.textEdit.setText(str(df))
            # cel = df.loc['1' , 'Cluster']
            commands = ""
            row = 0
            for i, item in df.iterrows():
                cell = "\\\\reddog\Builds\\branches\git_azure_compute_master_latest\\retail-amd64\Services\Controller\FcShell\scripts\BatchingUpdateForAllNodesOfTenantWhoSkippedHEUpdate.ps1 -clusterName " + \
                       item["Cluster"] + " -incidentId " + str(incident_id) + " -TenantName " + item["TenantName"]
                # print(cel)
                # dfs = df.values.tolist()
                # print(dfs)
                # self.textEdit.setText(str(dfs))
                # i=df.drop_duplicates()

                commands = commands + cell + "\n"
                self.textEdit.setText(str(commands))
                # print(ff)

        except (FileNotFoundError, KeyError) as error:

            self.textEdit.setText("No File Selected or Wrong file selected")

    def checkcsv(self):
        try:
            dialog = QFileDialog.getOpenFileName()
            path = dialog[0]
            print(path)
            self.label.setText("Commands :")
            self.textEdit_2.clear()

            # with open (path) as fileread:
            #    fileread1 = fileread.readlines()
            #    print(fileread1)

            text, incident_id = QtWidgets.QInputDialog.getText(Mainwindow, 'Incident details', 'Enter incident ID :')
            if text and incident_id:
                incident_id = text

            dfs = pandas.read_csv(path)
            df = pandas.DataFrame(dfs)
            self.textEdit.setText(str(df))
            #cel = df.loc['1' , 'Cluster']
            commands = ""
            row = 0
            for i,item in df.iterrows():

                cell = "\\\\reddog\Builds\\branches\git_azure_compute_master_latest\\retail-amd64\Services\Controller\FcShell\scripts\BatchingUpdateForAllNodesOfTenantWhoSkippedHEUpdate.ps1 -clusterName " + \
                 item["Cluster"] + " -incidentId " + incident_id + " -TenantName " + item["TenantName"]
                # print(cel)
                # dfs = df.values.tolist()
                # print(dfs)
                # self.textEdit.setText(str(dfs))
                # i=df.drop_duplicates()

                commands = commands + cell + "\n"
                self.textEdit.setText(str(commands))
                # print(ff)

        except (FileNotFoundError,KeyError) as error:
            self.textEdit.setText("No File Selected or Wrong file selected")

    def duplicate_check(self):

        x = self.textEdit.toPlainText()  #anchorAt(Mainwindow)  #text()
        self.label_2.setText("Duplicates :")

        y= x.splitlines()
        lst = list(y)

# using regular logic

        data_list = []
        final_list = []

        for item in lst:

            if item not in final_list:

                final_list.append(item)
            else:
                data_list.append(item)

            str0 = ""

            for elem in data_list:

                str0 = str0 + elem + "\n                             \n"
                str2 = str0.rstrip().lstrip()
                self.textEdit_2.setText(str(str2))

            #data_list.reverse()
            #rev_data2 = data_list[0]
            #self.textEdit_2.setText(str(data_list))

            #else:
             #   data_list.append(item)
              #  data_list2 = data_list.append(item)
               # print(item)
                #self.textEdit_2.setText("item")
        #self.textEdit_2.setText(data_list2)
                #data = []
                #data_final = data.append(item)

            #return final_list
        #data = final_list

### using dataframes
        #df = pd.DataFrame(lst)
        #dp = df.duplicated()
        #y = df[dp]
        #self.textEdit_2.setText(str(y))

    def clear(self):
        self.textEdit.clear()
        self.textEdit_2.clear()
        self.label.setText("Enter Data:")

#
# #
#     def Tenants(self):
#
#         try:
#             x = self.textEdit.toPlainText()  # anchorAt(Mainwindow)  #text()
#             self.label_2.setText("Duplicates :")
#
#             y = x.splitlines()
#             lst = list(y)
#             # using regular logic
#             data_list = []
#             final_list = []
#             for item in lst:
#
#                 if item not in final_list:
#
#                     final_list.append(item)
#                 else:
#                     data_list.append(item)
#
#                 str1 = ""
#                 strd2 = ""
#
#                 for elem in data_list:
#                     elem2 = elem.rstrip().lstrip().split()
#                     finalelem = elem2[6]
#                     strd = finalelem + "\n"
#                     strd2 = strd2 + strd
#                     self.textEdit_2.setText(str(strd2))
#
#                     # strd = " " + finalelem
#                     # strd2 = strd [:]
#
#                     # str1 = str1 + strd2 + "\n                             \n"
#         except IndexError:
#             self.textEdit_2.setText("Remove spaces between commands")
#
#
#
#
#
#     def NoDuplicates(self):
#
#         x = self.textEdit.toPlainText()  # anchorAt(Mainwindow)  #text()
#
#         y = x.splitlines()
#         lst = list(y)
#
#         # using regular logic
#
#         data_list = []
#         final_list = []
#         for item in lst:
#
#             if item not in final_list:
#
#                 final_list.append(item)
#
#
#             else:
#                 data_list.append(item)
#
#             str0 = ""
#
#             for elem in final_list:
#                 str0 = str0 + elem   + "\n                             \n"
#                 str2 = str0.rstrip().lstrip()
#                 self.textEdit_2.setText(str(str2))
#         self.label_2.setText("NoDuplicates :")
#
#

    def setupUi(self, Mainwindow):
        Mainwindow.setObjectName("Mainwindow")
        Mainwindow.resize(1200, 832)
        font = QtGui.QFont()
        font.setFamily("Century")
        font.setPointSize(9)
        font.setBold(False)
        font.setWeight(50)
        Mainwindow.setFont(font)
        Mainwindow.setFocusPolicy(QtCore.Qt.TabFocus)
        icon = QtGui.QIcon.fromTheme("CD")
        Mainwindow.setWindowIcon(icon)
        Mainwindow.setAnimated(True)
        Mainwindow.setTabShape(QtWidgets.QTabWidget.Rounded)
        Mainwindow.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks|QtWidgets.QMainWindow.AnimatedDocks)
        self.centralwidget = QtWidgets.QWidget(Mainwindow)
        self.centralwidget.setObjectName("centralwidget")

   #     self.Labelname = QLabel(Mainwindow)
    #    self.Labelname.setText('Name')
     #   self.Labelname.move(80, 20)

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setEnabled(True)
        self.pushButton.setGeometry(QtCore.QRect(780, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton.setFont(font)
        self.pushButton.setFocusPolicy(QtCore.Qt.NoFocus)
        self.pushButton.setFlat(False)
        self.pushButton.setObjectName("checkduplicates")

        self.pushButton.clicked.connect(self.duplicate_check)

        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 90, 141, 121))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
        self.label.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setFamily("Malgun Gothic Semilight")
        font.setPointSize(11)
        font.setBold(True)
        font.setUnderline(False)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.label.setMouseTracking(False)
        self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(10, 510, 141, 131))
        font = QtGui.QFont()
        font.setFamily("Malgun Gothic Semilight")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")

       # self.textbox = QLineEdit(Mainwindow)

        #self.textbox.move(200, 200)
###
#        self.process = QtCore.QProcess()
#        self.process.readyReadStandardOutput.connect(self.stdoutReady)
#        self.process.readyReadStandardError.connect(self.stderrReady)

###
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(160, 10, 900, 341))#160, 10, 661, 341))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.textEdit.sizePolicy().hasHeightForWidth())
        self.textEdit.setSizePolicy(sizePolicy)
        font = QtGui.QFont()
        font.setStyleStrategy(QtGui.QFont.PreferDefault)
        self.textEdit.setFont(font)
        #self.textEdit.setFrameShape(QtWidgets.QFrame.WinPanel)
        self.textEdit.setObjectName("textEdit")
        self.textEdit.setFrameShape(QtWidgets.QFrame.WinPanel)

        self.textEdit_2 = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit_2.setGeometry(QtCore.QRect(160, 410, 900, 341))
        font = QtGui.QFont()
        font.setStyleStrategy(QtGui.QFont.PreferDefault)
        self.textEdit_2.setFont(font)
        self.textEdit_2.setFrameShape(QtWidgets.QFrame.WinPanel)
        self.textEdit_2.setObjectName("textEdit_2")
        Mainwindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(Mainwindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 884, 22))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuexit = QtWidgets.QMenu(self.menubar)
        self.menuexit.setObjectName("menuexit")
        Mainwindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(Mainwindow)
        self.statusbar.setObjectName("statusbar")
        Mainwindow.setStatusBar(self.statusbar)
        self.menuexit.addSeparator()
        self.menuexit.addSeparator()
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuexit.menuAction())
##########
        self.pushButton1 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton1.setEnabled(True)
        self.pushButton1.setGeometry(QtCore.QRect(10, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(13)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton1.setFont(font)
        self.pushButton1.setFocusPolicy(QtCore.Qt.NoFocus)
        self.pushButton1.setFlat(False)
        self.pushButton1.setObjectName("clear")
        self.pushButton1.clicked.connect(self.clear)

#########
#get tenants button

        # self.pushButton2 = QtWidgets.QPushButton(self.centralwidget)
        # self.pushButton2.setEnabled(True)
        # self.pushButton2.setGeometry(QtCore.QRect(780, 360, 121, 31))
        # font = QtGui.QFont()
        # font.setFamily("Calibri")
        # font.setPointSize(9)
        # font.setBold(True)
        # font.setWeight(75)
        # self.pushButton2.setFont(font)
        # self.pushButton2.setFocusPolicy(QtCore.Qt.NoFocus)
        # self.pushButton2.setFlat(False)
        # self.pushButton2.setObjectName("checkduplicates")
        #
        # self.pushButton2.clicked.connect(self.Tenants)

###############No duplicates button

        self.pushButton3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton3.setEnabled(True)
        self.pushButton3.setGeometry(QtCore.QRect(920, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.pushButton3.setFont(font)
        self.pushButton3.setFocusPolicy(QtCore.Qt.NoFocus)
        self.pushButton3.setFlat(False)
        self.pushButton3.setObjectName("checkduplicates")

        self.pushButton3.clicked.connect(self.NoDuplicates)

##############
        self.checkingcsv = QtWidgets.QPushButton(self.centralwidget)
        self.checkingcsv.setEnabled(True)
        self.checkingcsv.setGeometry(QtCore.QRect(1065, 200, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.checkingcsv.setFont(font)
        self.checkingcsv.setFocusPolicy(QtCore.Qt.NoFocus)
        self.checkingcsv.setFlat(False)
        self.checkingcsv.setObjectName("checkduplicates")

        self.checkingcsv.clicked.connect(self.checkcsv)

#################
        self.jitcommands = QtWidgets.QPushButton(self.centralwidget)
        self.jitcommands.setEnabled(True)
        self.jitcommands.setGeometry(QtCore.QRect(160, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.jitcommands.setFont(font)
        self.jitcommands.setFocusPolicy(QtCore.Qt.NoFocus)
        self.jitcommands.setFlat(False)
        self.jitcommands.setObjectName("checkduplicates")

        self.jitcommands.clicked.connect(self.withjit)

####################
        self.nojitcommands = QtWidgets.QPushButton(self.centralwidget)
        self.nojitcommands.setEnabled(True)
        self.nojitcommands.setGeometry(QtCore.QRect(290, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.nojitcommands.setFont(font)
        self.nojitcommands.setFocusPolicy(QtCore.Qt.NoFocus)
        self.nojitcommands.setFlat(False)
        self.nojitcommands.setObjectName("checkduplicates")

        self.nojitcommands.clicked.connect(self.withoutjit)

#####################
        self.Updatebatch = QtWidgets.QPushButton(self.centralwidget)
        self.Updatebatch.setEnabled(True)
        self.Updatebatch.setGeometry(QtCore.QRect(430, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.Updatebatch.setFont(font)
        self.Updatebatch.setFocusPolicy(QtCore.Qt.NoFocus)
        self.Updatebatch.setFlat(False)
        self.Updatebatch.setObjectName("checkduplicates")

        self.Updatebatch.clicked.connect(self.updatebatch)

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

        self.UpdatebatchUM = QtWidgets.QPushButton(self.centralwidget)
        self.UpdatebatchUM.setEnabled(True)
        self.UpdatebatchUM.setGeometry(QtCore.QRect(555, 360, 121, 31))
        font = QtGui.QFont()
        font.setFamily("Calibri")
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.UpdatebatchUM.setFont(font)
        self.UpdatebatchUM.setFocusPolicy(QtCore.Qt.NoFocus)
        self.UpdatebatchUM.setFlat(False)
        self.UpdatebatchUM.setObjectName("checkduplicates")

        self.UpdatebatchUM.clicked.connect(self.updatebatchUM)

        self.retranslateUi(Mainwindow)
        QtCore.QMetaObject.connectSlotsByName(Mainwindow)

        #self.pandasTv = QtWidgets.QTableView(self)

    def retranslateUi(self, Mainwindow):
        _translate = QtCore.QCoreApplication.translate
        Mainwindow.setWindowTitle(_translate("Mainwindow", "CheckDuplicates"))
        self.pushButton.setText(_translate("Mainwindow", "Duplicate Commands"))
        self.pushButton1.setText(_translate("Mainwindow", "Clear Data"))
        #self.pushButton2.setText(_translate("Mainwindow", "Duplicate Tenants"))
        self.pushButton3.setText(_translate("Mainwindow", "NoDuplicates"))
        self.label.setText(_translate("Mainwindow", "Enter data :"))
        self.label_2.setText(_translate("Mainwindow", "Duplicates :"))
        #self.menuFile.setTitle(_translate("Mainwindow", "File"))
        #self.menuexit.setTitle(_translate("Mainwindow", "exit"))
        self.checkingcsv.setText(_translate("Mainwindow", "Browse .csv"))
        self.jitcommands.setText(_translate("Mainwindow","Batch Update\nWithJit"))
        self.nojitcommands.setText(_translate("Mainwindow", "Batch Update\nWithoutJit"))
        self.Updatebatch.setText(_translate("Mainwindow", "Mark Update\nBatch"))
        self.UpdatebatchUM.setText(_translate("Mainwindow", "UnMark Update\nBatch"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Mainwindow = QtWidgets.QMainWindow()
    ui = Ui_Mainwindow()

    ui.setupUi(Mainwindow)

    Mainwindow.show()
    sys.exit(app.exec_())


#!/usr/bin/env python
# coding:UTF-8
import sys
reload(sys)
sys.setdefaultencoding('UTF-8')

import json
import time
import redis
import random
import urllib
import urllib2
from urllib2 import Request, urlopen, URLError, HTTPError
import requests
import logging
import logging.handlers
import os
import re
from flask import Flask
from flask import render_template
from flask import request
import threading

app=Flask(__name__)
app.debug=True
r=redis.StrictRedis(host='localhost',port=6379,db=0)

url_access_token_weixin_base="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"

redis_access_token_dict_name="weixin_access_token_dict"
redis_weixin_appid="weixin_appid"
redis_weixin_secret="weixin_secret"

def GetWeixinAppid():
    result=r.get(redis_weixin_appid)
    return result

def GetWeixinSecret():
    result=r.get(redis_weixin_secret)
    return result

class Maintainer(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.locker=threading.Lock()
        if r.exists(redis_access_token_dict_name):
            self.access_token=r.hget(redis_access_token_dict_name,"access_token")
            self.time=r.hget(redis_access_token_dict_name,"time")
            app.logger.debug("[access_token][%s]" % (self.access_token))
            app.logger.debug("[time][%s]" % (str(self.time)))
            if time.time()-float(self.time)>7000:
                self.FreshAccessToken()
        else:
            self.FreshAccessToken()

    def FreshAccessToken(self):
        self.locker.acquire()
        self.access_token=""
        self.time=""
        url=url_access_token_weixin_base %(GetWeixinAppid(),GetWeixinSecret())
        app.logger.debug(url)
        req=Request(url)
        try:
            response=urlopen(req)
            data=json.loads(response.read())
            self.access_token=data['access_token']
            self.time=time.time()
            r.hset(redis_access_token_dict_name,"access_token",self.access_token)
            r.hset(redis_access_token_dict_name,"time",self.time)
        except BaseException as e:
            app.logger.debug("Failed")
            app.logger.debug(e)
        finally:
            self.locker.release()

    def GetAccessToken(self):
        self.locker.acquire()
        ans=self.access_token
        self.locker.release()
        return ans

    def run(self):
        while True:
            app.logger.debug(self.time)
            if time.time()-float(self.time)>7000:
                self.FreshAccessToken()
            time.sleep(200)

maintainer=Maintainer()
maintainer.start()

@app.route('/benben/access_token',methods=['GET'])
def GET():
    return maintainer.GetAccessToken()

if __name__=="__main__":
    # 普通模式
    app.run(port=9007)


import os
from flask import Flask, g
from flask_sijax import sijax
import flask_sijax
path = os.path.join('.', os.path.dirname(__file__), 'static/js/sijax/')
app = Flask(__name__)

app.config['SIJAX_STATIC_PATH'] = path
app.config['SIJAX_JSON_URI'] = '/static/js/sijax/json2.js'
flask_sijax.Sijax(app)

@app.route('/')
def index():
   return 'Index'

@flask_sijax.route(app, '/hello')
def hello():
   def say_hi(obj_response):
      obj_response.alert('Hi there!')
   if g.sijax.is_sijax_request:
      # Sijax request detected - let Sijax handle it
      g.sijax.register_callback('say_hi', say_hi)
      return g.sijax.process_request()
      return _render_template('sijaxexample.html')

if __name__ == '__main__':
   app.run(debug = True)


import os
from typing import Callable, Dict, Iterable, List, Optional, TypeVar, Union

import marshmallow
import marshmallow.validate
from web3 import Web3

DNS_REGEX = r'^((?!-)[${}a-z0-9-]{1,63}(?<!-)\.)+([a-z]{2,6}[\.]{0,1})$'

T = TypeVar('T')
TypeKey = TypeVar('TypeKey')
TypeValue = TypeVar('TypeValue')

ValidatorType = Callable[[T], Union[T, bool]]

# Validators for public use in config dataclasses.

def validate_regex_match(
        field_name: str, *, regex: str, allow_none: bool, regex_description: str) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be a legal {regex_description}'.format(
        field_name=field_name, regex_description=regex_description)
    validate_regex = marshmallow.validate.Regexp(regex=regex, error=error_message)

    def validator(value):
        if value is None:
            if allow_none:
                return True

            raise marshmallow.exceptions.ValidationError(message=error_message.format(input=value))

        return validate_regex(value)

    return validator

def validate_dns(*, allow_none: bool) -> ValidatorType:
    return validate_regex_match(
        field_name='dns', regex=DNS_REGEX, allow_none=allow_none, regex_description='DNS label')

HEX_REGEX = r'^0x[a-fA-F0-9]+$'
validate_optional_hex_str = validate_regex_match(
    field_name='fact', regex=HEX_REGEX, allow_none=True, regex_description='hex string')

def validate_url(
        *, url_name: str, schemes: marshmallow.types.StrSequenceOrSet,
        require_full_url: bool) -> ValidatorType:
    error_message = (
        'Invalid {url_name} URL: {{input}}; '
        'must be a legal URL starting with {schemes}').format(
        url_name=url_name, schemes=','.join(schemes))
    return marshmallow.validate.URL(
        schemes=schemes, require_tld=require_full_url, error=error_message)

validate_gateway_url = validate_url(
    url_name='Gateway endpoint', schemes={'http', 'https'}, require_full_url=False)

validate_internal_url = validate_url(
    url_name='Internal Gateway endpoint', schemes={'http', 'https'}, require_full_url=False)

validate_node_endpoint = validate_url(
    url_name='Node endpoint', schemes={'http', 'https'}, require_full_url=False)

def validate_one_of(
        field_name: str, *, choices: Iterable, allow_none: bool = False) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; allowed values: {{choices}}'.format(
        field_name=field_name)
    one_of_validator = marshmallow.validate.OneOf(choices=choices, error=error_message)

    def validator(value):
        if allow_none and value is None:
            return True

        return one_of_validator(value)

    return validator

def validate_equal(field_name: str, *, allowed_value: T) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be: {{other}}'.format(
        field_name=field_name)
    return marshmallow.validate.Equal(comparable=allowed_value, error=error_message)

def validate_in_range(
        field_name, *, min_value: Optional[int] = None, max_value: Optional[int] = None,
        min_inclusive: bool = True, max_inclusive: bool = True,
        allow_none: bool = False, error_message: Optional[str] = None) -> ValidatorType:
    if error_message is None:
        range_string = (
            f'{"[" if min_inclusive else "("}'
            f'{"-inf" if min_value is None else min_value},'
            f'{"inf" if max_value is None else max_value}'
            f'{"]" if max_inclusive else ")"}')
        error_message = \
            'Invalid {field_name}: {{input}}; must be in the range {range_string}'.format(
                field_name=field_name, range_string=range_string)

    range_validator = marshmallow.validate.Range(
        min=min_value, max=max_value, min_inclusive=min_inclusive, max_inclusive=max_inclusive,
        error=error_message)

    def validator(value):
        if allow_none and value is None:
            return True

        return range_validator(value)

    return validator

def validate_positive(field_name: str, *, allow_none: bool = False) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be a positive value'.format(
        field_name=field_name)
    return validate_in_range(
        field_name=field_name, min_value=0, min_inclusive=False, allow_none=allow_none,
        error_message=error_message)

def validate_non_negative(field_name, *, allow_none=False):
    error_message = 'Invalid {field_name}: {{input}}; must be a non-negative value'.format(
        field_name=field_name)
    return validate_in_range(
        field_name=field_name, min_value=0, min_inclusive=True, allow_none=allow_none,
        error_message=error_message)

def validate_positive_or_infinity(field_name: str) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be positive -1 (for unlimited)'.format(
        field_name=field_name)

    def validator(value):
        if value <= 0 and value != -1:
            raise marshmallow.ValidationError(error_message.format(input=value))

        return True

    return validator

def validate_probability(field_name: str, *, allow_none: bool = False) -> ValidatorType:
    return validate_in_range(
        field_name=field_name, min_value=0, max_value=1, min_inclusive=True, max_inclusive=True,
        allow_none=allow_none)

def validate_public_key(field_name: str) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be a legal Ethereum address'.format(
        field_name=field_name)

    address_regex = r'^0x[a-fA-F0-9]{40}$'
    validate_address_regex = marshmallow.validate.Regexp(regex=address_regex, error=error_message)

    def validator(addresses: Union[str, List[str]]):
        if isinstance(addresses, str):
            addresses = [addresses]

        for address in addresses:
            validate_address_regex(address)

            if not Web3.isChecksumAddress(address):
                raise marshmallow.ValidationError(error_message.format(input=address))

        return True

    return validator

def validate_private_key(field_name: str) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be a legal Ethereum private key'.format(
        field_name=field_name)

    private_key_regex = r'^0x[a-fA-F0-9]{64}$'
    return marshmallow.validate.Regexp(regex=private_key_regex, error=error_message)

def validate_customer_id(field_name: str) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be an alphanumeric string'.format(
        field_name=field_name)
    return marshmallow.validate.Regexp(regex=r'^[A-Za-z0-9_-]+$', error=error_message)

def validate_absolute_linux_path(field_name: str, *, allow_none: bool) -> ValidatorType:
    error_message = 'Invalid {field_name}: {{input}}; must be a legal absolute Linux path'.format(
        field_name=field_name)

    def validator(value: str):
        if allow_none and value is None:
            return True

        if not os.path.isabs(value):
            raise marshmallow.ValidationError(error_message.format(input=value))

        return True

    return validator

validate_certificates_path = validate_absolute_linux_path('certificates_path', allow_none=True)

def validate_communication_params(*, url: str, certificates_path: Optional[str]):
    https_used = url.startswith('https')
    certs_used = certificates_path is not None

    if certs_used and not https_used:
        raise ValueError('Certificates should be used together with a HTTPS URL')

def validate_dict(
        field_name: str,
        *, key_validator: Optional[Callable[[str], Callable[[TypeKey], bool]]] = None,
        value_validator: Optional[Callable[[str], Callable[[TypeValue], bool]]] = None,
        allow_none: bool = False) -> Callable[[Dict[TypeKey, TypeValue]], bool]:
    """
    Returns a validator for a dictionary, that validates the keys according to key_validator, and
    the values according to value_validator.
    These validators should be methods that get the field name, and return the validator for that
    field. Set these validators to None to have empty validators, which will always return True.
    """
    def validator(dictionary: Dict[TypeKey, TypeValue]):
        nonlocal key_validator, value_validator
        if allow_none and dictionary is None:
            return True
        if key_validator is None:
            key_validator = (lambda name: lambda key: True)
        if value_validator is None:
            value_validator = (lambda name: lambda value: True)
        for key, value in dictionary.items():
            try:
                (key_validator(str(key)))(key)
                (value_validator(str(key)))(value)
            except Exception as e:
                raise type(e)(f'Dictionary {field_name} is not valid: ' + str(e))
        return True

    return validator

def validate_power_of_two(field_name: str) -> ValidatorType:
    """
    Return a validator for a number, that validates that the number is a power of 2.
    """
    error_message = 'Invalid {field_name}: {{input}}; must be a power of 2'.format(
        field_name=field_name)

    def validator(value):
        tmp_value = value
        while tmp_value > 1:
            if tmp_value % 2 == 1:
                break
            tmp_value = tmp_value // 2

        if tmp_value != 1:
            raise marshmallow.ValidationError(error_message.format(input=value))
        return True

    return validator


import pytest
from hypothesis import given
from hypothesis.strategies import integers, tuples

import numpy as np
import numpy.random as npr
from stylo.image import Image

dimension = integers(min_value=2, max_value=5000)
smalldim = integers(min_value=2, max_value=256)
colvalue = integers(min_value=0, max_value=255)
color = tuples(colvalue, colvalue, colvalue, colvalue)

@given(width=smalldim, height=smalldim)
def test_width_height_init(width, height):

    img = Image(width, height)

    assert img.pixels.shape == (height, width, 4)
    assert img.pixels.dtype == np.uint8

    unique = np.unique(img.pixels)
    assert unique.shape == (1,)
    assert (unique == [(255, 255, 255, 255)]).all()

@given(width=smalldim, height=smalldim, background=color)
def test_width_height_background_init(width, height, background):

    img = Image(width, height, background=background)

    assert img.pixels.shape == (height, width, 4)
    assert img.pixels.dtype == np.uint8

    unique = np.unique(img.pixels, axis=0)
    unique = np.unique(unique, axis=1).flatten()
    assert unique.shape == (4,)
    assert (unique == [background]).all()

@given(width=smalldim, height=smalldim)
def test_pixel_init(width, height):

    px = npr.randint(0, 255, (height, width, 4), dtype=np.uint8)
    img = Image(pixels=px)

    assert img.pixels.shape == (height, width, 4)
    assert (img.pixels == px).all()

    img = Image.fromarray(px)

    assert img.pixels.shape == (height, width, 4)
    assert (img.pixels == px).all()

def test_init_exceptions():

    with pytest.raises(ValueError) as err:
        img = Image()

    assert 'specify a width and height' in str(err.value)

    with pytest.raises(ValueError) as err:
        img = Image(width=12)

    assert 'specify a width and height' in str(err.value)

    with pytest.raises(ValueError) as err:
        img = Image(height=12)

    assert 'specify a width and height' in str(err.value)

@given(width=smalldim, height=smalldim)
def test_pixel_init_exceptions(width, height):

    px = npr.randint(0, 255, (height, width), dtype=np.uint8)

    with pytest.raises(ValueError) as err:
        img = Image(pixels=px)

    assert 'must have shape:' in str(err.value)

    px = npr.randint(0, 255, (height, width, 5), dtype=np.uint8)

    with pytest.raises(ValueError) as err:
        img = Image(pixels=px)

    assert 'must have shape:' in str(err.value)

@given(width=smalldim, height=smalldim)
def test_repr(width, height):

    img = Image(width, height)
    assert repr(img) == '%ix%i Image' % (width, height)

@given(index=integers(min_value=4, max_value=512))
def test_getitem_pixels(index):

    img = Image(512, 512)

    # Test that slicing by x works as expected
    sliced_x = img[:index]

    assert isinstance(sliced_x, (Image,))
    assert sliced_x.width == index
    assert sliced_x.height == 512

    # Test that slicing by y works as expected
    sliced_y = img[:, :index]

    assert isinstance(sliced_y, (Image,))
    assert sliced_y.width == 512
    assert sliced_y.height == index

    # Test that slicing by both works as expected
    sliced_both = img[:index, :index]

    assert isinstance(sliced_both, (Image,))
    assert sliced_both.width == index
    assert sliced_both.height == index

    # As a further test ensure that the smaller images
    # point back to subsets of the original pixel
    # data
    sliced_both[:, :] = (255, 0, 0, 255)

    assert (img.pixels[:index, :index] == sliced_both.pixels).all()
    assert (img.pixels[index:, index:] == (255, 255, 255, 255)).all()


import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as T
import torch.nn.functional as F
import random
import numpy as np
from point_net import PointNet

class FusionNet(nn.Module):
    def __init__(self, num_points = 1024):
        super(FusionNet, self).__init__()
        self.pointnet = PointNet(num_points = num_points)
        self.resnet = ResNet50Features(torchvision.models.resnet50(pretrained = True))
        self.fc1 = nn.Linear(3072, 512)
        self.fc2 = nn.Linear(512, 128)
        self.fc3 = nn.Linear(128, 24)

    def forward(self, points, image):
        pointnet_global_feature, _ = self.pointnet(points)
        resnet_feature = self.resnet(image)
        fusion_feature = torch.cat((pointnet_global_feature, resnet_feature), dim = 1)
        fc1 = F.relu(self.fc1(fusion_feature))
        fc2 = F.relu(self.fc2(fc1))
        fc3 = self.fc3(fc2)
        out = fc3.view(-1, 8, 3)
        return out

class DenseFusionNet(nn.Module):
    def __init__(self, num_points = 1024, return_all = False):
        super(DenseFusionNet, self).__init__()
        self.num_points = num_points
        self.return_all = return_all
        self.pointnet = PointNet(num_points = num_points, global_feat = False)
        self.resnet = ResNet50Features(torchvision.models.resnet50(pretrained = True))
        self.fc1 = nn.Linear(3136, 512)
        self.fc2 = nn.Linear(512, 128)
        self.fc3 = nn.Linear(128, 25)
        self.softmax = nn.Softmax(dim = 1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, points, image, override_return_all = None):
        pointnet_point_features = self.pointnet(points)
        resnet_feature = self.resnet(image).view(-1, 2048, 1).repeat(1, 1, self.num_points)

        fusion_feature = torch.cat((pointnet_point_features, resnet_feature), dim = 1)
        fusion_feature = torch.transpose(fusion_feature, 1, 2)
        fusion_feature = fusion_feature.contiguous()
        fusion_feature = fusion_feature.view(-1, 3136)

        fc1 = F.relu(self.fc1(fusion_feature))
        fc2 = F.relu(self.fc2(fc1))
        fc3 = self.fc3(fc2)
        out = fc3.view(-1, self.num_points, 25)

        box_offsets = out[:, :, :24].view(-1, self.num_points, 8, 3)
        scores = out[:,:,24]

        if (override_return_all is not None and override_return_all == True) or (override_return_all is None and self.return_all):
            predicted_coords = box_offsets + points.unsqueeze(2)
            return predicted_coords, scores

        confidences = self.softmax(scores)
        best_confidences, best_confidence_indices = confidences.max(dim = 1)
        best_box_offsets = box_offsets[range(box_offsets.size()[0]), best_confidence_indices, :, :]
        predicted_coords = best_box_offsets + points[range(points.size()[0]), best_confidence_indices, :].unsqueeze(1)
        return predicted_coords, best_confidences

class ResNet50Features(nn.Module):
    def __init__(self, original_model):
        super(ResNet50Features, self).__init__()
        self.features = nn.Sequential(*list(original_model.children())[:-1]) # just remove last FC layer

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size()[0], x.size()[1])
        return x


"""
This file is not used anywhere in current version of the code.
"""

import numpy as np
import statsmodels.api as sm
from scipy import stats

def linear_f_test1(var, cov, pheno, var_size, test_vars):
    n_indiv = var.shape[0]
    n_var = var.shape[1]
    n_cov = cov.shape[1]

    design = np.zeros((n_indiv, var_size + n_cov))
    design[:, var_size : var_size + n_cov] = cov

    n_test = int(n_var / var_size)
    pvalues = np.zeros(n_test)

    for i_test in range(n_test):
        design[:, 0:var_size] = var[:, i_test * var_size : (i_test + 1) * var_size]
        beta = np.linalg.lstsq(design, pheno, rcond=None)[0]
        sigma = np.square(pheno - np.dot(design, beta)).sum() / (
            n_indiv - var_size - n_cov
        )
        iXtX = np.linalg.inv(np.dot(design.T, design))
        f_stat = (
            beta[test_vars]
            .T.dot(np.linalg.inv(iXtX[np.ix_(test_vars, test_vars)]))
            .dot(beta[test_vars])
        ) / (len(test_vars) * sigma)
        pvalues[i_test] = stats.f.sf(f_stat, len(test_vars), n_indiv - var_size - n_cov)

    return pvalues

def linear_f_test2(var, cov, pheno, var_size, test_vars):
    n_indiv = var.shape[0]
    n_var = var.shape[1]
    n_cov = cov.shape[1]

    design = np.zeros((n_indiv, var_size + n_cov))
    design[:, var_size : var_size + n_cov] = cov

    n_test = int(n_var / var_size)
    pvalues = np.zeros(n_test)

    reduced_index = np.concatenate(
        [
            [i for i in range(var_size) if i not in test_vars],
            np.arange(var_size, var_size + n_cov),
        ]
    ).astype(int)

    for i_test in range(n_test):
        design[:, 0:var_size] = var[:, i_test * var_size : (i_test + 1) * var_size]

        beta1 = np.linalg.lstsq(design[:, reduced_index], pheno, rcond=None)[0]
        ss1 = np.square(pheno - np.dot(design[:, reduced_index], beta1)).sum()
        p1 = len(beta1)
        beta2 = np.linalg.lstsq(design, pheno, rcond=None)[0]
        ss2 = np.square(pheno - np.dot(design, beta2)).sum()
        p2 = len(beta2)

        fstat = ((ss1 - ss2) / (p2 - p1)) / (ss2 / (n_indiv - p2))
        pvalues[i_test] = stats.f.sf(fstat, p2 - p1, n_indiv - p2)

    return pvalues

def linear_lrt(var, cov, pheno, var_size, test_vars):
    n_indiv = var.shape[0]
    n_var = var.shape[1]
    n_cov = cov.shape[1]

    design = np.zeros((n_indiv, var_size + n_cov))
    design[:, var_size : var_size + n_cov] = cov

    n_test = int(n_var / var_size)
    pvalues = np.zeros(n_test)

    reduced_index = np.concatenate(
        [
            [i for i in range(var_size) if i not in test_vars],
            np.arange(var_size, var_size + n_cov),
        ]
    ).astype(int)

    for i_test in range(n_test):
        design[:, 0:var_size] = var[:, i_test * var_size : (i_test + 1) * var_size]
        llf1 = sm.OLS(pheno, design[:, reduced_index]).fit().llf
        llf2 = sm.OLS(pheno, design).fit().llf
        pvalues[i_test] = stats.chi2.sf(-2 * (llf1 - llf2), len(test_vars))
    return pvalues

def linear_f_test3(var, cov, pheno, var_size, test_vars):
    n_indiv = var.shape[0]
    n_var = var.shape[1]
    n_cov = cov.shape[1]

    design = np.zeros((n_indiv, var_size + n_cov))
    design[:, var_size : var_size + n_cov] = cov

    n_test = int(n_var / var_size)
    pvalues = np.zeros(n_test)

    f_test_r_matrix = np.zeros((len(test_vars), design.shape[1]))
    for i, v in enumerate(test_vars):
        f_test_r_matrix[i, v] = 1

    for i_test in range(n_test):
        design[:, 0:var_size] = var[:, i_test * var_size : (i_test + 1) * var_size]
        model = sm.OLS(pheno, design, missing="drop").fit()
        print(model.f_test(f_test_r_matrix))
        pvalues[i_test] = model.f_test(f_test_r_matrix).pvalue.item()
    return pvalues


#!/bin/python
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 14 11:01:46 2018

@author: Suyong Choi (Department of Physics, Korea University suyong@korea.ac.kr)

This script applies nanoaod processing to one file
"""

import sys
import cppyy
import ROOT

if __name__=='__main__':
    from optparse import OptionParser
    parser = OptionParser(usage="%prog [options] inputDir outputDir")
    parser.add_option("-Y", "--year",  dest="json", type="string", default="", help="Select 2016, 2017, 2018 year of runs")
    parser.add_option("-J", "--json",  dest="json", type="string", default="", help="Select events using this JSON file, meaningful only for data")
    parser.add_option("--saveallbranches", dest="saveallbranches", action="store_true", default=False, help="Save all branches. False by default")
    parser.add_option("--globaltag", dest="globaltag", type="string", default="", help="Global tag to be used in JetMET corrections")

    (options, args) = parser.parse_args()
    if len(args) < 1:
        parser.print_help()
        sys.exit(1)
    infile = args[0]
    outfile = args[1]
    intreename = args[2]
    outtreename = args[3]

    # load compiled C++ library into ROOT/python
    cppyy.load_reflection_info("libnanoadrdframe.so")
    t = ROOT.TChain(intreename)
    t.Add(infile)
    aproc = ROOT.LQtopAnalyzer(t, outfile, options.year, options.json, options.globaltag)
    aproc.setupAnalysis()
    aproc.run(options.saveallbranches, outtreename)


import decimal
import json

from django.http import JsonResponse, HttpResponseRedirect
from django.shortcuts import render
from .models import Game, Level

LEVELS = {150:1, 120:2, 100:3}

def start(request):
    print('start game')
    print(request.POST)
    Game.objects.filter(player__isnull=True).delete()

    try:
        puzzle_length = int(request.POST.get('puzzle_length'))
        # level = LEVELS[puzzle_length]
        level = Level.objects.get(id=LEVELS[puzzle_length])
        print(level)
    except:
        return JsonResponse({'code': 400, 'error': 'Invalid puzzle_length'})
    else:
        if request.user.is_authenticated:
            game = Game(player=request.user, game_type=int(request.POST.get('game_type')))
        else:
            game = Game(game_type=int(request.POST.get('game_type')))
        print('game',game)
        game.level = level
        game.save()
        print('game info', game.id)

        return JsonResponse({'code': 200, 'image': game.image.url, 'game_id': game.id, 'level': level.id,'timer':level.timer})

def win(request):
    request_unicode = request.body.decode('utf-8')
    request_body = json.loads(request_unicode)
    game = Game.objects.get(id=request_body['game_id'])
    game.result = True
    game.save()
    if game.player:
        game.player.rating += game.level.rating
        print(game.player.balance)
        print(game.level.balance / 100)
        # game.player.balance += game.player.balance * decimal.Decimal((game.level.balance / 100))
        game.player.save()
        return JsonResponse({'rating': game.player.rating})
    else:
        return JsonResponse({'rating': 0})

def theme_light(request):
    request.session['theme']  = 'light'
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
def theme_dark(request):
    request.session['theme'] = 'dark'
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))


import asyncio
import time
import functools
from escape_room_006 import *
import playground
from ex6_game_packet_types import *

from playground.common.logging import EnablePresetLogging, PRESET_VERBOSE
EnablePresetLogging(PRESET_VERBOSE)

def new_write_function(string, transport, status):
    string = string + "<EOL>\n"
    transport.write(
            GameResponsePacket(
                server_response = string,
                server_status=status
                ).__serialize__()
            )
    print(string)

class StudentServer(asyncio.Protocol):
    def __init__(self):
        print("S: server started")
        self.responses = []
        self.status = None

    #async def wait_agents(self):
    #    await asyncio.wait([asyncio.create_task(a) for a in self.game.agents])

    def connection_made(self, transport):
        print("S: connection made")
        self.transport = transport
        game = EscapeRoomGame(output=functools.partial(new_write_function, transport=self.transport, status = self.status))
        game.create_game()
        game.start()
        self.game = game
        #asyncio.create_task(self.wait_agents())
        for a in game.agents:
            asyncio.ensure_future(a)
        self.d = PacketType.Deserializer()
        print("S: packet sent")

    def connection_lost(self, ex):
        print("S: closing transport")
        self.transport.close()

    def data_received(self, data):
        self.d.update(data)
        for packet in self.d.nextPackets():
            if packet.DEFINITION_IDENTIFIER == "exercise6.jaron.command":
                print("SR: ", packet.command)
                text = packet.command

            else:
                raise ValueError()
            time.sleep(.2)
            lines = text.split("<EOL>\n")
            #if self.game.status == "playing":
            for line in lines:
                if len(line) > 0:
                    print("S: ", line)
                    self.game.command(line)
                    self.status = self.game.status

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    coro = loop.create_server(StudentServer,"", 1292)
    server = loop.run_until_complete(coro)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass

    server.close()
    loop.run_until_complete(server.wait_close())
    loop.close()


"""
Operate overnight using min15 to daily periods

Results:
All periods have mean net profit positive, from 47 to 82 points

Conclusion:
Funny thing here... min60 and daily share many extrema. My hunch is that the other SM parameters
are not fit to daily.
"""
#

from navala.analysis import *
from navala.misc import quoteperiod as qp
from collections import OrderedDict
import numpy as np
import math

dataSpecs = "BMF_FUT_WINFUT"
numPoints = 50000
quotePeriods = range(qp.min15, qp.daily+1)

strategySpecs = [
    {"name": "Breakout",
     "strategyClass": EnterAdvisorStrategy,
     "singletonParams": {"advisorClass": TopBottomBreakoutAdvisor, "stopManagerClass": ParabolicStopLoss,
                         "flagMultiple": False,
                         "AD_TBDClass": TopBottomDetector4,
                         "AD_breakoutTolerance": 0,
                         "AD_TBD_size": 7,
                         "SM_distance": 250,
                         "SM_gainRiskRatio": 2,
                        },
     "paramssSpec": OrderedDict((
         ("SM_AF0", [0]+list(np.logspace(-4, 0.5, 20))),
         ("SM_AFIncrement", np.logspace(-4, -.3, 35)),
     ))
    }
]


from django import forms

from .mixins import APIFormMixin

from utils.api.client import MarketAccessAPIClient
from utils.forms import (
    ChoiceFieldWithHelpText,
    ClearableMixin,
    DayMonthYearField,
    MultipleChoiceFieldWithHelpText,
    YesNoBooleanField,
    YesNoDontKnowBooleanField,
)

class UpdateCommercialValueForm(APIFormMixin, forms.Form):
    commercial_value = forms.IntegerField(
        min_value=0,
        max_value=1000000000000,
        localize=True,
        label="What is the value of the barrier to the affected business(es) in GBP?",
        error_messages={
            "required": "Enter a value",
            "min_value": "Enter a valid number",
            "max_value": "Enter a valid number",
        },
    )
    commercial_value_explanation = forms.CharField(
        widget=forms.Textarea,
        error_messages={"required": "Enter a value description and timescale"},
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, **self.cleaned_data)

class UpdateBarrierTitleForm(APIFormMixin, forms.Form):
    title = forms.CharField(
        label="Suggest a title for this barrier",
        help_text=(
            "Include both the title or service name and the country being "
            "exported to, for example, Import quotas for steel rods in India."
        ),
        max_length=255,
        error_messages={
            "max_length": "Title should be %(limit_value)d characters or fewer",
            "required": "Enter a title for this barrier",
        },
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, title=self.cleaned_data["title"])

class UpdateBarrierProductForm(APIFormMixin, forms.Form):
    product = forms.CharField(
        label="What product or service is being exported?",
        max_length=255,
        error_messages={
            "max_length": "Product or service should be %(limit_value)d characters or fewer",
            "required": "Enter a product or service",
        },
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, product=self.cleaned_data["product"])

class UpdateBarrierSummaryForm(APIFormMixin, forms.Form):
    summary = forms.CharField(
        label="Give us a summary of the barrier and how you found out about it",
        widget=forms.Textarea,
        error_messages={"required": "Enter a brief description for this barrier"},
    )
    is_summary_sensitive = YesNoBooleanField(
        label="Does the summary contain OFFICIAL-SENSITIVE information?",
        error_messages={
            "required": (
                "Indicate if summary contains OFFICIAL-SENSITIVE information or not"
            )
        },
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            summary=self.cleaned_data["summary"],
            is_summary_sensitive=self.cleaned_data["is_summary_sensitive"],
        )

class UpdateBarrierSourceForm(APIFormMixin, forms.Form):
    CHOICES = [
        ("COMPANY", "Company"),
        ("TRADE", "Trade association"),
        ("GOVT", "Government entity"),
        ("OTHER", "Other "),
    ]
    source = forms.ChoiceField(
        label="How did you find out about the barrier?",
        choices=CHOICES,
        widget=forms.RadioSelect,
        error_messages={"required": "Select how you became aware of the barrier"},
    )
    other_source = forms.CharField(
        label="Please specify",
        required=False,
        max_length=255,
        error_messages={
            "max_length": "Other source should be %(limit_value)d characters or fewer",
        }
    )

    def clean(self):
        cleaned_data = super().clean()
        source = cleaned_data.get("source")
        other_source = cleaned_data.get("other_source")

        if source == "OTHER":
            if not other_source and "other_source" not in self.errors:
                self.add_error(
                    "other_source", "Enter how you became aware of the barrier"
                )
        else:
            cleaned_data["other_source"] = ""

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            source=self.cleaned_data["source"],
            other_source=self.cleaned_data["other_source"],
        )

class UpdateBarrierPriorityForm(APIFormMixin, forms.Form):
    CHOICES = [
        ("UNKNOWN", "Unknown priority"),
        ("HIGH", "High priority"),
        ("MEDIUM", "Medium priority"),
        ("LOW", "Low priority"),
    ]
    priority = forms.ChoiceField(
        label="What is the priority of the barrier?",
        choices=CHOICES,
        widget=forms.RadioSelect,
        error_messages={"required": "Select a barrier priority"},
    )
    priority_summary = forms.CharField(
        label="Why did the priority change? (optional)",
        widget=forms.Textarea,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        initial_priority = kwargs.get("initial", {}).get("priority")
        if initial_priority == "UNKNOWN":
            self.fields[
                "priority_summary"
            ].label = "Why did you choose this priority? (optional)"

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            priority=self.cleaned_data["priority"],
            priority_summary=self.cleaned_data["priority_summary"],
        )

class UpdateBarrierTermForm(APIFormMixin, forms.Form):
    CHOICES = [
        (
            1,
            "A procedural, short-term barrier",
            "for example, goods stuck at the border or documentation issue",
        ),
        (2, "A long-term strategic barrier", "for example, a change of regulation",),
    ]
    term = ChoiceFieldWithHelpText(
        label="What is the scope of the barrier?",
        choices=CHOICES,
        widget=forms.RadioSelect,
        error_messages={"required": "Select a barrier scope"},
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id, term=self.cleaned_data["term"]
        )

class UpdateBarrierEndDateForm(ClearableMixin, APIFormMixin, forms.Form):
    end_date = DayMonthYearField(
        label="End date",
        help_text=(
            "For example, 30 11 2020. If you don't know the day, please enter 1 for "
            "the first of the month."
        ),
        error_messages={"required": "Enter the end date"},
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        end_date = kwargs.get("initial", {}).get("end_date")
        if end_date:
            self.fields["end_date"].label = "Change end date"

    def clean_end_date(self):
        return self.cleaned_data["end_date"].isoformat()

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            end_date=self.cleaned_data.get("end_date"),
        )

class UpdateBarrierTagsForm(APIFormMixin, forms.Form):
    tags = MultipleChoiceFieldWithHelpText(
        label="Is this issue caused by or related to any of the following?",
        choices=[],
        required=False,
    )

    def __init__(self, tags, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["tags"].choices = tags

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(id=self.id, tags=self.cleaned_data["tags"])

class UpdateTradeDirectionForm(APIFormMixin, forms.Form):
    trade_direction = forms.ChoiceField(
        label="Which trade direction does this barrier affect?",
        choices=[],
        widget=forms.RadioSelect,
        error_messages={"required": "Select a trade direction"},
    )

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id, trade_direction=self.cleaned_data["trade_direction"]
        )

    def __init__(self, trade_direction_choices, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["trade_direction"].choices = trade_direction_choices

class CausedByTradingBlocForm(forms.Form):
    caused_by_trading_bloc = YesNoDontKnowBooleanField(
        label="",
        error_messages={
            "required": (
                "Indicate if the barrier was caused by the trading bloc"
            )
        },
    )

    def __init__(self, trading_bloc, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["caused_by_trading_bloc"].label = (
            f"Was this barrier caused by a regulation introduced by "
            f"{trading_bloc['short_name']}?"
        )
        self.fields["caused_by_trading_bloc"].help_text = (
            self.get_help_text(trading_bloc.get("code"))
        )

    def get_help_text(self, trading_bloc_code):
        help_text = {
            "TB00016": (
                "Yes should be selected if the barrier is a local application of an EU "
                "regulation. If it is an EU-wide barrier, the country location should "
                "be changed to EU in the location screen."
            )
        }
        return help_text.get(trading_bloc_code, "")

class UpdateCausedByTradingBlocForm(APIFormMixin, CausedByTradingBlocForm):
    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            caused_by_trading_bloc=self.cleaned_data["caused_by_trading_bloc"],
        )

class UpdateEconomicAssessmentEligibilityForm(APIFormMixin, forms.Form):
    economic_assessment_eligibility = YesNoBooleanField(
        label="Is the barrier eligible for an initial economic assessment?",
        error_messages={
            "required": (
                "Select yes if the barrier is eligible for an initial economic assessment"
            )
        },
    )
    economic_assessment_eligibility_summary = forms.CharField(
        label="Why is this barrier not eligible for an initial economic assessment?",
        help_text="Please explain why this barrier is not eligible",
        max_length=1500,
        widget=forms.Textarea,
        required=False,
    )

    def clean(self):
        cleaned_data = super().clean()
        economic_assessment_eligibility = cleaned_data.get("economic_assessment_eligibility")
        economic_assessment_eligibility_summary = cleaned_data.get("economic_assessment_eligibility_summary")

        if economic_assessment_eligibility is False:
            if not economic_assessment_eligibility_summary:
                self.add_error(
                    "economic_assessment_eligibility_summary",
                    "Enter why this barrier is not eligible",
                )
        else:
            cleaned_data["economic_assessment_eligibility_summary"] = ""

    def save(self):
        client = MarketAccessAPIClient(self.token)
        client.barriers.patch(
            id=self.id,
            economic_assessment_eligibility=self.cleaned_data["economic_assessment_eligibility"],
            economic_assessment_eligibility_summary=self.cleaned_data["economic_assessment_eligibility_summary"],
        )


from django import forms
from django.contrib import messages
from django.urls import reverse
from django.utils.html import mark_safe
from intercom.client import Client
from intercom.errors import TokenUnauthorizedError, TokenNotFoundError
from feedback.models import CustomerFeedbackImporterSettings

class IntercomSettingsUpdateForm(forms.ModelForm):
    feedback_tag_name = forms.ChoiceField()

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        self.cfis = CustomerFeedbackImporterSettings.objects.get(importer__name="Intercom", customer=self.request.user.customer)
        self.client = Client(personal_access_token=self.cfis.api_key)

        super().__init__(*args, **kwargs)
        self.fields['feedback_tag_name'].choices = self.get_tag_choices()
        self.fields['feedback_tag_name'].help_text = f"To create a new tag, first create it in Intercom, then refresh this page."
        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'form-control'

    def get_tag_choices(self):
        try:
            tag_choices = [(None, 'Choose a tag')] + [(tag.name, tag.name) for tag in self.client.tags.all()]
        except (TokenUnauthorizedError, TokenNotFoundError):
            tag_choices = []
            intercom_disconnect_url = reverse('customer-feedback-importer-settings-delete-item', args=[self.cfis.pk,])
            messages.add_message(
                self.request,
                messages.ERROR,
                mark_safe(f"Your Intercom token is invalid. Please disconnect from intercom and reconnect."))
        return tag_choices

    class Meta:
        model = CustomerFeedbackImporterSettings
        fields = ['feedback_tag_name',]

        widgets = {
            'feedback_tag_name': forms.Select(
                attrs={
                    'autofocus': True,
                    'class': 'form-control',
                }
            )
        }