from PyQt4.QtCore import (QObject, SIGNAL, SLOT, pyqtSignal,
                          pyqtSlot, QAbstractListModel, QModelIndex,
                          Qt, QVariant)
from download import DownloadInfo
import logging
import copy
import json

__author__ = 'Manuel Huber'
__copyright__ = "Copyright (c) 2012 Manuel Huber."
__license__ = 'GPLv2'
__docformat__ = "restructuredtext en"

_log = logging.getLogger(__name__)

class NamingException(Exception):
    pass

class WrongJSOError(NamingException):

    def __init__(self, name, wtype):
        self.name = name
        self.wtype = wtype

    def __str__(self):
        return "JSO '%s' is of type '%s'" % (str(self.name),
                                             str(self.wtype))

class SeriesInstance(DownloadInfo):

    _TNAME = "%s.S%02dE%02d"
    _DBG_SUCCESS = "Download of file '%s' has been successful."
    _WRN_FAILURE = "Download of file '%s' has failed."

    changedStatus = pyqtSignal()

    def __init__(self, url, series, season, episode):
        filename = self._TNAME % (series.name, season, episode)
        DownloadInfo.__init__(self, url, filename)
        self._series = series
        self.episode = episode
        self.season = season
        self.finished.connect(self.hasFinished)
        self.removed.connect(self.removeInstance)

    def getName(self):
        return self._series.name

    @pyqtSlot('bool')
    def hasFinished(self, succeeded):
        if succeeded:
            _log.debug(self._DBG_SUCCESS % self.getFilename())
        else:
            _log.warning(self._WRN_FAILURE % self.getFilename())
        # Tell Series class about it (in either case)
        self._series.finishedInstance(self, succeeded)

    @pyqtSlot()
    def removeInstance(self):
        _log.debug("Removed instance %s" % self.getFilename())
        self._series.removedInstance(self)

class Series(QObject):

    _WRN_LDSKIP = "Skipping season %d (series: '%s'); Illegal list format."
    _WRN_ILLSEASON = "Skipping illegal season value '%s'"
    _WRN_LAST = "Couldn't load last season, episode from '%s' \
(found type '%s')."
    _DBG_SKIP = "Skipping cause of exception '%s'."

    changedHistory = pyqtSignal()

    def __init__(self, name, curr_season=1, curr_episode=0):
        QObject.__init__(self)
        self.name = name
        self.currentSeason = curr_season
        self.currentEpisode = curr_episode
        self.accessPriority = 0
        self._history = dict()
        # DESC: (season, episode) will be added to this set if
        #       an instance has been created to prevent multiple
        #       downloads of the same file...
        self._instances = set()

    def createInstance(self, url, season, episode):
        season = int(season)
        episode = int(episode)
        entry = (season, episode)
        if entry not in self._instances:
            _log.debug("created instance '%s.S%02dE%02d'."
                        % (self.name, season, episode))
            self._instances.add(entry)
            # TODO: Maybe change to unicode
            inst = SeriesInstance(str(url), self, season, episode)
            return inst
        else:
            _log.info("'%s.S%02dE%02d' is being downloaded."
                      % (self.name, season, episode))

    def finishedInstance(self, instance, succeeded):
        season = instance.season
        episode = instance.episode
        if succeeded:
            self._addToHistory(season, episode)
        else:
            # ensure that element is not in history
            if self.inHistory(season, episode):
                self._removeFromHistory(season, episode)
        self.changedHistory.emit()

    def removedInstance(self, instance):
        entry = (instance.season, instance.episode)
        self._instances.discard(entry)
        _log.debug("Removed S%02dE%02d from instance list." % entry)
        self.changedHistory.emit()

    def _removeFromHistory(self, season, episode):
        if self.inHistory(season, episode):
            _log.info("Removing '%s.S%02dE%02d' from history!")
            self._history[season].remove(episode)

    def _addToHistory(self, season, episode):
        _log.info("Adding episode %d of season %d (series: '%s')."
                  % (episode, season, self.name))
        if season not in self._history:
            _log.debug("Creating entry for season %d (series: '%s')."
                       % (season, self.name))
            self._history[season] = set()
        if episode in self._history[season]:
            _log.debug("'%s.S%02dE%02d' already in history"
                       % (self.name, season, episode))
        else:
            _log.debug("Adding '%s.S%02dE%02d' to history"
                       % (self.name, season, episode))
            self._history[season].add(episode)

    def _tryLoadLast(self, obj):
        if 'last' in obj:
            if not isinstance(obj['last'], list):
                raise WrongJSOError("%s.last" % self.name,
                                    type(obj['last']))
            last = (obj['last'][0], obj['last'][1])
            if not isinstance(last[0], int):
                raise WrongJSOError("%s.last[0](season)" % self.name,
                                    type(last[0]))
            elif not isinstance(last[1], int):
                raise WrongJSOError("%s.last[1](episode)" % self.name,
                                    type(last[1]))
            else:
                return last

    def _mergeHistory(self, history):
        for (season, epilist) in history.items():
            try:
                season = int(season)
            except TypeError as ex:
                _log.debug(self._DBG_SKIP % str(ex))
                _log.warning(self._WRN_ILLSEASON % str(season))
                continue
            try:
                epi = set((int(i) for i in epilist))
            except TypeError as ex:
                _log.debug(self._DBG_SKIP % str(ex))
                _log.warning(self._WRN_LDSKIP % (season, self.name))
                continue
            if season not in self._history:
                _log.debug("Adding full season %d (series: '%s')."
                           % (season, self.name))
                self._history[season] = epi
            else:
                diff = self._history[season].difference(epi)
                _log.debug("Adding [%s] (season: %d, series: '%s')."
                           % (", ".join((str(i) for i in diff)),
                              season, self.name))
                self._history[season].update(diff)

    def inHistory(self, season, episode):
        season = int(season)
        episode = int(episode)
        if season in self._history:
            if episode in self._history[season]:
                return True
        return False

    def inProgress(self, season, episode):
        entry = (int(season), int(episode))
        if entry in self._instances:
            return True
        else:
            return False

    def mergeData(self, data):
        try:
            last = self._tryLoadLast(data)
            self.currentSeason = last[0]
            self.currentEpisode = last[1]
        except WrongJSOError as ex:
            _log.warning(self._WRN_LAST % (str(ex.name), str(ex.wtype)))
        if 'history' in data:
            history = data['history']
            if not isinstance(history, dict):
                raise WrongJSOError("%s.history" % self.name,
                                    type(history))
            self._mergeHistory(history)

    def _normalizeHistory(self):
        rm_list = list()
        for (season, eps) in self._history.items():
            if len(eps) == 0:
                rm_list.append(season)
        for i in rm_list:
            self._history.pop(i, None)

    def _createJsonHistoryObject(self):
        history = dict()
        for (season, episodes) in self._history.items():
            history[season] = tuple(episodes)
        return history

    def getData(self):
        obj = dict()
        self._normalizeHistory()
        obj['history'] = self._createJsonHistoryObject()
        obj['last'] = (self.currentSeason, self.currentEpisode)
        return obj

class SeriesStorage(QAbstractListModel):

    _WRN_SKIPENTRY = "Skipped entry because of '%s' (having type '%s')."

    def __init__(self, storage_file):
        """Creates a series storage object

        :param storage_file: The default file where to store the JSON
                             represenation of this object.
        """
        QAbstractListModel.__init__(self, None)
        self._series = list()
        self._idbyname = dict()
        self.safeToExit = True
        self._def_path = storage_file

    def _addSeries(self, name):
        name = str(name)
        series = Series(name)
        series.changedHistory.connect(self._history_changed)
        self._series.append(series)
        index = self._series.index(series)
        self._idbyname[name] = index
        self.reset()
        return index

    def _loadFile(self, path):
        with open(path, 'r') as f:
            return json.load(f)

    def load(self, path=None):
        if path is None:
            path = self._def_path
        jobj = self._loadFile(path)
        if not isinstance(jobj, dict):
            raise WrongJSOError("root", type(jobj))
        for (name, obj) in jobj.items():
            try:
                if not isinstance(name, unicode):
                    raise WrongJSOError("name", type(name))
                if not isinstance(obj, dict):
                    raise WrongJSOError(name, type(obj))
                if name not in self._idbyname:
                    self._addSeries(name)
                index = self._idbyname[name]
                series = self._series[index]
                series.mergeData(obj)
            except WrongJSOError as ex:
                _log.warning(self._WRN_SKIPENTRY % (str(ex.name),
                                                    str(ex.wtype)))

    @pyqtSlot()
    def _history_changed(self):
        _log.debug("Series storage history changed!")
        self.safeToExit = False

    def store(self, path=None, override=False):
        if path is None:
            path = self._def_path
        if override:
            jobj = dict()
        else:
            jobj = self._loadFile(path)
        for series in self._series:
            # TODO: maybe add member to mark unmodified entries (they should
            #       be reloaded from file)
            jobj[series.name] = series.getData()
        with open(path, 'w') as f:
            json.dump(jobj, f)
        self.safeToExit = True

    def get(self, index):
        if index.isValid():
            return self._series[index.row()]

    def find(self, name):
        name = str(name)
        if name in self._idbyname:
            # column is not used => 0
            index = self.createIndex(self._idbyname[name], 0)
            return (True, index)
        else:
            return (False, None)

    def getOrCreateSeries(self, name):
        name = unicode(name)
        if name in self._idbyname:
            index = self._idbyname[name]
        else:
            index = self._addSeries(name)
        return self.createIndex(index, 0)

    def data(self, index, role):
        if index.isValid() and role == Qt.DisplayRole:
            return QVariant(self._series[index.row()].name)
        else:
            return QVariant()

    def rowCount(self, parent=QModelIndex()):
        return len(self._series)


import cv2
from darkflow.net.build import TFNet
import numpy as np
import time

import tensorflow as tf
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)

options = {

        'model':'C:/Users/LENOVO/Anaconda3/darkflow-master/cfg/yolo.cfg',
        'load':'C:/Users/LENOVO/Desktop/project/darkflow-master/darkflow-master/bin/yolov2.weights',
        'threshold':0.3,
        'gpu': 1.0
        }

tfnet = TFNet(options)  #print modlw arch
count=0
capture = cv2.VideoCapture("C:\\Users\\LENOVO\\Desktop\\project\\mansi\\video.mp4")
colors = [tuple(255 * np.random.rand(3)) for i in range(5)]
#it returns a tuple containing 5 (R,G,B) sets
print(colors)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out11 = cv2.VideoWriter('C:\\Users\\LENOVO\\Desktop\\project\\mansi\\output2.mp4',fourcc, 20.0, (1500,800))
#This time we create a VideoWriter object. We should specify the output file name (eg: output.avi).
#Then we should specify the FourCC code (details in next paragraph). Then number of frames per
#second (fps) and frame size should be passed. And last one is isColor flag. If it is True,
#encoder expect color frame, otherwise it works with grayscale frame.
count=0
while (capture.isOpened()):
    stime = time.time()
    ret, frame = capture.read()
    if ret:
        results = tfnet.return_predict(frame)
        for color, result in zip(colors, results):
            tl = (result['topleft']['x'], result['topleft']['y'])
            br = (result['bottomright']['x'], result['bottomright']['y'])
            label = result['label']
            frame = cv2.rectangle(frame, tl, br, color, 7)
            frame = cv2.putText(frame, label, tl, cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 0), 2)
        resize=cv2.resize(frame,(640,480))
        cv2.imshow('video',resize)
        out11.write(resize)
        print('FPS {:.1f}'.format(1 / (time.time() - stime)))
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        capture.release()
        cv2.destroyAllWindows()
        break
