# -*- coding: utf-8 -*-
"""
Created on Fri Dec  7 16:10:13 2018

@author: Silence
"""
import tensorflow as tf
from tensorflow.contrib import image
from tensorflow.python.ops import math_ops
import matplotlib.pyplot as plt
import math
import csv
import random
from PIL import Image
PI = math.pi

def getRotatePoint(map_shape, rotate_center, rotate_theta, origin_point):
    """
    实现功能，得到绕旋转中心旋转theta角度后的坐标
    :param map_shape:原始地图的尺寸，因为Image中的坐标原点在图片左上角，需要改变坐标系    Tensor-[height,width,channel]
    :param rotate_center:旋转中心   Tensor-[loc_x,loc_y]
    :param rotate_theta:旋转角度   Tensor-[theta]
    :param origin_point:需要进行旋转操作的点集 Tensor-[loc_x,loc_y]
    :return: rotate_point_list: Tensor-[loc_x,loc_y]
    """
    row = map_shape[0]
    center_x = rotate_center[0]
    center_y = row - rotate_center[1]
    point_x = origin_point[0]
    point_y = row - origin_point[1]

    after_rotate_x = math_ops.round(
        (point_x - center_x) * math_ops.cos(rotate_theta) - (point_y - center_y) * math_ops.sin(
            rotate_theta) + center_x)
    after_rotate_y = row - math_ops.round(
        (point_x - center_x) * math_ops.sin(rotate_theta) + (point_y - center_y) * math_ops.cos(
            rotate_theta) + center_y)
    rotate_point = [after_rotate_x, after_rotate_y]
    rotate_point = tf.reshape(rotate_point, [2])
    return rotate_point

def pointLegalCheck(map_shape, point, box_shape):
    """
    检测旋转后的点是否越界
    :param map_shape: 原始地图大小Tensor-[height,width,channel]
    :param point: 旋转后的点集Tensor-[4,2]
    :param box_shape: 裁剪图片区域的大小Tensor-[2]
    :return: 合法性检测后的点集
    """
    x_move_list = []
    y_move_list = []
    map_shape = tf.cast(map_shape, tf.float32)
    # 依次计算四个顶点与地图边界的偏移大小
    for i in range(4):
        x_move = tf.cond(tf.less(point[i][0], 0.0),
                         true_fn=lambda: 0.0 - point[i][0],  # 若坐标小于零，则需要向正方向移动
                         false_fn=lambda: tf.cond(tf.less(map_shape[1], point[i][0]),
                                                  # 若坐标大于地图边界，则需要向负方向移动
                                                  true_fn=lambda: map_shape[1] - point[i][0],
                                                  false_fn=lambda: 0.0  # 坐标在地图中无需移动
                                                  )
                         )
        y_move = tf.cond(tf.less(point[i][1], 0.0),
                         true_fn=lambda: 0.0 - point[i][1],
                         false_fn=lambda: tf.cond(tf.less(map_shape[0], point[i][1]),
                                                  true_fn=lambda: map_shape[0] - point[i][1],
                                                  false_fn=lambda: 0.0
                                                  )
                         )
        x_move_list.append(x_move)
        y_move_list.append(y_move)

    # 依据四个顶点的偏移，得到坐标的修正值
    x_move = getPixelMove(tf.reshape(x_move_list, [4]))
    y_move = getPixelMove(tf.reshape(y_move_list, [4]))

    # 得到修正后的四个顶点坐标
    point_x = tf.add(point[:, 0], x_move)
    point_y = tf.add(point[:, 1], y_move)
    point = tf.stack([point_x, point_y], 1)
    return point

def getPixelMove(move_list):
    """
    pointLegalCheck的附加函数，返回最大的绝对值位移
    :param move_list: 四个角点与是否越界检测得到的与图片的差值 Tensor-[4]
    :return: max_move 最大位移 Tensor-[1]
    """
    move_max = tf.argmax(move_list)
    move_min = tf.argmin(move_list)
    max_move_index = tf.cond(tf.less(tf.abs(move_min), move_max),
                             true_fn=lambda: move_max,
                             false_fn=lambda: move_min
                             )
    max_move = move_list[max_move_index]
    return max_move

def mapCut(map_data, particle_map_length, old_partcile_states, new_particle_states):
    """
    给定前后坐标，根据运动方向旋转并裁剪地图，得到基于当前坐标的局部地图
    :param map_data: 原始地图数据 Tensor[height,width,channel=3] int
    :param particle_map_length: 局部地图的形状大小，默认正方形 Tensor[1] float32
    :param old_partcile_states: 前一时刻的坐标 Tensor[2](loc_x,loc_y) float32
    :param new_particle_states: 当前时刻的坐标 Tensor[2](loc_x,loc_y) float32
    :return: particle_map 基于运动方向的局部地图 Tensor[height,width,channel=3] float32
    """
    particle_map_length = particle_map_length
    map_shape = tf.shape(map_data)[0:]
    map_shape = tf.cast(map_shape, tf.float32)

    # 计算前后坐标的变化量，并以此计算运动向量的角度temp_theta
    dis = (tf.subtract(new_particle_states[1], old_partcile_states[1]),
           tf.subtract(new_particle_states[0], old_partcile_states[0]))
    temp_theta = tf.to_float(math_ops.atan2(dis[1], dis[0]))

    # 计算围绕在新坐标周围的，没有经过旋转的局部地图的四个顶点坐标
    top_left_point = [new_particle_states[0] - particle_map_length / 2,
                      new_particle_states[1] - particle_map_length / 2]
    top_right_point = [new_particle_states[0] + particle_map_length / 2,
                       new_particle_states[1] - particle_map_length / 2]
    bottom_left_point = [new_particle_states[0] - particle_map_length / 2,
                         new_particle_states[1] + particle_map_length / 2]
    bottom_right_point = [new_particle_states[0] + particle_map_length / 2,
                          new_particle_states[1] + particle_map_length / 2]

    # 计算四个顶点坐标旋转后得到的新坐标
    new_top_left_point = getRotatePoint(map_shape, new_particle_states, temp_theta, top_left_point)
    new_top_right_point = getRotatePoint(map_shape, new_particle_states, temp_theta, top_right_point)
    new_bottom_left_point = getRotatePoint(map_shape, new_particle_states, temp_theta, bottom_left_point)
    new_bottom_right_point = getRotatePoint(map_shape, new_particle_states, temp_theta, bottom_right_point)
    new_point = tf.reshape([new_top_left_point, new_top_right_point, new_bottom_left_point, new_bottom_right_point],
                           [4, 2])

    # 计算四个新坐标的横纵坐标之差的极值，该极值构成了能完整圈住旋转后的局部地图的大矩形的shape
    new_shape_x = tf.cast(new_point[tf.argmax(new_point[:, 0], 0), 0] - new_point[tf.argmin(new_point[:, 0], 0), 0],
                          tf.int32)
    new_shape_y = tf.cast(new_point[tf.argmax(new_point[:, 1], 0), 1] - new_point[tf.argmin(new_point[:, 1], 0), 1],
                          tf.int32)

    # 对四个新坐标的合法性进行判断，使其不会越出地图的边界
    new_point = pointLegalCheck(map_shape, new_point, [new_shape_x, new_shape_y])

    # 计算该大矩形的左上顶点坐标，依据大矩形的左上顶点坐标切割地图
    new_corner_x = tf.cast(new_point[tf.argmin(new_point[:, 0], 0), 0], tf.int32)
    new_corner_y = tf.cast(new_point[tf.argmin(new_point[:, 1], 0), 1], tf.int32)
    map_cut = tf.image.crop_to_bounding_box(map_data, offset_height=new_corner_y,
                                            offset_width=new_corner_x,
                                            target_height=new_shape_y,
                                            target_width=new_shape_x)

    # 反向旋转切割后的地图，使原本的运动方向与坐标轴方向（Y轴正方向）平行
    map_rotate = image.rotate(map_cut, -1.0 * temp_theta)

    # 计算位于居中的，我们最终需要的particle_map_length大小的局部地图的左上顶点，进行第二次切割
    particle_map_length = tf.to_int32(particle_map_length)
    temp_corner_width = tf.cast(tf.div(tf.subtract(new_shape_x, particle_map_length), 2), tf.int32)
    temp_corner_height = tf.cast(tf.div(tf.subtract(new_shape_y, particle_map_length), 2), tf.int32)
    particle_map = tf.image.crop_to_bounding_box(map_rotate, offset_height=temp_corner_height,
                                                 offset_width=temp_corner_width,
                                                 target_height=particle_map_length,
                                                 target_width=particle_map_length)
    return particle_map

origin_path = "map.jpg"
local_map_size = 100.0
ephochs = 10
int_local_map_size = int(local_map_size)
middle = 50
length = 5.0

f = open('label.csv', 'a+', newline='')
data_path = 'data/'
csv_write = csv.writer(f, dialect='excel')

for i in range(ephochs):
    tf.reset_default_graph()
    graph = tf.Graph()
    with graph.as_default() as g:
        file = tf.read_file(origin_path)
        map_data = tf.image.decode_image(file, channels=3)
        map_data = tf.cast(map_data, tf.float64)
        a = random.uniform(290, 570)
        b = random.uniform(288, 2029)
        theta = random.uniform(0.1, 3.0)

        old_particle_state = [a, b]
        new_particle_state = [a + length * math.cos(theta), b + length * math.sin(theta)]
        old_particle_state = tf.convert_to_tensor(old_particle_state)
        new_particle_state = tf.convert_to_tensor(new_particle_state)
        part_map = mapCut(map_data, local_map_size, old_particle_state, new_particle_state)

        with tf.Session(graph=g) as sess:
            index = 100
            trans_image = sess.run(part_map)
            for column in range(int_local_map_size):
                if(trans_image[column][middle][0]+trans_image[column][middle][1]+trans_image[column][middle][2]<600.0):
                    index = column
                    break
            im = Image.fromarray(trans_image.astype('uint8')).convert('RGB')
            im.thumbnail([100, 100])
            im.save('data/'+str(i) + ".png")
            csv_write.writerow([str(i), str(old_particle_state[0].eval()), str(old_particle_state[1].eval()), str(new_particle_state[0].eval()),
                                    str(new_particle_state[1].eval()),str(int(index/10))])
f.close()


#
# @lc app=leetcode.cn id=111 lang=python3
#
# [111] 二叉树的最小深度
#

# @lc code=start
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def minDepth(self, root: TreeNode) -> int:
        # 方法一
        """
        这道题的关键是搞清楚递归结束条件

        叶子节点的定义是左孩子和右孩子都为 null 时叫做叶子节点
        当 root 节点左右孩子都为空时，返回 1
        当 root 节点左右孩子有一个为空时，返回不为空的孩子节点的深度
        当 root 节点左右孩子都不为空时，返回左右孩子较小深度的节点值
        """
        # if not root:
        #     return 0
        # d = list(map(self.minDepth, (root.left, root.right))) if root else [-1]
        # return 1 + (min(d) or max(d))
        # 方法二：递归法：深度优先
        """
        最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

        说明: 叶子节点是指没有子节点的节点。
        递归法
        节点不存在时，返回0
        左右子节点均不存在时，说明该节点为叶子节点，返回1
        左右子节点存在一个时，返回1+minDepth(子节点)
        左右子节点均存在时，返回1+较小的minDepth(子节点)

        """

        # if not root:
        #     return 0
        # l, r = self.minDepth(root.left), self.minDepth(root.right)
        # # 左右孩子都不为空，返回最小深度+1即可
        # if root.left and root.right:
        #     return 1 + min(l, r)
        # else:
        #     return 1 + l + r
            # 这里其中一个节点为空，说明m1和m2有一个必然为0，所以可以返回l + r + 1;

        # 方法三：广度优先：BFS
        # 当我们找到一个叶子节点时，直接返回这个叶子节点的深度。
        # 广度优先搜索的性质保证了最先搜索到的叶子节点的深度一定最小
        # 时间复杂度，O(n)，因为每个节点访问一次 其实就类似于一个前序遍历
        if not root:
            return 0
        from collections import deque
        que = deque([(root, 1)])
        while que:
            # print("que = ", que)
            node, depth = que.popleft()
            if not node.left and not node.right:
                return depth
            if node.left:
                que.append((node.left, depth + 1))
            if node.right:
                que.append((node.right, depth + 1))

        return 0

