import torch
import torch.nn as nn
import sparseconvnet as scn

from src import utils

FLAGS = utils.flags.FLAGS()

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

class SparseBlock(nn.Module):

    def __init__(self, inplanes, outplanes, nplanes=1):

        nn.Module.__init__(self)

        self.conv1 = scn.SubmanifoldConvolution(dimension=3,
            nIn=inplanes,
            nOut=outplanes,
            filter_size=[nplanes,3,3],
            bias=False)

        # if FLAGS.BATCH_NORM:
        self.bn1 = scn.BatchNormReLU(outplanes)
        # self.relu = scn.ReLU()

    def forward(self, x):

        out = self.conv1(x)
        # if FLAGS.BATCH_NORM:
        out = self.bn1(out)
        # else:
            # out = self.relu(out)

        return out

class SparseResidualBlock(nn.Module):

    def __init__(self, inplanes, outplanes, nplanes=1):
        nn.Module.__init__(self)

        self.conv1 = scn.SubmanifoldConvolution(dimension=3,
            nIn         = inplanes,
            nOut        = outplanes,
            filter_size = [nplanes,3,3],
            bias=False)

        # if FLAGS.BATCH_NORM:
        self.bn1 = scn.BatchNormReLU(outplanes)

        self.conv2 = scn.SubmanifoldConvolution(dimension=3,
            nIn         = outplanes,
            nOut        = outplanes,
            filter_size = [nplanes,3,3],
            bias        = False)

        # if FLAGS.BATCH_NORM:
        self.bn2 = scn.BatchNormalization(outplanes)

        self.residual = scn.Identity()
        self.relu = scn.ReLU()

        self.add = scn.AddTable()

    def forward(self, x):

        residual = self.residual(x)

        out = self.conv1(x)
        # if FLAGS.BATCH_NORM:
        out = self.bn1(out)
        # else:
            # out = self.relu(out)
        out = self.conv2(out)

        # if FLAGS.BATCH_NORM:
        out = self.bn2(out)

        # The addition of sparse tensors is not straightforward, since

        out = self.add([out, residual])

        out = self.relu(out)

        return out

class SparseConvolutionDownsample(nn.Module):

    def __init__(self, inplanes, outplanes,nplanes=1):
        nn.Module.__init__(self)

        self.conv = scn.Convolution(dimension=3,
            nIn             = inplanes,
            nOut            = outplanes,
            filter_size     = [nplanes,2,2],
            filter_stride   = [1,2,2],
            bias            = False
        )
        # if FLAGS.BATCH_NORM:
        self.bn   = scn.BatchNormalization(outplanes)
        self.relu = scn.ReLU()

    def forward(self, x):
        out = self.conv(x)

        # if FLAGS.BATCH_NORM:
        out = self.bn(out)

        out = self.relu(out)
        return out

class SparseBlockSeries(torch.nn.Module):

    def __init__(self, inplanes, n_blocks, nplanes, residual=False):
        torch.nn.Module.__init__(self)

        if residual:
            self.blocks = [ SparseResidualBlock(inplanes, inplanes, nplanes=nplanes) for i in range(n_blocks) ]
        else:
            self.blocks = [ SparseBlock(inplanes, inplanes, nplanes=nplanes) for i in range(n_blocks)]

        for i, block in enumerate(self.blocks):
            self.add_module('block_{}'.format(i), block)

    def forward(self, x):
        for i in range(len(self.blocks)):
            x = self.blocks[i](x)
        return x

def filter_increase(input_filters):
    # return input_filters * 2
    return input_filters + FLAGS.N_INITIAL_FILTERS

class ResNet(torch.nn.Module):

    def __init__(self, output_shape):
        torch.nn.Module.__init__(self)
        # All of the parameters are controlled via the flags module

        # Create the sparse input tensor:
        # (first spatial dim is plane)
        self.input_tensor = scn.InputLayer(dimension=3, spatial_size=[FLAGS.NPLANES,2048, 1280])

        spatial_size = [2048, 1280]

        # The convolutional layers, which can be shared or not across planes,
        # are defined below

        # We apply an initial convolution, to each plane, to get n_inital_filters

        self.initial_convolution = scn.SubmanifoldConvolution(dimension=3,
            nIn=1,
            nOut=FLAGS.N_INITIAL_FILTERS,
            filter_size=[1,5,5],
            bias=False)
        n_filters = FLAGS.N_INITIAL_FILTERS
        # Next, build out the convolution steps

        self.pre_convolutional_layers = []
        for layer in range(FLAGS.NETWORK_DEPTH_PRE_MERGE):
            out_filters = filter_increase(n_filters)

            self.pre_convolutional_layers.append(
                SparseBlockSeries(inplanes = n_filters,
                    n_blocks = FLAGS.RES_BLOCKS_PER_LAYER,
                    nplanes  = 1,
                    residual = True)
                )
            self.pre_convolutional_layers.append(
                SparseConvolutionDownsample(inplanes=n_filters,
                    outplanes = out_filters,
                    nplanes = 1)
                )
            n_filters = out_filters

            spatial_size =  [ ss / 2 for ss in spatial_size ]
            self.add_module("pre_merge_conv_{}".format(layer),
                self.pre_convolutional_layers[-2])
            self.add_module("pre_merge_down_{}".format(layer),
                self.pre_convolutional_layers[-1])

        # n_filters *= FLAGS.NPLANES
        self.post_convolutional_layers = []
        for layer in range(FLAGS.NETWORK_DEPTH_POST_MERGE):
            out_filters = filter_increase(n_filters)

            self.post_convolutional_layers.append(
                SparseBlockSeries(
                    inplanes = n_filters,
                    n_blocks = FLAGS.RES_BLOCKS_PER_LAYER,
                    nplanes  = FLAGS.NPLANES,
                    residual = True)
                )
            self.post_convolutional_layers.append(
                SparseConvolutionDownsample(
                    inplanes  = n_filters,
                    outplanes = out_filters,
                    nplanes   = 1)
                )
            n_filters = out_filters

            spatial_size =  [ ss / 2 for ss in spatial_size ]

            self.add_module("post_merge_conv_{}".format(layer),
                self.post_convolutional_layers[-2])
            self.add_module("post_merge_down_{}".format(layer),
                self.post_convolutional_layers[-1])

        # Now prepare the output operations.  In general, it's a Block Series,
        # then a 1x1 to get the right number of filters, then a global average pooling,
        # then a reshape

        # This is either once to get one set of labels, or several times to split the network
        # output to multiple labels

        if FLAGS.LABEL_MODE == 'all':
            self.final_layer = SparseBlockSeries(n_filters,
                n_filters,
                FLAGS.RES_BLOCKS_PER_LAYER,
                nplanes=FLAGS.NPLANES)
            spatial_size =  [ ss / 2 for ss in spatial_size ]

            self.bottleneck = scn.SubmanifoldConvolution(dimension=3,
                        nIn=n_filters,
                        nOut=output_shape[-1],
                        filter_size=1,
                        bias=False)

            self.sparse_to_dense = scn.SparseToDense(dimension=3, nPlanes=output_shape[-1])
        else:
            self.final_layer = {
                    key : SparseBlockSeries(
                        inplanes = n_filters,
                        n_blocks = FLAGS.RES_BLOCKS_PER_LAYER,
                        nplanes  = FLAGS.NPLANES,
                        residual = True)
                    for key in output_shape
                }
            spatial_size =  [ ss / 2 for ss in spatial_size ]
            self.bottleneck  = {
                    key : scn.SubmanifoldConvolution(dimension=3,
                        nIn=n_filters,
                        nOut=output_shape[key][-1],
                        filter_size=1,
                        bias=False)
                    for key in output_shape
                }
            self.sparse_to_dense = {
                    key : scn.SparseToDense(dimension=3, nPlanes=output_shape[key][-1])
                    for key in output_shape
                }

            for key in self.final_layer:
                self.add_module("final_layer_{}".format(key), self.final_layer[key])
                self.add_module("bottleneck_{}".format(key), self.bottleneck[key])
                self.add_module("sparse_to_dense_{}".format(key), self.sparse_to_dense[key])

        # Sparse to Dense conversion to apply before global average pooling:

        # The rest of the final operations (reshape, softmax) are computed in the forward pass

        # # Configure initialization:
        # for m in self.modules():
        #     if isinstance(m, nn.Conv2d):
        #         nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
        #     elif isinstance(m, nn.BatchNorm2d):
        #         nn.init.constant_(m.weight, 1)
        #         nn.init.constant_(m.bias, 0)
        #     elif isinstance(m, scn.SubmanifoldConvolution):
        #         nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
        #     elif isinstance(m, scn.BatchNormReLU) or isinstance(m, scn.BatchNormalization):
        #         nn.init.constant_(m.weight, 1)
        #         nn.init.constant_(m.bias, 0)

    def forward(self, x):

        FLAGS = utils.flags.FLAGS()

        # # Split the input into NPLANES streams
        # x = [ _ for _ in torch.split(x, 1, dim=1)]
        # for the sparse input data, it's ALREADY split

        batch_size = x[-1]

        # Convert to the right format:
        x = self.input_tensor(x )
        # Apply all of the forward layers:
        x = self.initial_convolution(x)
        for i in range(len(self.pre_convolutional_layers)):
            x = self.pre_convolutional_layers[i](x)

        for i in range(len(self.post_convolutional_layers)):
            x = self.post_convolutional_layers[i](x)

        # Apply the final steps to get the right output shape

        if FLAGS.LABEL_MODE == 'all':
            # Apply the final residual block:
            output = self.final_layer(x)
            # Apply the bottle neck to make the right number of output filters:
            output = self.bottleneck(output)

            # Apply global average pooling
            kernel_size = output.shape[2:]
            output = torch.squeeze(nn.AvgPool2d(kernel_size, ceil_mode=False)(output))

            # output = nn.Softmax(dim=1)(output)

        else:
            output = {}
            for key in self.final_layer:
                # Apply the final residual block:
                output[key] = self.final_layer[key](x)

                # Apply the bottle neck to make the right number of output filters:
                output[key] = self.bottleneck[key](output[key])

                # Convert to dense tensor:
                output[key] = self.sparse_to_dense[key](output[key])

                kernel_size = output[key].shape[2:]

                output[key] = torch.squeeze(nn.AvgPool3d(kernel_size, ceil_mode=False)(output[key]))

                # Squeeze off the last few dimensions:
                output[key] = output[key].view([batch_size, output[key].shape[-1]])

                # output[key] = scn.AveragePooling(dimension=3,
                #     pool_size=kernel_size, pool_stride=kernel_size)(output[key])

                # print (output[key].spatial_size)
                # print (output[key])

                # print (output[key].size())

                # output[key] = nn.Softmax(dim=1)(output[key])

        return output


# -*- coding: utf-8 -*-
import os
import json

from luscious_dl.logger import logger

def cls():
  os.system('cls' if os.name == 'nt' else 'clear')

def get_config_setting(setting):
  with open('./config.json') as config:
    data = json.load(config)
  return data[setting]

def create_default_files():
  if not (os.path.exists('./config.json')):
    data = {
      "directory": "./Albums/",
      "pool": os.cpu_count()
    }
    with open('./config.json', 'a+') as config_file:
      json.dump(data, config_file, indent=2)
  if not (os.path.exists('./list.xt')):
    open('./list.txt', 'a+')
  if not (os.path.exists('./list_completed.txt')):
    open('./list_completed.txt', 'a+')

def create_folder(directory):
  try:
    if not os.path.exists(directory):
      os.makedirs(directory)
      logger.info(f'Album folder created: {directory}')
    else:
      logger.warn(f'Album folder {directory} already exist.')
  except OSError:
    logger.error(f'Creating directory: {directory}\n{e}')