print("finished")
out11.release()
cv2.destroyAllWindows()


from os import getenv
from os.path import splitext

from rest_framework.exceptions import ValidationError
from rest_framework.serializers import (
    ModelSerializer,
    FileField,
    PrimaryKeyRelatedField,
    CharField,
    DateTimeField,
    SerializerMethodField,
)

from .models import Video, Channel, Comment, WebPushToken

class VideoSerializer(ModelSerializer):

    video_file = FileField(required=False)
    channel = PrimaryKeyRelatedField(queryset=Channel.objects.all(), required=False)
    username = CharField(source="channel.owner.first_name", read_only=True)
    user_email = CharField(source="channel.owner.email", read_only=True)
    user_avatar = CharField(source="channel.owner.avatar.url")
    upload_date = DateTimeField(format="%d-%m-%Y")
    imagekit_url = SerializerMethodField()

    class Meta:
        model = Video
        fields = (
            "id",
            "channel",
            "title",
            "description",
            "video_file",
            "hashtag",
            "upload_date",
            "likes",
            "username",
            "user_email",
            "user_avatar",
            "views",
            "imagekit_url",
        )

    def get_imagekit_url(self, obj):
        if not obj.video_file:
            return None
        elif getenv("IMAGEKIT") == "imagekit":
            imagekit_url = "ik.imagekit.io/videohub"
        elif getenv("IMAGEKIT") == "imgix":
            imagekit_url = "doszhan.imgix.net"
        else:
            imagekit_url = obj.video_file.url
            return imagekit_url
        aws_url = "mediastatic.s3.amazonaws.com"
        url = obj.video_file.url.replace(aws_url, imagekit_url)
        return url

class UpdateCreateVideoSerializer(ModelSerializer):

    video_file = FileField(required=False)

    class Meta:
        model = Video
        exclude = ("channel",)

    def validate_video_file(self, value):
        file_extension = splitext(value.name)[-1].lower()
        extensions = [".mov", ".avi", ".mp4", ".webm", ".mkv"]
        if file_extension not in extensions:
            raise ValidationError
        return value

class CommentSerializer(ModelSerializer):
    class Meta:
        model = Comment
        fields = ("id", "text", "user", "create")

class CreateCommentSerializer(ModelSerializer):
    class Meta:
        model = Comment
        fields = ("text", "video")

class WebPushSerializer(ModelSerializer):
    class Meta:
        model = WebPushToken
        fields = "__all__"


# -*- coding: utf-8 -*-
from wtforms import SelectField

from includes.creator import FormCreator
from project import app
from flask import render_template, redirect, request
from flask_wtf import FlaskForm
from project.components import Settings

class FormController(FlaskForm):
    controller_name = "form"
    method = SelectField("method", choices=[("POST", "POST"), ("GET", "GET")])
    page = SelectField("page")

    @staticmethod
    def create_pages_drop_down(pages):
        drop_down = []

        for (identifier, page) in pages.items():
            drop_down.append((identifier, identifier))

        return drop_down

@app.route('/<test_id>/<page_id>/form')
def view_form(test_id, page_id):
    settings = Settings.load()

    form_creator = settings.tests[test_id][page_id].form

    if not form_creator:
        return redirect("/" + test_id + "/" + page_id + "/form/new", 302)

    return render_template('form/form.html',
                           form_creator=form_creator,
                           test_id=test_id,
                           page_id=page_id
                           )

@app.route('/<test_id>/<page_id>/form/new', methods=['GET', 'POST'])
def new_form(test_id, page_id):
    settings = Settings.load()

    form = FormController(request.form)
    form.page.choices = FormController.create_pages_drop_down(settings.tests[test_id])

    if request.method == "POST" and form.validate():
        settings.tests[test_id][page_id].form = FormCreator(form.method.data, form.page.data)
        settings.save()

        return redirect("/" + test_id + "/" + page_id + "/form", 302)

    return render_template('form/new.html', form=form, test_id=test_id, page_id=page_id)

@app.route('/<test_id>/<page_id>/form/delete/')
def delete_form(test_id, page_id, form_id):
    settings = Settings.load()

    del settings.tests[test_id][page_id].forms[form_id]
    settings.save()

    return redirect("/" + test_id + "/" + page_id + "/forms", 302)


import time

from POM.Pages.taskPage import taskPage
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import pytest
#from selenium import *

from Zeuz1.POM.Locators import locators
from Zeuz1.POM.Pages import taskPage

#from selenium.webdriver.support.ui import WebDriverWait
#from selenium.webdriver.support import expected_conditions as EC

class TestTask:
    @pytest.fixture()
    def test_setup(self):
        self.locator_obj = locators
        global driver
        self.driver = webdriver.Firefox(executable_path= self.locator_obj.locators.geckoDriver)

        self.driver.implicitly_wait(5)
        self.driver.maximize_window()
        self.driver.delete_all_cookies()

        yield
        self.driver.close()
        self.driver.quit()
        print("test completed")

    def test_task_for_Successful_statusMassage(self, test_setup):
        self.driver.get(self.locator_obj.locators.task_page_URL)

        self.taskPage_obj = taskPage(self.driver)

        randomText= self.taskPage_obj.taskpage.catch_randomText()
        print(randomText)
        self.taskPage_obj.taskpage.input_randomText_WE(randomText)
        self.taskPage_obj.taskpage.click_on_Verify_button()
        statusMassage = self.taskPage_obj.taskpage.status_Massage()

        if statusMassage == "You have successfully verified the text":
            assert True
        else:
            assert False


import re
import glob
import json
import torch
import pickle
import random
import constant as C
from allennlp.modules.elmo import batch_to_ids

DIGIT_PATTERN = re.compile('\d')

def mask_to_distance(mask, mask_len, decay=.1):
    start = mask.index(1)
    end = mask_len - list(reversed(mask)).index(1)
    dist = [0] * mask_len
    for i in range(start):
        dist[i] = max(0, 1 - (start - i - 1) * decay)
    for i in range(end, mask_len):
        dist[i] = max(0, 1 - (i - end) * decay)
    return dist

def offset_to_distance(start, end, seq_len, decay=.1):
    dist = [0] * seq_len
    for i in range(start):
        dist[i] = max(0, 1 - (start - i - 1) * decay)
    for i in range(end, seq_len):
        dist[i] = max(0, 1 - (i - end) * decay)
    return dist

class BufferDataset(object):
    def __init__(self,
                 path,
                 buffer_size=100000,
                 max_seq_len=-1,
                 buffer=True,
                 pad=C.PAD_INDEX):
        self.path = path
        self.pad = pad
        self.data = []
        self.files = []
        self.batches = []
        self.max_seq_len = max_seq_len
        self.buffer_size = buffer_size
        self.total_size = 0
        self.buffer = buffer
        self.count_total_size()

    @property
    def chunk_num(self):
        return len(self.chunks)

    @property
    def chunks(self):
        chunks = glob.glob(self.path + '.bin.*')
        return chunks

    def __len__(self):
        return self.total_size

    def count_total_size(self):
        line_idx = 0
        with open(self.path + '.meta', 'r', encoding='utf-8') as r:
            for line_idx, _ in enumerate(r, 1):
                pass
        self.total_size = line_idx

    @staticmethod
    def preprocess(input_file, output_file, label_stoi, chunk_size=10000):
        # shuffle the data
        print('Shuffling and chunking data')
        inst_num = 0
        with open(input_file, 'r', encoding='utf-8') as r:
            for inst_num, _ in enumerate(r, 1):
                pass
        chunk_num = inst_num // chunk_size + (inst_num % chunk_size > 0)
        inst_idxs = [i for i in range(inst_num)]
        random.shuffle(inst_idxs)
        inst_chunk = [0] * inst_num
        for chunk_idx, chunk_start in enumerate(range(0, inst_num, chunk_size)):
            chunk = inst_idxs[chunk_start:chunk_start + chunk_size]
            for inst_idx in chunk:
                inst_chunk[inst_idx] = chunk_idx

        # metadata
        print('Writing metadata')
        with open(output_file + '.meta', 'w', encoding='utf-8') as w:
            for idx, chunk_idx in enumerate(inst_chunk):
                w.write('{}\t{}\n'.format(idx, chunk_idx))

        # split the original file into chunks
        print('Writing chunks')
        writers = [open(output_file + '.txt.{:03d}'.format(idx), 'w')
                   for idx in range(chunk_num)]
        with open(input_file, 'r', encoding='utf-8') as r:
            for inst_idx, line in enumerate(r):
                writers[inst_chunk[inst_idx]].write(line)
        for w in writers:
            w.close()

        # numberize data
        print('Numberizing chunks')
        for chunk_idx in range(chunk_num):
            print('\rProcessed {}/{}'.format(chunk_idx + 1, chunk_num), end='')
            with open(output_file + '.txt.{:03d}'.format(chunk_idx), 'r') as r, \
                open(output_file + '.bin.{:03d}'.format(chunk_idx), 'wb') as w:
                chunk = [BufferDataset.numberize(json.loads(line), label_stoi)
                         for line in r]
                pickle.dump(chunk, w)
        print()

    @staticmethod
    def numberize(inst, label_stoi):
        tokens = inst['tokens']
        tokens = [C.TOK_REPLACEMENT.get(t, t) for t in tokens]
        seq_len = len(tokens)
        char_ids = batch_to_ids([tokens])[0].tolist()
        labels_nbz, men_mask, ctx_mask, men_ids = [], [], [], []
        annotations = inst['annotations']
        anno_num = len(annotations)
        for annotation in annotations:
            mention_id = annotation['mention_id']
            labels = annotation['labels']
            labels = [l.replace('geograpy', 'geography') for l in labels]
            start = annotation['start']
            end = annotation['end']

            men_ids.append(mention_id)
            labels = [label_stoi[l] for l in labels if l in label_stoi]
            labels_nbz.append(labels)
            men_mask.append([1 if i >= start and i < end else 0
                             for i in range(seq_len)])
            ctx_mask.append([1 if i < start or i >= end else 0
                             for i in range(seq_len)])
        return (char_ids, labels_nbz, men_mask, ctx_mask, men_ids, anno_num,
                seq_len)

    def load(self, shuffle=False):
        self.data = []
        if self.buffer:
            while len(self.data) < self.buffer_size and len(
                    self.data) < self.total_size:
                if len(self.files) == 0:
                    self.files = glob.glob(self.path + '.bin.*')
                    if shuffle:
                        random.shuffle(self.files)
                file = self.files.pop()
                if self.max_seq_len > 0:
                    data = pickle.load(open(file, 'rb'))
                    for inst in data:
                        if inst[-1] < self.max_seq_len:
                            self.data.append(inst)
                else:
                    self.data.extend(pickle.load(open(file, 'rb')))
        else:
            files = glob.glob(self.path + '.bin.*')
            if shuffle:
                random.shuffle(files)
            # Load all files
            for file in files:
                if self.max_seq_len > 0:
                    data = pickle.load(open(file, 'rb'))
                    for inst in data:
                        if inst[-1] < self.max_seq_len:
                            self.data.append(inst)
                else:
                    self.data.extend(pickle.load(open(file, 'rb')))

    def sample_batches(self, batch_size=100, drop_last=False,
                       shuffle=False):
        # Load data
        if self.buffer or len(self.data) == 0:
            self.load(shuffle)
        inst_num = len(self.data)
        inst_idxs = [i for i in range(inst_num)]
        # Shuffle instance indexes
        if shuffle:
            random.shuffle(inst_idxs)
        # Split the indexes into batches
        self.batches = [inst_idxs[i:i + batch_size]
                        for i in range(0, inst_num, batch_size)]
        # Drop the last batch
        if drop_last and len(self.batches[-1]) != batch_size:
            self.batches = self.batches[:-1]

    def next_batch(self, label_size, batch_size=100, drop_last=False,
                   shuffle=False, gpu=True):
        # Load data and generate batches
        if len(self.batches) == 0:
            self.sample_batches(batch_size, drop_last, shuffle)

        # Get the batch
        batch_idxs = self.batches.pop()
        batch = [self.data[idx] for idx in batch_idxs]
        # Process the batch
        seq_lens = [x[-1] for x in batch]
        max_seq_len = max(seq_lens)

        batch_char_ids = []
        batch_labels = []
        batch_men_mask = []
        batch_dist = []
        batch_ctx_mask = []
        batch_gathers = []
        batch_men_ids = []
        for inst_idx, inst in enumerate(batch):
            char_ids, labels, men_mask, ctx_mask, men_ids, anno_num, seq_len = inst
            batch_char_ids.append(char_ids + [[self.pad] * C.ELMO_MAX_CHAR_LEN
                                              for _ in range(max_seq_len - seq_len)])
            for ls in labels:
                batch_labels.append([1 if l in ls else 0
                                     for l in range(label_size)])
            for mask in men_mask:
                batch_men_mask.append(mask + [self.pad] * (max_seq_len - seq_len))
                batch_dist.append(mask_to_distance(mask, seq_len)
                                  + [self.pad] * (max_seq_len - seq_len))
            for mask in ctx_mask:
                batch_ctx_mask.append(mask + [self.pad] * (max_seq_len - seq_len))
            batch_gathers.extend([inst_idx] * anno_num)
            batch_men_ids.extend(men_ids)

        if gpu:
            batch_char_ids = torch.cuda.LongTensor(batch_char_ids)
            batch_labels = torch.cuda.FloatTensor(batch_labels)
            batch_men_mask = torch.cuda.FloatTensor(batch_men_mask)
            batch_ctx_mask = torch.cuda.FloatTensor(batch_ctx_mask)
            batch_gathers = torch.cuda.LongTensor(batch_gathers)
            batch_dist = torch.cuda.FloatTensor(batch_dist)

        else:
            batch_char_ids = torch.LongTensor(batch_char_ids)
            batch_labels = torch.FloatTensor(batch_labels)
            batch_men_mask = torch.FloatFloatTensorTensor(batch_men_mask)
            batch_ctx_mask = torch.LongTensor(batch_ctx_mask)
            batch_gathers = torch.LongTensor(batch_gathers)
            batch_dist = torch.FloatTensor(batch_dist)

        return (batch_char_ids, batch_labels, batch_men_mask, batch_ctx_mask,
                batch_dist, batch_gathers, batch_men_ids)

    def all_batches(self, label_size, batch_size, drop_last=False,
                    shuffle=False, gpu=True):
        self.sample_batches(batch_size, drop_last, shuffle)
        while len(self.batches) > 0:
            yield self.next_batch(label_size, batch_size, drop_last,
                                  shuffle, gpu)