# @lc code=end

111.二叉树的最小深度.py


import torch
from torchvision import transforms
# from dataloader import get_loader
from train3 import Trainer
from ILSVRC_loader import get_loader
#from eval import Eval
import argparse
import os

def main(config):
    # train_transform = transforms.Compose([transforms.ToTensor()])
    # test_transform = transforms.Compose([transforms.ToTensor()])
    # trainloader = get_loader('train', train_transform)
    # testloader = get_loader('test', test_transform)
    # trainer = Trainer(trainloader, testloader)
    #trainer.train_classifier()
    #trainer.train_adversarial()
    # trainer.evaluation()
    trainloader, testloader = get_loader(config)
    trainer = Trainer(trainloader, testloader, config)
    # trainer.train_classifier(config)
    # trainer.train_conv_mask(config)
    trainer.train_adversarial(config)
    # elif config.mode == 'sample':

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='PyTorch ImageNet Training')
    parser.add_argument('--data', default='/home/mipal/psw_exp/exp_adv/NoiseGAN/imagenet50', type=str,
                        metavar='DIR',
                        help='path to dataset')
    parser.add_argument('-j', '--workers', default=3, type=int, metavar='N',
                        help='number of data loading workers (default: 4)')
    parser.add_argument('--epochs', default=90, type=int, metavar='N',
                        help='number of total epochs to run')
    parser.add_argument('--start-epoch', default=0, type=int, metavar='N',
                        help='manual epoch number (useful on restarts)')
    parser.add_argument('-b', '--batch-size', default=20, type=int,
                        metavar='N', help='mini-batch size (default: 256)')
    parser.add_argument('--lr', '--learning-rate', default=0.1, type=float,
                        metavar='LR', help='initial learning rate')
    parser.add_argument('--momentum', default=0.9, type=float, metavar='M',
                        help='momentum')
    parser.add_argument('--weight-decay', '--wd', default=1e-4, type=float,
                        metavar='W', help='weight decay (default: 1e-4)')
    parser.add_argument('--print-freq', '-p', default=10, type=int,
                        metavar='N', help='print frequency (default: 10)')
    parser.add_argument('--resume', default='', type=str, metavar='PATH',
                        help='path to latest checkpoint (default: none)')
    parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true',
                        help='evaluate model on validation set')
    parser.add_argument('--pretrained', dest='pretrained', action='store_true',
                        help='use pre-trained model')
    args = parser.parse_args()
    main(args)


# -*- coding:UTF-8 -*-
import tornado.web
from handlers.handler import BaseHandler
from database.models import db_Session
from services.paramsManager.roleManager import *
import json
import logging

###状态码:-1 失败，异常  0 成功，正常  1 提示##

class RoleManagerHandler(BaseHandler):
    @tornado.web.authenticated
    async def get(self):
        self.render('paramsManager/roleManage/roleManager.html')

    @tornado.web.authenticated
    async def post(self):
        page = int(self.get_argument('page'))
        limit = int(self.get_argument('limit'))
        roleType = self.get_argument('roleType', None)
        db = db_Session()
        count, data = await getRoles(db, page, limit, roleType)
        db.commit()
        db.close()
        self.write(json.dumps({"code": 0, "msg": "", "count": count, "data": data}))

class OpenRoleQueryHandler(BaseHandler):
    @tornado.web.authenticated
    async def post(self):
        roleType = self.get_argument('roleType', None)
        self.render('paramsManager/roleManage/query.html', roleType=roleType)

class OpenAddRoleHandler(BaseHandler):
    @tornado.web.authenticated
    async def post(self):
        db = db_Session()
        status = await getAddRoleParams(db)
        self.render('paramsManager/roleManage/addRole.html', status=status)
        db.commit()
        db.close()

class SaveRoleHandler(BaseHandler):
    @tornado.web.authenticated
    async def post(self):
        name = self.get_argument('name', None)
        roleType = self.get_argument('roleType', None)
        db = db_Session()
        try:
            status, msg = await addRole(db, name, roleType)
            db.commit()
            self.write({'status': status, 'msg': msg})
        except Exception as e:
            db.rollback()
            self.write({'status': -1, 'msg': '角色添加失败，请重试'})
        finally:
            db.close()

class OpenRoleSetHandler(BaseHandler):
    @tornado.web.authenticated
    async def post(self):
        id = self.get_argument('id', None)
        db = db_Session()
        role, parents, childs = await getRoleSet(db, id)
        self.render("paramsManager/roleManage/changeRole.html", role_type=role.role_type, parents=parents,
                    childs=childs)
        db.commit()
        db.close()

class RoleSetHandler(BaseHandler):
    @tornado.web.authenticated
    async def post(self):
        id = self.get_argument('id', None)
        roles = self.get_argument('roles', None)
        db = db_Session()
        try:
            status, msg = await setRole(db, id, roles)
            db.commit()
            self.write({'status': status, 'msg': msg})
        except Exception as e:
            db.rollback()
            logging.error(e)
            self.write({'status': -1, 'msg': '权限修改失败，请重试'})
        finally:
            db.close()


#!/data/exec/python/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019/11/28 9:46
# @Author  : YuZhiYi
# @Email   : yuzhiyi@54.com
import sys

from elasticsearch import Elasticsearch

# 系统传入参数 [索引名,字段名,字段值,查询间隔]
# 返回的输出是 匹配的结果数
# 用于后续zabbix中日志监控脚本

def es_log_count_search(idx,key,value,interval="1h"):
    '''
    :param idx: 索引名
    :param key:  查询字段
    :param value:  匹配的值
    :param interval:  查询的时间周期
    :return:
    '''
    es = Elasticsearch(['ops-es.00joy.com'], scheme='https', port=443)
    body = {
        "query": {
            "bool": {
                "must": [
                    {"match": {key: value}},
                    # {"match": {"content": "Elasticsearch"}}
                ],
                "filter": [
                    {"range": {"@timestamp": {
                        # "gte": "2019-11-21T00:00:00.000+0800",
                        # "lt": "2018-06-15T13:00:00.000+0800"
                        "gt": "now-" + interval
                        # "gt": "2014-01-01 00:00:00",
                        # "lt": "2014-01-01 00:00:00||+1M"     #加一个月
                    }}}
                ]
            }
        }
    }
    # ret = es.search(index='loginprocess', )
    ret = es.count(index=idx, body=body)
    print(ret['count'])

# ret = es.search(index='loginprocess', body=body,size=100)
# pprint.pprint(ret)
# for i in ret['hits']['hits']:
#     print(i)

if __name__ == '__main__':
    idx = sys.argv[1]
    key = sys.argv[2]
    value =sys.argv[3]
    interval = sys.argv[4]
    es_log_count_search(idx,key,value,interval)
    # es_log_count_search('loginprocess', "channel_id", "116", "24h")


from lib.utils import stems
from lib.tfidf import TfidfModel
from lib.doc2vec import Doc2Vec
from lib.word2vec import Word2Vec
from lib.text_tiling import TextTiling
from lib import utils
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

import datetime
import sys

if __name__ == '__main__':
    args = sys.argv
    if 2 <= len(args):
        if not(args[1] == 'tfidf' or args[1] == 'doc2vec' or args[1] == 'word2vec'):
            print('Argument is invalid')
            exit()
    else:
        print('Arguments are too sort')
        exit()

    model_type = args[1]

    # docs: インタビュー全体
    # 文章番号
    doc_num = '01'
    print('Load data')
    path = './data/interview-text_01-26_' + doc_num + '.txt'
    # path = './data/interview-text_01-26_all.txt'
    data = utils.load_data(path)
    print('Done')

    if model_type == 'tfidf':
        # TFIDFモデル
        model = TfidfModel(no_below=10, no_above=0.1, keep_n=100000)
        model.load_model()
    elif model_type == 'doc2vec':
        model = Doc2Vec(alpha=0.025, min_count=10, vector_size=300, epochs=50, workers=4)
        # model.load_model('./model/doc2vec/doc2vec_' + str(model.vector_size) + '.model')
        # model.load_model('./model/doc2vec/doc2vec_wiki.model')
        model.load_model('./model/doc2vec/updated_doc2vec_300.model')
    elif model_type == 'word2vec':
        model = Word2Vec(alpha=0.025, min_count=10, vector_size=200, epochs=50, workers=4)
        model.load_model('./model/word2vec/word2vec_' + str(model.vector_size) + '.model')
        # model.load_model('./model/word2vec/word2vec_wiki.model')
        # model.load_model('./model/word2vec/updated_word2vec_50.model')
    else:
        print('Invalid model type')
        exit()

    # 発言単位
    docs = [row[1] for row in data]
    print(docs[:1])

    # print('===セグメンテーション===')
    # コサイン類似度
    # 可視化
    window_size = 3
    text_tiling = TextTiling(window_size=window_size, p_limit=0.1, a=0.5, model=model)
    res = text_tiling.segment([stems(doc) for doc in docs])
    print(res)

    save_path = './result/segmentation/' + model_type + '/' + model_type + '_doc_num_' + doc_num +'_window_size_' + str(text_tiling.window_size) + '_' + str(datetime.date.today())

    fig = plt.figure()
    text_tiling.sim_arr.plot(title=model_type)
    # text_tiling.sim_arr.plot(title=model_type, yticks=[0, 0.5, 1.0])
    plt.savefig(save_path + '.png')
    plt.close('all')

    with open(save_path + '.txt', 'w') as f:
        print("window_size:", text_tiling.window_size, ", p_limit:", text_tiling.p_limit, ", a:", text_tiling.a, file=f)
        for i in res.index.values:
            print('index: ', i, 'p: ', text_tiling.p_arr[i], file=f)
            i = float(i)
            print(docs[int(i - 3.5):int(i - 0.5) + 1], file=f)
            print(docs[int(i + 0.5):int(i + 4.5)], file=f)


# -*- coding: utf-8 -*-
import ui_navigate as nav

from cfme.fixtures import pytest_selenium as sel
from cfme.web_ui import accordion, toolbar
from fixtures.pytest_store import store
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains
from utils import version, classproperty
from utils.wait import wait_for
from utils.version import before_date_or_version

class Loc(object):

    @classproperty
    def toplevel_tabs_loc(cls):
        return version.pick({version.LOWEST: '//div[@class="navbar"]/ul',
            '5.4': '//nav[contains(@class, "navbar")]/div/ul[@id="maintab"]'})

    @classproperty
    def toplevel_loc(cls):
        return version.pick({version.LOWEST: ('//div[@class="navbar"]/ul/li'
                                              '/a[normalize-space(.)="{}"]'),
                             '5.4': cls.toplevel_tabs_loc + ('/li/a[normalize-space(.)="{}"'
                                'and (contains(@class, "visible-lg"))]')})

    @classproperty
    def secondlevel_first_item_loc(cls):
        return version.pick({version.LOWEST: ('//div[@class="navbar"]/ul/li'
                                              '/a[normalize-space(.)="{}"]/../ul/li[1]/a'),
            '5.4': cls.toplevel_tabs_loc + '/li/a[normalize-space(.)="{}"]/../ul/li[1]/a'})

    @classproperty
    def inactive_box_loc(cls):
        return version.pick({version.LOWEST: ("//ul[@id='maintab']//"
                                              "ul[contains(@class, 'inactive')]"),
            '5.4': "//ul[@id='maintab']//ul[contains(@class, 'inactive')]"})

    @classproperty
    def a(cls):
        return version.pick({version.LOWEST: "./a",
            '5.4': "./a[contains(@class, 'visible-lg')]"})