def list_organizer(album_url):
  with open('./list.txt') as list_txt:
    temp = ['' if album_url in line else line for line in list_txt]
  with open('./list.txt', 'w') as list_txt:
    for line in temp:
      list_txt.write(line)
  with open('./list_completed.txt') as completed:
    text = completed.read()
  with open('./list_completed.txt', 'a') as completed:
    if not text.endswith("\n"):
      completed.write('\n')
    completed.write(album_url)
    logger.log(5, 'Album url added to completed list.')

def open_config_menu():
  with open('./config.json', 'r+') as j:
    data = json.load(j)
    while True:
      config_menu = input(f'1 - Change Directory [Current: {data["directory"]}]\n'
                          f'2 - CPU Pool [Current: {data["pool"]}]\n'
                          '0 - Back and Save.\n'
                          '> ')
      cls()
      if config_menu == '1':
        new_path = input('For default directory enter 0\n'
                         f'Current directory: {data["directory"]}\n'
                         'Directory: ')
        if new_path not in ['0', ' ']:
          new_path = new_path.replace('\\', '/')
          data['directory'] = new_path if new_path.endswith('/') else f'{new_path}/'
        else:
          data['directory'] = './Albums/'
      elif config_menu == '2':
        print(f'You have: {os.cpu_count()} cores.')
        data['pool'] = int(input('Enter CPU Pool for Download Pictures.\n> '))
      elif config_menu == '0':
        cls()
        break
      else:
        print('Invalid Option.\n')
    j.seek(0)
    json.dump(data, j, indent=2)
    j.truncate()


from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import classification_report
from math import sqrt
import jsonlines

def read_data(data_file):
	data = []
	with jsonlines.open(data_file) as reader:
		for obj in reader:
			data.append(obj)
	return data

def evaluate(data):
	score_af = []
	score_rt = []

	cleaned_data = []
	for line in data:
		if line[0] != None:
			cleaned_data.append(line)
	data = cleaned_data
	print ("size clean data %d" % len(data))

	for line in data:
		score_rt.append(int(line[0]))
		score_af.append(round(int(line[1])))

	tomatoes_rt = ['F' if x >= 60 else 'R' for x in score_rt]
	tomatoes_af = ['F' if x >= 60 else 'R' for x in score_af]
	print (classification_report(tomatoes_rt, tomatoes_af))

	rmse = sqrt(mean_squared_error(score_rt, score_af))
	print ("original rmse %f" % rmse)

	mae = mean_absolute_error(score_rt, score_af)
	print ("original mae %f" % mae)

	score_rt = [int(x/10) if x!=100 else 9 for x in score_rt]
	score_af = [int(x/10) if x!=100 else 9 for x in score_af]

	rmse = sqrt(mean_squared_error(score_rt, score_af))
	print ("point rmse %f" % rmse)

	mae = mean_absolute_error(score_rt, score_af)
	print ("point mae %f" % mae)

	score_af = []
	score_rt = []
	for line in data:
		if int(line[0]) != 100 and int(line[0]) != 0:
			score_rt.append(int(line[0]))
			score_af.append(round(int(line[1])))

	print ("size removed 0/100RT original rmse %d" % len(score_af))

	rmse = sqrt(mean_squared_error(score_rt, score_af))
	print ("removed 0/100RT original rmse %f" % rmse)

	mae = mean_absolute_error(score_rt, score_af)
	print ("removed 0/100RT original mae %f" % mae)

	score_rt = [int(x/10) if x!=100 else 9 for x in score_rt]
	score_af = [int(x/10) if x!=100 else 9 for x in score_af]

	rmse = sqrt(mean_squared_error(score_rt, score_af))
	print ("removed 0/100RT point rmse %f" % rmse)

	mae = mean_absolute_error(score_rt, score_af)
	print ("removed 0/100RT point mae %f" % mae)

if __name__ == "__main__":
	semantics = input("semantics? dfquad/quad/euler ")
	method = input("method? sent/nlp ")
	if semantics == "dfquad":
		if method == "sent":
			data = read_data('all_sent_dfquad_sent.jsonl')
		elif method == "nlp":
			data = read_data('all_nlp_dfquad_sent.jsonl')
	elif semantics == "quad":
		if method == "sent":
			data = read_data('all_sent_quad_sent.jsonl')
		elif method == "nlp":
			data = read_data('all_nlp_quad_sent.jsonl')
	elif semantics == "euler":
		if method == "sent":
			data = read_data('all_sent_euler_sent.jsonl')
		elif method == "nlp":
			data = read_data('all_nlp_euler_sent.jsonl')

	evaluate(data)


import pygame
import random

# initialize pygame
pygame.init()

# set window dimensions
windowwidth, windowheight = 799, 532

# display window and title
win = pygame.display.set_mode((windowwidth, windowheight))
pygame.display.set_caption("DEMONS")

# load sprites and sounds
walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
             pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
             pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]
walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
            pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
            pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
char = pygame.image.load('standing.png')
bg = pygame.image.load('bg.jpg')
bulletSound = pygame.mixer.Sound('bullet.wav')
hitSound = pygame.mixer.Sound('hit.wav')
music = pygame.mixer.music.load('music.mp3')
pygame.mixer.music.play(-1)
# score variable
score = 0
start_ticks = 0
end_ticks = 0
# game clock
clock = pygame.time.Clock()