import subprocess

import yaml

# Open the YAML file and load the contents
with open("hosts.yml", "r") as f:
    data = yaml.safe_load(f)

# Loop over each section and print its contents
for section, config in data.items():
    ssh_cmd = (
        f"ssh {config['user']}@{config['host']} 'apt show nvidia-jetpack|grep version'"
    )
    output = subprocess.check_output(ssh_cmd, shell=True).decode().strip()

    # Print the output of the command
    print(f"{config['host']} Jetpack version: {output}")


from httpx import Response

from livedivulgador.twitch.exceptions import (
    InsufficientPermissions,
    InvalidCredentialsException,
    ObjectNotFoundException,
    TwitchException,
    UnexpectedResponseException,
)

def handle_response(response: Response) -> dict:
    """Return a json object otherwise raises an error
    Args:
            response (Response): HTTP response object
    Raises:
            InvalidCredentialsException: Credentials are invalid (401)
            InsufficientPermissions: User has insufficient permissions (403)
            ObjectNotFoundException: The object was not found (404)
            TwitchException: Miro specific exceptions (5xx)
            UnexpectedResponseException: For unexpected events raises unexpected response from server
    Returns:
            Dict: Dictionary object with the json response from the server
    """

    if is_2xx_status_code(response.status_code):
        return response.json()

    if response.status_code == 401:
        raise InvalidCredentialsException(response.status_code)

    if response.status_code == 403:
        raise InsufficientPermissions(response.status_code)

    if response.status_code == 404:
        raise ObjectNotFoundException(response.status_code)

    if is_5xx_status_code(response.status_code):
        raise TwitchException(response.status_code)

    raise UnexpectedResponseException(response.status_code)

def is_2xx_status_code(status_code: int) -> bool:
    return str(status_code).startswith("2")

def is_5xx_status_code(status_code: int) -> bool:
    return str(status_code).startswith("5")


# from django.shortcuts import render
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.decorators import authentication_classes, permission_classes
# from rest_framework.authentication import SessionAuthentication
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.tokens import RefreshToken
from .serializers import UserRegisterSerializer, UserLogInSerializer, UserSerializer
from database.models import Word, WordLearned, User
from django.contrib.auth import login, logout
from django.shortcuts import get_object_or_404
from django.db.models import F

# from rest_framework.authtoken.models import Token

# Create your views here.
# class UserRegisterView(APIView):
#     def post(self, request):
#         serializer = UserRegisterSerializer(data = request.data)
#         if serializer.is_valid():
#             user = serializer.save()
#             return Response(serializer.data, status=status.HTTP_201_CREATED)
#         return Response(status=status.HTTP_400_BAD_REQUEST)