def any_box_displayed():
    """Checks whether any of the not-currently-selected toplevel items is hovered (active).

    First part of the condition is for the 5.3+ pop-up, second is for 5.2.
    """
    return version.pick({
        version.LOWEST:
        lambda: sel.is_displayed("//a[contains(@class, 'maintab_active')]", _no_deeper=True),
        "5.3":
        lambda: any(map(
            lambda e: sel.is_displayed(e, _no_deeper=True),
            sel.elements(Loc.inactive_box_loc))),
        "5.4":
        lambda: sel.is_displayed(
            "//li[contains(@class, 'dropdown') and contains(@class, 'open')]", _no_deeper=True)
    })()

def get_top_level_element(title):
    """Returns the ``li`` element representing the menu item in top-level menu."""
    return sel.element((Loc.toplevel_loc + "/..").format(title))

def open_top_level(title):
    """Opens the section."""
    sel.raw_click(sel.element(Loc.a, root=get_top_level_element(title)))

def get_second_level_element(top_level_el, title):
    """Returns the ``li`` element representing the menu item in second-level menu."""
    return sel.element("./ul/li/a[normalize-space(.)='{}']/..".format(title), root=top_level_el)

def open_second_level(top_level_element, title):
    """Click on second-level menu."""
    second = get_second_level_element(top_level_element, title)
    sel.raw_click(sel.element("./a", root=second))

def get_current_toplevel_name():
    """Returns text of the currently selected top level menu item."""
    get_rid_of_the_menu_box()
    return sel.text(
        version.pick({
            "5.4": "//ul[@id='maintab']/li[not(contains(@class, 'drop'))]/a[2]",
            "5.3": "//ul[@id='maintab']/li[not(contains(@class, 'in'))]/a",
            version.LOWEST: "//ul[@id='maintab']/li/ul[not(contains(@style, 'none'))]/../a"
        })).encode("utf-8").strip()

def get_rid_of_the_menu_box():
    """Moves the mouse pointer away from the menu location and waits for the popups to hide."""
    # We received quite a lot of errors based on #tP not being visible. This tries to wait for it.
    wait_for(sel.is_displayed, ["#tP"], num_sec=5, delay=0.1, message="page ready")
    ActionChains(sel.browser()).move_to_element(sel.element("#tP")).perform()
    wait_for(lambda: not any_box_displayed(), num_sec=10, delay=0.1, message="menu box")

def os_infra_specific(without_infra, with_infra, with_both=None):
    """If there is even one OS Infra provider, UI changes. This is wrapper for it.

    Args:
        without_infra: What the text should be when there are not OS infra providers.
        with_infra: What the text should be when there is at least on OS Infra provider.
        with_both: If specified, will be used when there are both kinds of providers. If not
            specified, ``without_infra / with_infra`` will be used.
    """
    def _decide():
        if before_date_or_version(date="2015-04-30", version="5.4.0.0.25"):
            # Don't bother, the code is not in
            return without_infra

        if store.current_appliance.has_os_infra and store.current_appliance.has_non_os_infra:
            return with_both or "{} / {}".format(without_infra, with_infra)
        elif store.current_appliance.has_os_infra:
            return with_infra
        else:
            return without_infra
    return _decide

def _tree_func_with_grid(*args):
    def f():
        accordion.tree(*args)
        toolbar.set_vms_grid_view()
    return f

# Dictionary of (nav destination name, section title) section tuples
# Keys are toplevel sections (the main tabs), values are a supertuple of secondlevel sections
sections = {
    ('cloud_intelligence', 'Cloud Intelligence'): (
        ('dashboard', 'Dashboard'),
        ('reports', 'Reports'),
        ('chargeback', 'Chargeback'),
        ('timelines', 'Timelines'),
        ('rss', 'RSS')
    ),
    ('services', 'Services'): (
        ('my_services', 'My Services'),
        ('services_catalogs', 'Catalogs'),
        ('services_workloads', 'Workloads'),
        ('services_requests', 'Requests')
    ),
    ('clouds', 'Clouds'): (
        ('clouds_providers', 'Providers', toolbar.set_vms_grid_view),
        ('clouds_availability_zones', 'Availability Zones'),
        ('clouds_tenants', 'Tenants'),
        ('clouds_flavors', 'Flavors'),
        ('clouds_security_groups', 'Security Groups'),
        ('clouds_instances', 'Instances',
            _tree_func_with_grid("Instances by Provider", "Instances by Provider")),
        ('clouds_stacks', 'Stacks')
    ),
    ('infrastructure', 'Infrastructure'): (
        ('infrastructure_providers', 'Providers', toolbar.set_vms_grid_view),
        ('infrastructure_clusters', os_infra_specific('Clusters', 'Deployment Roles')),
        ('infrastructure_hosts', os_infra_specific('Hosts', 'Nodes')),
        ('infrastructure_virtual_machines', 'Virtual Machines',
            _tree_func_with_grid("VMs & Templates", "All VMs & Templates")),
        ('infrastructure_resource_pools', 'Resource Pools'),
        ('infrastructure_datastores', 'Datastores'),
        ('infrastructure_repositories', 'Repositories'),
        ('infrastructure_pxe', 'PXE'),
        ('infrastructure_requests', 'Requests'),
        ('infrastructure_config_management', 'Configuration Management')
    ),
    ('storage', 'Storage'): (
        ('filers', 'Filers'),
        ('volumes', 'Volumes'),
        ('luns', 'LUNs'),
        ('file_shares', 'File Shares'),
        ('storage_managers', 'Storage Managers')
    ),
    ('control', 'Control'): (
        ('control_explorer', 'Explorer'),
        ('control_simulation', 'Simulation'),
        ('control_import_export', 'Import / Export'),
        ('control_log', 'Log')
    ),
    ('automate', 'Automate'): (
        ('automate_explorer', 'Explorer'),
        ('automate_simulation', 'Simulation'),
        ('automate_customization', 'Customization'),
        ('automate_import_export', 'Import / Export'),
        ('automate_log', 'Log'),
        ('automate_requests', 'Requests')
    ),
    ('optimize', 'Optimize'): (
        ('utilization', 'Utilization'),
        ('planning', 'Planning'),
        ('bottlenecks', 'Bottlenecks')
    ),
    ('configure', 'Configure'): (
        ('my_settings', 'My Settings'),
        ('tasks', 'Tasks'),
        ('configuration', 'Configuration'),
        ('smartproxies', 'SmartProxies'),
        ('about', 'About')
    )
}

def is_page_active(toplevel, secondlevel=None):
    try:
        if get_current_toplevel_name() != toplevel:
            return False
    except NoSuchElementException:
        return False
    if secondlevel:
        try:
            sel.element(version.pick({
                "5.4": ("//nav[contains(@class, 'navbar')]//ul/li[@class='active']"
                        "/a[normalize-space(.)='{}']/..".format(secondlevel)),
                version.LOWEST: ("//div[@class='navbar']//ul/li[@class='active']"
                                 "/a[normalize-space(.)='{}']/..".format(secondlevel))
            }))
        except NoSuchElementException:
            return False
    return True

def nav_to_fn(toplevel, secondlevel=None, reset_action=None):
    def f(_):
        if callable(toplevel):
            top_level = toplevel()
        else:
            top_level = toplevel
        if not is_page_active(top_level):
            try:
                # Try to circumvent the issue on fir
                get_rid_of_the_menu_box()
                open_top_level(top_level)
                get_rid_of_the_menu_box()
                if get_current_toplevel_name() != top_level:
                    # Infrastructure / Requests workaround
                    sel.move_to_element(get_top_level_element(top_level))
                    # Using pure move_to_element to not move the mouse anywhere else
                    # So in this case, we move the mouse to the first item of the second level
                    ActionChains(sel.browser())\
                        .move_to_element(sel.element(Loc.secondlevel_first_item_loc.format(
                            top_level)))\
                        .click()\
                        .perform()
                    get_rid_of_the_menu_box()
                    # Now when we went directly to the first item, everything should just work
                    tl = get_current_toplevel_name()
                    if tl != top_level:
                        raise Exception("Navigation screwed! (wanted {}, got {}".format(top_level,
                                                                                tl))
            except NoSuchElementException:
                if visible_toplevel_tabs():  # Target menu is missing
                    raise
                else:
                    return  # no menu at all, assume single permission

        # Can't do this currently because silly menu traps us
        # if is_page_active(toplevel, secondlevel):
        #     return
        if secondlevel is not None:
            get_rid_of_the_menu_box()
            if callable(secondlevel):
                second_level = secondlevel()
            else:
                second_level = secondlevel
            open_second_level(get_top_level_element(top_level), second_level)
            get_rid_of_the_menu_box()

        if reset_action is not None:
            if callable(reset_action):
                reset_action()
            else:
                sel.click(reset_action)
    return f

def reverse_lookup(toplevel_path, secondlevel_path=None):
    """Reverse lookup for navigation destinations defined in this module, based on menu text

    Usage:

        # Returns 'clouds'
        reverse_lookup('Clouds')

        # Returns 'clouds_providers'
        reverse_lookup('Clouds', 'Providers')

        # Returns 'automate_import_export'
        reverse_lookup('Automate', 'Import / Export')

    Note:

        It may be tempting to use this when you don't know the name of a page, e.g.:

            go_to(reverse_lookup('Infrastructure', 'Providers'))

        Don't do that; use the nav tree name.

    """
    if secondlevel_path:
        menu_path = '%s/%s' % (toplevel_path, secondlevel_path)
    else:
        menu_path = toplevel_path

    for (toplevel_dest, toplevel), secondlevels in sections.items():
        if callable(toplevel):
            top_level = toplevel()
        else:
            top_level = toplevel
        if menu_path == top_level:
            return toplevel_dest
        for level in secondlevels:
            if len(level) == 2:
                secondlevel_dest, secondlevel = level
                reset_action = None
            else:
                secondlevel_dest, secondlevel, reset_action = level
            if callable(secondlevel):
                second_level = secondlevel()
            else:
                second_level = secondlevel
            if menu_path == '%s/%s' % (toplevel, second_level):
                return secondlevel_dest

def visible_toplevel_tabs():
    menu_names = []
    ele = version.pick({
        "5.4": 'li/a[2]',
        version.LOWEST: 'li/a'})
    for menu_elem in sel.elements(ele, root=Loc.toplevel_tabs_loc):
        menu_names.append(sel.text(menu_elem))
    return menu_names

def visible_pages():
    """Return a list of all the menu pages currently visible top- and second-level pages

    Mainly useful for RBAC testing

    """
    # Gather up all the visible toplevel tabs
    menu_names = visible_toplevel_tabs()

    # Now go from tab to tab and pull the secondlevel names from the visible links
    displayed_menus = []
    for menu_name in menu_names:
        menu_elem = sel.element(Loc.toplevel_loc.format(menu_name))
        sel.move_to_element(menu_elem)
        for submenu_elem in sel.elements('../ul/li/a', root=menu_elem):
            displayed_menus.append((menu_name, sel.text(submenu_elem)))

    # Do reverse lookups so we can compare to the list of nav destinations for this group
    return sorted([reverse_lookup(*displayed) for displayed in displayed_menus])