# player class
class player(object):
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5
        self.isJump = False
        self.jumpCount = 10
        self.left = False
        self.right = True
        self.walkCount = 0
        # self.standing = True
        self.hitbox = (self.x + 17, self.y + 11, 28, 54)
        self.health = 50

    def draw(self, win):
        if man.health:
            if not (self.standing):
                if self.walkCount + 1 >= 27:
                    self.walkCount = 0
                if self.left:
                    win.blit(walkLeft[self.walkCount // 3], (self.x, self.y))
                    self.walkCount += 1
                elif self.right:
                    win.blit(walkRight[self.walkCount // 3], (self.x, self.y))
                    self.walkCount += 1
            else:
                if self.left:
                    win.blit(walkLeft[0], (self.x, self.y))
                else:
                    win.blit(walkRight[0], (self.x, self.y))
            self.hitbox = (self.x + 17, self.y + 11, 28, 54)
            pygame.draw.rect(win, (255, 0, 0), (self.hitbox[0] - 5, self.hitbox[1] - 20, 50, 10))
            pygame.draw.rect(win, (0, 240, 0), (self.hitbox[0] - 5, self.hitbox[1] - 20, self.health, 10))
            # pygame.draw.rect(win, (255, 0, 0), self.hitbox, 2)

    def hit(self):
        self.isJump = False
        self.jumpCount = 10
        self.x = 20
        self.y = windowheight-30-self.height
        self.right = True
        self.left = False
        self.walkCount = 0
        self.health -= 10
        font1 = pygame.font.SysFont('comicsans', 100)
        text = font1.render('-5', 1, (255, 0, 0))
        win.blit(text, (windowwidth // 2 - (text.get_width() / 2), windowheight // 2))
        pygame.display.update()
        i = 0
        while i < 100:
            pygame.time.delay(10)
            i += 1
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    i = 301
                    pygame.quit()

# projectile class
class projectile(object):
    def __init__(self, x, y, radius, color, facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing
        self.vel = 10 * facing

    def draw(self, win):
        # pygame.draw.circle(win, self.color, (self.x, self.y), self.radius)
        if man.right and not man.left:
            pygame.draw.polygon(win, self.color,
                                [(self.x + 20, self.y + 5), (self.x + 20, self.y - 5), (self.x + 25, self.y)])
            pygame.draw.line(win, self.color, (self.x, self.y), (self.x + 20, self.y))
            pygame.draw.polygon(win, self.color, [(self.x - 5, self.y + 5), (self.x - 5, self.y - 5), (self.x, self.y)])
        elif man.left and not man.right:
            pygame.draw.polygon(win, self.color,
                                [(self.x - 20, self.y + 5), (self.x - 20, self.y - 5), (self.x - 25, self.y)])
            pygame.draw.line(win, self.color, (self.x, self.y), (self.x - 20, self.y))
            pygame.draw.polygon(win, self.color, [(self.x + 5, self.y + 5), (self.x + 5, self.y - 5), (self.x, self.y)])

# enemy class
class enemy(object):
    walkRight = [pygame.image.load('R1E.png'), pygame.image.load('R2E.png'), pygame.image.load('R3E.png'),
                 pygame.image.load('R4E.png'), pygame.image.load('R5E.png'), pygame.image.load('R6E.png'),
                 pygame.image.load('R7E.png'), pygame.image.load('R8E.png'), pygame.image.load('R9E.png'),
                 pygame.image.load('R10E.png'), pygame.image.load('R11E.png')]
    walkLeft = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
                pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
                pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png'),
                pygame.image.load('L10E.png'), pygame.image.load('L11E.png')]

    def __init__(self, x, y, width, height, end, bossLevel=1):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.end = end
        self.path = [20+man.width, self.end]  #################################################################################
        self.walkCount = 0
        self.bossLevel = bossLevel
        self.vel = 3 * self.bossLevel
        self.hitbox = (self.x + 15, self.y + 2, 32, 57)
        self.health = 10 * self.bossLevel
        self.visible = True

    def draw(self, win):
        self.move()
        if self.visible:
            if self.walkCount + 1 >= 33:
                self.walkCount = 0
            if self.vel > 0:
                win.blit(self.walkRight[self.walkCount // 3], (self.x, self.y))
                self.walkCount += 1
            else:
                win.blit(self.walkLeft[self.walkCount // 3], (self.x, self.y))
                self.walkCount += 1
            self.hitbox = (self.x + 15, self.y + 2, 32, 57)
            pygame.draw.rect(win, (255, 0, 0), (self.hitbox[0] - 5, self.hitbox[1] - 20, 50 , 10))
            pygame.draw.rect(win, (0, 240, 0), (self.hitbox[0] - 5, self.hitbox[1] - 20, round(5 * self.health / self.bossLevel),10))
            # pygame.draw.rect(win, (255, 0, 0), self.hitbox, 2)

    def move(self):
        if self.vel > 0:
            if self.x + self.vel < self.path[1]:
                self.x += self.vel
                if self.y + self.height + 20 < windowheight:
                    self.y += self.vel//random.randint(1,10)
            else:
                self.vel = self.vel * -1
                self.walkCount = 0
        else:
            if self.x - self.vel > self.path[0]:
                self.x += self.vel
                if self.y > windowheight//2:
                    self.y += self.vel//random.randint(1,10)
            else:
                self.vel = self.vel * -1
                self.walkCount = 0

    def hit(self):
        if self.health > 1:
            self.health -= 1
        else:
            self.visible = False
            global start_ticks
            start_ticks = pygame.time.get_ticks()
        print(f'Score: {score}')

    def respawn(self):
        if self.visible == False:
            global end_ticks
            end_ticks = pygame.time.get_ticks()
            if end_ticks - start_ticks >= 3000:
                global goblin
                goblin = enemy(windowwidth +20, windowheight-30-self.height, 64, 64, windowwidth-self.width-20, goblin.bossLevel+1)
                self.visible = True

# redraw window function
def redrawGameWindow():
    win.blit(bg, (0, 0))
    text = font.render('Score: ' + str(score), 1, (255, 255, 255))
    win.blit(text, (10, 10))
    man.draw(win)
    goblin.draw(win)
    for bullet in bullets:
        bullet.draw(win)
    pygame.draw.rect(win, (6, 125, 8), (0, windowheight-30 , windowwidth, 30))
    if goblin.visible == False and goblin.bossLevel<6:
        text2 = font.render('RESPAWNING...', 1, (0, 0, 0))
        win.blit(text2, (windowwidth // 2 - (text2.get_width() / 2), windowheight // 2))
    if man.health <= 0:
        gameover = font.render('GAME OVER! Press R to Restart', 1, (0,0,0))
        win.blit(gameover, (windowwidth // 2 - (gameover.get_width() / 2), windowheight // 2))
    if goblin.bossLevel == 7:
        winmsg = font.render('YOU WIN, Exiting in 3s', 1, (0, 0, 0))
        win.blit(winmsg, (windowwidth // 2 - (winmsg.get_width() / 2), windowheight // 2))

    pygame.display.update()

# mainloop
font = pygame.font.SysFont('comicsans', 30, True)
man = player(20, windowheight-30-64, 64, 64)  # create player instance
goblin = enemy(250, windowheight-30-64, 64, 64, windowwidth-20-64)  # create enemy instance
shootLoop = 0  # for separate bullets
bullets = []  # no of bullets list

run = True
while run:
    clock.tick(27)  # set framerate
    if goblin.bossLevel == 7:
        pygame.time.delay(3000)
        break
    if goblin.visible == True and man.health:
        if man.hitbox[1] < goblin.hitbox[1] + goblin.hitbox[3] and man.hitbox[1] + man.hitbox[3] > goblin.hitbox[1]:
            if man.hitbox[0] + man.hitbox[2] > goblin.hitbox[0] and man.hitbox[0] < goblin.hitbox[0] + goblin.hitbox[2]:
                man.hit()
                score -= 5

    if shootLoop > 0:
        shootLoop += 1
    if shootLoop > 3:
        shootLoop = 0

    for bullet in bullets:
        if goblin.visible == True and man.health:
            if bullet.y - bullet.radius < goblin.hitbox[1] + goblin.hitbox[3] and bullet.y + bullet.radius > \
                    goblin.hitbox[1]:
                if bullet.x + bullet.radius > goblin.hitbox[0] and bullet.x - bullet.radius < goblin.hitbox[0] + \
                        goblin.hitbox[2]:
                    hitSound.play()
                    goblin.hit()
                    score += 1
                    bullets.pop(bullets.index(bullet))
        if bullet.x < windowwidth and bullet.x > 0:
            bullet.x += bullet.vel
        else:
            try:
                bullets.pop(bullets.index(bullet))
            except ValueError:
                pass

    keys = pygame.key.get_pressed()
    if man.health:
        if keys[pygame.K_SPACE] and shootLoop == 0:
            bulletSound.play()
            if man.left:
                facing = -1
            else:
                facing = 1
            if len(bullets) < 5:
                bullets.append(
                    projectile(round(man.x + (man.width) // 2), round(man.y + (man.height) // 2), 6, (255, 225, 0), facing))
            shootLoop = 1

        if keys[pygame.K_LEFT] and man.x > man.vel:
            man.x -= man.vel
            man.left = True
            man.right = False
            man.standing = False
        elif keys[pygame.K_RIGHT] and man.x < windowwidth - man.width - man.vel:
            man.x += man.vel
            man.right = True
            man.left = False
            man.standing = False
        else:
            man.standing = True
            man.walkCount = 0
        if not (man.isJump):
            if keys[pygame.K_UP]:
                man.isJump = True
                # man.right = False
                # man.left = False
                # man.standing = True
                man.walkCount = 0
        else:
            if man.jumpCount >= -10:
                neg = 1
                if man.jumpCount < 0:
                    neg = -1
                man.y -= (man.jumpCount ** 2) * 0.5 * neg
                man.jumpCount -= 1
            else:
                man.isJump = False
                man.jumpCount = 10

    if goblin.visible == False:
        goblin.respawn()

    if man.health <= 0:
        if keys[pygame.K_r]:
            man.health = 50

    for event in pygame.event.get():  # gets a list
        if event.type == pygame.QUIT:
            run = False
    redrawGameWindow()

pygame.quit()


import logging
import requests

logger = logging.getLogger(__name__)

def encoded_dict(in_dict):
    out_dict = {}
    for k, v in in_dict.iteritems():
        if isinstance(v, unicode):
            v = v.encode('utf8')
        elif isinstance(v, str):
            v.decode('utf8')
        out_dict[k] = v
    return out_dict

class VKApiConnector(object):
    __base_url = "https://api.vk.com/method/"
    __v = 5.68
    __resolve_screen_name_method = "utils.resolveScreenName"
    __wall_get_method = "wall.get"
    __token = NotImplemented
    __client_id = NotImplemented
    __sleep_time = NotImplemented

    @classmethod
    def config(cls, version, client_id, token, sleep_time=1):
        cls.version = version
        cls.__sleep_time = sleep_time
        cls.__client_id = client_id
        cls.__token = token

    @classmethod
    def __get_base_params(cls):
        return {
            'v': cls.__v,
            'client_id': cls.__client_id,
            'access_token': cls.__token
        }

    @classmethod
    def resolve_screen_name(cls, screen_name):
        try:
            logger.info("Access {} method".format(cls.__resolve_screen_name_method))
            request_params = cls.__get_base_params()
            request_params['screen_name'] = screen_name

            url = '{}{}'.format(cls.__base_url, cls.__resolve_screen_name_method)
            response = requests.post(url, encoded_dict(request_params) if request_params else None)

            if not response.ok:
                logger.error(response.text)
                return

            return response.json()['response']
        except Exception as ex:
            logger.exception(ex)

    @classmethod
    def get_wall(cls, owner_id):
        try:
            logger.info("Access {} method".format(cls.__wall_get_method))
            request_params = cls.__get_base_params()
            request_params['owner_id'] = owner_id
            request_params['count'] = 100

            url = '{}{}'.format(cls.__base_url, cls.__wall_get_method)
            response = requests.post(url, encoded_dict(request_params) if request_params else None)

            if not response.ok:
                logger.error(response.text)
                return

            return response.json()['response']
        except Exception as ex:
            logger.exception(ex)


from keras.layers.pooling import Layer
import keras.backend as K

class GlobalAveragePooling1D_Mask0(Layer):
    """
    Global average pooling operation for temporal data.
    Masking out 0-padded input.
    """

    def __init__(self, data_format='channels_last', **kwargs):
        super(GlobalAveragePooling1D_Mask0, self).__init__(**kwargs)
        self.data_format = K.normalize_data_format(data_format)

    def compute_output_shape(self, input_shape):
        input_shape = input_shape[0]
        if self.data_format == 'channels_first':
            return (input_shape[0], input_shape[1])
        else:
            return (input_shape[0], input_shape[2])

    def call(self, inputs):
        inputs, model_inputs = inputs
        steps_axis = 1 if self.data_format == 'channels_last' else 2
        mask = K.max(model_inputs, axis=2, keepdims=True)
        inputs *= mask
        return K.sum(inputs, axis=steps_axis) / K.maximum(
            K.sum(mask, axis=steps_axis), K.epsilon())


import os.path
import sys
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))

from data.base_dataset import BaseDataset, get_transform
from data.image_folder import make_dataset
from data.image_folder import is_image_file
from PIL import Image
import cv2

class TestDataset(BaseDataset):
    def initialize(self, opt):
        self.opt = opt
        self.root = opt.data_directory
        self.dir_A = os.path.join(opt.data_directory)

        self.A_paths = make_dataset(self.dir_A)

        self.A_paths = sorted(self.A_paths)

        self.transform = get_transform(opt)

    def __getitem__(self, index):
        A_path = self.A_paths[index]
        A_img = Image.open(A_path).convert('RGB')
        A_size = A_img.size

        A = self.transform(A_img)
        input_nc = 3

        return {'A': A, 'A_paths': A_path, 'A_sizes': A_size}

    def __len__(self):
        return len(self.A_paths)

    def name(self):
        return 'TestDataset'

class RealDataset(BaseDataset):
    def initialize(self, opt):
        self.opt = opt
        self.root = opt.data_directory
        self.dir_real = os.path.join(opt.data_directory, "real")

        self.A_paths = sorted(make_dataset(self.dir_real))

        self.transform = get_transform(opt)

    def __getitem__(self, index):
        A_path = self.A_paths[index]
        A_img = Image.open(A_path).convert('RGB')
        A_size = A_img.size

        A = self.transform(A_img)

        return {'A': A, 'A_paths': A_path, 'A_sizes': A_size}

    def __len__(self):
        return len(self.A_paths)

    def name(self):
        return 'RealDataset'

class KITTIDataset(BaseDataset):
    def initialize(self, opt):
        self.opt = opt
        self.root = opt.data_directory
        self.data_dir = os.path.join(opt.data_directory, "kitti")

        self.A_paths = sorted(self.make_kitti_dataset(self.data_dir))

        self.transform = get_transform(opt)

    def make_kitti_dataset(self, dir):
        images = []
        assert os.path.isdir(dir), '%s is not a valid directory' % dir

        for root, _, fnames in sorted(os.walk(dir)):

            for fname in fnames:
                if is_image_file(fname) and (root.find('image_02') >= 0):
                    path = os.path.join(root, fname)
                    images.append(path)

        return images

    def __getitem__(self, index):
        A_path = self.A_paths[index]
        A_img = Image.open(A_path).convert('RGB')
        A_size = A_img.size

        A = self.transform(A_img)

        return {'A': A, 'A_paths': A_path, 'A_sizes': A_size}

    def __len__(self):
        return len(self.A_paths)

    def name(self):
        return 'RealDataset'

class SyntheticDataset(BaseDataset):
    # def initialize(self, opt):
    #     self.opt = opt
    #     self.root = opt.data_directory
    #     self.dir_syn = os.path.join(opt.data_directory, "fifa")
    #     self.depth_postfix = '_d'
    #
    #     self.B_paths = []
    #     self.C_paths = []
    #
    #     syn_paths = make_dataset(self.dir_syn)
    #
    #     # split Syn and Depth
    #     for path in syn_paths:
    #         if path.split('/')[-1].split('.')[-2][-2:] == self.depth_postfix:
    #             self.C_paths.append(path)
    #         else:
    #             self.B_paths.append(path)
    #
    #     self.B_paths = sorted(self.B_paths)
    #     self.C_paths = sorted(self.C_paths)
    #
    #     self.transform = get_transform(opt)
    #
    # def __getitem__(self, index):
    #     B_path = self.B_paths[index]
    #     B_img = Image.open(B_path).convert('RGB')
    #     B_size = B_img.size
    #
    #     B = self.transform(B_img)
    #
    #     C_path = self.C_paths[index]
    #     C_img = Image.open(C_path).convert('L')
    #     C_size = C_img.size
    #
    #     C = self.transform(C_img)
    #
    #     return {'B': B, 'B_paths': B_path, 'B_sizes': B_size, \
    #             'C': C, 'C_paths': C_path, 'C_sizes': C_size}
    #
    # def __len__(self):
    #     return len(self.B_paths)
    #
    # def name(self):
    #     return 'SyntheticDataset'

    def initialize(self, opt):
        self.opt = opt
        self.root = opt.data_directory
        self.dir_B = os.path.join(opt.data_directory, "vkitti_1.3.1_rgb")
        self.dir_C = os.path.join(opt.data_directory, "vkitti_1.3.1_depthgt")

        self.B_paths = make_dataset(self.dir_B)
        self.C_paths = make_dataset(self.dir_C)

        self.B_paths = sorted(self.B_paths)
        self.C_paths = sorted(self.C_paths)

        self.transform = get_transform(opt)

    def __getitem__(self, index):
        B_path = self.B_paths[index]
        B_img = Image.open(B_path).convert('RGB')
        B_size = B_img.size

        B = self.transform(B_img)

        C_path = self.C_paths[index]
        C_img = Image.open(C_path).point(lambda i: i*(1./256)).convert('L')
        C_size = C_img.size

        # C_img.save("./input_check/1.jpg")

        C = self.transform(C_img)

        return {'B': B, 'B_paths': B_path, 'B_sizes': B_size, \
                'C': C, 'C_paths': C_path, 'C_sizes': C_size}

    def __len__(self):
        return len(self.B_paths)

    def name(self):
        return 'TestDataset'


from os import walk
from os.path import join, basename, exists
from cv2 import selectROI, imshow, destroyWindow
from pandas import DataFrame, concat, ExcelWriter
from imageio import get_reader, get_writer

from skimage.morphology import thin, remove_small_holes, remove_small_objects, closing
from skimage.util import img_as_ubyte, img_as_bool
from skimage.filters import threshold_otsu
from skimage.util import invert
from skimage import color

from fil_finder import FilFinder2D
from astropy.units import pix, pc

from warnings import filterwarnings
from tkinter import filedialog, messagebox, Button, Label, Entry, StringVar, Checkbutton, IntVar, Tk, Toplevel, Canvas, PhotoImage
from tkinter.font import Font
from tkinter.ttk import Button as tButton
from tkinter.ttk import Separator, Progressbar

#from time import process_time

"""
-----
WormRuler by Marius Seidenthal and Dennis Vettkötter

Changelog:
Version 0.1.0 (Seidenthal)
- original script written
Version 0.1.1 (Vettkötter)
- GUI added
Version 0.2.0 (Seidenthal)
- Included Entry field for Gamma values
Version 0.2.1 (Vettkötter)
- Included new button "Start all" for batch processing
Version 0.3.0 (Vettkötter)
- Improved skeletonization: Removed branches in skeletons
Version 0.3.1 (Vettkötter)
- Skeletonization step of v3 resulted in too short GIFs if only black images
  appeared in black&white GIFs:
    - Removed suppress Exception with try and except lines
Version 0.4.0 (Vettkötter + Seidenthal)
- Removed skan from skeletonize function
- Raw length values (in pixel) will be saved in separate textfile "*_raw_lengths.txt"
- Added separate normalize function to load raw lengths data from skeletonize step
  - normalizes lengths to data before pulsestart
  - new normalize function will be started directly after skeletonize step (no additional GUI interface included)
Version 0.4.1 (Vettkötter)
- Added GUI option to start normalization on its own.
Version 0.4.2 (Seidenthal)
- Added .mov/.MOV support
Version 0.4.3 (Vettkötter)
- Added file name to final results table as column name for each worm
Version 0.5.0 (Vettkötter)
- Added input field to ask whether user will override existing skeleton files or skip to unskeletonized files.
Version 0.5.1 (Seidenthal + Vettkötter)
- Added input of framerate to GUI
Version 1.0.0 (Seidenthal + Vettkötter)
- Adjusted changelog information
- publishing first WormRuler version on GitHub
Version 1.0.1 (Seidenthal)
- Added input of normalization data boundaries
Version 1.1.0 (Seidenthal)
- Added Preview of background correction
- Added exclusion of animals where more than 50% of Datapoints are invalid
-----
"""

# GUI window
gui = Tk()
gui.geometry('340x570')
gui.title("WormRuler")
gui.iconbitmap('wormruler_ico.ico')

# Ignore warnings
filterwarnings('ignore', '.*No beam width given.*', )
filterwarnings('ignore', '.*Graph pruning reached max iterations.*', )

# WormRuler code

# Function to crop video according to ROI which ist needed if round field of view is used
def crop_center(img, cropx, cropy):
    y, x = img.shape
    startx = x // 2 - (cropx // 2)
    starty = y // 2 - (cropy // 2)
    return img[starty:starty + cropy, startx:startx + cropx]

#checks first 10 frames of one video to see if background correction works properly
def background_check():
    Gamma_value = gamma.get()
    if Gamma_value == "":
        messagebox.showerror("Error", "Please enter Gamma value.\nShould be approximately between 0.7 and 1.3.")
    else:
        # open vid
        Gamma_value = float(Gamma_value)
        video_root = video_path.get() + "/"

        # find all subfolders which are labeled according to the measurement conditions
        folders = []
        for r, d, f in walk(video_root):
            for folder in d:
                folders.append(folder)

        for folder in folders:
            print("Preview of background correction of condition " + "\"" + folder + "\":")

            # find all videos in the respective folder
            video_paths = []
            for r, d, f in walk(str(video_root) + "/" + str(folder)):
                for file in f:
                    if ".AVI" in file or ".avi" in file or ".mov" in file or ".MOV" in file:
                        video_paths.append(join(r, file))
            v_path = video_paths[0]
            print(v_path)
            vid = get_reader(v_path, 'ffmpeg')

            with get_writer(video_root + "Background_preview.gif", mode='I', fps=int(framerate.get())) as writer:
                # get frames
                for num, image in enumerate(vid):
                    # convert to grayscale
                    img = color.rgb2gray(image)

                    # get threshold and make binary
                    otsu = threshold_otsu(img)
                    binary = img > otsu * Gamma_value
                    binary = invert(binary)
                    # close holes, remove small objects
                    binary = remove_small_objects(binary, min_size=2000)
                    binary = closing(binary)
                    binary = remove_small_holes(binary, area_threshold=700)
                    # write image to file
                    binary = img_as_ubyte(binary)
                    writer.append_data(binary)
                    if num == 9:
                        break
            break
        toplvl = Toplevel()  # created Toplevel widger
        photo = PhotoImage(file=video_root + "Background_preview.gif")
        lbl = Label(toplvl, image=photo)
        lbl.image = photo  # keeping a reference in this line
        lbl.grid(row=0, column=0)

        print("\nPreview done.")

# substracts background and writes binary gif file
def background_correction():
    bw_done.grid_remove()
    print("Background correction started... \n")

    Gamma_value = gamma.get()
    if Gamma_value == "":
        messagebox.showerror("Error", "Please enter Gamma value.\nShould be approximately between 0.7 and 1.3.")
    else:
        # open vid
        Gamma_value = float(Gamma_value)
        video_root = video_path.get() + "/"

        # find all subfolders which are labeled according to the measurement conditions
        folders = []
        for r, d, f in walk(video_root):
            for folder in d:
                folders.append(folder)
        print("Following conditions found: " + str(folders) + "\n")

        progress_bw_value = 0
        progress_bw_list = []
        for r, d, f in walk(str(video_root)):
            for file in f:
                if ".AVI" in file or ".avi" in file or ".mov" in file or ".MOV" in file:
                    progress_bw_list.append(file)
        progress_bw_steps = 100 / len(progress_bw_list)

        for folder in folders:
            print("Background correction of condition " + "\"" + folder + "\":")

            # find all videos in the respective folder
            video_paths = []
            for r, d, f in walk(str(video_root) + "/" + str(folder)):
                for file in f:
                    if ".AVI" in file or ".avi" in file or ".mov" in file or ".MOV" in file:
                        video_paths.append(join(r, file))
            for v_path in video_paths:
                print(v_path)
                vid = get_reader(v_path, 'ffmpeg')

                with get_writer(v_path[:-4] + "_bw.gif", mode='I', fps=int(framerate.get())) as writer:
                    # get frames
                    for num, image in enumerate(vid):
                        # convert to grayscale
                        img = color.rgb2gray(image)

                        # get threshold and make binary
                        otsu = threshold_otsu(img)
                        binary = img > otsu * Gamma_value
                        binary = invert(binary)
                        # close holes, remove small objects
                        binary = remove_small_objects(binary, min_size=2000)
                        binary = closing(binary)
                        binary = remove_small_holes(binary, area_threshold=700)
                        # write image to file
                        binary = img_as_ubyte(binary)
                        writer.append_data(binary)

                    progress_bw_value += progress_bw_steps
                    progressbar_bw['value'] = progress_bw_value
                    progressbar_bw.update()

            print("\n")
        bw_done.grid(row=6, column=1, sticky='w', padx=200)
        print("Background correction complete!")
        print("Ready for skeletonization.")

# create ROI to remove edges, write ROI coordinates to text file, make new for each day of measurement
# simply draw ROI over whole image if the field of view is rectengular

def ROI_set():
    print("\nSelect ROI for skeletonization!\n")
    # open vid
    video_root = video_path.get() + "/"
    root_name = basename(video_path.get())
    folders = []
    for r, d, f in walk(video_root):
        for folder in d:
            folders.append(folder)

    video_paths = []
    for r, d, f in walk(str(video_root) + "/" + str(folders[0])):
        for file in f:
            if "_bw.gif" in file:
                video_paths.append(join(r, file))
    # read first video and set ROI
    vid1 = get_reader(video_paths[0], 'ffmpeg')
    for frame in vid1:
        fromCenter = False
        roi = selectROI(frame, fromCenter)
        imCrop = frame[int(roi[1]):int(roi[1] + roi[3]), int(roi[0]):int(roi[0] + roi[2])]
        imshow("ROI", imCrop)
        textfile = open(video_root + str(root_name) + "_ROI.txt", "w")
        textfile.write('\n'.join(str(s) for s in roi))

        textfile.close()
        destroyWindow('ROI selector')
        destroyWindow('ROI')
        break

# takes background corrected gifs and crops them using the predefined ROI
# makes skeleton of worms and writes them to new gif
# analyzes length of skeleton and stores values in textfile for each worm
def skeletonize():

    print("ROI selected. Starting skeletonization...")
    # open vid
    video_root = video_path.get() + "/"
    progress_skel_value = 0
    progress_skel_list = []
    if check.get() == 1:
        for r, d, f in walk(str(video_root)):
            for file in f:
                if "_bw.gif" in file:
                    progress_skel_list.append(file)
        progress_skel_steps = 100 / len(progress_skel_list)
    else:
        for r, d, f in walk(str(video_root)):
            for file in f:
                if "_bw.gif" in file:
                    if exists(join(r, file[:-7]) + "_raw_lengths.txt"):
                        pass
                    else:
                        progress_skel_list.append(file)
        if len(progress_skel_list) == 0:
            print("\nAll files skeletonized! Check override or proceed to normalization!\n")
        else:
            progress_skel_steps = 100 / len(progress_skel_list)

    folders = []
    for r, d, f in walk(video_root):
        for folder in d:
            folders.append(folder)

    print("Following conditions found: " + str(folders) + "\n")

    # get roi from txtfile
    roi_file = []
    for r, d, f in walk(video_root):
        for file in f:
            if file.endswith("_ROI.txt"):
                roi_file.append(join(r, file))
    textfile = open(roi_file[0], "r")
    lines = textfile.readlines()
    roi = []
    for line in lines:
        line.strip(r"\n")
        roi.append(int(line))
    textfile.close()

    for folder in folders:
        print("Skeletonizing condition " + "\"" + folder + "\":")

        video_paths = []
        if check.get() == 1:
            for r, d, f in walk(str(video_root) + "/" + str(folder)):
                for file in f:
                    if "_bw.gif" in file:
                        video_paths.append(join(r, file))
        else:
            for r, d, f in walk(str(video_root) + "/" + str(folder)):
                for file in f:
                    if "_bw.gif" in file:
                        if exists(join(r, file[:-7]) + "_raw_lengths.txt"):
                            pass
                        else:
                            video_paths.append(join(r, file))

        for v_path in video_paths:
            print(v_path)
            vid = get_reader(v_path, 'ffmpeg')
            # get frames
            skel_txt = open(v_path[:-7] + "_raw_lengths.txt", "w")

            with get_writer(v_path[:-7] + "_skel.gif", mode='I', fps=int(framerate.get())) as writer:
                for num, frame in enumerate(vid):
                    img = color.rgb2gray(frame)
                    # crop image
                    a, b, c, d = roi
                    img_crop = img[int(b):int(b + d), int(a):int(a + c)]
                    binary = img_as_bool(img_crop)
                    skel = thin(binary)
                    try:
                        fil = FilFinder2D(skel, distance=250 * pc, mask=skel)
                        fil.medskel(verbose=False)
                        fil.analyze_skeletons(branch_thresh=5 * pix, skel_thresh=10 * pix, prune_criteria='length')
                        skel_fil = fil.skeleton_longpath
                        skel_length = fil.lengths()
                        skel_str = str(skel_length)
                        skel_num = skel_str[1:-5]
                        skel_list = skel_num.split("  ")
                        skel_list2 = ' '.join(skel_list).split()
                        skel_floats = [float(x) for x in skel_list2]
                        skel_floats.sort(reverse=True)
                        if len(skel_floats) == 1:
                            skel_txt.write(str(skel_floats[0]) + "\n")
                        elif len(skel_floats) == 2:
                            combined = skel_floats[0] + skel_floats[1]
                            skel_txt.write(str(combined) + "\n")
                        else:
                            skel_txt.write("None" + "\n")
                        skel_fil_gif = img_as_ubyte(skel_fil)
                        writer.append_data(skel_fil_gif)
                    except:
                        skel_txt.write("None" + "\n")
            skel_txt.close()
            progress_skel_value += progress_skel_steps
            progressbar_skel['value'] = progress_skel_value
            progressbar_skel.update()

        print("\n")
    skel_done.grid(row=10, column=1, sticky='w', padx=200)
    print("Skeletonization complete.")
    print("Ready for normalization.\n")

# normalizes bodylengths to predefined pulsestart
# writes normalized bodylengths to textfile for each worm
def normalize():
    print("Starting normalization...\n")
    # open vid
    video_root = video_path.get() + "/"
    pulsestart_f = pulse_start.get()
    if pulsestart_f == "":
        messagebox.showerror("Error", "Please enter start of light pulse (in seconds)")
    else:
        pulsestart_s = int(pulse_start.get())
        print("Pulse started after " + str(pulsestart_s) + "s")
        pulsestart_f = pulsestart_s * int(framerate.get())
        print("(or after " + str(pulsestart_f) + " frames!)\n")

        normalize_done.grid_remove()
        progress_norm_value = 0
        progress_norm_list = []
        for r, d, f in walk(str(video_root)):
            for file in f:
                if "_bw.gif" in file:
                    progress_norm_list.append(file)
        progress_norm_steps = 100 / len(progress_norm_list)

        folders = []
        for r, d, f in walk(video_root):
            for folder in d:
                folders.append(folder)

        print("Following conditions found: " + str(folders) + "\n")

        for folder in folders:
            print("Normalize skeleton data for condition " + "\"" + folder + "\":")

            text_paths = []
            for r, d, f in walk(str(video_root) + "/" + str(folder)):
                for file in f:
                    if "_raw_lengths.txt" in file:
                        text_paths.append(join(r, file))

            for text_path in text_paths:
                print(text_path)
                file = open(text_path, "r")
                lines = file.readlines()
                body_lengths = []
                for body_length in lines:
                    length = body_length.rstrip("\n")
                    if length == "None":
                        body_lengths.append(None)
                    else:
                        body_lengths.append(float(length))

                list_tillpulsestart = []
                for worm in body_lengths[5:pulsestart_f - 1]:
                    # remove None values
                    if worm:
                        list_tillpulsestart.append(worm)

                # check if worm before pulse is usable for normalization
                if len(list_tillpulsestart) != 0:
                    # get average before pulse
                    average_before_pulse = sum(list_tillpulsestart) / len(list_tillpulsestart)

                    # normalization
                    bodylength_norm = []
                    for value in body_lengths:
                        if value:
                            value_norm = value / average_before_pulse
                            # remove values above upper boundary and below lower boundary
                            if float(lower_bound.get()) < value_norm < float(upper_bound.get()):
                                bodylength_norm.append(value_norm)
                            else:
                                bodylength_norm.append(None)
                        else:
                            bodylength_norm.append(None)

                    # writes bodylengths to textfiles
                    textfile = open(text_path[:-16] + "_data.txt", "w")
                    for element in bodylength_norm:
                        textfile.write(str(element) + "\n")
                    textfile.close()
                else:
                    print("Error found for " + text_path)
                    print("Please check if gamma value was adjusted correctly!\n")

                progress_norm_value += progress_norm_steps
                progressbar_normalize['value'] = progress_norm_value
                progressbar_normalize.update()
            normalize_done.grid(row=14, column=1, sticky='w', padx=200)
            print("Ready for data analyis.")

# Combining functions roi_set, skeletonize and normalization
def skeletonization():
    skel_done.grid_remove()
    video_root = video_path.get() + "/"
    root_name = basename(video_path.get())
    if exists(video_root + str(root_name) + "_ROI.txt"):
        skeletonize()
    else:
        ROI_set()
        skeletonize()

# takes textfiles containing normalized bodylengths and writes them to excelfile
# calculates mean, sem and N
def data_analyis():
    data_done.grid_remove()
    print("\nData Analysis started...")
    video_root = video_path.get() + "/"

    progress_data_value = 0
    progress_data_list = []

    folders = []
    for r, d, f in walk(video_root):
        for folder in d:
            folders.append(folder)
            progress_data_list.append(folder)
    progress_data_steps = 100 / len(progress_data_list)
    print("Following conditions found: " + str(folders) + "\n")

    for folder in folders:
        print("Analyze data for condition " + "\"" + folder + "\":")
        # get textfiles with normalized bodylengths
        text_paths = []
        file_names = []
        for r, d, f in walk(str(video_root) + "/" + str(folder)):
            for file in f:
                if "_data.txt" in file:
                    text_paths.append(join(r, file))
                    file_names.append(file[:-9])
        body_lengths_list = []

        body_lengths_list_deleted = []
        file_names_deleted =[]

        print(file_names)
        for num, text_path in enumerate(text_paths):
            print("\nFile: " + text_path)
            file = open(text_path, "r")
            lines = file.readlines()
            body_lengths = []
            for body_length in lines:
                length = body_length.rstrip("\n")
                if length == "None":
                    body_lengths.append(None)
                else:
                    body_lengths.append(float(length))
            value_numer = sum(x is not None for x in body_lengths)
            total_number = len(body_lengths)
            percentage_of_values = value_numer*100/total_number
            print ("Fraction of measured bodylengths: " + str(percentage_of_values) + " %")
            if percentage_of_values > 50:
                body_lengths_list.append(body_lengths)
            else:
                body_lengths_list_deleted.append(body_lengths)
                print ("This animal is excluded from analysis.")
                popped = file_names.pop(num)
                file_names_deleted.append(popped)
        print("\nThese animals were removed: " + str(file_names_deleted))
        if any(body_lengths_list):
            df = DataFrame(body_lengths_list)
            df = DataFrame.transpose(df)
            mean = df.mean(axis=1, skipna=True)
            sem = df.sem(axis=1, skipna=True)
            n = df.count(axis=1)
            df_final = concat([df, mean, sem, n], axis=1)
            column_names = [str(x) for x in file_names]
            column_names.append("Mean")
            column_names.append("SEM")
            column_names.append("n")
            df_final.columns = [column_names]

        if any(body_lengths_list_deleted):
            df2 = DataFrame(body_lengths_list_deleted)
            df2 = DataFrame.transpose(df2)
            df2.columns = [str(x) for x in file_names_deleted]

        with ExcelWriter(video_root + "/" + folder + "/" + folder + "_results.xlsx") as writer:
            if any(body_lengths_list):
                df_final.to_excel(writer, sheet_name=folder, engine='openpyxl')
            if any(body_lengths_list_deleted):
                df2.to_excel(writer, sheet_name="Omitted animals", engine='openpyxl')
        print("Results written as: " + str(video_root) + str(folder) + "_results.xlsx")
        print("\n")

        progress_data_value += progress_data_steps
        progressbar_data['value'] = progress_data_value
        progressbar_data.update()

    data_done.grid(row=17, column=1, sticky='w', padx=200)
    print("Data analysis complete.")
    print("Go and turn your data into beautiful graphs!")

def run_all():
    print("WormRuler - \"Run all\" function started:")
    # open vid
    folders = []
    video_root = video_path.get() + "/"
    root_name = basename(video_path.get())
    pulsestart_f = pulse_start.get()
    Gamma_value = gamma.get()
    if Gamma_value == "":
        messagebox.showerror("Error", "Please enter Gamma value.\nShould be approximately between 0.7 and 1.3.")
    else:
        if pulsestart_f == "":
            messagebox.showerror("Error", "Please enter start of light pulse (in seconds).")
        else:
            if exists(video_root + str(root_name) + "_ROI.txt"):
                background_correction()
                skeletonize()
                normalize()
                data_analyis()
            else:
                print("\nSelect ROI for skeletonization first!\n")
                for r, d, f in walk(video_root):
                    for folder in d:
                        folders.append(folder)

                video_paths = []
                for r, d, f in walk(str(video_root) + "/" + str(folders[0])):
                    for file in f:
                        if ".AVI" in file or ".avi" in file or ".mov" in file or ".MOV" in file:
                            video_paths.append(join(r, file))
                # read first video and set ROI
                vid1 = get_reader(video_paths[0], 'ffmpeg')
                for frame in vid1:
                    fromCenter = False
                    roi = selectROI(frame, fromCenter)
                    imCrop = frame[int(roi[1]):int(roi[1] + roi[3]), int(roi[0]):int(roi[0] + roi[2])]
                    imshow("ROI", imCrop)
                    textfile = open(video_root + str(root_name) + "_ROI.txt", "w")
                    textfile.write('\n'.join(str(s) for s in roi))

                    textfile.close()
                    destroyWindow('ROI selector')
                    destroyWindow('ROI')
                    break
                background_correction()
                skeletonize()
                normalize()
                data_analyis()

def close():
    gui.destroy()

# Get path functions
def getvideo_path():
    video_selected = filedialog.askdirectory(title="Select directory of raw videos")
    video_path.set(video_selected)

# Tooltip code
class ToolTip(object):

    def __init__(self, widget):
        self.widget = widget
        self.tipwindow = None
        self.id = None
        self.x = self.y = 0

    def showtip(self, text):
        """Display text in tooltip window"""
        self.text = text
        if self.tipwindow or not self.text:
            return
        x, y, cx, cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx() + 57
        y = y + cy + self.widget.winfo_rooty() + 27
        self.tipwindow = tw = Toplevel(self.widget)
        tw.wm_overrideredirect(1)
        tw.wm_geometry("+%d+%d" % (x, y))
        label = Label(tw, text=self.text, justify="left",
                         background="#ffffe0", relief="solid", borderwidth=1,
                         font=("tahoma", "10", "normal"))
        label.pack(ipadx=1)

    def hidetip(self):
        tw = self.tipwindow
        self.tipwindow = None
        if tw:
            tw.destroy()

def CreateToolTip(widget, text):
    toolTip = ToolTip(widget)

    def enter(event):
        toolTip.showtip(text)

    def leave(event):
        toolTip.hidetip()

    widget.bind('<Enter>', enter)
    widget.bind('<Leave>', leave)

# GUI setup

# GUI font styles
myFont = Font(family='Cambria', size=10, weight="bold")
titleFont = Font(family='Cambria', size=20, weight="bold")
fileFont = Font(size=9, weight="bold")

# Title
gui_title = Label(gui, text="WormRuler", font=titleFont)
gui_title.grid(row=1, column=1, pady=15, sticky='w', padx=70)

border_label = Label(gui, text="   ")
border_label.grid(row=2, column=0, sticky="w")

# Path selection
video_path = StringVar()
path_label = Label(gui, text="Path")
path_label.grid(row=2, column=1, sticky="w")
path_entry = Entry(gui, textvariable=video_path, width=28)
path_entry.grid(row=2, column=1, sticky='w', padx=30)
btn_path_entry = tButton(gui, text="Browse", command=getvideo_path)
btn_path_entry.grid(row=2, column=1, sticky='w', padx=210)

# Path selection info button
path_info = "Browse to folder with original videos.\n\n" \
            "Optional:\n \"To merge experiments from different\n" \
            " days, create a new folder with sub-\n" \
            " folders for each condition to be merged.\n" \
            " Copy all *_bw_data.txt from each condition\n" \
            " into this new folder.\n" \
            " Select this folder path and run \"Analyze Data\" again!\""

path_infobutton = Button(gui, text='i', font=myFont,
                            bg='white', fg='blue', bd=0)
CreateToolTip(path_infobutton, text=path_info)
path_infobutton.grid(row=2, column=1, padx=290)

# GUI Separator background correction
Separator(gui, orient="horizontal").grid(row=3, column=0, columnspan=2, sticky='ew', pady=5)

# background correction GUI

gamma = StringVar()

gamma_label = Label(gui, text="Gamma:          ")
gamma_label.grid(row=5, column=1, sticky="w")
gamma_entry = Entry(gui, textvariable=gamma, width=3)
gamma_entry.grid(row=5, column=1, pady=5, padx=68, sticky='w')

btn_preview_start = tButton(gui, text="Preview", command=background_check)
btn_preview_start.grid(row=5, column=1, padx=210, sticky='w')

# Gamma info button
gamma_info = "Enter Gamma value depending on the brightness of the videos.\n" \
             "Should be approximately between 0.7 and 1.3.\n" \
             "Preview button creates a short video to check whether Gamma value is appropriate."

gamma_infobutton = Button(gui, text='i', font=myFont,
                             bg='white', fg='blue', bd=0)
CreateToolTip(gamma_infobutton, text=gamma_info)
gamma_infobutton.grid(row=5, column=1, padx=290)

bg_title = Label(gui, text="Background Correction", font=myFont)
bg_title.grid(row=4, column=1, pady=10, sticky='w')

btn_bg_start = tButton(gui, text="Start", command=background_correction)
btn_bg_start.grid(row=6, column=1, sticky='w')

progressbar_bw = Progressbar(gui, length=100)
progressbar_bw.grid(row=6, column=1, sticky='w', padx=90)

bw_done = Label(gui, text="Done!", font=fileFont)

# GUI Separator skeletonize
Separator(gui, orient="horizontal").grid(row=7, column=0, columnspan=2, sticky='ew', pady=5)

# skeletonize GUI
skel_title = Label(gui, text="Skeletonize", font=myFont)
skel_title.grid(row=9, column=1, pady=5, sticky='w')

# Check info button
check_info = "Keep unchecked if starting WormRuler for the first time.\n\n" \
            "Unchecked:\n Skeletonization step will ignore videos" \
            " already skeletonized.\n" \
            " Can be useful if program was stopped in between.\n" \
            " Consider deleting last \"*_raw_lengths.txt\"" \
            " in folder.\n" \
            "Checked:\n Skeletonization will be done for all videos.\n" \
             " Can be useful if gamma value needed to be adjusted."

check_infobutton = Button(gui, text='i', font=myFont,
                            bg='white', fg='blue', bd=0)
CreateToolTip(check_infobutton, text=check_info)
check_infobutton.grid(row=9, column=1, padx=290)
check = IntVar()
skel_check = Checkbutton(gui, text="(Override existing skeletons)", variable=check)
skel_check.grid(row=9, column=1, sticky='w', padx=90)

framerate = StringVar()
framerate.set("30")

framerate_label = Label(gui, text= "Framerate:           (fps)")
framerate_label.grid(row=10, column=1, sticky="w")
framerate_entry = Entry(gui, textvariable=framerate, width=3)
framerate_entry.grid(row=10, column=1, pady=5, padx=68, sticky='w')

btn_skel_start = tButton(gui, text="Start", command=skeletonization)
btn_skel_start.grid(row=11, column=1, sticky="w")

progressbar_skel = Progressbar(gui, length=100)
progressbar_skel.grid(row=11, column=1, sticky='w', padx=90)

skel_done = Label(gui, text="Done!", font=fileFont)

# GUI Separator normalize data
Separator(gui, orient="horizontal").grid(row=12, column=0, columnspan=2, sticky='ew', pady=5)

# Normalize Data GUI
normalize_title = Label(gui, text="Normalize Data", font=myFont)
normalize_title.grid(row=13, column=1, pady=10, sticky='w')

pulse_start = StringVar()

pulse_label = Label(gui, text="Pulse-start:          (s)")
pulse_label.grid(row=14, column=1, sticky="w")
pulse_entry = Entry(gui, textvariable=pulse_start, width=3)
pulse_entry.grid(row=14, column=1, pady=5, padx=68, sticky='w')

#Entry for boundaries
lower_bound = StringVar()
lower_bound.set("0.8")

lower_bound_label = Label(gui, text="Lower boundary:       ")
lower_bound_label.grid(row=15, column=1, sticky="w")
lower_bound_entry = Entry(gui, textvariable=lower_bound, width=3)
lower_bound_entry.grid(row=15, column=1, pady=5, padx=100, sticky='w')

upper_bound = StringVar()
upper_bound.set("1.2")

upper_bound_label = Label(gui, text="Upper boundary:       ")
upper_bound_label.grid(row=15, column=1, padx=130, sticky="w")
upper_bound_entry = Entry(gui, textvariable=upper_bound, width=3)
upper_bound_entry.grid(row=15, column=1, pady=5, padx=230, sticky='w')

# Boundaries info button
bound_info = "Enter lower and upper boundaries.\n" \
             "Boundaries refer to the relative change compared to the average before pulse.\n" \
             "Values lower or higher than the set boundaries\n" \
             "are discarded from the analysis after normalization.\n" \
             "For C. elegans we suggest using 0.8 and 1.2."

bound_infobutton = Button(gui, text='i', font=myFont,
                            bg='white', fg='blue', bd=0)
CreateToolTip(bound_infobutton, text=bound_info)
bound_infobutton.grid(row=15, column=1, padx=290)

btn_normalize_start = tButton(gui, text="Normalize", command=normalize)
btn_normalize_start.grid(row=17, column=1, sticky='w')

progressbar_normalize = Progressbar(gui, length=100)
progressbar_normalize.grid(row=17, column=1, sticky='w', padx=90)

normalize_done = Label(gui, text="Done!", font=fileFont)

# GUI Separator analyze data
Separator(gui, orient="horizontal").grid(row=18, column=0, columnspan=2, sticky='ew', pady=5)

# Analyze Data GUI
data_title = Label(gui, text="Analyze Data", font=myFont)
data_title.grid(row=19, column=1, pady=10, sticky='w')

btn_data_start = tButton(gui, text="Analyze", command=data_analyis)
btn_data_start.grid(row=20, column=1, sticky='w')

progressbar_data = Progressbar(gui, length=100)
progressbar_data.grid(row=20, column=1, sticky='w', padx=90)

data_done = Label(gui, text="Done!", font=fileFont)

# GUI Separator all and close buttons
Separator(gui, orient="horizontal").grid(row=21, column=0, columnspan=2, sticky='ew', pady=10)

# GUI All-in-one button
btn_all = Button(gui, text="Start all",
                    relief='groove', activebackground='#99ccff',
                    command=run_all)
btn_all.grid(row=22, column=1, padx=90, sticky="w")

# GUI Close Window Button
btn_close = Button(gui, text="Close",
                      bg='#ff6666', relief='groove',
                      command=close)
btn_close.grid(row=22, column=1, padx=150, sticky="w")

# GUI window loop
gui.mainloop()


import asyncio
import json
import re
from logging import getLogger
from random import randrange
from uuid import uuid4

import telnyx
from aiohttp import web
from telnyx.aio import Call, Message
from telnyx.aio.util import convert_to_telnyx_object

from telnyx_2fa import settings
from telnyx_2fa.call_control import TwoFactorAuthCC

telnyx.api_key = settings.TELNYX_API_KEY
telnyx.default_http_client = telnyx.aio.http_client.TelnyxClient()

e164_re = re.compile('^\\+?[1-9]\\d{1,14}$')
phone_data_url = 'https://api.telnyx.com/v1/phone_number/{tn}'

log = getLogger()

async def _write_json(response, data):
    data = (json.dumps(data) + '\n').encode()
    await response.write(data)

class Telnyx2FApp:
    def __init__(self):
        self.sessions = {}

    def handle_cc_event(self, session_id, event_type, event):
        session = self.sessions.get(session_id)
        if session is None:
            log.debug(f'Unknown session: {session_id}')
            raise web.HTTPBadRequest()
        return session.handle_event(event_type, event)

    async def voice_2fa(self, to, token, uuid=None, language=settings.DEFAULT_LANGUAGE):
        call = await Call.create(from_=settings.VOICE_ANI, to=f'{to}',
                                 connection_id=settings.TELNYX_CONNECTION_ID)
        uuid = uuid or str(uuid4())
        sess = self.sessions[call.call_session_id] = \
            TwoFactorAuthCC(token=token,
                            language=language,
                            uuid=uuid)
        sess.create_update_leg(call)
        result = await sess.result
        del self.sessions[call.call_session_id]
        return result

class WebhookHandler:
    def __init__(self, session_class=TwoFactorAuthCC):
        self.session_class = session_class
        self.sessions = {}

    async def handle_event(self, request):
        data = (await request.json()).get('data')
        event_type = data['event_type']
        payload = data['payload']
        event = convert_to_telnyx_object(payload)
        sess_id = payload['call_session_id']
        request.app['telnyx'].handle_cc_event(sess_id, event_type, event)
        return web.json_response({'status': 'ok'})

def request_handler(f):
    """
    decorator for request handlers
    """

    def request_wrapper(self, request):
        api_key = request.headers.get('X-API-Key')
        if api_key != settings.API_KEY:
            raise web.HTTPUnauthorized()
        if 'to' not in request.query or not e164_re.match(request.query['to']):
            raise web.HTTPBadRequest(body='{"error": "To parameter must be in e164 format."}')
        return f(self, request)
    return request_wrapper

class RequestHandler:
    def __init__(self, client=None):
        self.client = client or telnyx.default_http_client

    async def is_mobile(self, tn):
        data, status, _ = await \
            self.client.request('GET', phone_data_url.format(tn=tn),
                                headers={'Accept': 'application/json'})
        if status != 200:
            raise web.HTTPServerError()
        data = json.loads(data)
        if data['carrier'].get('type') == 'mobile':
            return True
        return False

    @request_handler
    async def handle_2fa(self, request):
        to = request.query['to'].replace('+', '%2B')
        language = request.query.get('language', settings.DEFAULT_LANGUAGE)
        ret = {}
        if await self.is_mobile(to):
            token = ''.join(str(randrange(0, 9)) for i in
                            range(settings.SMS_TOKEN_DIGITS))
            ret['sms'] = {'url': settings.BASE_URL +
                          f'2fa/sms?to={to}&token={token}&language={language}',
                          'token': token}

        token = ''.join(str(randrange(0, 9)) for i in
                        range(settings.VOICE_TOKEN_DIGITS))
        ret['voice'] = {'url': settings.BASE_URL +
                        f'2fa/voice?to={to}&token={token}&language={language}',
                        'token': token}
        return web.json_response(ret)

    @request_handler
    async def handle_voice(self, request):
        to = request.query['to']
        language = request.query.get('language', settings.DEFAULT_LANGUAGE)
        token = request.query.get('token')
        if not token:
            raise web.HTTPBadRequest(body='{"error": "Missing token parameter."}')

        uuid = str(uuid4())
        response = web.StreamResponse()
        await response.prepare(request)
        await _write_json(response, {'status': 'waiting', 'uuid': uuid})

        fut = request.app['telnyx'].voice_2fa(to, token, language=language,
                                              uuid=uuid)
        to_wait = [fut]
        success = False
        err = None

        while True:
            done, to_wait = await asyncio.wait(to_wait, timeout=15)
            if done:
                try:
                    success = done.pop().result()
                except telnyx.error.TelnyxError as e:
                    err = e
                break
            await _write_json(response, {'status': 'waiting', 'uuid': uuid})

        r = {'status': 'failure', 'uuid': uuid}
        if err is not None:
            r['status'] = 'error'
            r['reason'] = f'Telnyx Error'
            r['details'] = err.errors
        elif success:
            r['status'] = 'success'

        await _write_json(response, r)
        await response.write_eof()
        return response

    @request_handler
    async def handle_sms(self, request):
        to = request.query['to']
        language = request.query.get('language', settings.DEFAULT_LANGUAGE)
        token = request.query.get('token')
        if not token:
            raise web.HTTPBadRequest(body='{"error": "Missing token parameter."}')

        v = f'SMS_MESSAGE_{language.upper().replace("-","_")}'
        text = settings.get(v, settings.DEFAULT_SMS_MESSAGE) + ' ' + token
        await Message.create(from_=settings.SMS_ANI, to=to,
                             text=text)
        return web.json_response({'status': 'ok'})

def main():
    app = web.Application()
    app['telnyx'] = Telnyx2FApp()
    webhooks = app['webhook-handler'] = WebhookHandler()
    requests = app['request-handler'] = RequestHandler()

    app.router.add_route('POST', '/event',
                         webhooks.handle_event, name='event')
    app.router.add_route('GET', '/2fa',
                         requests.handle_2fa, name='_2fa')
    app.router.add_route('GET', '/2fa/voice',
                         requests.handle_voice, name='voice')
    app.router.add_route('GET', '/2fa/sms',
                         requests.handle_sms, name='sms')
    web.run_app(app, host='0.0.0.0', port=settings.PORT)

if __name__ == '__main__':
    main()


import logging
import boto3
from botocore.exceptions import ClientError
from eks_config import  keypair_name, instance_type, Linux_image_id, Linux_subnet, Linux_sg

def create_ec2_instance( Linux_image_id, instance_type, keypair_name, Linux_subnet, Linux_sg):

    ec2_client = boto3.client('ec2')
    try:
        response = ec2_client.run_instances(
                                            ImageId=Linux_image_id,
                                            InstanceType=instance_type,
                                            KeyName=keypair_name,
                                            SubnetId=Linux_subnet,
                                            SecurityGroupIds=Linux_sg,
                                            MinCount=1,
                                            MaxCount=1)
    except ClientError as e:
        logging.error(e)
        return None
    return response['Instances'][0]

def main():

    # Set up logging
    logging.basicConfig(level=logging.DEBUG,
                        format='%(levelname)s: %(asctime)s: %(message)s')

    # Provision and launch the EC2 instance
    instance_info = create_ec2_instance(Linux_image_id, instance_type, keypair_name,Linux_subnet, Linux_sg)
    if instance_info is not None:
        logging.info(f'Launched EC2 Instance {instance_info["InstanceId"]}')
        logging.info(f'    VPC ID: {instance_info["VpcId"]}')
        logging.info(f'    Private IP Address: {instance_info["PrivateIpAddress"]}')
        logging.info(f'    Current State: {instance_info["State"]["Name"]}')

if __name__ == '__main__':
    main()


from django.contrib import admin
from django.contrib.sites.shortcuts import get_current_site

from documents.models import Document

class DocumentAdmin(admin.ModelAdmin):
	def save_model(self, request, obj, form, change):
		obj.site = get_current_site(request)
		obj.author = request.user
		obj.save()

	def queryset(self, request):
		qs = super(DocumentAdmin, self).queryset(request)
		return qs.filter(site=get_current_site(request))

admin.site.register(Document, DocumentAdmin)


from django.conf.urls import patterns, include, url
from django.contrib.auth.models import User, Group
from django.contrib import admin

from .views import ApiEndpoint
admin.autodiscover()

from rest_framework import viewsets, routers
from rest_framework import permissions
from oauth2_provider.ext.rest_framework import TokenHasReadWriteScope, TokenHasScope

# from: http://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/getting_started.html
# ViewSets define the view behavior.
class UserViewSet(viewsets.ModelViewSet):
    permission_classes = [permissions.IsAuthenticated, TokenHasReadWriteScope]
    model = User

class GroupViewSet(viewsets.ModelViewSet):
    permission_classes = [permissions.IsAuthenticated, TokenHasScope]
    required_scopes = ['groups']
    model = Group

# Routers provide an easy way of automatically determining the URL conf
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)

urlpatterns = patterns('',
    # Login/logout
    url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
    url(r'^accounts/logout/$', 'django.contrib.auth.views.logout'),

    # default pages
    url(r'^$', 'bbp.views.home', name='home'),
    url(r'^about/$', 'bbp.views.about', name='about'),
    url(r'^faq/$', 'bbp.views.faq', name='faq'),
    url(r'^contact/$', 'bbp.views.contact', name='contact'),
    url(r'^terms/$', 'bbp.views.terms', name='terms'),
    url(r'^privacy/$', 'bbp.views.privacy', name='privacy'),

    # Link in subsidiary modules
    url(r'^device/', include('device.urls', namespace='device')),
    url(r'^member/', include('bbp.member.urls', namespace='member')),

    # API test -(login_required)
    url(r'^secret$', 'bbp.views.secret_page', name='secret'),
    # http://django-oauth-toolkit.readthedocs.org/en/latest/tutorial/tutorial_03.html

    # OAuth2 Provider
    # url(r'^oauth2/', include('provider.oauth2.urls', namespace = 'oauth2')),

    # OAuth Provider
    # http://django-oauth-toolkit.readthedocs.org/en/latest/tutorial/tutorial_01.html
    url(r'^o/', include('oauth2_provider.urls', namespace='oauth2_provider')), # look ma, I'm a provider!
    url(r'^api/hello', ApiEndpoint.as_view()),  # and also a resource server!

    # API
    url(r'^1.0/api/', include(router.urls)),

    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
)


# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /home/vagrant/envs/conversocial/lib/python2.7/site-packages/shardmonster/tests/test_sharder.py
# Compiled at: 2016-06-16 06:14:05
from mock import Mock
from shardmonster import api, sharder
from shardmonster.tests.base import ShardingTestCase

class TestSharder(ShardingTestCase):

    def setUp(self):
        api.activate_caching(0.5)
        super(TestSharder, self).setUp()

    def tearDown(self):
        api.activate_caching(0)
        super(TestSharder, self).tearDown()

    def test_basic_copy(self):
        api.set_shard_at_rest('dummy', 1, 'dest1/test_sharding')
        doc1 = {'x': 1, 'y': 1}
        doc1['_id'] = self.db1.dummy.insert(doc1)
        api.start_migration('dummy', 1, 'dest2/test_sharding')
        manager = Mock(insert_throttle=None)
        sharder._do_copy('dummy', 1, manager)
        doc2, = self.db2.dummy.find({})
        self.assertEquals(doc1, doc2)
        return

    def test_sync_after_copy(self):
        api.set_shard_at_rest('dummy', 1, 'dest1/test_sharding')
        api.start_migration('dummy', 1, 'dest2/test_sharding')
        doc1 = {'x': 1, 'y': 1}
        doc1['_id'] = self.db1.dummy.insert(doc1)
        self.db2.dummy.insert(doc1)
        initial_oplog_pos = sharder._get_oplog_pos('dummy', 1)
        self.db1.dummy.update({'x': 1}, {'$inc': {'y': 1}})
        api.set_shard_to_migration_status('dummy', 1, api.ShardStatus.MIGRATING_SYNC)
        sharder._sync_from_oplog('dummy', 1, initial_oplog_pos)
        doc2, = self.db2.dummy.find({})
        self.assertEquals(2, doc2['y'])

    def test_delete_after_migration(self):
        api.set_shard_at_rest('dummy', 1, 'dest1/test_sharding')
        api.start_migration('dummy', 1, 'dest2/test_sharding')
        doc1 = {'x': 1, 'y': 1}
        doc1['_id'] = self.db1.dummy.insert(doc1)
        self.db2.dummy.insert(doc1)
        api.set_shard_to_migration_status('dummy', 1, api.ShardStatus.POST_MIGRATION_DELETE)
        manager = Mock(delete_throttle=None)
        sharder._delete_source_data('dummy', 1, manager)
        self.assertEquals(0, self.db1.dummy.find({}).count())
        doc1_actual, = self.db2.dummy.find({})
        self.assertEquals(doc1, doc1_actual)
        return

    def test_sync_ignores_other_collection(self):
        api.set_shard_at_rest('dummy', 1, 'dest1/test_sharding')
        api.start_migration('dummy', 1, 'dest2/test_sharding')
        doc1 = {'x': 1, 'y': 1}
        doc1['_id'] = self.db1.dummy.insert(doc1)
        self.db2.dummy.insert(doc1)
        initial_oplog_pos = sharder._get_oplog_pos('dummy', 1)
        self.db1.other_coll.insert(doc1)
        self.db1.other_coll.update({'x': 1}, {'$inc': {'y': 1}})
        api.set_shard_to_migration_status('dummy', 1, api.ShardStatus.MIGRATING_SYNC)
        sharder._sync_from_oplog('dummy', 1, initial_oplog_pos)
        doc2, = self.db2.dummy.find({})
        self.assertEquals(1, doc2['y'])

    def test_sync_uses_correct_connection(self):
        """This tests for a bug found during a rollout. The connection for the
        metadata was assumed to be the same connection as the source data was
        going to be coming from. This is *not* always the case.
        """
        api.set_shard_at_rest('dummy', 1, 'dest2/test_sharding')
        api.start_migration('dummy', 1, 'dest1/test_sharding')
        doc1 = {'x': 1, 'y': 1}
        doc1['_id'] = self.db1.dummy.insert(doc1)
        self.db2.dummy.insert(doc1)
        initial_oplog_pos = sharder._get_oplog_pos('dummy', 1)
        self.db2.dummy.update({'x': 1}, {'$inc': {'y': 1}})
        api.set_shard_to_migration_status('dummy', 1, api.ShardStatus.MIGRATING_SYNC)
        sharder._sync_from_oplog('dummy', 1, initial_oplog_pos)
        doc2, = self.db1.dummy.find({})
        self.assertEquals(2, doc2['y'])


import os
import numpy as np
from PIL import Image

from . import matrixGame

class TextScroll(matrixGame.MatrixGame):

    def __init__(self, text, text_colour=[255, 255, 255], back_colour=[0, 0, 0], scroll_speed=.1, font='tahoma.fnt'):
        super(TextScroll, self).__init__()
        self._load_font('fonts', font)

        self._coloured_pixels = []
        self.i = 0
        self.scroll_speed = scroll_speed
        self.passed_time = 0

        self._show_message(text, text_colour, back_colour)

    ####
    # Text assets
    ####

    def _load_font(self, path, filename):
        atlas = self._load_glyph_atlas(os.path.join(path, filename))
        image_file = atlas['page'][0]['file']
        img = Image.open(os.path.join(path, image_file)).convert('RGB')
        pix = img.load()
        self._text_dict = {}
        for c in atlas['char']:
            char_info = atlas['char'][c]
            char = []

            for y in range(int(char_info['y']), int(char_info['y'] + char_info['height'])):
                line = []
                for x in range(int(char_info['x']), int(char_info['x'] + char_info['width'])):
                    line.append(pix[x, y])
                char.append(line)
            self._text_dict[c] = np.rot90(char, -1).reshape(-1, 3)

        return img

    # loads a BMFont Text format glyph atlas into a dictionary
    # see https://71squared.com/blog/bitmap-font-file-format for more info
    @staticmethod
    def _load_glyph_atlas(filename):
        atlas = {}
        for line in open(filename):
            attributes = line.split(" ")
            attributes = [x for x in attributes if x != '' and x != '\n']
            dictkey = attributes[0]
            if dictkey in atlas:
                attribdict = atlas[dictkey]
            else:
                attribdict = atlas[dictkey] = {}
            if dictkey in ['char', 'page']:
                c = int(attributes[1].split("=")[1])
                entry = {}
                for attrib in attributes[2:]:
                    key, value = attrib.split("=")
                    try:
                        entry[key] = float(value)
                    except:
                        entry[key] = value.strip('\"\n')
                    attribdict[c] = entry
            else:
                for attrib in attributes[1:]:
                    key, value = attrib.split("=")
                    try:
                        attribdict[key] = float(value)
                    except ValueError:
                        strval = value.strip('\"\n')
                        if ',' in strval:
                            arry = strval.split(',')
                            try:
                                arry = map(float, arry)
                            finally:
                                attribdict[key] = arry
                        else:
                            attribdict[key] = strval
        return atlas

    def _get_char_pixels(self, s):
        """
        Internal. Safeguards the character indexed dictionary for the
        show_message function below
        """

        if len(s) == 1 and ord(s) in self._text_dict.keys():
            return list(self._text_dict[ord(s)])
        else:
            return list(self._text_dict[-1])

    def _show_message(
            self,
            text_string,
            text_colour,
            back_colour
    ):
        """
        Scrolls a string of text across the LED matrix using the specified
        speed and colours
        """
        dummy_colour = [0, 0, 0]
        string_padding = [dummy_colour] * self.PIXELS * self.PIXELS
        letter_padding = [dummy_colour] * self.PIXELS
        # Build pixels from dictionary
        scroll_pixels = []
        scroll_pixels.extend(string_padding)
        for s in text_string:
            #scroll_pixels.extend(self._trim_whitespace(self._get_char_pixels(s)))
            scroll_pixels.extend(self._get_char_pixels(s))
            scroll_pixels.extend(letter_padding)
        scroll_pixels.extend(string_padding)
        # Recolour pixels as necessary
        self._coloured_pixels = [
            [(text_colour[0] * pixel[0] / 255) + (back_colour[0] * (255-pixel[0]) / 255),
             (text_colour[1] * pixel[1] / 255) + (back_colour[1] * (255-pixel[1]) / 255),
             (text_colour[2] * pixel[2] / 255) + (back_colour[2] * (255-pixel[2]) / 255)]
            for pixel in scroll_pixels
            ]

    def update(self, passed_time):
        self.passed_time += passed_time
        if self.passed_time > self.scroll_speed * 1000:
            self.i += 1
            self.passed_time -= self.scroll_speed * 1000

        previous_rotation = self.rotation
        self.rotation -= 90

        # Shift right by 16 pixels per frame to scroll
        scroll_length = len(self._coloured_pixels) // self.PIXELS
        if self.i > scroll_length - self.PIXELS:
            self.i = 0

        start = self.i * self.PIXELS
        end = start + (self.PIXELS * self.PIXELS)
        self.set_pixels(self._coloured_pixels[start:end])
        self._rotation = previous_rotation


import torch
from torch import nn
import torch.nn.functional as F
from torch import optim
from torchvision import datasets, transforms
from torch.autograd import Variable
from torchvision import models

# model = models.densenet201(pretrained=True)

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.conv2_drop = nn.Dropout2d()
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

        # Initialize params.
        for name, param in self.named_parameters():
            if 'bias' not in name:
                nn.init.kaiming_normal(param)
            else:
                nn.init.constant(param, 0)

    def forward(self, x):
        x = x.view(-1, 1, 28, 28)
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = self.fc2(x)
        return F.log_softmax(x)

class Q(nn.Module):
    def __init__(self):
        super(Q, self).__init__()
        self.fc1 = nn.Linear(20, 10)
        self.fc2 = nn.Linear(10, 5)
        self.fc3 = nn.Linear(5, 1)

        # Initialize params.
        for name, param in self.named_parameters():
            if 'bias' not in name:
                nn.init.kaiming_normal(param)
            else:
                nn.init.normal(param, 0, 1)

    def forward(self, x):
        # print(x)
        x = x.view(-1, 20)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, training=self.training)
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return F.relu(x)


import heapq
import collections
import numpy as np
import matplotlib.pyplot as plt
import os
from sklearn.model_selection import train_test_split
from natsort import natsorted
from PIL import Image

traindata_img = os.listdir(r'001.Black_footed_Albatross_img')
traindata_img2 = natsorted(traindata_img)
print(traindata_img2)
trainlen = []
trainlen6 = []

"""
for i in traindata2:
    datafile = '0/' + i
    num_lines = sum(1 for line in open(datafile))
    if num_lines == 6:
        root, ext = os.path.splitext(i)
        trainlen6.append(root)
        print("aaaaaaaaa")

"""

train = []
count = 0
#  訓練とテストのデータセット用意
for f in traindata_img2:
    #root, ext = os.path.splitext(f)
    img = np.array(Image.open(
        '001.Black_footed_Albatross_img/' + f), dtype='float32')
    img = img / 255
    img = img.astype('float32')
    img = img.transpose(2, 0, 1)
    print(img.shape)
    for i in range(10):
        train.append(img)

    """
    if root in trainlen6:
        for i in range(6):
            train.append(img)
    else:
        for i in range(5):
            train.append(img)
    """
    print(count)
    count = count + 1

    #img = img.transpose(2,0,1)
train = np.array(train,dtype = 'float32')
print(train.shape)
print(train[0])
np.save("birds_img",train)


import pytest

from .jtrace import *

@pytest.mark.parametrize('region_start, word_size', [pytest.param(0x08000000, 0x20000)])
def test_l2_sram_is_initialized_to_zero(probe, boot_elf, region_start, word_size):
    """
    check if each region of the L2 SRAM memory is initialized to zero after reset
    """
    probe_setup_breakpoints(probe, addresses=(boot_elf.get_symbol('ram_init').address,
                                              boot_elf.get_symbol('test_point_startup_30').address,))
    unexpected = [address * 4 for address in range(word_size)]
    probe.reset(halt=False)
    probe_wait_halt(probe)
    probe.memory_write32(region_start, unexpected)
    probe.restart(skip_breakpoints=True)
    probe_wait_halt(probe)
    actual = probe.memory_read32(region_start, len(unexpected))
    for word in actual:
        assert word == 0


from datetime import datetime
import json
import uuid
import requests  # http://docs.python-requests.org/en/master/
from django.conf import settings
from tworaven_apps.utils.view_helper import \
    (get_request_body_as_json,
     get_json_error,
     get_json_success)
from tworaven_apps.utils.basic_response import (ok_resp,
                                                err_resp,
                                                err_resp_with_data)

class GetDataSetFileInfo(object):

    def __init__(self):
        """ to get the JSON representation of the dataset"""
        self.status_code = None
        self.res = None
        dataverse_server = settings.DATAVERSE_SERVER  # no trailing slash
        persistentId = settings.DATASET_PERSISTENT_ID  # doi or hdl of the dataset

        # Get JSON Representation of a Dataset
        publish_url = '%s/api/datasets/:persistentId/?persistentId=%s'% (dataverse_server,
                                                                        persistentId)

        print('-' * 40)
        print('making request: %s' % publish_url)
        r = requests.get(publish_url)

        # -------------------
        # Print the response
        # -------------------
        print('-' * 40)
        # print(r.json())
        # print(r.status_code)
        self.status_code = r.status_code
        if r.status_code == 200:
            self.res = r.json()
        else:
            self.res = None

    def return_status(self):
        if self.res is None:
            return err_resp(self.res)
        else:
            # print("The response we are looking for ", self.res)
            return ok_resp(self.res)

    def get_dataset_id(self):
        """ return dataset Id from the Info"""
        if self.status_code == 200:
            dataset_id = self.res['data']['id']
            print("dataset ID ", dataset_id)
            return ok_resp(dataset_id)
        else:
            return err_resp(self.res)

    def get_version_id(self):
        """ return version ID"""
        if self.status_code == 200:
            # print("The dataset file info :  ", self.res)
            version_id = self.res['data']['latestVersion']['id']
            # print("version ID", version_id)
            return ok_resp(version_id)
        else:
            return err_resp(self.res)

    def get_version_number(self):
        """return latest version number"""
        if self.status_code == 200:
            # print("The dataset file info for version number :  ", self.res)
            version_number = self.res['data']['latestVersion']['versionNumber']
            print("version number", version_number)
            return ok_resp(version_number)
        else:
            return err_resp(self.res)


import os
import sys
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager

def init_db(app):
	# ORM 框架
	# sqlite 的写法  sqlite:////数据库文件的绝对地址（Linux）  sqlite:///数据库文件的绝对地址 （windows）
	WIN = sys.platform.startswith('win')
	if WIN:  # 如果是 Windows 系统，使用三个斜线
		prefix = 'sqlite:///'
	else:  # 否则使用四个斜线
		prefix = 'sqlite:////'
	app.config['SQLALCHEMY_DATABASE_URI'] = prefix + os.path.join(app.root_path, 'db/data.db')
	app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 关闭对模型修改的监控
	db = SQLAlchemy(app)  # 初始化扩展，传入程序实例 app
	return db

app = Flask(__name__)
app.secret_key = "adfaksdhfk^&*^(%&^%"
db = init_db(app)

login_manager = LoginManager(app)  # 实例化扩展类
login_manager.login_view = 'login'   # 登录视图端点（函数名）

# 用户加载回调函数
@login_manager.user_loader
def load_user(user_id):  # 创建用户加载回调函数，接受用户 ID 作为参数
	user = User.query.get(int(user_id))  # 用 ID 作为 User 模型的主键查询对应的用户
	return user   # 返回用户对象

@app.context_processor
def now_user():  # 函数名可以随意修改
	"""
	这个函数返回的变量（以字典键值对的形式）将会统一注入到每一个模板的上下文环境中，因此可以直接在模板中使用
	:return:
	"""
	user = User.query.first()

	return dict(user=user.name)  # 需要返回字典，等同于return {'user': user}

# 为了避免循环依赖（A 导入 B，B 导入 A），我们把这一行导入语句放到构造文件的结尾

from watchurls.models import User, Website
from watchurls import views, errors