class UserRegisterView(APIView):
    def post(self, request):
        serializer = UserRegisterSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()

            refresh = RefreshToken.for_user(user)

            response_data = {
                'refresh': str(refresh),
                'access': str(refresh.access_token),
                'user': serializer.data
            }

            return Response(response_data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# class UserLogInView(APIView):
#     def post(self, request):
#         serializer = UserLogInSerializer(data = request.data)
#         if serializer.is_valid():
#             user = serializer.check_user(request.data)
#             login(request, user)
#             if not user.is_login:
#                 user.score += 100
#                 user.is_login = True
#                 user.save()
#             return Response(serializer.data, status=status.HTTP_200_OK)
#         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserLogInView(TokenObtainPairView):
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        if response.status_code == 200:
            user = User.objects.get(username=request.data['username'])
            user.update_login()
            if not user.is_login:
                user.score += 100
                user.is_login = True
                user.save()
        return response

# class UserLogOutView(APIView):
#     def post(self, request):
#         logout(request)
#         return Response(status=status.HTTP_200_OK)

class UserLogOutView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        try:
            refresh_token = request.data.get("refresh_token")
            if refresh_token:
                token = RefreshToken(refresh_token)
                token.blacklist()
            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception as e:
            return Response(status=status.HTTP_400_BAD_REQUEST)

class UserView(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (JWTAuthentication,)
    def get(self, request):
        serializer = UserSerializer(request.user)
        user = request.user
        if user:
            user.reset_quest_status()
        if not user.is_login:
            user.score += 100
            user.is_login = True
            user.save()
        return Response({'user': serializer.data}, status=status.HTTP_200_OK)

# class SessionDataView(APIView):
#     def get(self, request):
#         session_data = {}
#         if request.session:
#             # Retrieve session data
#             session_data['session_id'] = request.session.session_key
#             session_data['user_id'] = request.session.get('user_id', None)
#             session_data['username'] = request.session.get('username', None)
#             # Add more session data as needed
#         return Response(session_data)

@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
class WordLearnedView(APIView):
    def post(self, request):
        word_ids = request.data.get('word_ids', [])
        user = request.user  # Assuming you have user authentication in place

        for word_id in word_ids:
            word = get_object_or_404(Word, id=word_id)  # Retrieve the Word instance
            word_learned_exists = WordLearned.objects.filter(user_id=user, word_id=word).exists()
            if not word_learned_exists:
                WordLearned.objects.create(user_id=user, word_id=word)

        return Response({'message': 'Word IDs stored successfully'})

def ordinalize(number):
    suffixes = {1: 'st', 2: 'nd', 3: 'rd'}
    if 10 <= number % 100 <= 20:
        suffix = 'th'
    else:
        suffix = suffixes.get(number % 10, 'th')
    return f"{number}{suffix}"

@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
class LeaderboardAPIView(APIView):
    def get(self, request):
        users = User.objects.order_by('-score')  # Retrieve users sorted by score in descending order

        # Annotate the queryset with the rank based on the score
        users = users.annotate(rank=F('score'))

        leaderboard = []
        current_user = None
        for index, user in enumerate(users, start=1):
            if user == request.user:
                current_user = {
                    'rank': ordinalize(index),
                    'username': user.username,
                    'score': user.score
                }
            leaderboard.append({
                'rank': ordinalize(index),
                'username': user.username,
                'score': user.score
            })

        return Response({'leaderboard': leaderboard, 'current_user': current_user}, status=status.HTTP_200_OK)


#!/usr/bin/env python

import urwid
from urwid.container import WidgetContainerListContentsMixin

__all__ = [
    'SearchableWidgetWrapper',
]

class SearchableWidgetWrapper(urwid.WidgetWrap):
    """
    This class wrap a container and allow to focus on the looked field.
    The looked field is the first field that match the pressed key of
        the user
    """
    def __init__(self, wrapped_widget, looked_field=lambda x: x):
        """
        :param wrapped_widget: the container where the value will
            be look for
        :type wrapped_widget: ContainerListContentsMixin

        :param looked_field: function returning the lookable value
            for each item available in the wrapped_widget
        :type looked_field: function

        >>> items = ['abc','aab','aaa','bcd','bdd']
        >>> w = urwid.Pile(list(map(urwid.Text, items)))
        >>> sw = SearchableWidgetWrapper(w, lambda x: x.text)
        >>> sw.get_focus().text
        'abc'
        >>> silent=sw.keypress((40, 40), 'b'); sw.get_focus().text
        'bcd'
        >>> silent=sw.keypress((40, 40), 'b'); sw.get_focus().text
        'bcd'
        >>> silent=sw.keypress((40, 40), 'escape'); sw.get_focus().text
        'bcd'
        >>> silent=sw.keypress((40, 40), 'a'); sw.get_focus().text
        'abc'
        >>> silent=sw.keypress((40, 40), 'a'); sw.get_focus().text
        'aab'
        """
        super().__init__(wrapped_widget)
        if not isinstance(wrapped_widget, WidgetContainerListContentsMixin):
            raise ValueError("SearchableListBox must wrap "
                             "ContainerListContentsMixin, wrapped is {}".
                             format(type(wrapped_widget)))
        self.looked_field = looked_field
        self._search = ''

    def __getattr__(self, attr):
        return getattr(self._wrapped_widget, attr)

    def _set_search(self, new_search):
        """
        Update the search and the focus *only* if a field matches

        :param new_search: the new_searchable field
        :type new_search: str
        """
        # FIXME: see https://github.com/urwid/urwid/pull/201
        # for index in self._w:
        for index in self._w.__iter__():
            item = self._w[index]
            if self.looked_field(item).startswith(new_search):
                self._search = new_search
                self.set_focus(index)
                self._invalidate()
                break

    search = property(lambda self: self._search, _set_search, doc="""
    The looked string

    .. note:: this string is updated *only* if it matches
    """)

    def keypress(self, size, key):
        """
        Capture the key that may be used for searching item
        """
        key = super().keypress(size, key)
        if key is None:
            # Clear the search if key was used for something else
            self._search = ''
            return key
        if key == 'backspace':
            if self.search:
                self.search = self.search[:-1]
        elif len(key) == 1:
            self.search = self.search + key
        else:
            # Clear the search if key is not a character
            self._search = ''
            return key

def _test():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    _test()


import argparse
from dataclasses import dataclass
import filecmp
import os
import re
import shutil

from collections import Counter, defaultdict
from contextlib import ExitStack
from pathlib import Path

# typing.Final isn't available until 3.8+
from typing import DefaultDict, Dict, Generator, List, Optional, Tuple

PYB11_BEGIN_BINDINGS: str = 'PYB11_BEGIN_BINDINGS'
PYB11_END_BINDINGS: str = 'PYB11_END_BINDINGS'
PYB11_PROPERTY: str = 'PYB11_PROPERTY'
PYB11_METHOD: str = 'PYB11_METHOD'
PYB11_STATIC_CREATION: str = 'PYB11_STATIC_CREATION'
PYB11_CREATION: str = 'PYB11_CREATION'
PYB11_ENUMERATION: str = 'PYB11_ENUMERATION'
PYB11_STATIC_NEW_MACRO: str = 'PYB11_STATIC_NEW_MACRO'
PYB11_FILTER_NEW_MACRO: str = 'PYB11_FILTER_NEW_MACRO'
PYB11_SHARED_POINTERS: str = 'PYB11_SHARED_POINTERS'
PYB11_FILTER: str = 'PYB11_FILTER'
PYB11_CUSTOM: str = 'PYB11_CUSTOM'
PYB11_FIELD: str = 'PYB11_FIELD'

PYB11_SUPERCLASS: str = 'SUPERCLASS'
PYB11_READ: str = 'READ'
PYB11_WRITE: str = 'WRITE'
PYB11_CONST_GET_OVERLOAD: str = 'CONST_GET_OVERLOAD'
PYB11_CONST_METHOD: str = 'CONST_METHOD'
PYB11_RETURN_VALUE_POLICY: str = 'RETURN_VALUE_POLICY'
PYB11_ARGS: str = 'ARGS'
PYB11_OVERLOAD: str = 'OVERLOAD'

OBSERVER_ARG_NAME: str = 'observer'

class PyField():
  def __init__(self):
    self.cpp_name: str = ''
    self.py_name: str = ''

class PyProperty():
  def __init__(self):
    self.name: str = ''
    self.type: str = ''
    self.read: str = ''
    self.write: str = ''
    self.is_const_overload: bool = False

class PyMethod():
  def __init__(self):
    self.name: str = ''
    self.return_type: str = ''
    self.args: List[str] = []
    self.arg_types: List[str] = []
    self.is_const: bool = False
    self.return_value_policy: str = ''
    self.is_overload: bool = False

class PyStaticCreation():
  def __init__(self):
    self.name: str = ''
    self.args: List[str] = []
    self.is_overload: bool = False

class PyConstructor():
  def __init__(self):
    self.args: List[str] = []

class PyEnum():
  def __init__(self):
    self.name: str = ''
    self.values: List[str] = []

class PyClass():
  def __init__(self):
    self.name: str = ''
    self.superclass: str = ''
    self.properties: List[PyProperty] = []
    self.fields: List[PyField] = []
    self.methods: List[PyMethod] = []
    self.static_creation_methods: List[PyStaticCreation] = []
    self.constructors: List[PyConstructor] = []
    self.enums: List[PyEnum] = []
    self.has_static_new: bool = False
    self.uses_shared_pointer: bool = False
    self.is_filter: bool = False
    self.is_custom: bool = False

  def __repr__(self):
    return self.name

  def generate_forward_declaration(self) -> str:
    template_param = self.name
    instance = f'instance{self.name}'
    if self.superclass:
      template_param += f', {self.superclass}'
    if self.uses_shared_pointer:
      template_param += f', std::shared_ptr<{self.name}>'
    code = f'py::class_<{template_param}> {instance}(mod, \"{self.name}\");\n'

    for enum in self.enums:
      enum_instance = f'instance{self.name}{enum.name}'
      code += f'py::enum_<{self.name}::{enum.name}> {enum_instance}({instance}, \"{enum.name}\");\n'

    return code

  def generate_bindings(self, foward_declared: bool=False) -> str:
    template_param = self.name
    if self.superclass:
      template_param += f', {self.superclass}'
    if self.uses_shared_pointer:
      template_param += f', std::shared_ptr<{self.name}>'

    needs_var: bool = self.constructors or self.has_static_new or self.static_creation_methods or self.properties or self.methods or self.fields

    instance = f'instance{self.name}'
    code = ''

    if not foward_declared:
      if self.enums or self.is_custom:

        code += f'py::class_<{template_param}> {instance}(mod, \"{self.name}\");\n'

        if needs_var:
          code += f'{instance}\n'
      else:
        code = f'py::class_<{template_param}>(mod, \"{self.name}\")'
        if not needs_var:
          code += ';'
        code += '\n'
    else:
      if needs_var:
        code += f'{instance}\n'

    for constructor in self.constructors:
      args = ', '.join(constructor.args)
      code += f'  .def(py::init<{args}>())\n'

    if self.has_static_new:
      code += f'  .def(py::init([]()\n    {{ \n      return {self.name}::New();\n    }}))\n'
      code += f'  .def_static(\"New\", &{self.name}::New)\n'

    for static_new_method in self.static_creation_methods:
      if static_new_method.args:
        args = ', '.join([f'{arg} var_{i}' for i, arg in enumerate(static_new_method.args)])
        values = ', '.join([f'var_{i}' for i, arg in enumerate(static_new_method.args)])

        code += f'  .def(py::init([]({args}) {{\n      return {self.name}::{static_new_method.name}({values});\n    }}))\n'
      else:
        code += f'  .def(py::init(&{self.name}::{static_new_method.name}))\n'
      if not static_new_method.is_overload:
        code += f'  .def_static(\"{static_new_method.name}\", &{self.name}::{static_new_method.name})\n'

    for prop in self.properties:
      if prop.read and prop.write:
        if prop.is_const_overload:
          code += f'  .def_property(\"{prop.name}\", py::overload_cast<>(&{self.name}::{prop.read}, py::const_), &{self.name}::{prop.write})\n'
        else:
          code += f'  .def_property(\"{prop.name}\", &{self.name}::{prop.read}, &{self.name}::{prop.write})\n'
      elif prop.read:
        code += f'  .def_property_readonly(\"{prop.name}\", &{self.name}::{prop.read})\n'
      elif prop.write:
        code += f'  .def(\"set{prop.name}\", &{self.name}::set{prop.name}, \"{prop.name}\"_a)\n'

    for field in self.fields:
      code += f'  .def_readwrite(\"{field.py_name}\", &{self.name}::{field.cpp_name})\n'

    for method in self.methods:
      if method.is_overload:
        template_param = ', '.join(method.arg_types)
        code += f'  .def(\"{method.name}\", py::overload_cast<{template_param}>(&{self.name}::{method.name}'
        if method.is_const:
          code += ', py::const_'
        code += ')'
      else:
        code += f'  .def(\"{method.name}\", &{self.name}::{method.name}'
      if method.return_value_policy:
        code += f', {method.return_value_policy}'
      if method.args:
        args = ', '.join([f'\"{arg}\"_a' for arg in method.args])
        code += f', {args}'
      code += ')\n'

    if needs_var:
      code += ';\n\n'
    else:
      code += '\n'

    for enum in self.enums:
      enum_instance = f'instance{self.name}{enum.name}'
      if not foward_declared:
        code += f'py::enum_<{self.name}::{enum.name}>({instance}, \"{enum.name}\")\n'
      else:
        code += f'{enum_instance}\n'
      for value in enum.values:
        code += f'  .value(\"{value}\", {self.name}::{enum.name}::{value})\n'
      code += ';\n\n'

    return code

  def generate_python_interface(self, module_name: str) -> str:
    arg_list = [replace_python_keywords(camel_to_snake(prop.name)) for prop in self.properties]
    if OBSERVER_ARG_NAME in arg_list:
      raise RuntimeError(f'A filter parameter in \"{self.name}\" is called \"{OBSERVER_ARG_NAME}\" which conflicts with the Pythonic interface')
    parameter_list = [f'{prop} = None' for prop in arg_list]
    args_text = ', '.join(parameter_list)
    if args_text:
      args_text = ', ' + args_text
    code = f'def {camel_to_snake(self.name)}(data_container_array{args_text}, observer = None) -> int:\n'
    code += f'  \"\"\"Pythonic interface to {self.name} Filter which will execute the filter immediately and return.\n'
    code += f'  \n'
    code += f'  Args:\n'
    code +=  '    data_container_array (DataContainerArray): The DataContainerArray that will be used as input\n'
    for prop, arg in zip(self.properties, arg_list):
      code += f'    {arg} ({prop.type}): Sets the "{prop.name}" filter property\n'
    code += '    observer (Observer): The observer that can report back warnings/errors.\n'
    code += '\n  Returns:\n    int\n'
    code += '  \"\"\"\n\n'
    code += f'  filter = {module_name}.{self.name}()\n'
    code += f'  filter.setDataContainerArray(data_container_array)\n'
    code += '  if observer is not None:\n'
    code += '    filter.connectObserver(observer)\n'

    for prop, arg in zip(self.properties, arg_list):
      code += f'  if {arg} is not None:\n'
      code += f'    filter.{prop.name} = {arg}\n'

    code += '  filter.execute()\n'
    code += '  return filter.ErrorCode\n\n'
    return code

  def generate_unit_test_snippet(self, module_name: str) -> str:
    code = f'  print(\'# --- {self.name}\')\n'
    code += f'  filter = {module_name}.{self.name}()\n'
    code += f'  filter.preflight()\n'
    code += f'  assert filter.NameOfClass == \'{self.name}\', f\'Error: Filter class name is not correct. {{filter.NameOfClass}} != {self.name}\'\n\n'
    return code

def replace_python_keywords(text: str) -> str:
  if text == 'lambda':
    return 'lambda_value'
  return text

def camel_to_snake(text: str) -> str:
  result = re.sub(r'(.)([A-Z][a-z]+)', r'\1_\2', text)
  return re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', result).lower()

def is_child_path(child_path: str, parent_path: str) -> bool:
  return os.path.commonpath([os.path.abspath(parent_path)]) == os.path.commonpath([os.path.abspath(parent_path), os.path.abspath(child_path)])

def find_enum_values(file_path: str, name: str) -> List[str]:
  enum_values = []

  with open(file_path, 'r') as file:
    line: str
    for line in file:
      line = line.strip()
      if f'enum class {name}' in line:
        while '{' not in line:
          line = next(file).strip()
        line = next(file).strip()
        while '};' not in line:
          value = line.strip(',')
          enum_values.append(value.split(' ')[0])
          line = next(file).strip()
        break

  return enum_values

def find_index(lst: list, value) -> Optional[int]:
  if value in lst:
    return lst.index(value)
  else:
    return None

def extract_macro_args(line: str) -> List[str]:
  match = re.search(r'\((.*?)\)', line)
  if not match:
    raise RuntimeError('No match found')
  return list(filter(bool, match.group(1).split(' ')))

def file_line_generator(file_path: str) -> Generator[str, None, None]:
  with open(file_path, 'r') as file:
    line: str
    for line in file:
      yield line

def parse_class(line: str) -> PyClass:
  tokens = extract_macro_args(line)
  py_class = PyClass()
  py_class.name = tokens.pop(0)
  while tokens:
    token = tokens.pop(0)
    if token == PYB11_SUPERCLASS:
      py_class.superclass = tokens.pop(0)
  return py_class

def parse_property(line: str) -> PyProperty:
  tokens = extract_macro_args(line)
  prop = PyProperty()
  prop.type = tokens.pop(0)
  prop.name = tokens.pop(0)
  while tokens:
    token = tokens.pop(0)
    if token == PYB11_READ:
      prop.read = tokens.pop(0)
    elif token == PYB11_WRITE:
      prop.write = tokens.pop(0)
    elif token == PYB11_CONST_GET_OVERLOAD:
      prop.is_const_overload = True
  return prop

def parse_method_arg(arg: str) -> Tuple[str, str]:
  arg_values = arg.split(',')
  arg_name = arg_values[1]
  arg_type = arg_values[0]
  arg_type = arg_type.replace('.', ' ')
  return (arg_name, arg_type)

def parse_method(line: str) -> PyMethod:
  tokens = extract_macro_args(line)
  method = PyMethod()
  method.return_type = tokens.pop(0)
  method.name = tokens.pop(0)

  if tokens:
    if tokens[-1] == PYB11_CONST_METHOD:
      method.is_const = True
      tokens.pop()

    index = find_index(tokens, PYB11_RETURN_VALUE_POLICY)

    if index is not None:
      method.return_value_policy = tokens.pop(index + 1)
      tokens.pop(index)

    token = tokens.pop(0)
    if token == PYB11_ARGS:
      while tokens:
        arg = tokens.pop(0)
        if ',' in arg:
          arg_name, arg_type = parse_method_arg(arg)
          method.args.append(arg_name)
          method.arg_types.append(arg_type)
        else:
          method.args.append(arg)
    elif token == PYB11_OVERLOAD:
      method.is_overload = True
      while tokens:
        overload_arg = tokens.pop(0)
        arg_name, arg_type = parse_method_arg(overload_arg)
        method.args.append(arg_name)
        method.arg_types.append(arg_type)

  return method

def parse_static_creation(line: str) -> PyStaticCreation:
  tokens = extract_macro_args(line)
  py_static_creation = PyStaticCreation()
  py_static_creation.name = tokens.pop(0)
  if tokens:
    token = tokens.pop(0)
    if token == PYB11_ARGS:
      while tokens:
        py_static_creation.args.append(tokens.pop(0))
    elif token == PYB11_OVERLOAD:
      py_static_creation.is_overload = True
      while tokens:
        py_static_creation.args.append(tokens.pop(0))
  return py_static_creation

def parse_creation(line: str) -> PyConstructor:
  tokens = extract_macro_args(line)
  constructor = PyConstructor()
  tokens = [item.replace('.', ' ') for item in tokens]
  constructor.args = tokens
  return constructor

def parse_enumeration(line: str) -> PyEnum:
  tokens = extract_macro_args(line)
  enum = PyEnum()
  enum.name = tokens.pop(0)
  return enum

def parse_static_new_macro(line: str) -> bool:
  return True

def parse_filter_new_macro(line: str) -> bool:
  return True

def parse_shared_pointers(line: str) -> bool:
  return True

def parse_filter(line: str) -> bool:
  return True

def parse_custom(line: str) -> bool:
  return True

def parse_field(line: str) -> PyField:
  tokens = extract_macro_args(line)
  field = PyField()
  size = len(tokens)
  if size == 2:
    field.cpp_name = tokens[0]
    field.py_name = tokens[1]
  elif size == 1:
    field.cpp_name = tokens[0]
    field.py_name = tokens[0]
  else:
    raise RuntimeError('incorrect number of arguments for PyField')
  return field

def parse_bindings(class_line: str, file: Generator[str, None, None]) -> PyClass:
  py_class = parse_class(class_line)
  line: str
  for line in file:
    line = line.strip()
    if line.startswith(PYB11_END_BINDINGS):
      break
    elif line.startswith(PYB11_PROPERTY):
      py_class.properties.append(parse_property(line))
    elif line.startswith(PYB11_METHOD):
      py_class.methods.append(parse_method(line))
    elif line.startswith(PYB11_STATIC_CREATION):
      py_class.static_creation_methods.append(parse_static_creation(line))
    elif line.startswith(PYB11_CREATION):
      py_class.constructors.append(parse_creation(line))
    elif line.startswith(PYB11_ENUMERATION):
      py_class.enums.append(parse_enumeration(line))
    elif line.startswith(PYB11_STATIC_NEW_MACRO):
      py_class.has_static_new = parse_static_new_macro(line)
    elif line.startswith(PYB11_FILTER_NEW_MACRO):
      py_class.has_static_new = parse_filter_new_macro(line)
    elif line.startswith(PYB11_SHARED_POINTERS):
      py_class.uses_shared_pointer = parse_shared_pointers(line)
    elif line.startswith(PYB11_FILTER):
      py_class.is_filter = parse_filter(line)
    elif line.startswith(PYB11_CUSTOM):
      py_class.is_custom = parse_custom(line)
    elif line.startswith(PYB11_FIELD):
      py_class.fields.append(parse_field(line))
  return py_class

def parse_file(file_path: str) -> List[PyClass]:
  file_gen = file_line_generator(file_path)
  classes = []
  line: str
  for line in file_gen:
    line = line.strip()
    if line.startswith(PYB11_BEGIN_BINDINGS):
      py_class = parse_bindings(line, file_gen)
      for enum in py_class.enums:
        enum.values = find_enum_values(file_path, enum.name)
      classes.append(py_class)
  return classes

def dfs(graph: DefaultDict[str, List[str]], vertex: str) -> List[str]:
  visited = {key : False for key in graph.keys()}
  def dfs_impl(graph: DefaultDict[str, List[str]], vertex: str, visited: Dict[str, bool]) -> List[str]:
    visited[vertex] = True
    path = [vertex]

    for item in graph[vertex]:
      if item not in graph:
        path.append(item)
      elif not visited[item]:
        path.extend(dfs_impl(graph, item, visited))
    return path
  return dfs_impl(graph, vertex, visited)

def is_sublist(parent: list, child: list) -> bool:
  it = iter(parent)
  return all(any(parent_item == child_item for parent_item in it) for child_item in child)

def remove_sublists(lists: list) -> list:
  lists.sort(key=lambda s: len(s))
  out = []
  n = len(lists)
  for i, item in enumerate(lists):
    is_sub = False
    for j in range(i + 1, n - 1):
      is_sub = is_sublist(lists[j], item)
      if is_sub:
        break
    if not is_sub:
      out.append(item)
  return out

def sort_inherited_classes(classes: List[PyClass]) -> List[PyClass]:
  # assumes single inheritance
  class_lookup = {item.name : item for item in classes}
  superclasses = {item.superclass for item in classes}
  class_names = {item.name for item in classes}

  intersection = superclasses.intersection(class_names)

  base_classes = []

  for item in classes:
    if item.superclass not in intersection:
      base_classes.append(item.name)

  graph: DefaultDict[str, List[str]] = defaultdict(list)

  for py_class in classes:
    graph[py_class.superclass].append(py_class.name)

  sorted_classes = []

  for name in base_classes:
    sorted_classes.append(dfs(graph, name))

  sorted_classes = remove_sublists(sorted_classes)

  sorted_classes = [item for items in sorted_classes for item in items]

  result = []

  for name in sorted_classes:
    if name in class_lookup:
      result.append(class_lookup[name])

  if Counter(classes) != Counter(result):
    raise RuntimeError('sorted results must contain same elements as input')

  return result

def replace_file_if_different(temp_file: str, target_file: str) -> None:
  target_file_path = Path(target_file)

  if target_file_path.exists():
    if filecmp.cmp(temp_file, target_file, shallow=False):
      os.remove(temp_file)
    else:
      os.remove(target_file)
      os.rename(temp_file, target_file)
  else:
    os.rename(temp_file, target_file)

@dataclass
class PythonFiltersInfo:
  files: List[str]
  filters: List[str]
  package_dir: str

def write_plugin_filters(output_dir: str, plugin_name: str, filters_info: PythonFiltersInfo) -> None:
  module_dir = Path(output_dir) / f'{plugin_name}_filters'
  module_dir.mkdir(exist_ok=True)

  for filepath in filters_info.files:
    shutil.copy(filepath, module_dir)

  with open(module_dir / '__init__.py', 'w') as file:
    file.write('from dream3d.simpl import registerPluginPythonFilter\n')
    for filename in filters_info.files:
      file.write(f'from .{Path(filename).stem} import *\n')

    filter_list_str = ', '.join(filters_info.filters)

    file.write('def get_filters():\n')
    file.write(f'  return [{filter_list_str}]\n')

    file.write('def register_filters():\n')
    file.write('  for f in get_filters():\n')
    file.write('    registerPluginPythonFilter(f)\n')
    file.write('register_filters()\n')

def generate_simpl_bindings(output_dir: str, header_path: str, body_path: str, files: List[str], source_dir: str, python_output_dir: str, plugin_name: str, body_top_path: str = '', post_types_path: str = '', no_tests: bool = False, relative_imports: bool = False) -> None:
  module_target_file_path = f'{output_dir}/py_simpl.cpp'
  module_temp_file_path = f'{module_target_file_path}.temp'
  with open(module_temp_file_path, 'w') as module_file, open(f'{python_output_dir}/simplpy.py', 'w') as python_file, ExitStack() as exit_stack:
    if not no_tests:
      test_file = exit_stack.enter_context(open(f'{python_output_dir}/simpl_UnitTest.py', 'w'))
    with open(header_path, 'r') as header_file:
      header_code = header_file.read()
      module_file.write(f'// This file is automatically generated during build time by {__file__}\n\n')
      module_file.write(header_code)

    module_file.write('\n')

    for file_path in files:
      file_path = Path(file_path).relative_to(source_dir).as_posix()
      module_file.write(f'#include \"{file_path}\"\n')

    module_file.write('\nPYBIND11_MODULE(simpl, mod)\n{\n')

    if body_top_path:
      with open(body_top_path, 'r') as body_top_file:
        custom_body_top_code = body_top_file.read()
        module_file.write(f'{custom_body_top_code}\n')

    module_classes = []

    for file_path in files:
      classes = parse_file(file_path)
      module_classes.extend(classes)

    module_classes = sort_inherited_classes(module_classes)

    if not relative_imports:
      python_file.write(f'import simpl\n\n')
    else:
      python_file.write(f'from . import simpl\n\n')

    if not no_tests:
      test_file.write(f'import simpl\n\n')
      test_file.write(f'def simplUnitTest():\n')

    for py_class in module_classes:
      code = py_class.generate_forward_declaration()
      module_file.write(code)

    if post_types_path:
      with open(post_types_path, 'r') as post_types_file:
        custom_post_types_code = post_types_file.read()
        module_file.write(f'{custom_post_types_code}\n')

    for py_class in module_classes:
      code = py_class.generate_bindings(foward_declared=True)
      module_file.write(code)
      if py_class.is_filter:
        python_code = py_class.generate_python_interface('simpl')
        python_file.write(python_code)
        if not no_tests:
          test_code = py_class.generate_unit_test_snippet('simpl')
          test_file.write(test_code)

    if not no_tests:
      test_file.write('\n')
      test_file.write('if __name__ == \'__main__\':\n')
      test_file.write('  print(\'simpl UnitTest Starting\')\n')
      test_file.write('  simplUnitTest()\n')
      test_file.write('  print(\'simpl UnitTest Complete\')\n')

    with open(body_path, 'r') as body_file:
      body_code = body_file.read()
      module_file.write(body_code)

    module_file.write('}\n')
  replace_file_if_different(module_temp_file_path, module_target_file_path)

def generate_plugin_bindings(output_dir: str, module_name: str, files: List[str], include_dir: Optional[str], python_output_dir: str, plugin_name: str, header_path: str = '', body_path: str = '', body_top_path: str = '', post_types_path: str = '', no_tests: bool = False, relative_imports: bool = False, python_filters_info: Optional[PythonFiltersInfo] = None) -> None:
  module_target_file_path = f'{output_dir}/py_{module_name}.cpp'
  module_temp_file_path = f'{module_target_file_path}.temp'
  with open(module_temp_file_path, 'w') as module_file, open(f'{python_output_dir}/{module_name}py.py', 'w') as python_file, ExitStack() as exit_stack:
    if not no_tests:
      test_file = exit_stack.enter_context(open(f'{python_output_dir}/{module_name}_UnitTest.py', 'w'))
    includes = files
    if include_dir:
      includes = []
      for file_path in files:
        path = Path(file_path)
        include_path = Path(include_dir)
        path = path.relative_to(include_path)
        path = include_path.parts[-1] / path
        includes.append(path.as_posix())

    include_code = '\n'.join([f'#include \"{file_path}\"' for file_path in includes])

    custom_header_code = ''
    if header_path:
      with open(header_path, 'r') as header_file:
        custom_header_code = header_file.read()

    custom_body_code = ''
    if body_path:
      with open(body_path, 'r') as body_file:
        custom_body_code = body_file.read()

    relative_import_code = 'simpl'
    if relative_imports:
      relative_import_code = 'dream3d.simpl'

    header_code = (
      f'// This file is automatically generated during build time by {__file__}\n\n'
      '#include <memory>\n\n'
      '#include <pybind11/pybind11.h>\n\n'
      '#include \"SIMPLib/Filtering/FilterManager.h\"\n\n'
      f'#include \"{plugin_name}/{plugin_name}Plugin.h\"\n\n'
      '#include \"Binding/Pybind11CustomTypeCasts.h\"\n\n'
      f'{custom_header_code}\n'
      f'{include_code}\n\n'
      'namespace py = pybind11;\n'
      'using namespace py::literals;\n\n'
      f'PYBIND11_MODULE({module_name}, mod){{\n'
      'mod.doc() = R"pbdoc(\n'
      f' Python module "{module_name}" wrapping the "{plugin_name}" DREAM3D Plugin\n'
      ' -----------------------\n'
      f'  .. currentmodule:: {module_name} \n\n'
    ')pbdoc";\n'
      f'py::module::import("{relative_import_code}");\n\n'
    )
    module_file.write(header_code)

    if body_top_path:
      with open(body_top_path, 'r') as body_top_file:
        custom_body_top_code = body_top_file.read()
        module_file.write(f'{custom_body_top_code}\n')

    module_classes = []

    for file_path in files:
      classes = parse_file(file_path)
      module_classes.extend(classes)

    module_classes = sort_inherited_classes(module_classes)

    if not relative_imports:
      python_file.write(f'import {module_name}\n\n')
    else:
      python_file.write(f'from . import {module_name}\n\n')

    if not no_tests:
      test_file.write(f'import {module_name}\n\n')
      test_file.write(f'def {module_name}UnitTest():\n')

    for py_class in module_classes:
      code = py_class.generate_forward_declaration()
      module_file.write(code)

    if post_types_path:
      with open(post_types_path, 'r') as post_types_file:
        custom_post_types_code = post_types_file.read()
        module_file.write(f'{custom_post_types_code}\n')

    for py_class in module_classes:
      code = py_class.generate_bindings(foward_declared=True)
      module_file.write(code)
      if py_class.is_filter:
        python_code = py_class.generate_python_interface(module_name)
        python_file.write(python_code)
        if not no_tests:
          test_code = py_class.generate_unit_test_snippet(module_name)
          test_file.write(test_code)

    if not no_tests:
      test_file.write('\n')
      test_file.write('if __name__ == \'__main__\':\n')
      test_file.write(f'  print(\'{module_name} UnitTest Starting\')\n')
      test_file.write(f'  {module_name}UnitTest()\n')
      test_file.write(f'  print(\'{module_name} UnitTest Complete\')\n')

    module_file.write(f'{custom_body_code}\n')

    module_file.write(f'  //Ensure all the filters are loaded when this module loads\n')
    module_file.write('  py::module_ os = py::module_::import("os");\n')
    module_file.write('  auto env_value = os.attr(\"getenv\")(\"DREAM3D_PLUGINS_LOADED\");\n')
    module_file.write('  if(env_value.is_none())\n')
    module_file.write('  {\n')
    module_file.write(f'    {plugin_name}Plugin {module_name}Plugin;\n')
    module_file.write(f'    {module_name}Plugin.registerFilters(FilterManager::Instance());\n')
    module_file.write('  }\n')
    module_file.write('\n}\n')
  replace_file_if_different(module_temp_file_path, module_target_file_path)
  if python_filters_info:
    write_plugin_filters(python_filters_info.package_dir, module_name, python_filters_info)

def read_plugin_file_list(file_list_path: str, source_dir: str) -> List[str]:
  files = []
  with open(file_list_path, 'r') as file:
    lines = file.read().splitlines()
    for line in lines:
      if line.startswith('#'):
        continue
      path = line.strip()
      path = f'{source_dir}/{line}'
      files.append(path)
  return files

def read_simpl_file_list(file_list_path: str, source_dir: str) -> List[str]:
  files = []
  with open(file_list_path, 'r') as file:
    lines = file.read().split(';')
    for line in lines:
      path = line.strip()
      if '.h' in path and is_child_path(path, source_dir):
        with open(path, 'r') as file:
          data = file.read()
          if re.search(PYB11_BEGIN_BINDINGS, data) and not re.search(f'#define {PYB11_BEGIN_BINDINGS}', data):
            files.append(path)
  files = list(dict.fromkeys(files))
  return files

if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument('output_dir')
  parser.add_argument('file_list_path')
  parser.add_argument('source_dir')
  parser.add_argument('python_output_dir')
  parser.add_argument('--module_name')
  parser.add_argument('--header_path')
  parser.add_argument('--body_path')
  parser.add_argument('--body_top_path')
  parser.add_argument('--post_types_path')
  parser.add_argument('--include_dir')
  parser.add_argument('--plugin_name')
  parser.add_argument('--package_dir',)
  parser.add_argument('--python_files', nargs='+')
  parser.add_argument('--python_filters', nargs='+')
  parser.add_argument('--plugin', action='store_true')
  parser.add_argument('--no_tests', action='store_true')
  parser.add_argument('--relative_imports', action='store_true')
  parser.add_argument('--has_python_filters', action='store_true')

  args = parser.parse_args()

  python_filters_info = None

  if args.has_python_filters:
    if not args.plugin:
      parser.error('--has_python_filters requires --plugin')
    if args.python_files is None:
      parser.error('--has_python_filters requires --python_files')
    if args.python_filters is None:
      parser.error('--has_python_filters requires --python_filters')
    if args.package_dir is None:
      parser.error('--has_python_filters requires --package_dir')

    python_filters_info = PythonFiltersInfo(files=args.python_files, filters=args.python_filters, package_dir=args.package_dir)

  if args.plugin:
    if args.module_name is None:
      parser.error('--plugin requires --module_name')
    files = read_plugin_file_list(args.file_list_path, args.source_dir)
    generate_plugin_bindings(args.output_dir, args.module_name, files, args.include_dir, args.python_output_dir, args.plugin_name, args.header_path, args.body_path, args.body_top_path, args.post_types_path, args.no_tests, args.relative_imports, python_filters_info)
  else:
    if args.header_path is None:
      parser.error('requires --header_path')
    if args.body_path is None:
      parser.error('requires --body_path')
    files = read_simpl_file_list(args.file_list_path, args.source_dir)
    generate_simpl_bindings(args.output_dir, args.header_path, args.body_path, files, args.source_dir, args.python_output_dir, args.plugin_name, args.body_top_path, args.post_types_path, args.no_tests, args.relative_imports)


from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.core.exceptions import ValidationError
from datetime import date
from django.contrib.auth.models import User
from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField

class Event(models.Model):
    title = models.CharField(max_length=150, blank=True, null=True)
    description = RichTextUploadingField(config_name='default', blank=True,
                                         null=True)
    date_posted = models.DateTimeField(default=timezone.now)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def check_overlap(self, start_1, end_1, start_2, end_2):
        if start_2 == end_1 or end_2 == start_1:
            return False
        elif(start_2 >= start_1 and start_2 <= end_1) or (end_2 >= start_1 and
                                                          end_2 <= end_1):
            return True
        elif start_2 <= start_1 and end_2 >= end_1:
            return True

    def clean(self):
        if self.end_time <= self.start_time:
            raise ValidationError('End time must be after starting time')

        events = Event.objects.filter(start_time__date=date(self.start_time.year,
                                                           self.start_time.month,
                                                          self.start_time.day)).exclude(pk=self.pk)
        if events.exists():
            for event in events:
                if self.check_overlap(event.start_time, event.end_time,
                                      self.start_time, self.end_time):
                    raise ValidationError('There is an overlap with another \
                                          event: ' + str(event.title))

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('event-detail', kwargs={'pk': self.pk})


# -*- coding: utf-8 -*-
"""
Created on Thu Sep  6 08:41:59 2018

@author: jfarrugia
"""

from obspy import read_inventory, read, Stream
import sys
import tkinter as tk
from tkinter import filedialog
import matplotlib.pyplot as plt

class MarisString():
    def __init__(self):
        self.maris_inv = read_inventory(r'\\ONC-FILESERVER\redirect4\jfarrugia\Documents\GitHub\StationXML_NV\NV_MarisString_September2018.dataless')
        self.locations = ['W1', 'W2', 'W3']
        self.channels = ['HNE', 'HNN', 'HNZ']

    def write_xmls(self):
        for l in self.locations:
            for c in self.channels:
                self.maris_inv.select(location=l, channel=c).write('NV.KEMF.{}.{}_200.xml'.format(l, c), format='stationxml')

    def load_slarchive_mseed(self, starttime=None, endtime=None, station='KEMF', sr=200.0):
        """
        Accesses the Google Drive folder "slarchive\data2" for MSEED files from the Maris String.

        Instrument correction and some basic filtering is applied.
        """
        root = tk.Tk()
        root.withdraw()

        self.hne_mseed_paths = filedialog.askopenfilenames(initialdir=r'G:\Team Drives\ONC_Seismic_Data\slarchive\data2\2018\NV\KEMF\HNE.D',
                                                        title='Choose HNE files')
        self.hnn_mseed_paths = filedialog.askopenfilenames(initialdir=r'G:\Team Drives\ONC_Seismic_Data\slarchive\data2\2018\NV\KEMF\HNN.D',
                                                        title='Choose HNN files')
        self.hnz_mseed_paths = filedialog.askopenfilenames(initialdir=r'G:\Team Drives\ONC_Seismic_Data\slarchive\data2\2018\NV\KEMF\HNZ.D',
                                                        title='Choose HNZ files')

        self.st = Stream()
        for file in self.hne_mseed_paths:
            try:
                for tr in read(file, format='mseed'):
                    self.st.append(tr)

            except:
                print("Unexpected error on HNE load:", sys.exc_info())
                continue
        for file in self.hnn_mseed_paths:
            try:
                for tr in read(file, format='mseed'):
                    self.st.append(tr)

            except:
                print("Unexpected error on HNN load:", sys.exc_info())
                continue
        for file in self.hnz_mseed_paths:
            try:
                for tr in read(file, format='mseed'):
                    self.st.append(tr)

            except:
                print("Unexpected error on HNZ load:", sys.exc_info())
                continue

        for tr in self.st:
            if tr.stats.sampling_rate != sr:
                tr.stats.sampling_rate = sr
        self.onc_inv = read_inventory(r'\\ONC-FILESERVER\redirect4\jfarrugia\Documents\GitHub\ONC_StationXML\NV_StationXML.xml')
        self.st.remove_response(self.onc_inv, output='acc', pre_filt=(0.01, 0.1, 50, 100))
        return self.st


from lib.config import get_config
from lib.utils import get_prop, get_int_prop, make_date

def orcid_api_url(path):
    return f"{get_config(['orcid', 'apiBaseURL'])}/{path}"

def raw_work_to_work(work_summary):
    # #
    # # Work Summary
    # # TODO: Why is it an array? We just take the first element
    # #
    # work_summary = get_prop(work, ["work-summary", 0], None)

    # ids = []
    # for work_id in get_prop(work_summary, ["external-ids", "external-id"], []):
    #     id_type = get_prop(work_id, ["external-id-type"], None)
    #     id_normalized = get_prop(work_id, ["external-id-normalized", "value"], None)
    #     id_url = get_prop(work_id, ["external-id-url", "value"], None)
    #     ids.append({"type": id_type, "value": id_normalized, "url": id_url})

    put_code = get_int_prop(work_summary, ["put-code"], None)

    created_at = get_int_prop(work_summary, ["created-date", "value"], None)

    updated_at = get_int_prop(work_summary, ["last-modified-date", "value"], None)

    # TODO: should also get the source app id
    source = get_prop(work_summary, ["source", "source-name", "value"], None)

    date = make_date(
        get_prop(work_summary, ["publication-date", "year", "value"]),
        get_prop(work_summary, ["publication-date", "month", "value"]),
        get_prop(work_summary, ["publication-date", "day", "value"]),
    )

    title = get_prop(work_summary, ["title", "title", "value"], None)

    journal = get_prop(work_summary, ["journal-title", "value"], None)

    work_type = get_prop(work_summary, ["type"], None)

    url = get_prop(work_summary, ["url", "value"], None)

    # Now for external ids
    external_ids = []
    for external_id in get_prop(work_summary, ["external-ids", "external-id"], []):
        id_type = get_prop(external_id, ["external-id-type"])
        id_value = get_prop(external_id, ["external-id-value"])
        id_url = get_prop(external_id, ["external-id-url", "value"])
        id_relationship = get_prop(external_id, ["external-id-relationship"])
        external_ids.append(
            {
                "type": id_type,
                "value": id_value,
                "url": id_url,
                "relationship": id_relationship,
            }
        )

    return {
        "putCode": put_code,
        "createdAt": created_at,
        "updatedAt": updated_at,
        "source": source,
        "title": title,
        "journal": journal,
        "date": date,
        "workType": work_type,
        "url": url,
        "externalIds": external_ids,
    }

def parse_date(date_string):
    date_parts = date_string.split("/")
    if len(date_parts) == 1:
        return {
            "year": {
                "value": date_parts[0]
            }
        }
    elif len(date_parts) == 2:
        return {
            "year": {
                "value": date_parts[0]
            },
            "month": {
                "value": date_parts[1].rjust(2, "0")
            }
        }
    elif len(date_parts) == 3:
        return {
            "year": {
                "value": date_parts[0]
            },
            "month": {
                "value": date_parts[1].rjust(2, "0")
            },
            "day": {
                "value": date_parts[2].rjust(2, "0")
            },
        }


import argparse
import pandas as pd

from desidulate.fileio import read_csv, out_path
from desidulate.sidlib import set_sid_dtype, control_labels, unique_control_labels

parser = argparse.ArgumentParser(description='Index SSFs with waveforms')
parser.add_argument('ssffile', help='SSF file')
parser.add_argument('--max_clock', default=500000, type=int, help='include number of cycles')
parser.add_argument('--max_pr_speed', default=8, type=int, help='max pr_speed')

def main():
    args = parser.parse_args()
    df = set_sid_dtype(read_csv(args.ssffile, dtype=pd.Int64Dtype()))
    if not df.empty:
        df = df[(df.clock <= args.max_clock) & (df.pr_speed <= args.max_pr_speed)]
        df = control_labels(df)
        df = unique_control_labels(df)
        vols = df[df['vol'].notna()]['vol'].nunique()
        for labels, ssf_df in df.groupby('unique_control_labels'):
            if labels:
                ssf_df[['hashid', 'hashid_noclock']].drop_duplicates().to_csv(out_path(args.ssffile, '%u.%s.index_ssf.zst' % (vols, labels)), index=False)

if __name__ == '__main__':
    main()


import face_recognition
import cv2
import numpy as np
import pandas as pd
import csv
import os
from datetime import datetime
import FolderScanner as fs

df = pd.DataFrame({
    'Name': [],
    'ID': []
})

def CsvFileCheck():
    try:
        now = datetime.now()
        current_date= now.strftime("%Y-%m-%d")
        df_data = pd.read_csv(current_date+' .csv')
        print(df_data)

    except:
        print("ERROR HANDLED")

def SaveFile():
    try:
        now = datetime.now()
        current_date= now.strftime("%Y-%m-%d")
        df.to_csv(current_date+' .csv', index=False)
    except:
        print("ERROR HANDLED")

folder_path = "E:\FYP\ImageData\CS"
files = fs.get_files_in_folder(folder_path)
fs.get_The_Student_Details(files)

known_faces_names = fs.StudentsData
load_images =  [face_recognition.load_image_file(x) for x in files]
known_face_encoding = [face_recognition.face_encodings(x)[0] for x in load_images]

CsvFileCheck()

video_capture = cv2.VideoCapture(0)

face_locations = []
face_encodings = []
s=True

while True:
    _,frame=video_capture.read()
    small_frame = cv2.resize(frame, (0,0), fx=0.25,fy=0.25)
    rgb_small_frame = small_frame[:,:,::-1]
    if s:
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
        for face_encoding in face_encodings:
            matches = face_recognition.compare_faces (known_face_encoding, face_encoding)
            face_distance = face_recognition.face_distance (known_face_encoding, face_encoding)
            best_match_index = np.argmin (face_distance)
            if matches[best_match_index]:
                record = known_faces_names[best_match_index]
                record_exists = (df['Name'] == record['Name']) & (df['ID'] == record['ID'])
                if not record_exists.any():
                    df = df.append(record, ignore_index=True)
                    print("Record added to the DataFrame.")
        cv2.imshow("attendence system", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

SaveFile()
video_capture.release()
cv2.destroyAllWindows()


# Get picture from NexiGo-Webcam N60 and detect the numbers of Lego Minifigures

import cv2
import time
from legodetector import LegoDetector
from global_setting import *

if __name__ == "__main__":

    cap = cv2.VideoCapture(0)

    if not cap.isOpened():
        print("Could not open camera")
        exit()

    detector = LegoDetector(model=detect_model_name, conf=detect_conf, lego_class_name=detect_class_name)

    while cap.isOpened():
        success, frame = cap.read()

        if success:
            picture = frame
            lego_people_num, result_image = detector.detect_lego_people(picture)
            cv2.imshow("Detect Lego with USB Camera", result_image)

            # Control the detection interval if needed
            if enable_detect_interval:
                time.sleep(detect_interval)

            if cv2.waitKey(1) & 0xFF == ord("q"):
                break
        else:
            break
    cv2.destroyAllWindows()
    cap.release()


import datetime
import os
from multiprocessing import Process
import time
import random

# for processes to work correctly, finction has to be defined outside the main
# or imported from different file.
# define function for multiprocessing
def print_time():
    wait_time = random.choice(range(1, 5))
    time.sleep(wait_time)
    print(f"Wait time: ", wait_time, " seconds. Current time:", time.ctime())

if __name__ == '__main__':

    ### 1 ###
    today = datetime.date.today()
    with open("today.txt", 'w') as f:
        f.write(str(today))
    # ### ###

    # ### 2 ###
    with open("today.txt", 'r') as f:
        today_string = f.read()
    # ### ###

    # ### 3 ###
    parsed_date = datetime.date.fromisoformat(today_string)
    print("Parsed date object: ", parsed_date)
    # ### ###

    # ### 4 ###
    curr_dir = os.listdir('.')
    print("current directory: ", curr_dir)
    # # ### ###

    # # ### 5 ###
    parent_dir = os.listdir('..')
    print("parent directory: ", parent_dir)
    # ### ###

    ### 6 ###

    process1 = Process(target=print_time)
    process2 = Process(target=print_time)
    process3 = Process(target=print_time)

    process1.start()
    process2.start()
    process3.start()
    # wait untill 3 processes are done
    process1.join()
    process2.join()
    process3.join()
    print("Processes are done!")
    ### ###

    ### 7 ###
    dob = datetime.datetime(1986, 11, 24)
    print("Date of Birth: ", dob)
    # ### ###

    # ### 8 ###
    print("Day of the week: ", dob.strftime('%A'))
    # ### ###

    # ### 9 ###
    ten_thousand_days_old = dob + datetime.timedelta(days=10000)
    print("10,000 years old was: ", ten_thousand_days_old)
    ### ###

python_basic_assignmemt/Assignment_21/assignment 21 datetime and files/datetime_files.py


import sqlite3
from config import bot2
import random

def sql_create() -> object:
    global db, cursor
    db = sqlite3.connect("bot.sqlite3")
    "="
    cursor = db.cursor()
    if db:
        print("База данных подключена!")

    db.execute("CREATE TABLE IF NOT EXISTS mentors "
               "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
               "idm VARCHAR (255), "
               "name VARCHAR (255), "
               "dir VARCHAR (255), "
               "age INTEGER, "
               "groupm VARCHAR (255))")
    db.commit()

async def sql_command_insert(state):
    async with state.proxy() as data:
        cursor.execute("INSERT INTO mentors(idm, name, dir, age, groupm) VALUES"
                       " (?, ?, ?, ?, ?)", tuple(data.values()))
        db.commit()

async def sql_command_random(message):
    result = cursor.execute("SELECT * FROM mentors").fetchall()
    rand_ment = random.choice(result)
    await bot2.send_message(message.from_user.id,
        text=f"ID: {rand_ment[1]},\n"
             f"Name: {rand_ment[2]},\n"
             f"Direction: {rand_ment[3]},\n"
             f"Age:{rand_ment[4]},\n"
             f"Group:{rand_ment[5]}"
            )

async def sql_command_all():
    return cursor.execute("SELECT * FROM mentors").fetchall()

async def sql_command_delete(user_id):
    cursor.execute("DELETE FROM mentors WHERE id = ?", (user_id,))
    db.commit()


import glob
import os
import sys
import time

try:
    sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
        sys.version_info.major,
        sys.version_info.minor,
        'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
except IndexError:
    pass

import carla
from agents.navigation.basic_agent import BasicAgent
from agents.navigation.controller import VehiclePIDController
from agents.navigation.global_route_planner import GlobalRoutePlanner
from agents.navigation.global_route_planner_dao import GlobalRoutePlannerDAO

import random

from carla import VehicleLightState as vls

import argparse
import logging
from numpy import random
from random import randrange

def main():

    #pygame.init()
    client = carla.Client('localhost', 2000)
    client.set_timeout(10.0)
    world = client.get_world()
    frame = None

    #Create WaypointMap
    amap = world.get_map()
    sampling_resolution = 2
    dao = GlobalRoutePlannerDAO(amap, sampling_resolution)
    grp = GlobalRoutePlanner(dao)
    grp.setup()
    spawn_points = world.get_map().get_spawn_points()

    #Spawn Cars on Waypoint

    model1 = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))
    model2 = random.choice(world.get_blueprint_library().filter('vehicle.bmw.*'))

    spawn_points = world.get_map().get_spawn_points()
    spawn_point_numeric_value1 = randrange(250)
    print("Spawpoint 1: ")
    print(spawn_point_numeric_value1)
    spawn_point1 = spawn_points[spawn_point_numeric_value1]
    vehicle1 = world.try_spawn_actor(model1, spawn_point1)

    time.sleep(5)
    location1 = vehicle1.get_location()
    print(location1)
    print(vehicle1.id)

    spawn_point_numeric_value2 = randrange(250)
    print("Spawpoint 2: ")
    print(spawn_point_numeric_value2)
    spawn_point2 = spawn_points[spawn_point_numeric_value2]
    vehicle2 = world.try_spawn_actor(model2, spawn_point2)

    time.sleep(5)
    location2 = vehicle1.get_location()
    print(location2)
    print(vehicle2.id)

    #print path of vehicle 2

    a = carla.Location(spawn_point1.location)
    b = carla.Location(spawn_point2.location)
    w1 = grp.trace_route(a, b)

    i=0
    for w in w1:
        if i % 10 == 0:
            world.debug.draw_string(w[0].transform.location, 'O', draw_shadow=False,
            color=carla.Color(r=255, g=0, b=0), life_time=120.0,
            persistent_lines=True)
        else:
            world.debug.draw_string(w[0].transform.location, 'O', draw_shadow=False,
            color = carla.Color(r=0, g=0, b=255), life_time=1000.0,
            persistent_lines=True)
        i += 1

    #Start Car
    vehicle1.set_simulate_physics(True)
    driving_car = BasicAgent(vehicle1, target_speed=200)
    destiny = spawn_point2.location
    driving_car.set_destination((destiny.x, destiny.y, destiny.z))

    #vehicle1.set_autopilot(True)

    vehicle1_waypoint = amap.get_waypoint(vehicle1.get_location())
    vehicle2_waypoint = amap.get_waypoint(vehicle2.get_location())

    while vehicle2_waypoint != vehicle1_waypoint:
            world.tick()
            ts = world.wait_for_tick()
            vehicle1_waypoint = amap.get_waypoint(vehicle1.get_location())

            print("Vehicle 1 Waypoint: " + str(vehicle1_waypoint))
            print("Vehicle 2 Waypoint: " + str(vehicle2_waypoint))
            # Get control commands
            control_hero = driving_car.run_step()
            vehicle1.apply_control(control_hero)

                #if frame is not None:
                    #if ts.frame_count != frame + 1:
                        #logging.warning('frame skip!')
                        #print("frame skip!")

            frame = ts.frame_count

if __name__ == '__main__':

    try:
        main()
    except KeyboardInterrupt:
        pass
    finally:
        print('\ndone.')


import requests
from bs4 import BeautifulSoup

URL = "https://web.archive.org/web/20200518073855/https://www.empireonline.com/movies/features/best-movies-2/"

response = requests.get(url=URL)
arch_web_page = response.text

soup = BeautifulSoup(arch_web_page, "html.parser")
all_movies = soup.find_all(name='h3', class_='title')
movie_titles = [movie.getText() for movie in all_movies]
top_100_movie = movie_titles[::-1]

with open('movies.txt', 'w', encoding='utf-8') as movies:
    for movie in top_100_movie:
        movies.write(f"{movie}\n")


'''
Created on 2018年6月25日

缓存常用淘汰算法之一：LRU（least recently used 最近最少使用）算法根据数据的历史访问记录来进行淘汰数据，其核心思想是：如果数据最近被访问过，那么将来被访问的几率也更高。
当存在热点数据时，LRU的效率很好，但偶发性的、周期性的批量操作会导致LRU命中率急剧下降，缓存污染情况比较严重。

@author: zwustudy
'''
import collections

class LRUCache(collections.OrderedDict):

    def __init__(self, size=5):
        self.size = size
        self.cache = collections.OrderedDict()

    def get(self, key):

        if self.cache.__contains__(key):
            value = self.cache.pop(key)  #新访问了缓存，因此缓存需要移到最新的位置
            self.cache[key] = value
            return value
        else:
            return None

    def set(self, key, value):

        if self.cache.__contains__(key):
            self.cache.pop(key)  #新访问了缓存，因此缓存需要移到最新的位置
        elif len(self.cache) >= self.size:
            self.cache.popitem(last = False)
        self.cache[key] = value

class LRUCache1(object):

    def __init__(self, size = 5):
        self.size = size
        self.cache = dict()
        self.keyset = list()

    def get(self, key):
        if self.cache.__contains__(key):
            self.keyset.remove(key)  #新访问了缓存，因此缓存需要移到最新的位置
            self.keyset.insert(0, key)
            return self.cache.get(key)
        else:
            return None

    def set(self, key, value):
        if self.cache.__contains__(key):
            self.keyset.remove(key) #原来的key移除，好让后面把key的位置移到最新访问
        elif len(self.cache) >= self.size:
            removeKey = self.keyset.pop() #移除最近最少访问的缓存，给新缓存让个位置
            self.cache.pop(removeKey)
        self.keyset.insert(0, key)
        self.cache[key] = value

def main():
    cache = LRUCache1(5)
    for i in range(0, 6, 1):
        if i == 3:
            cache.set("key0", 0) #本来最早的缓存key是 key0,但是这里更新了之后，最早更新的就是key1，key1的缓存应该被淘汰
        cache.set("key" + str(i), i)

    for i in range(0, 7, 1):
        key = "key" + str(i)
        print(key + ":" + str(cache.get(key)))

if __name__ == "__main__":
    main()


## author: xin luo
## creat: 2022.3.16; modify: 2022.4.4
## des: layer stacking for remote sensing images
## usage(command line): python lay_stack.py path_imgs path_out

from osgeo import gdal
from osgeo import osr
import numpy as np
import argparse

def get_args():

    """ Get command-line arguments. """
    parser = argparse.ArgumentParser(
            description='layer stacking for remote sensing images')
    parser.add_argument(
            'path_imgs', metavar='path_imgs', type=str, nargs='*',
            help='contains the paths of bands/imgs to be stacked')
    parser.add_argument(
            'path_out', metavar='path_out', type=str, nargs='+',
            help='the output path of the layer stacked image')
    parser.add_argument(
            '--union',
            choices=('True','False'),
            default='True')
    parser.add_argument(
            '--resolution', type=int, nargs=1,
            help='resolution of the output image',
            default=[None])
    return parser.parse_args()

def lay_stack(path_imgs, path_out, union=True, res=None):
    '''
    input:
    path_imgs: list, contains the paths of bands/imgs to be stacked
    path_out: str, the output path of the layer stacked image
    union: bool, if true, the output extent is the extents union of input images.
            otherwise, the output extent is the extents intersection of input images.
    res: resolution of the layer stacked image.
    note: the first image in the path_imgs is the reference image.
    '''

    ## base image
    left_min, right_min, bottom_min, up_min = float("inf"), float("inf"), float("inf"), float("inf")
    left_max, right_max, bottom_max, up_max = -float("inf"), -float("inf"), -float("inf"), -float("inf")
    for i, path_img in enumerate(path_imgs):
        img = gdal.Open(path_img, gdal.GA_ReadOnly)
        if i == 0:
            base_proj = img.GetProjection()
        im_geotrans = img.GetGeoTransform()
        im_x = img.RasterXSize  #
        im_y = img.RasterYSize  #
        left = im_geotrans[0]
        up = im_geotrans[3]
        right = left + im_geotrans[1] * im_x + im_geotrans[2] * im_y
        bottom = up + im_geotrans[5] * im_y + im_geotrans[4] * im_x
        if left_min > left: left_min = left;
        if right_min > right: right_min = right
        if up_min > up: up_min = up
        if bottom_min > bottom: bottom_min = bottom
        if left_max < left: left_max = left
        if right_max < right: right_max = right
        if up_max < up: up_max = up
        if bottom_max < bottom: bottom_max = bottom
    if union == True:
        extent = [left_min, right_max, up_max, bottom_min]
    else:
        extent = [left_max, right_min, up_min, bottom_max]

    if res is not None:
        dx, dy = res, -res
    else:
        dx, dy = im_geotrans[1], im_geotrans[5]

    base_x = int(np.round((extent[1] - extent[0]) / float(dx)))  # new col, integer
    base_y = int(np.round((extent[3] - extent[2]) / float(dy)))  # new row, integer
    base_dx = (extent[1] - extent[0]) / float(base_x) #update dx and dy, may be a little bias with the original dx and dy.
    base_dy = (extent[3] - extent[2]) / float(base_y)
    base_geotrans = (extent[0], base_dx, 0.0, extent[2], 0.0, base_dy)

    ## layer stacking
    base_n = 0
    for i_img, path_stack in enumerate(path_imgs):
        ## image to be layer stacked
        stack_img = gdal.Open(path_stack)
        stack_Proj = stack_img.GetProjection()
        stack_n = stack_img.RasterCount

        ## align image to the base image
        driver= gdal.GetDriverByName('GTiff')
        stack_align = driver.Create(path_out, base_x, base_y, stack_n, gdal.GDT_Float32)
        stack_align.SetGeoTransform(base_geotrans)
        stack_align.SetProjection(base_proj)
        gdal.ReprojectImage(stack_img, stack_align, stack_Proj, base_proj, gdal.GRA_Bilinear)

        ## layer stacking
        n_bands = base_n+stack_n
        img_stack = driver.Create(path_out, base_x, base_y, n_bands, gdal.GDT_Float32)

        if(img_stack!= None):
            img_stack.SetGeoTransform(base_geotrans)       #
            img_stack.SetProjection(base_proj)      #

        for i_band in range(base_n):
            img_stack.GetRasterBand(i_band+1).WriteArray(base_img.GetRasterBand(i_band+1).ReadAsArray())
        for i_band in range(stack_n):
            img_stack.GetRasterBand(base_n+i_band+1).WriteArray(stack_align.GetRasterBand(i_band+1).ReadAsArray())
        ## update base image
        base_n = n_bands
        base_img = img_stack
    print('Images layer stacking done.')
    del img_stack, base_img, stack_img

if __name__ == '__main__':

    # extract arguments
    args = get_args()
    path_imgs = args.path_imgs
    path_out = args.path_out[0]
    union = args.union
    res = args.resolution[0]
    lay_stack(path_imgs, path_out, union, res)