# Construct the nav tree based on sections
_branches = dict()
# The main tab destination is usually the first secondlevel page in that tab
# Since this is redundant, it's arguable that the toplevel tabs should be
# nav destination at all; they're included here "just in case". The toplevel
# and secondlevel destinations exist at the same level of nav_tree because the
# secondlevel destinations don't depend on the toplevel nav taking place to reach
# their destination.
for (toplevel_dest, toplevel), secondlevels in sections.items():
    for level in secondlevels:
        if len(level) == 2:
            secondlevel_dest, secondlevel = level
            reset_action = None
        elif len(level) == 3:
            secondlevel_dest, secondlevel, reset_action = level
        else:
            raise Exception("Wrong length of menu navigation tuple! ({})".format(len(level)))
        _branches[secondlevel_dest] = nav_to_fn(toplevel, secondlevel, reset_action)
    _branches[toplevel_dest] = [nav_to_fn(toplevel, None), {}]

nav.add_branch('toplevel', _branches)


# Copyright 2015, Google, Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# [START get_service]
def get_service():
    """returns an initialized and authorized bigquery client"""

    from googleapiclient.discovery import build
    from oauth2client.client import GoogleCredentials

    credentials = GoogleCredentials.get_application_default()
    if credentials.create_scoped_required():
        credentials = credentials.create_scoped(
            'https://www.googleapis.com/auth/bigquery')
    return build('bigquery', 'v2', credentials=credentials)
# [END get_service]

# [START poll_job]
def poll_job(service, projectId, jobId, interval=5.0, num_retries=5):
    """checks the status of a job every *interval* seconds"""

    import time

    job_get = service.jobs().get(projectId=projectId, jobId=jobId)
    job_resource = job_get.execute(num_retries=num_retries)

    while not job_resource['status']['state'] == 'DONE':
        print('Job is {}, waiting {} seconds...'
              .format(job_resource['status']['state'], interval))
        time.sleep(float(interval))
        job_resource = job_get.execute(num_retries=num_retries)

    return job_resource
# [END poll_job]

# [START paging]
def paging(service, request_func, num_retries=5, **kwargs):
    """pages though the results of an asynchronous job"""

    has_next = True
    while has_next:
        response = request_func(**kwargs).execute(num_retries=num_retries)
        if 'pageToken' in response:
            kwargs['pageToken'] = response['pageToken']
        else:
            has_next = False
        yield response
# [END paging]


import pygame, sys
from pygame import rect
from pygame.locals import *
import time

#mendenifisikan lebar dan panjang layar
#pemberian nama/judul output saat di running
WIDTH, HEIGHT = 800, 600
pygame.display.set_caption('Smooth Movement')

pygame.init()#menginisialisasi semua modul yang diperlukan untuk PyGame
win = pygame.display.set_mode((WIDTH, HEIGHT)) #Memanggil nilai HIGHT dan Widht
clock = pygame.time.Clock()#clock Mengetahui Waktu yang di perlukan untuk benda bergerak

#Set Warna Menggunakan RGB Colors
DARKCYAN = (0,139,139)

#membuat sebuah objek. Di setiap metode class harus selalu ada self sebagai
class Player:
    def __init__(self, x, y):
        self.x = int(x)
        self.y = int(y)
        self.rect = pygame.Rect(self.x, self.y, 32, 32)
        self.color = (250, 120, 60)
        self.velX = 0
        self.velY = 0
        self.left_pressed = False
        self.right_pressed = False
        self.up_pressed = False
        self.down_pressed = False
        self.speed = 4

    def draw(self, win):
        pygame.draw.rect(win, self.color, self.rect)

    def update(self): #mengupdate properti-properti pada object
        self.velX = 0 #memberikan arah gerak pada object yaitu secara horizontal, dimulai dari titik 0
        self.velY = 0 #memberikan arah gerak pada object yaitu secara vertical, dimulai dari titik 0
        if self.left_pressed and not self.right_pressed:
            self.velX = -self.speed
        if self.right_pressed and not self.left_pressed:
            self.velX = -self.speed
        if self.up_pressed and not self.down_pressed:
            self.velY = -self.speed
        if self.down_pressed and not self.up_pressed:
            self.velY = -self.speed

        self.x += self.velX
        self.y += self.velY

        self.rect = pygame.Rect(int(self.x), int(self.y), 32, 32)

#Hegiht dan Widht tadi yaitu 400 dan 400 di bagi menjadi 2
player = Player(WIDTH/2, HEIGHT/2)
#untuk merubah Warna Huruf
font_color = (154, 205,50)
#Untuk mendefinisikan Font apa dan besar fontnya
font_obj = pygame.font.Font("QaskinBlack_PersonalUse.ttf",25)
#Tulisan akan muncul di layar
text = "ALGEORI WIRA WAHYU HIDAYAT"
#Font akan muncul
img = font_obj.render(text, True, (0,0,0))

rect = img.get_rect()
rect.topleft = (20,20)
cursor = Rect(rect.topright, (3, rect.height))

#untuk membuat keyboard down dan keybord up, Keyboard left dan right
while  True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.left_pressed = True
            if event.key == pygame.K_RIGHT:
                player.right_pressed = True
            if event.key == pygame.K_UP:
                player.up_pressed = True
            if event.key == pygame.K_DOWN:
                player.down_pressed = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                player.left_pressed = False
            if event.key == pygame.K_RIGHT:
                player.right_pressed = False
            if event.key == pygame.K_UP:
                player.up_pressed = False
            if event.key == pygame.K_DOWN:
                player.down_pressed = False

            if event.type == QUIT:
                    running = False

            if event.type == KEYDOWN:
                if event.key == K_BACKSPACE:
                    if len(text)>0:
                        text = text[:-1]

                else:
                    text += event.unicode
                    img = font_obj.render(text, True, DARKCYAN)
                    rect.size = img.get_size()
                    cursor.topleft = rect.topright

    #Menampilkan warna background
    win.fill((143, 188, 143))
    pygame.draw.rect(win, (172, 57, 208), player)

    win.blit(img,rect)
    if time.time() % 1 > 0.5:
        pygame.draw.rect(win, DARKCYAN, cursor)
    pygame.display.update()

    #Menampilkan hasil dari semuanya
    player.update()
    pygame.display.flip()

    clock.tick(120)
    pygame.display.update()

pygame.quit()


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

from setuptools import setup, find_packages

VAgent_VERSION = '0.0.1'

if __name__ == "__main__":
    setup(
        name = 'src',
        version = VAgent_VERSION,
        packages = find_packages(),
        long_description=__doc__,
        description = 'src common lib',
        include_package_data = True,
        zip_safe = False
    )


# import DIFFICULTY from __init__
# import VERSION from __init__
import hashlib
import time
import json
from Crypto.Hash import SHA256
class block:
    def __init__(self, diffculty, time_stamp, transactions, prev_hash, Nonce):
        self.difficulty = diffculty
        self.time_stamp = time_stamp
        self.transactions = transactions
        self.Nonce = Nonce
        self.prev_hash = prev_hash
        self.current_hash = self.calculate_hash()

    def __str__(self):
        block_str = json.dumps(self, default=lambda o: o.__dict__)
        # print(test_str)
        return block_str

    def calculate_hash(self):
        data = {}
        data['Difficulty'] = self.difficulty
        data['Time_Stamp'] = self.time_stamp
        data['Transactions'] = self.transactions
        data['Nonce'] = self.Nonce
        data['Prev_hash'] = self.prev_hash
        json_data = json.dumps(data)
        hash_val = hashlib.sha256(json_data).hexdigest()
        self.current_hash = hash_val
        return hash_val

    def has_valid_transactions(self):
        for transaction in self.transactions:
            if not transaction.isvalid():
                return false
        return true


'''
Created on Apr 5, 2012

Author - Neeraj Gaur
'''

import numpy as np
import scipy.sparse as sp
from learn_scoal import learn_scoal
from scipy.cluster.vq import whiten, vq
import sys
import SCOAL.general_scoal_model as scoal

convergence_threshold = 1e-6

def run_scoal(K, L, X1, X2, train_I, train_J, train_Y, learner, reg_lambda):

    model = scoal.GeneralScoalModel()

    Xs = [0,0]
    Xs[0] = X1
    Xs[1] = X2
    M = Xs[0].shape[0]
    N = Xs[1].shape[0]

    vals = train_Y
    train_W = sp.csr_matrix((np.ones(len(train_Y)),(train_I,train_J)), shape=(M,N))
    Z = sp.csr_matrix((vals, (train_I,train_J)), shape=(M,N))

    # Train Hard SCOAL
    rowAttr = Xs[0]
    colAttr = Xs[1]
    model.set_attributes(rowAttr, colAttr, crossAttr=None)
    obj = learn_scoal(model, Z, train_W, K, L, learner, reg_lambda,None,None, initial_R=None, initial_C=None)
    parameters = np.zeros((K,L,rowAttr.shape[1] + colAttr.shape[1]))
    for k in range(K):
        for l in range(L):
            parameters[k,l,:] = model.models[k,l].model.coef_

    params = {'I':model.I,
              'J':model.J,
              'row_assignment':model.R,
              'col_assignment':model.C,
              'parameters':parameters
              }

    train_op = {'params':params,
                'obj':obj,
                'model':model
                }

    return train_op

def hotStartTrainRMSE(K, L, X1, X2, train_I, train_J, train_Y, train_op):
    M = X1.shape[0]
    N = X2.shape[0]
    model = train_op['model']
    predictions = predict_scoal(train_I, train_J, train_Y, M, N, model)
    Z = sp.csr_matrix((train_Y, (train_I,train_J)), shape=(M,N))
    nonzero_Z = np.array(Z[(train_I,train_J)]).ravel()
    hotStartTrainRMSE = np.sqrt(np.mean((predictions-nonzero_Z)**2))
    return hotStartTrainRMSE

'''def warmStartTrainRMSE(K, L, X1, X2, train_I, train_J, train_Y, train_op):
    M = X1.shape[0]
    N = X2.shape[0]
    model = train_op['model']
    predictions = predict_scoal(train_I, train_J, train_Y, M, N, model)
    Z = sp.csr_matrix((train_Y, (train_I,train_J)), shape=(M,N))
    nonzero_Z = np.array(Z[(train_I,train_J)]).ravel()
    warmStartTrainRMSE = np.sqrt(np.mean((predictions-nonzero_Z)**2))
    return warmStartTrainRMSE

def coldStartTrainRMSE(K, L, X1, X2, train_I, train_J, train_Y, train_op):
    coldStartTrainRMSE = hotStartTrainRMSE(K, L, X1, X2, train_I, train_J, train_Y, train_op)
    return coldStartTrainRMSE'''

def hotStartValRMSE(K, L, X1, X2, val_I, val_J, val_Y, train_op):
    M = X1.shape[0]
    N = X2.shape[0]
    model = train_op['model']
    predictions = predict_scoal(val_I, val_J, val_Y, M, N, model)
    Z = sp.csr_matrix((val_Y, (val_I,val_J)), shape=(M,N))
    nonzero_Z = np.array(Z[(val_I,val_J)]).ravel()
    hotStartValRMSE = np.sqrt(np.mean((predictions-nonzero_Z)**2))
    return hotStartValRMSE

def warmStartValRMSE(K, L, X1, X2, val_I, val_J, val_Y, train_op, centroids):
    M = X1.shape[0]
    N = X2.shape[0]
    I = train_op['params']['I']
    J = train_op['params']['J']
    model = train_op['model']
    # Map the warm/cold start Validation set users and movies to their clusters
    # Users
    user_cluster = vq(whiten(X1), centroids['user_centroids'])[0]
    user_cluster_seen = user_cluster[list(set(I))]
    user_cocluster = model.R[list(set(I))]
    mapping = np.zeros((K,1))
    for k_clust in range(K):
        users_in_cluster = [x for x in range(len(user_cluster_seen)) if user_cluster_seen[x] == k_clust]
        users_in_cluster = user_cocluster[users_in_cluster]
        temp = [len(filter(lambda x: x == k_coclust, users_in_cluster)) for k_coclust in range(K)]
        mapping[k_clust] = temp.index(max(temp))
    val_users = np.array(list(set(val_I)))
    for user in val_users:
        model.R[user] = mapping[user_cluster[user]]
    # Movies
    movie_cluster = vq(whiten(X2), centroids['movie_centroids'])[0]
    movie_cluster_seen = movie_cluster[list(set(J))]
    movie_cocluster = model.C[list(set(J))]
    mapping = np.zeros((L,1))
    for l_clust in range(L):
        movies_in_cluster = [x for x in range(len(movie_cluster_seen)) if movie_cluster_seen[x] == l_clust]
        movies_in_cluster = movie_cocluster[movies_in_cluster]
        temp = [len(filter(lambda x: x == l_coclust, movies_in_cluster)) for l_coclust in range(L)]
        mapping[l_clust] = temp.index(max(temp))
    val_movies = np.array(list(set(val_J)))
    for movie in val_movies:
        model.C[movie] = mapping[movie_cluster[movie]]

    # Use the same prediction logic from now on
    predictions = predict_scoal(val_I, val_J, val_Y, M, N, model)
    Z = sp.csr_matrix((val_Y, (val_I,val_J)), shape=(M,N))
    nonzero_Z = np.array(Z[(val_I,val_J)]).ravel()
    warmStartValRMSE = np.sqrt(np.mean((predictions-nonzero_Z)**2))
    return warmStartValRMSE

def coldStartValRMSE(K, L, X1, X2, val_I, val_J, val_Y, train_op, centroids):
    coldStartValRMSE = warmStartValRMSE(K, L, X1, X2, val_I, val_J, val_Y, train_op, centroids)
    return coldStartValRMSE

def predict_scoal(I, J, Y, M, N, model):
    W = sp.csr_matrix((np.ones(len(Y)),(I,J)), shape=(M,N))
    I,J = sp.find(W)[:2]
    predictions = model.predict(I,J)
    return predictions

if '__main__' == __name__:
    sys.exit()


"""
@Author         : Ailitonia
@Date           : 2021/09/12 0:09
@FileName       : rate_limiting.py
@Project        : nonebot2_miya
@Description    : 速率限制
@GitHub         : https://github.com/Ailitonia
@Software       : PyCharm
"""

import time
from datetime import datetime, timedelta
from typing import Union, Dict
from nonebot import get_driver, logger
from nonebot.exception import IgnoredException
from nonebot.typing import T_State
from nonebot.adapters.cqhttp.bot import Bot
from nonebot.adapters.cqhttp.event import MessageEvent, GroupMessageEvent
from omega_miya.database import DBBot, DBBotGroup, DBCoolDownEvent

global_config = get_driver().config
SUPERUSERS = global_config.superusers

# 速率限制次数阈值, 触发超过该次数后启用限制
RATE_LIMITING_THRESHOLD: int = 5
# 速率限制时间阈值, 判断连续消息触发的时间间隔小于该值, 单位为秒, 判断依据时间戳为标准
RATE_LIMITING_TIME: float = 1.0
# 启用后判断依据将以处理时的系统时间戳为准, 而不是上报 event 的时间戳
USING_SYSTEM_TIMESTAMP: bool = False
# 记录用户上次消息的时间戳, 作为对比依据
USER_LAST_MSG_TIME: Dict[int, Union[int, float]] = {}
# 记录用户消息在速率限制时间阈值内触发的次数
RATE_LIMITING_COUNT: Dict[int, int] = {}
# 触发速率限制时为用户设置的全局冷却时间, 单位秒
RATE_LIMITING_COOL_DOWN: int = 1800
# 缓存的已被限制的用户id及到期时间, 避免多次查数据库
RATE_LIMITING_USER_TEMP: Dict[int, datetime] = {}
# 群组流控配置冷却时间, 与 plugins.omega_rate_limiting 中配置保持一致
GROUP_GLOBAL_CD_SETTING_NAME: str = 'group_global_cd'

async def preprocessor_rate_limiting(bot: Bot, event: MessageEvent, state: T_State):
    """
    速率限制处理 T_EventPreProcessor
    """
    global USER_LAST_MSG_TIME
    global RATE_LIMITING_COUNT
    global RATE_LIMITING_USER_TEMP

    user_id = event.user_id
    # 忽略超级用户
    if user_id in [int(x) for x in SUPERUSERS]:
        return

    # 检测该用户是否已经被速率限制
    if RATE_LIMITING_USER_TEMP.get(user_id, datetime.now()) > datetime.now():
        logger.info(f'Rate Limiting | User: {user_id} 仍在速率限制中, 到期时间 {RATE_LIMITING_USER_TEMP.get(user_id)}')
        raise IgnoredException('速率限制中')

    # 获取上条消息的时间戳
    last_msg_timestamp = USER_LAST_MSG_TIME.get(user_id, None)

    # 获取当前消息时间戳
    if USING_SYSTEM_TIMESTAMP:
        this_msg_timestamp = time.time()
    else:
        this_msg_timestamp = event.time

    # 更新上次消息时间戳为本次消息时间戳
    if last_msg_timestamp is None:
        USER_LAST_MSG_TIME.update({user_id: this_msg_timestamp})
        # 上次消息时间戳为空则这是第一条消息
        return
    else:
        USER_LAST_MSG_TIME.update({user_id: this_msg_timestamp})

    # 获取速录限制触发计数
    over_limiting_count = RATE_LIMITING_COUNT.get(user_id, 0)

    # 进行速率判断
    if this_msg_timestamp - last_msg_timestamp < RATE_LIMITING_TIME:
        # 小于时间阈值则计数 +1
        over_limiting_count += 1
        logger.info(f'Rate Limiting | User: {user_id} over rate limiting, counting {over_limiting_count}')
    else:
        # 否则重置计数
        over_limiting_count = 0

    # 更新计数
    RATE_LIMITING_COUNT.update({user_id: over_limiting_count})

    # 判断计数大于阈值则触发限制, 为用户设置一个全局冷却并重置计数
    if over_limiting_count > RATE_LIMITING_THRESHOLD:
        RATE_LIMITING_USER_TEMP.update({user_id: datetime.now() + timedelta(seconds=RATE_LIMITING_COOL_DOWN)})
        logger.success(f'Rate Limiting | User: {user_id} 触发速率限制, Upgrade RATE_LIMITING_USER_TEMP completed')

        result = await DBCoolDownEvent.add_global_user_cool_down_event(
            user_id=user_id,
            stop_at=datetime.now() + timedelta(seconds=RATE_LIMITING_COOL_DOWN),
            description='Rate Limiting CoolDown')
        RATE_LIMITING_COUNT.update({user_id: 0})

        if result.error:
            logger.error(f'Rate Limiting | Set rate limiting cool down failed: {result.info}')
        else:
            logger.success(f'Rate Limiting | User: {user_id} 触发速率限制, 已设置 {RATE_LIMITING_COOL_DOWN} 秒全局冷却限制')
        raise IgnoredException('触发速率限制')

async def postprocessor_rate_limiting(bot: Bot, event: MessageEvent, state: T_State):
    """
    速率限制事件后处理 T_EventPostProcessor
    """
    if not state.get('_prefix', {}).get('raw_command') and not state.get('_suffix', {}).get('raw_command'):
        # 限流仅能由命令触发
        logger.debug(f'Rate Limiting | Not command event, ignore global group cool down')
        return

    self_bot = DBBot(self_qq=int(bot.self_id))
    if isinstance(event, GroupMessageEvent):
        group_id = event.group_id
        group = DBBotGroup(group_id=group_id, self_bot=self_bot)
        setting_result = await group.setting_get(setting_name=GROUP_GLOBAL_CD_SETTING_NAME)
        if setting_result.success():
            main, second, extra = setting_result.result
            if main:
                # 配置有效, 为群组设置一个全局冷却
                result = await DBCoolDownEvent.add_global_group_cool_down_event(
                    group_id=group_id,
                    stop_at=datetime.now() + timedelta(seconds=int(main)),
                    description='Rate Limiting Global Group CoolDown')
                if result.error:
                    logger.error(f'Rate Limiting | Set global group cool down failed: {result.info}')
                else:
                    logger.debug(f'Rate Limiting | Set Group: {group_id} global group cool down, times: {main}')
            else:
                logger.error(f'Rate Limiting | Group: {group_id} global group cool down setting not found')
        elif setting_result.error and setting_result.info == 'NoResultFound':
            logger.debug(f'Rate Limiting | Group: {group_id} not set global group cool down, pass')
        else:
            logger.error(f'Rate Limiting | Set global group cool down getting setting failed: {setting_result.info}')

__all__ = [
    'preprocessor_rate_limiting',
    'postprocessor_rate_limiting'
]


# %%
import networkx as nx
import matplotlib.pyplot as plt
import nxviz as nz

# %%
# initialize the graph
G = nx.Graph()

# add nodes
G.add_nodes_from([1, 2, 3])

# print the nodes
print(G.nodes())

# %%

# adding data to the node, you have to mention node name here 1 is the node name not the index
G.nodes[1]['label'] = 'blue'

# printing nodes with the data
print(G.nodes(data=True))

# %%

# adding edges unweighted and undirected
G.add_edge(1, 2)
G.edges[(1, 2)]['label'] = 'cutie'
print(G.edges())

# to
print(G.edges(data=True))
# %%
# draw the graph
nx.draw(G)

# you also need matplotlib to show the graph
plt.show()

# %%
# to work with the directed graph use DiGraph
D = nx.DiGraph()
print(type(D))

# you can also initiate multiGraph
M = nx.MultiGraph()

# multiDiGraph
MD = nx.MultiDiGraph()

# %%

# you can use nxviz to for matrix plot or circos plot or arc plot

# https://stackoverflow.com/questions/53366634/how-to-set-edge-color-in-nxviz-arcplot
D = nx.DiGraph()
D.add_nodes_from([1, 2, 3])
D.add_edge(1, 2)
D.add_edge(2, 3)

m = nz.MatrixPlot(D)
m.draw()
plt.show()

a = nz.ArcPlot(D)
a.draw()  # here you can provide node_order and node_color which is provided in nodes metadata
plt.show()

c = nz.CircosPlot(D)
c.draw()
plt.show()
# %%

# to get the neighbours of the node
D = nx.DiGraph()
D.add_nodes_from([1, 2, 3])
D.add_edge(1, 2)
D.add_edge(2, 3)

list(D.neighbors(2))  # this is the directed graph

G = nx.Graph()
G.add_nodes_from([1, 2, 3])
G.add_edge(1, 2)
G.add_edge(2, 3)

print(list(G.neighbors(2)))  # this is the undirected graph

b = nx.barbell_graph(m1=5, m2=2)
nx.draw(b)
plt.show()

# %%
# degree centrality = number of neighbours I have / number of neighbours I could possibly have
# degree centrality tells us about the highly connected node

G = nx.Graph()
G.add_nodes_from([1, 2, 3, 4])
G.add_edge(1, 2)
G.add_edge(2, 3)
# G.add_edge(2,2)

print(nx.degree_centrality(G))  # self loops are not considered here and should not be mentioned during edge creation

# %%

# betweeness centrality = number of shortest path through nodes/ all possible shortest paths
# it tells us about the bottleneck path
b = nx.barbell_graph(m1=5, m2=2)
print(nx.betweenness_centrality(b))

# %%
# generating the graph using erdos_renyi_graph

E = nx.erdos_renyi_graph(20, 0.2) # 20 is the number of nodes and 0.2 is the probability that edge should exist between
# nx.connected_component(E) --> it tells us about the how many subgraphs are there in E

print(nx.degree_centrality(E))

# pagerank concept explained below again with directed graph
pr = [nx.pagerank(G)]
import pandas as pd

print(pd.DataFrame(pr))

# two nodes
nx.draw(E)
plt.show()

# %%

E = nx.erdos_renyi_graph(20, 0.2)  # 20 is the number of nodes and 0.2 is the probability that edge should exist between
# two nodes
nodes = list(E.neighbors(1))
nodes.append(1)

# generate the subgraph of graph E with nodes nodes
S = E.subgraph(nodes)
print(S.edges())

nx.draw(S, with_labels=True)
plt.show()
# %%
# pagerank concept
import random

N = 7
G = nx.erdos_renyi_graph(20, 0.2)
for (start, end) in G.edges:
    G.edges[start, end]['weight'] = random.random()
t = nx.pagerank(G)
print(t)
nx.draw(G, with_labels=True)
plt.show()

#%%
# connected component
G = nx.erdos_renyi_graph(20, 0.1)
print(list(nx.find_cliques(G)))
t = sorted(list(nx.connected_components(G)), key=lambda x: len(x))[-1]
print(t)

L = nx.subgraph(G, t)
nx.draw(L)
plt.show()

t = nx.connected_components(G)
i = 1
for n in t:
    for k in n:
        G.nodes[k]['grouping'] = i
        G.nodes[k]['alphabetically'] = i
    i+=1

c = nz.CircosPlot(G, node_grouping='alphabetically', node_color='grouping')
c.draw()
plt.show()

#%%


from django.shortcuts import render
from rest_framework.permissions import IsAuthenticated
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status

from .models import UserProfile
from .serializer import UserProfileSerializer

# Create your views here.

class CustomAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data, context={"request": request}
        )
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data["user"]
        token, created = Token.objects.get_or_create(user=user)
        return Response(
            {
                "token": token.key,
                "user_id": user.pk,
                "email": user.email,
                "username": user.username,
            }
        )

class SignupView(APIView):
    def post(self, request):
        serializer = UserProfileSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


import matplotlib.pyplot as plt
import seaborn as sn
import unicodecsv as csv

from models.topological_compat_matrix import TopologicalCompatMatrix
from utils.constants import LOG_ENTRY_DELIMITER, SENSOR_ID_POS, NOISE_THRESHOLD

class BStep(object):
    def __init__(self):
        """
        Gather the two sets of segments that must be combined to contribute to the validation set.
        """
        self.closed_segments = []  # the segments closed at this B-step.
        self.compat_segments = []  # the segments opened between this B-step and the next that are compatible.
        self.crossing_points =  []
    def add_closed_segment(self, s):
        self.closed_segments.append(s)

    def add_compat_segment(self, s):
        self.compat_segments.append(s)

class SegmentedSensorLog(object):
    def __init__(self, sensor_log=None, top_compat_matrix=None, compat_threshold=None, segments=None,
                 sensor_id_pos=SENSOR_ID_POS, noise_threshold=NOISE_THRESHOLD):
        """
        Segmented version of the given log, built according to the given probabilistic topological compatibility matrix.

        :type sensor_log: file
        :type top_compat_matrix: TopologicalCompatMatrix
        :type compat_threshold: float
        :type segments: list
        :type sensor_id_pos: int
        :type noise_threshold: int
        :param sensor_log: the tab-separated file containing the sensor log.
        :param top_compat_matrix: the topological compatibility matrix of the sensor log.
        :param compat_threshold: the threshold to reach for a direct succession to be significant.
        :param segments: a precomputed list of segments.
        :param sensor_id_pos: the position of the sensor id in the log entry.
        :param noise_threshold: the minimum length of a segment.
        """
        if segments:
            self.segments = segments

        elif sensor_log and top_compat_matrix and compat_threshold:
            self.segments = []
            self.top_compat_matrix = top_compat_matrix
            self.compat_threshold = compat_threshold
            self.noise_threshold = noise_threshold
            self.sensor_id_pos = sensor_id_pos

            self.b_steps = []  # the B-steps performed during the segmentation (to be used in validation).

            self._find_segments(sensor_log)

        else:
            raise ValueError('Not enough inputs provided.')

    def plot_stats(self, distribution=True, time_series=False):
        """
        Visualize segmented sensor log statistics.
        Notice that time-series visualization is significant only when the segments are chronologically ordered.

        :param distribution: whether the distribution visualization must be shown.
        :param time_series: whether the time-series visualization must be shown.
        """
        segments_num = len(self.segments)
        segments_lengths = [len(s) for s in self.segments]

        print('segments num:', segments_num)
        print('min length:  ', len(min(self.segments, key=len)))
        print('max length:  ', len(max(self.segments, key=len)))
        print('avg length:  ', int(sum(segments_lengths) / segments_num))
        print('b-steps num: ', len(self.b_steps))

        if distribution:
            plt.figure()
            sn.distplot(segments_lengths)

        if time_series:
            plt.figure()
            sn.tsplot(segments_lengths)

        plt.show()

    """ UTILITY FUNCTIONS """

    def _find_segments(self, sensor_log):
        """
        Find segments in the given sensor log.

        :type sensor_log: file
        :param sensor_log: the tab-separated file containing the sensor log.
        """
        sensor_log_reader = csv.reader(sensor_log, delimiter=LOG_ENTRY_DELIMITER)
        open_segments = []
        for measure in sensor_log_reader:

            sensor_id = measure[self.sensor_id_pos]
            # find compatible open segments
            compat_segments_idxs = self._get_compat_segments_indices(open_segments, sensor_id)

            # check compatibility results
            if len(compat_segments_idxs) == 1:
                # only one compat segment exists, append the measure
                segment_idx = compat_segments_idxs[0]
                open_segments[segment_idx].append(measure)

            else:
                if len(compat_segments_idxs) > 1:
                    # if many compat segments exist, close them (B-step)
                    self._close_segments(open_segments, compat_segments_idxs)

                # open new segment and append the measure
                new_segment = [measure]
                open_segments.append(new_segment)

                # check whether the new segment is compatible with at least a segment in last B-step
                if self.b_steps:
                    if self._get_compat_segments_indices(self.b_steps[-1].closed_segments, sensor_id):

                        # add new segment to last B-step compatibility list
                        self.b_steps[-1].add_compat_segment(new_segment)
                        #print(str(measure[0])+ "_"+str(sensor_log_reader.line_num))
                        self.b_steps[-1].crossing_points.append(str(measure[0])+ "_"+str(sensor_log_reader.line_num))

        # close remaining open segments
        self._close_segments(open_segments)

    def _get_compat_segments_indices(self, segments, sensor_id):
        """
        Return tho positions of the segments that are compatible (according to the given threshold) with the provided
        sensor identifier.

        :type segments: list
        :param segments: the list of open segments.
        :param sensor_id: the sensor identifier.
        :return: a list containing the indices of the compatible segments.
        """
        compat_segments_idxs = []
        for idx, os in enumerate(segments):
            # consider the sensor id of the last measure in segment
            old_sensor_id = os[-1][self.sensor_id_pos]

            if self.top_compat_matrix.prob_matrix[old_sensor_id][sensor_id] >= self.compat_threshold:
                # the direct succession value is above the threshold -> segment is compatible
                compat_segments_idxs.append(idx)
        return compat_segments_idxs

    def _close_segments(self, open_segments, indices=None):
        """
        Remove the segments identified by the given indices from the open list and add them to close list (if the
        minimum length is matched). If the indices are not provided, then all segments will be closed.

        :type open_segments: list
        :type indices: list
        :param open_segments: the list of open segments.
        :param indices: the positions of the segments to be closed.
        """
        if indices:
            indices = sorted(indices)
        else:
            # build a list of all possible indices to use the same approach for both cases.
            indices = [x for x in range(len(open_segments))]

        # add all segments to be closed to the global segments list and group them in a B-step
        b_step = BStep()
        for idx in reversed(indices):
            closed_segment = open_segments.pop(idx)          # remove segment from open list
            if len(closed_segment) >= self.noise_threshold:  # noise filtering
                self.segments.append(closed_segment)
                b_step.add_closed_segment(closed_segment)
        if b_step.closed_segments:
            self.b_steps.append(b_step)

    """ DEPRECATED FUNCTIONS """

    def _find_segments_old(self, sensor_log):
        """
        Find segments in the given sensor log (old version).

        :type sensor_log: file
        :param sensor_log: the tab-separated file containing the sensor log.
        """
        sensor_log_reader = csv.reader(sensor_log, delimiter=LOG_ENTRY_DELIMITER)

        s0 = next(sensor_log_reader, None)  # consider a sliding window of two events per step
        s1 = next(sensor_log_reader, None)
        segment = [list(s0)]
        while s0 is not None and s1 is not None:
            s0_id = s0[self.sensor_id_pos]
            s1_id = s1[self.sensor_id_pos]

            if self.top_compat_matrix.prob_matrix[s0_id][s1_id] >= self.compat_threshold:
                # the direct succession value is above the threshold
                segment.append(list(s1))  # continue the segment
            else:
                # the direct succession value is under the threshold
                if len(segment) >= self.noise_threshold:  # only segments longer than a threshold are considered
                    self.segments.append(list(segment))   # store a copy of the segment so far
                segment = [list(s1)]                      # start the new segment from the second item in the window

            # prepare next step (slide the window by one position)
            s0 = s1
            s1 = next(sensor_log_reader, None)


import pygame.font
class Score():
    def __init__(self,game_settings,screen,game_stats):
        self.game_settings = game_settings
        self.screen = screen
        self.game_stats = game_stats
        self.screen_rect = screen.get_rect()
        self.text_color = (255, 255, 255)
        self.font = pygame.font.SysFont(None, 48)
        self.prep_score(game_stats,screen)
    def prep_score(self,game_stats,screen):
        score_str = str(self.game_stats.score)
        self.score_image=self.font.render(score_str,True,self.text_color,None)
        self.score_rect=self.score_image.get_rect()
        self.score_rect.right=self.screen_rect.right-20
        self.score_rect.top=self.screen_rect.top+20
    def show_score(self):
        self.screen.blit(self.score_image,self.score_rect)


import logging
import logging.config
from datetime import datetime

import pandas as pd

from v1.core.constant import SerialType

# 缓存指定日期的时间序列值
_cache_day_period = {}

# 详细
TRACE = 5
BIZ = 35

def init_logging(config_file):
    logging.addLevelName(TRACE, 'TRACE')
    logging.addLevelName(BIZ, 'BIZ')

    # logging._addHandlerRef(V1FileHandler)

    logging.config.fileConfig(config_file)

def K(num) -> float:
    return num * 1000.

def M(num) -> float:
    return num * 10000.

def _(f: float):
    return round(f, 2)

def is_list(data) -> bool:
    return isinstance(data, (tuple, list, set))

def as_list(data, attr=None, dropna=True) -> [] or None:
    if data is None:
        return None

    if not is_list(data):
        data = [data]

    if attr is not None:
        data = [i.__getattribute__(attr) for i in data]

    if dropna:
        filter(lambda i: i is not None, data)

    return data

def generate_str(cls):
    """
    自动生成类的__str__和__repr__
    类中可以配置类属性_ignore_fields设置忽略的字段
    """

    def __str__(self):
        return '%s(%s)' % (
            type(self).__name__,
            ', '.join('%s=%s' % item for item in vars(self).items() if
                      not hasattr(cls, '_ignore_fields') or item[0] not in cls._ignore_fields)
        )

    def __repr__(self):
        return '%s(%s)' % (
            type(self).__name__,
            ', '.join('%s=%s' % item for item in vars(self).items() if
                      not hasattr(cls, '_ignore_fields') or item[0] not in cls._ignore_fields)
        )

    cls.__str__ = __str__
    cls.__repr__ = __repr__

    return cls

def fix(dt, fix_tz=True, fix_time=False):
    if fix_tz:
        dt = dt.replace(tzinfo=None)

    if fix_time:
        dt = dt.replace(hour=0, minute=0, second=0, microsecond=0)

    return dt

def fix_period(start, end, serial_type):
    """
    行情分析和数据获取时，需要指定时间区间，此函数用来规范化时间
    如果是日期的区间，那么开始时间总是对应的日期的0点0分，结束时间总是对应的日期的23:59分
    如果是时间的区间，那么开始时间总是对应的分钟的0秒，结束时间总是对应日期的59秒
    除了以上时间的规整，会去除时区信息
    :param start: 开始时间
    :param end: 结束时间
    :param serial_type: 周期类型
    :return:
    """
    assert start is not None
    assert end is not None
    assert serial_type is not None

    if SerialType.is_day(serial_type):
        return start.replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None), \
               end.replace(hour=23, minute=59, second=59, microsecond=0, tzinfo=None)
    else:
        return start.replace(second=0, microsecond=0, tzinfo=None), end.replace(second=59, microsecond=0, tzinfo=None)

def day_period(date: datetime, serial_type: SerialType, reversed: bool = False):
    """
    计算一个日期中指定周期类型的所有交易结束时间
    :param date: 指定日期
    :param serial_type: SerialType
    :param reversed: 返回结果是否倒排
    :return: 包含当日内的所有指定周期类型的时间清单
    """

    freq = str(minutes(serial_type)) + 'T'

    # 缓存
    key = date.strftime("%Y-%m-%d") + freq + "." + str(reversed)
    if key in _cache_day_period:
        return _cache_day_period[key]

    period = [
        datetime(date.year, date.month, date.day, hour=9, minute=30),
        datetime(date.year, date.month, date.day, hour=11, minute=30),
        datetime(date.year, date.month, date.day, hour=13, minute=0),
        datetime(date.year, date.month, date.day, hour=15, minute=0)]

    am = pd.date_range(start=period[0], end=period[1], freq=freq)
    pm = pd.date_range(start=period[2], end=period[3], freq=freq)

    data = [i for i in am.append(pm).to_pydatetime()]

    if reversed:
        data.reverse()

    _cache_day_period[key] = data
    return data

def minutes(serial_type: SerialType):
    """
    获取SerialType的分钟数
    :param serial_type: SerialType
    :return:
    """
    type_str = serial_type.name
    if not type_str.startswith("M"):
        return None

    return serial_type.value

def is_market_code(code: str):
    if code.startswith('_'):
        return True
    return False

def fix_code(df, col='code', col_bak="code_bak"):
    """
    修复code的前缀
    :param df:
    :param col:
    :return:
    """
    df[col] = df[col].map(fix_code_fn, na_action='ignore')
    return df

def fix_code_fn(v):
    assert v is not None, "na_action='ignore'"

    if not isinstance(v, str):
        return v

    if v.isnumeric():
        return v

    if v.startswith('sh'):
        return v.replace('sh', '')
    if v.startswith('sz'):
        return v.replace('sz', '')
    else:
        logging.getLogger().debug("不能识别的代码前缀:%s", v)
        return v


"""
    Imhotrack.io @ Imperial College London - Summer 2017
    Project: A Low-Power Motion sensor box with WebApp for Administion.
    Contributors: Pranav Prabhu
    Module: boxtracker
    Description: This file defines the url redirects within the Django Project File to the App (boxtracker)
"""
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^boxtracker/', include('boxtracker.urls')),
    url(r'^admin/', admin.site.urls),
    url(r'^$', include('boxtracker.urls'))
]


#!/usr/bin/env python3
# -*- coding=utf-8 -*-
# 本脚由亁颐堂现任明教教主编写，用于乾颐盾Python课程！
# 教主QQ:605658506
# 亁颐堂官网www.qytang.com
# 教主技术进化论拓展你的技术新边疆
# https://ke.qq.com/course/271956?tuin=24199d8a

import exifread
import re

def FindGPSimage(filepath):
    GPS = {}
    Date = ''
    f = open(filepath, 'rb')
    tags = exifread.process_file(f)
    for tag, value in tags.items():
        if re.match('GPS GPSLatitudeRef', tag):
            GPS['GPSLatitudeRef'] = str(value)
        elif re.match('GPS GPSLongitudeRef', tag):
            GPS['GPSLongitudeRef'] = str(value)
        elif re.match('GPS GPSAltitudeRef', tag):
            GPS['GPSAltitudeRef'] = int(str(value))
        elif re.match('GPS GPSLatitude', tag):
            try:
                match_result = re.match('\[(\w*), (\w*), (\w.*)/(\w.*)\]', str(value)).groups()
                GPS['GPSLatitude'] = int(match_result[0]), int(match_result[1]), int(match_result[2])/int(match_result[3])
            except:
                GPS['GPSLatitude'] = str(value)
        elif re.match('GPS GPSLongitude', tag):
            try:
                match_result = re.match('\[(\w*), (\w*), (\w.*)/(\w.*)\]', str(value)).groups()
                GPS['GPSLongitude'] = int(match_result[0]), int(match_result[1]), int(match_result[2])/int(match_result[3])
            except:
                GPS['GPSLongitude'] = str(value)
        elif re.match('GPS GPSAltitude', tag):
            GPS['GPSAltitude'] = str(value)
        elif re.match('.*Date.*', tag):
            Date = str(value)
    return {'GPS信息': GPS, '时间信息': Date}
    # ttp://www.gpsspg.com/maps.htm

if __name__ == '__main__':
    print(FindGPSimage(r"C:\Users\Administrator\PycharmProjects\Python_Network_2018_HTTP\8_Spider\Photo_Spider\Download_IMG\gps_test_1.jpg"))

# 运行结果
# {'GPS信息': {'GPSLatitudeRef': 'N', 'GPSLatitude': (39, 58, 38.481445), 'GPSLongitudeRef': 'E', 'GPSLongitude': (116, 17, 59.598999), 'GPSAltitudeRef': 1, 'GPSAltitude': '0'}, '时间信息': '2016:05:25 20:43:46'}


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

"""BoardGameGeek hotness spider."""

from datetime import timezone
from pathlib import Path

from pytility import parse_date
from scrapy import Request, Spider

from ..items import GameItem
from ..loaders import GameLoader
from ..utils import now

DATE_FORMAT = "%Y-%m-%dT%H-%M-%S"

class BggHotnessSpider(Spider):
    """BoardGameGeek hotness spider."""

    name = "bgg_hotness"
    allowed_domains = ("boardgamegeek.com",)
    start_urls = ("https://www.boardgamegeek.com/xmlapi2/hot?type=boardgame",)
    item_classes = (GameItem,)

    custom_settings = {
        "DOWNLOAD_DELAY": 0,
        "CONCURRENT_REQUESTS_PER_DOMAIN": 1024,
        "CONCURRENT_REQUESTS_PER_IP": 1024,
        "AUTOTHROTTLE_ENABLED": False,
        "AUTOTHROTTLE_TARGET_CONCURRENCY": 1024,
        "AUTOTHROTTLE_HTTP_CODES": (429, 503, 504),
    }

    def _local_requests(self, path_dir="."):
        path_dir = Path(path_dir).resolve()

        for path_file in path_dir.iterdir():
            if not path_file.is_file():
                continue

            self.logger.info("Processing <%s>", path_file)

            date = parse_date(
                path_file.stem,
                tzinfo=timezone.utc,
                format_str=DATE_FORMAT,
            )

            yield Request(
                url=path_file.as_uri(),
                callback=self.parse,
                meta={"published_at": date},
            )

    def start_requests(self):
        """Initial requests, either locally or from BGG."""

        hotness_dir = self.settings.get("BGG_HOTNESS_DIR")

        if hotness_dir:
            self.logger.info("Loading local files from <%s>", hotness_dir)
            yield from self._local_requests(hotness_dir)

        else:
            yield from super().start_requests()

    def parse(self, response):
        """
        @url https://www.boardgamegeek.com/xmlapi2/hot?type=boardgame
        @returns items 50 50
        @returns requests 0 0
        @scrapes published_at rank bgg_id name year image_url scraped_at
        """

        scraped_at = now()

        for game in response.xpath("/items/item"):
            ldr = GameLoader(item=GameItem(), selector=game, response=response)

            ldr.add_xpath("bgg_id", "@id")
            ldr.add_xpath("rank", "@rank")
            ldr.add_xpath("name", "name/@value")
            ldr.add_xpath("year", "yearpublished/@value")
            ldr.add_xpath("image_url", "thumbnail/@value")

            ldr.add_value("published_at", response.meta.get("published_at"))
            ldr.add_value("published_at", scraped_at)
            ldr.add_value("scraped_at", scraped_at)

            yield ldr.load_item()


import pandas as pd
from selenium import webdriver
from bs4 import BeautifulSoup
import sys
import os
import math
import time
from datetime import datetime
import xlwt

# 입력 받기
input_title = input('1. 크롤링할 영화 제목을 입력하세요: ')

while(True):
    input_num = input('2. 크롤링할 리뷰 건수는 몇 건입니까?: ')
    try:
        input_num = int(input_num)
        break
    except:
        print('다시 입력해주세요.')
        continue

input_path = input('3. 파일을 저장할 폴더명만 쓰세요: ')

if(input_path == '0'):
    input_path = os.getcwd()

# 웹드라이버 실행
driver = webdriver.Chrome(os.getcwd() + "/chromedriver.exe")
url = 'https://movie.naver.com'
driver.get(url)

# 검색어 입력
search_box =  driver.find_element_by_id('ipt_tx_srch')
search_box.send_keys(input_title)
time.sleep(2)

#검색어 클릭
driver.find_element_by_xpath('//*[@class="auto_tx_area"]/div[1]/ul/li[1]/a').click()
time.sleep(2)

#가장 정확도를 내는 코드 (사용X)
#driver.find_element_by_class_name('btn_srch').click()
#time.sleep(2)

# 검색목록에서 맨 첫번째 영화 클릭
#driver.find_element_by_xpath('//*[@id="old_content"]/ul[2]/li[1]/dl/dt/a').click()
#time.sleep(1)

# 평점
driver.find_element_by_xpath('//*[@id="movieEndTabMenu"]/li[5]/a').click()
time.sleep(1)

# 칼럼 리스트 준비
score = []
text = []
user = []
date = []
good = []
bad = []

# iframe 이동
driver.switch_to_default_content()
driver.switch_to_frame('pointAfterListIframe')

# 전체 소스 가져오기
full_html = driver.page_source
soup = BeautifulSoup(full_html, 'html.parser')

# 전체 글 수를 가져와서 입력받은 건수와 비교
total_comment = soup.find('div', class_='score_total').find('strong',class_='total').em.string
total_comment = int(total_comment.replace(",",""))
print('전체 글 수:',total_comment,'건\n')
if(total_comment < input_num):
    print('입력된 건수가 전체 리뷰 수보다 큽니다. 전체 리뷰 수로 대체합니다.')
    input_num = total_comment

# 크롤링한 글 수 카운트
count = 0

# 각 파일경로와 파일이름 설정
f_txt = input_path + '/' + input_title + '_' + '.txt'
f_csv = input_path + '/' + input_title + '_' + '.csv'
f_xls = input_path + '/' + input_title + '_' + '.xls'

while(True):

    # 리뷰 리스트 가져오기
    content_list =  soup.find('div',class_='ifr_area basic_ifr').find('div', class_ = 'score_result').find('ul').find_all('li')

    for li in content_list:

        count += 1

        # 각 요소 가져오기
        tmp_score = li.find('div', class_='star_score').find('em').text
        tmp_text = li.find('div', class_='score_reple').find('p').text
        tmp_user = li.find('div', class_='score_reple').find('dl').find('span').text
        tmp_date = li.find('div', class_='score_reple').find_all('em')[1].text
        tmp_good = li.find('div', class_='btn_area').find_all('strong')[0].text
        tmp_bad = li.find('div', class_='btn_area').find_all('strong')[1].text

        # 칼럼 리스트에 추가
        score.append(tmp_score)
        text.append(tmp_text)
        user.append(tmp_user)
        date.append(tmp_date)
        good.append(tmp_good)
        bad.append(tmp_bad)

        # 확인용 프린트
        print("총 %s 건 중 %s 번째 리뷰 데이터를 수집합니다===================================="%(input_num, count))
        print('1) 별점:', tmp_score)
        print('2) 리뷰내용:', tmp_text)
        print('3) 작성자:', tmp_user)
        print('4) 작성일자:', tmp_date)
        print('5) 공감:', tmp_good)
        print('6) 비공감:',tmp_bad)
        print('\n')

        # txt파일에 저장
        f = open(f_txt, 'a',encoding='UTF-8')
        f.write("총 %s 건 중 %s 번째 리뷰 데이터를 수집합니다===================================="%(input_num, count) + '\n')
        f.write('1) 별점: ' + tmp_score + '\n')
        f.write('2) 리뷰내용: ' + tmp_text + '\n')
        f.write('3) 작성자: ' + tmp_user + '\n')
        f.write('4) 작성일자: ' + tmp_date + '\n')
        f.write('5) 공감: ' + tmp_good + '\n')
        f.write('6) 비공감: ' + tmp_bad + '\n')
        f.write('\n')

        # 만약 현재 글 수가 입력건수에 도달하면 루프 종료
        if(count == input_num):
            break

    if(count == input_num):
        break

    # 아직 입력건수에 도달하지 않았다면 다음 페이지를 열고 루프 계속
    else:
        driver.find_element_by_class_name('pg_next').click()
        time.sleep(1)

        driver.switch_to_default_content()
        driver.switch_to_frame('pointAfterListIframe')

        full_html = driver.page_source
        soup = BeautifulSoup(full_html, 'html.parser')

# 데이터프레임 생성, 각 칼럼 리스트 넣기
df = pd.DataFrame()
df['별점'] = score
df['리뷰내용'] = text
df['작성자'] = user
df['작성일자'] = date
df['공감'] = good
df['비공감'] = bad

# 공백 줄바꿈 제거
for i in range(len(df)):
    df['리뷰내용'][i] = df['리뷰내용'][i].replace("\t","")
    df['리뷰내용'][i] = df['리뷰내용'][i].replace("\n","")

# 엑셀과 csv로 저장
df.to_excel(f_xls,encoding="utf-8-sig",index=True)
df.to_csv(f_csv,encoding="utf-8-sig",index=True)

data = pd.read_csv(f'./{input_title}/{input_path}_.csv')


import webapp2
from webapp2_extras.users import users
from webapp2_extras import jinja2
import models.user as user_model
import models.book as book_model

class BooksHandler(webapp2.RequestHandler):
    def get(self):

        usr = users.get_current_user()
        user = user_model.retrieve(usr)

        if usr and user:
            url_usr = users.create_logout_url("/")
            book_list = False
            books = book_model.all_books()
            listBooks = True
            template_values = {
                "books": books,
                "usr": usr,
                "user": user,
                "book_list": book_list,
                "listBooks": listBooks,
                "url_usr": url_usr
            }
            jinja = jinja2.get_jinja2(app=self.app)
            self.response.write(jinja.render_template("list_book.html", **template_values))
        else:
            return self.redirect("/")

app = webapp2.WSGIApplication([
    ('/books', BooksHandler)
], debug=True)


import bisect
import codecs
import io
import weakref
import re

DEFAULT_BUFSIZE = 4 * 1024

class UnicodeStreamer(object):
    """
    Class in charge of input byte stream. Input is converted to unicode,
    split in chunks, which are registered in a weakref dictionary.
    """

    def __init__(self, stream, encoding='utf-8', bufsize=None):
        if bufsize is None:
            bufsize = DEFAULT_BUFSIZE
        self.bufsize = bufsize
        self.lines = 0
        self.buffers = 0
        self.store = weakref.WeakValueDictionary()

        # We need to get a unicode stream, because otherwise dealing with
        # offsets, marks and errors will be a pain.

        # noinspection PyPep8Naming
        ReaderClass = codecs.getreader(encoding)
        if isinstance(stream, unicode):
            self.stream = io.StringIO(stream)
        elif isinstance(stream, str):
            self.stream = ReaderClass(io.BytesIO(stream))
        # TODO: coverage - test for stream created with codecs.open()
        elif getattr(stream, 'encoding', None):
            # This is a file opened using codecs.open() with an encoding
            # specified. It produces unicode output by itself, no wrapping
            # necessary.
            self.stream = stream
        else:
            self.stream = ReaderClass(stream)

    def _add_buffer(self, data):
        buf = Buffer(self.lines, data)
        self.store[self.buffers] = buf
        self.buffers += 1
        self.lines += len(buf.lines)
        return buf

    def chunks3(self):
        """
        Cut stream into chunks, register then in weakref dictionary and
        yield as  3-tuples: (previous, current, next).

        This way, a strong reference to current and surrounding chunks can be
        acquired for marks and such.
        """
        prev = None

        def next_buffer():
            data = read(self.bufsize)
            if data:
                return self._add_buffer(data)

        read = self.stream.read
        current = next_buffer()
        while current:
            next_ = next_buffer()
            yield prev, current, next_
            prev, current = current, next_

def find_newlines(s):
    """ Find locations of all newlines in the string """
    return [m.start() for m in re.finditer(u'\n', s)]

class Buffer(object):

    def __init__(self, start_line, data):
        assert isinstance(data, unicode)
        self.start_line = start_line
        self.data = data
        self.bytes_cnt = data.encode('utf-8')

        # Accumulated line lengths
        self.lines = find_newlines(data)
        # Don't forget the last line if it doesn't end in newline
        if self.data[-1] != u'\n':
            self.lines.append(len(self.data))

    def line_and_col(self, offset):
        """ Return line and column numbers given the offset """
        line = bisect.bisect_left(self.lines, offset)
        col = offset
        if line > 0:
            col -= self.lines[line - 1] + 1

        return line + self.start_line, col

class Mark(object):
    """
    Marks a position in the input character (or, more precisely,
    codepoint) stream. Holds a strong reference for the buffer it points to,
    and maybe some others as requested.
    """

    @property
    def pos(self):
        return "%s:%s" % (self.line, self.col)

    def __init__(self, manager, bufno, buf_offset, keep_buffers=()):
        self.manager = manager
        self.bufno = bufno
        self.buf = buf = manager.store[bufno]

        self.offset = bufno * manager.bufsize + buf_offset
        self.line, self.col = buf.line_and_col(buf_offset)

        # Keep the buffers from being garbage-collected
        self._kept_buffers = set()
        keep_buffers = set(keep_buffers).union({bufno - 1, bufno + 1})
        for x in keep_buffers:
            if not isinstance(x, Buffer):
                x = self.manager.store.get(x)
            if x:
                self._kept_buffers.add(x)


from argparse import ArgumentParser
from .commands import commands
from .constants import ReturnCodes

parser = ArgumentParser(
    description='Lock and convert dependencies between formats.',
)
parser.add_argument('command', choices=commands.keys(), help='command to execute')

def main(argv):
    args = parser.parse_args(argv[:1])
    if args.command is None:
        parser.parse_args('--help')
    command = commands[args.command]
    task = command(argv[1:])

    is_valid = task.validate()
    if not is_valid:
        return ReturnCodes.INVALID_CONFIG.value

    result = task()
    if not result:
        return ReturnCodes.COMMAND_ERROR.value
    return ReturnCodes.OK.value


import _thread
from multiprocessing.pool import ThreadPool
from multiprocessing.connection import Listener
from array import array

def setupConnection(address, debugFlag):
    #Gets the size of the item with 20 length
    print("Always Be coding")
    choice = 'y'
    while choice == 'y':
        with Listener(address, authkey=b'go beyond Plus ULTRA!') as listener:
            with listener.accept() as conn:
                print('connection accepted from', listener.last_accepted)
                while True:
                    try:
                        print("Attempting the thread.")
                        message = conn.recv_bytes()
                        email = message.decode("utf-8")
                        #print(email)
                        emailChk = ['utkeitaro_gmail.com', 'db_gmail.com', 'minecraft_gmail.com']
                        flag = False
                        for emails in emailChk:
                            if emails == email:
                                flag = True
                                print(str(emails) + ' == ' + email )
                                print("Found email, preparing process.")
                                break
                        #print("Email == " + str(email))
                        if flag:
                            print("Running item.")
                        elif(email == 'TM86'):
                            print('closing the connection.')
                            conn.close()
                            choice = 'n'
                            #return choice
                        else:
                            print(email)
                            print("email is non existant")
                    except KeyboardInterrupt:
                        conn.close()
                        print("Terminating server...")
                        choice == 'n'
                        #return choice
                        break

if __name__ == '__main__':
    address = ('localhost', 6001)   #Auto determines AF_INET
    choice = 'y'
    numOfThreads = 0

    while choice == 'y':
        print("This begins")
        pool = ThreadPool(processes = 2)
        asyncResult = pool.apply_async(setupConnection, (address, True))
        choice = asyncResult
        print("This ends ", choice)


from django.http import response
from django.http.response import HttpResponse
from django.shortcuts import render

def index(request):
    return render(request, "index.html")

def analyze(request):

    # Get the text
    djtext = request.POST.get('text', 'default')
    removepunc1 = request.POST.get('removepunc1', 'off')
    fullcaps = request.POST.get('fullcaps', 'off')
    nlr = request.POST.get('nlr', 'off')
    extraspace = request.POST.get('extraspace', 'off')
    charcount = request.POST.get('charcount', 'off')

    # analyzed = djtext
    # print(analyzed)

    if removepunc1 == "on":
        punctuations = ''' !"#$%&'()*+, -./:;<=>?@[\]^_`{|}~ '''
        analyzed = ""

        for char in djtext:
            if char not in punctuations:
                analyzed = analyzed+char

        params = {'purpose': 'Removed Punctuations', 'analyzed_text': analyzed}
        djtext = analyzed
        # return render(request, 'analyze.html', params)

    if (fullcaps == "on"):
        analyzed = ""
        for char in djtext:
            analyzed = analyzed+char.upper()

        params = {'purpose': 'changed to UpperCase Character',
                  'analyzed_text': analyzed}
        djtext = analyzed
        # return render(request, 'analyze.html', params)

    if (nlr == "on"):
        analyzed = ""

        for char in djtext:
            if char != "\n" and char != "\r":
                analyzed = analyzed+char.upper()

        params = {'purpose': 'Removed NewLines',
                  'analyzed_text': analyzed}
        djtext = analyzed
        # return render(request, 'analyze.html', params)

    if (extraspace == "on"):
        analyzed = ""

        for char in djtext:
            if char != " ":
                analyzed = analyzed+char

        params = {'purpose': 'Removed Extra Space',
                  'analyzed_text': analyzed}
        djtext = analyzed
        # return render(request, 'analyze.html', params)

    if (charcount == "on"):
        count = 0

        for char in djtext:
            count = count+1

        params = {'purpose': 'No of characters in text',
                  'analyzed_text': count}
        #djtext = analyzed
        # return render(request, 'analyze.html', params)
    if (charcount != "on" and extraspace != "on" and nlr != "on" and removepunc1 != "on" and fullcaps != "on"):
        return HttpResponse("
Please select anyone option:
 ")

    return render(request, 'analyze.html', params)

def removepunc(request):
    return HttpResponse("remove punc")

def capitalisefirst(request):
    return HttpResponse("capitalize first")

def NewLineremove(request):
    return HttpResponse("capitalize first")

def spaceRemover(request):
    return HttpResponse("space remover")

def characterCounter(request):
    return HttpResponse("charcount ")