import time
import datetime
import json
import re

import requests

class WeiBo:

    def __init__(self):
        self.profile_url = "https://m.weibo.cn/profile/info"
        self.config_url = "https://m.weibo.cn/api/config"
        self.get_ch_url = "https://m.weibo.cn/api/container/getIndex?containerid=100803_-_followsuper&since_id={}"
        self.check_url = "https://api.weibo.cn/2/page/button"
        self.web_check_url = "https://weibo.com/p/aj/general/button"
        self.day_score_url = "https://huati.weibo.cn/aj/super/receivescore"
        self.get_super_score_url = "https://huati.weibo.cn/aj/super/getscore"
        self.pick_url = "https://huati.weibo.cn/aj/super/picktop"
        self.report_story_url = "https://m.weibo.cn/api/statuses/repost"
        self.comment_story_url = "https://m.weibo.cn/api/comments/create"
        self.star_story_url = "https://m.weibo.cn/api/attitudes/create"
        self.seconds = 5
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, "
                          "like Gecko) Chrome/83.0.4103.116 Mobile Safari/537.36 ",
            "cookie": ""
        }
        self.gsid = ""
        self.log = []

    def set_cookie(self, cookies):
        """
        配置类对象的cookie和gsid参数
        :param cookies: 通过 https://m.weibo.cn/ 登陆获取cookie
        :return: None
        """
        self.headers['cookie'] = cookies
        self.gsid = re.findall("SUB=(.*?);", cookies)[0]

    def get_profile(self):
        """
        获取个人信息
        :return: user_dict
        """
        profile_response = requests.get(self.profile_url, headers=self.headers)
        user = profile_response.json()["data"]["user"]
        user_dict = {
            "profile_id": user["id"],
            "profile_name": user["screen_name"],
            "profile_description": user["description"] if user["description"] else "nothing",
            "profile_avatar": user["avatar_hd"],
            "profile_gender": "fmale" if user["gender"] == "f" else "male",
            "statuses_count": user["statuses_count"],
            "follow_count": user["follow_count"],
            "followers_count": user["followers_count"],
            "profile_url": user["profile_url"],
            "all_container_id": profile_response.json()["data"]["more"].split("/")[-1]
        }
        self.log.append(f"""ID: {user["id"]}
NAME: {user["screen_name"]}
简介: {user["description"] if user["description"] else "这个人很懒，什么也没有"}
微博数: {user["statuses_count"]}
关注数: {user["follow_count"]}
粉丝数: {user["followers_count"]}
        """)
        print(f"User:{user['screen_name']}")
        return user_dict

    def get_ch_list(self):
        """
        获取超话关注列表
        :return: ch_list(列表套字典)
        """
        ch_list = []
        since_id = ""
        while True:
            ch_res = requests.get(
                url=self.get_ch_url.format(since_id),
                headers=self.headers
            )
            print(len(ch_res.json()["data"]["cards"]))
            # print(ch_res.json()["data"]["cards"])
            chg_list = []
            for chg in ch_res.json()["data"]["cards"]:
                chg_list.extend(chg["card_group"])
            # ch_json = ch_res.json()["data"]["cards"][0]["card_group"]
            ch_json = chg_list
            # print(ch_json)
            for ch in ch_json:
                if ch["card_type"] == "8":
                    ch_dict = {
                        "title": ch["title_sub"],
                        "level": ch["desc1"],
                        "status": ch["buttons"][0]["name"],
                        "url": ch["scheme"],
                        "id": re.findall('[0-9a-z]{38}', ch["scheme"])[0]
                    }
                    msg = '标题 {}，{}，签到状态 {}'.format(ch_dict["title"], ch_dict["level"], ch_dict["status"])
                    print(msg)
                    # self.log.append(msg)
                    ch_list.append(ch_dict)
            since_id = ch_res.json()["data"]["cardlistInfo"]["since_id"]
            if since_id == "":
                return ch_list

    def get_story_list(self, ch_url):
        """
        获取超话微博（前两页）
        :param ch_url: 超话url
        :return: story_list（列表套字典）
        """
        count = 0
        since_id = ""
        story_list = []
        while True:
            index_url = f"https://m.weibo.cn/api/container/getIndex?{ch_url.split('?')[-1]}&since_id={since_id}"
            index_res = requests.get(index_url, headers=self.headers)
            cards = index_res.json()["data"]["cards"]
            scheme_list = []
            for card_group in cards:
                if card_group["itemid"] == "":
                    for card in card_group["card_group"]:
                        if card["card_type"] == "9":
                            scheme_list.append(card["scheme"])
            for scheme in scheme_list:
                show_url = f"https://m.weibo.cn/statuses/show?id={re.findall('[0-9a-zA-Z]{9}', scheme)[0]}"
                detail_res = requests.get(show_url, headers=self.headers)
                story_dict = {
                    "user": detail_res.json()["data"]["user"]["screen_name"],
                    "mid": detail_res.json()["data"]["id"]
                }
                story_list.append(story_dict)
            since_id = index_res.json()["data"]["pageInfo"]["since_id"]
            count = count + 1
            if count == 2:
                return story_list

    def check_in(self, s, ch_dict):
        """
        微博国际版APP签到接口
        :param s: 特定的数字，抓包获取
        :param ch_dict: 超话信息字典,具体格式请看get_ch_list函数中
        :return:
        """
        check_data = {
            "c": "weicoabroad",
            "s": s,
            "wm": "2468_1001",
            "gsid": self.gsid,
            "from": "1299295010",
            "source": "4215535043",
            "lang": "zh_CN",
            'ua': "Redmi+K20+Pro+Premium+Edition_10_WeiboIntlAndroid_3610",
            "request_url": f"http%3A%2F%2Fi.huati.weibo.com%2Fmobile%2Fsuper%2Factive_checkin%3Fpageid%3D{ch_dict['id']}",
        }
        check_res = requests.get(
            url=self.check_url,
            params=check_data,
        )
        print(check_res.json())
        errmsg = check_res.json().get('errmsg')
        if errmsg:
            msg = f'TopicName：{ch_dict["title"]}  s参数设置有误'
            print(msg)
            self.log.append(msg)
            return msg
        elif check_res.json()['result']==388000:
            msg = f'TopicName：{ch_dict["title"]}  状态异常,需手动签到'
            print(msg)
            self.log.append(msg)
            return msg
        else:
            c_msg = check_res.json()["msg"].replace("\n", "/")
            msg = f'TopicName：{ch_dict["title"]}--{ch_dict["level"][-4:]}\n' \
                  f'Message：{c_msg}'
            print(msg)
            self.log.append(msg)
            return msg

    def get_day_score(self):
        """
         超话每日积分领取
        :return:
        """
        day_score_headers = {
            'X-Requested-With': 'XMLHttpRequest',
            'Referer': 'https://huati.weibo.cn'
        }
        day_score_headers.update(self.headers)
        score_data = {
            'type': 'REQUEST',
            'user_score': 999
        }
        day_score_res = requests.post(
            url=self.day_score_url,
            headers=day_score_headers,
            data=score_data
        )
        if day_score_res.json()["code"] == 100000:
            msg = f'今日签到获取:{day_score_res.json()["data"]["add_score"]}分'
            print(msg)
            self.log.append(msg)
            return msg
        elif day_score_res.json()["code"] == 386011:
            msg = f'{day_score_res.json()["msg"]}'
            print(msg)
            self.log.append(msg)
            return msg
        elif day_score_res.json()["code"] == 100002:
            msg = f'{day_score_res.json()["msg"]}'
            print(msg)
            self.log.append(msg)
            return msg

    def get_score_bang(self, ch_dict):
        """
        获取超话积分&打榜
        :param ch_dict: 超话信息字典,具体格式请看get_ch_list函数中
        :return:
        """
        referer_url = f"https://huati.weibo.cn/aj/super/getscore?page_id={ch_dict['id']}&aid=&from={re.findall('WEIBOCN_FROM=(.*?);', self.headers['cookie'])[0]}"
        get_score_headers = {
            "Referer": referer_url,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36",
            "cookie": self.headers.get("cookie"),
            "X-Requested-With": "XMLHttpRequest"
        }
        score_res = requests.get(referer_url, headers=get_score_headers)
        topic_name = score_res.json()["data"]["topic_name"]
        score = score_res.json()["data"]["score"]
        rank = score_res.json()["data"]["rank"]
        # print(score_res.json())
        if score_res.json()["data"]["user_total_score"] > 100:
            while True:
                pick_data = {
                    "topic_name": ch_dict["title"],
                    "page_id": ch_dict["id"],
                    "score": score_res.json()["data"]["user_total_score"],
                    "is_pub": "0",
                    "cur_rank": score_res.json()["data"]["rank"],
                    "ctg_id": score_res.json()["data"]["ctg_id"],
                    "topic_score": score_res.json()["data"]["score"],
                    "index": "select256",
                    "user_score": score_res.json()["data"]["user_total_score"],
                    "aid": "",
                    "device": '{"timezone":"Asia/Shanghai","lang":"zh","plat":"Win32",'
                              '"ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'
                              ' Chrome/84.0.4147.105 Safari/537.36","screen":"864*1536","aid":"","from":"1110006030"}',
                    "param": score_res.json()["data"]["encryption_param"]
                }
                pick_res = requests.post(self.pick_url, headers=get_score_headers, data=pick_data)
                if pick_res.json()["code"] == 402001:
                    continue
                elif pick_res.json()["code"] == 302001:
                    print(pick_res.json()["msg"])
                    return pick_res.json()["msg"]
                else:
                    msg = f"TopicName：{topic_name}\nRank：{rank}/{score}分\nMsg：{pick_res.json()['data']['add_int_msg']}"
                    self.log.append(msg)
                    print(msg)
                    return msg
        else:
            msg = f'TopicName：{topic_name}\nRank：{rank}/{score}分\n' \
                  f'Message：当前积分为{score_res.json()["data"]["user_total_score"]}, 积分少于100，暂不打榜'
            self.log.append(msg)
            print(msg)
            return msg

    def get_st(self):
        """
        获取st参数,用于转发评论与点赞
        :return: st
        """
        st_response = requests.get(self.config_url, headers=self.headers)
        if st_response.json()["ok"] == 1:
            if str(st_response.json()["data"]["login"]) == "True":
                st = st_response.json()["data"]["st"]
                return st
            else:
                return ""
        else:
            return ""

    def report_story(self, mid, st, content):
        """
         转发微博
        :param mid: 微博mid
        :param st: get_st()获取
        :param content: 评论内容
        :return:
        """
        report_data = {
            "id": mid,
            "content": content,
            "mid": mid,
            "st": st,
            "_spr": "screen:411x731"
        }
        report_headers = {
            "referer": f"https://m.weibo.cn/compose/repost?id={mid}"
        }
        report_headers.update(self.headers)
        report_res = requests.post(self.report_story_url, headers=report_headers, data=report_data)
        if report_res.json()["ok"] == 1:
            msg = f"转发微博MID：{mid} {report_res.json()['data']['created_at']} " \
                  f"{content} 转发成功 转发后微博MID: {report_res.json()['data']['id']}"
            print(msg)
            # self.log.append(msg)
            # return msg
        else:
            msg = f"{mid} {report_res.json()['msg']}/转发失败"
            print(msg)
            # self.log.append(msg)
            # return msg

    def comment_story(self, mid, st, content):
        """
        评论微博
        :param mid: 微博mid
        :param st: get_st()获取
        :param content: 转发描述
        :return:
        """
        comment_data = {
            "content": content,
            "mid": mid,
            "st": st,
            "_spr": "screen:411x731"
        }
        comment_headers = {
            "referer": f"https://m.weibo.cn/detail/{mid}"
        }
        comment_headers.update(self.headers)
        comment_res = requests.post(self.comment_story_url, headers=comment_headers, data=comment_data)
        if comment_res.json()["ok"] == 1:
            msg = f"评论微博MID：{mid} {comment_res.json()['data']['created_at']} {content} 评论成功"
            print(msg)
            # self.log.append(msg)
            # return msg
        else:
            msg = f"{comment_res.json()['msg']}评论失败"
            print(msg)
            # self.log.append(msg)
            # return msg

    def star_story(self, mid, st):
        """
        点赞微博
        :param mid: 微博mid
        :param st: get_st()获取
        :return:
        """
        star_data = {
            "id": mid,
            "attitudes": "heart",
            "st": st,
            "_spr": "screen:411x731"
        }
        star_headers = {
            "referer": f"https://m.weibo.cn/detail/{mid}"
        }
        star_headers.update(self.headers)
        star_response = requests.post(url=self.star_story_url, headers=star_headers, data=star_data)
        if star_response.json()["ok"] == 1:
            msg = f"点赞微博MID：{mid} {star_response.json()['data']['created_at']} 点赞成功"
            print(msg)
            # self.log.append(msg)
            # return msg
        else:
            msg = "点赞失败"
            print(msg)
            # self.log.append(msg)
            # return msg

    def server_push(self, sckey):
        """
        Sever酱推送
        :param sckey: 微信推送key，通过https://sc.ftqq.com/3.version获取
        :return:
        """
        now_time = datetime.datetime.now()
        bj_time = now_time + datetime.timedelta(hours=8)
        test_day = datetime.datetime.strptime('2020-12-19 00:00:00', '%Y-%m-%d %H:%M:%S')
        date = (test_day - bj_time).days
        text = f"微博超话打卡---{bj_time.strftime('%H:%M:%S')}"
        desp = f"""
------
### 🚁Now：
```
{bj_time.strftime("%Y-%m-%d %H:%M:%S %p")}
```
{self.get_log()}

### 🚀Deadline:
```
考研倒计时--{date}天
```

>
> [GitHub项目地址](https://github.com/ReaJason/WeiBo_SuperTopics)
>
>期待你给项目的star✨
"""
        server_push_headers = {
            "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
        }
        send_url = f"https://sc.ftqq.com/{sckey}.send"
        params = {
            "text": text,
            "desp": desp
        }
        response = requests.post(send_url, data=params, headers=server_push_headers)
        return response.json()["errmsg"]

    def get_log(self):
        """
        获取日志信息
        :return: log_str
        """
        return "\n".join(self.log)

    # 每超话签到+每日积分获取+超话打榜
    def daily_task(self, cookie, s, pick_name, sckey):
        self.set_cookie(cookies=cookie)
        ch_list = self.get_ch_list()
        print("获取个人信息")
        self.log.append("### 💫User：")
        self.log.append("```")
        self.get_profile()
        self.log.append("```")
        print("开始超话签到")
        self.log.append("### ✨CheckIn：")
        self.log.append("```")
        for i in ch_list:
            time.sleep(self.seconds)
            self.check_in(s, i)
        self.log.append("```")
        print("获取每日积分")
        self.log.append("### 🔰DailyScore：")
        self.log.append("```")
        self.get_day_score()
        self.log.append("```")
        # print("开始打榜")
        # self.log.append("### 💓Pick：")
        # self.log.append("```")
        # self.get_score_bang([i for i in ch_list if i["title"] == pick_name][0])
        # self.log.append("```")
        self.server_push(sckey)

if __name__ == '__main__':
    # test()
    cookie = input()
    s = input()
    pick = input()
    sckey = input()
    check = WeiBo()
    check.daily_task(cookie=cookie, s=s, pick_name=pick, sckey=sckey)


from torch._C import device
import torch.nn as nn
import torch.nn.functional as F
from torch.nn import init
import torch
import numpy as np

class CMD_BLOCK(nn.Module):
    def __init__(self,emb_s=256):
        super(CMD_BLOCK,self).__init__()
        dim = emb_s*2
        # self.emb_Layer = EmbfixLayer()
        self.L1 = nn.Linear(dim,dim)
        self.activation = nn.ReLU()
        self.L2 = nn.Linear(dim,int(dim/2))
        self.L3 = nn.Linear(int(dim/2),int(dim/4))
        self.L4 = nn.Linear(int(dim/4),1)
        self.dropout = nn.Dropout(0.2)
        self.sig_class = nn.Sigmoid()

    def forward(self,x):
        # x = self.emb_Layer(x)
        x = self.L1(x) #.type(torch.FloatTensor)
        x = self.activation(x)
        x = self.L2(x)
        x = self.activation(x)
        x = self.L3(x)
        x = self.activation(x)
        x = self.dropout(x)
        x = self.L4(x)
        # x = self.sig_class(x)
        return x

class CIND_Block(nn.Module):
    def __init__(self, dim = 7):
        super(CIND_Block,self).__init__()
        in_ch = 2048
        n_ch = 256
        self.dim = dim
        # self.op_1 = CIN_diff
        self.cnv1 = nn.Conv2d(n_ch, n_ch, 5, 5)
        self.cnv2 = nn.Conv2d(n_ch, n_ch, 3)
        self.cnv3 = nn.Conv2d(n_ch, n_ch, 3)
        self.relu = nn.ReLU(inplace=True)
        self.bn = nn.BatchNorm2d(n_ch)
        self.avgpool = nn.AdaptiveAvgPool2d(1)
        self.L1 = nn.Linear(n_ch, 1)

    def forward(self, x):

        # x = self.op_1(x)
        x = self.cnv1(x)
        x = self.relu(x)
        x = self.cnv2(x)
        x = self.relu(x)
        x = self.cnv3(x)
        x = self.relu(x)
        x = self.bn(x)
        x = self.avgpool(x)
        #dropout Flatten, Dense, Lambda
        x = x.view(x.size(0), -1)
        x = self.L1(x)

        return x

class CIND(nn.Module):
    def __init__(self):
        super(CIND, self).__init__()
        cind_block = CIND_Block
        self.f_block = self._make_layers(cind_block)

    def _make_layers(self,block):
        layers = []
        layers.append(block())
        return nn.Sequential(*layers)
    def forward(self, x):
        x = self.f_block(x)
        return x

class CMD(nn.Module):
    def __init__(self, emb_s = 256):
        super(CMD, self).__init__()
        cmd_block = CMD_BLOCK
        self.f_block = self._make_layers(cmd_block)
        # device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    def _make_layers(self,block):
        layers = []
        layers.append(block())
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.f_block(x)
        return x

class EmbfixLayer(nn.Module):
    def __init__(self):
        super(EmbfixLayer,self).__init__()
        # self.no_img, self.emb_size = x.size()[0], x.size()[1]

    def forward(self, x):
        x = torch.cat((
            x.view(1,x.size()[0],x.size()[1]).tile((x.size()[0],1,1)),
            x.tile(1,1,x.size()[0]).reshape(x.size()[0], x.size()[0],x.size()[1])
            ),2).reshape(-1,x.size()[1]*2)
        return x

def CMDLoss(input, target):
    # edit targets
    no_img = target.size()[0]
    t_v = torch.transpose(target.tile(1,no_img),0,1)
    t_h = target.view(no_img,1).tile(1,no_img).view(no_img*no_img,1)
    target_mat = torch.eq(t_v, t_h).type(torch.FloatTensor).to(torch.device('cuda'))
    loss = nn.BCEWithLogitsLoss()
    return loss(input, target_mat)

def CMD_Lbl_maker(target): #(1744, 1)
    if not torch.is_tensor(target):
            target = torch.tensor(target)
    no_img = target.size()[0]
    t = target.view((-1))
    t_v = torch.transpose(t.tile(1,no_img),0,1)
    t_h = t.view(no_img,1).tile(1,no_img).view(no_img*no_img,1)
    t = torch.eq(t_v, t_h).type(torch.FloatTensor).to(torch.device('cuda'))
    return t

def CIN_diff(target): #(32 128 7 7)
    scale = 5
    upsam_op = torch.nn.Upsample(scale_factor=scale,mode='nearest') ## fixit
    pading = torch.nn.ZeroPad2d(2)

    # A to B tiling the batch dimension
    x_r = torch.tile(target,(target.size()[0],1,1,1)) # 123,123,123
    x_l = torch.tile(target,(1,target.size()[0],1,1)).view(-1,target.size()[1],target.size()[2],target.size()[3]) #111,222,333

    # tiling in the spacial dimension
    x_l = upsam_op(x_l)

    x_r = pading(x_r)
    slice_x = []
    slice_y = []
    for x_i in range(2, x_r.size()[2] -2):
        for x_j in range(2, x_r.size()[3]-2):
            slice_y.append(x_r[:,:,x_i-2:x_i+3,x_j-2:x_j+3])
            # print(x_i, x_j)
            # print(x_r[0,0,x_i-2:x_i+3,x_j-2:x_j+3])
        slice_x.append(torch.cat(slice_y,dim=3))
        slice_y= []

    x_r = torch.cat(slice_x,dim=2)

    diff = torch.sub(x_l,x_r)

    # B to A tiling the batch dimension
    x_l = torch.tile(target,(target.size()[0],1,1,1)) # 123,123,123
    x_r = torch.tile(target,(1,target.size()[0],1,1)).view(-1,target.size()[1],target.size()[2],target.size()[3]) #111,222,333

    # tiling in the spacial dimension
    x_l = upsam_op(x_l)

    x_r = pading(x_r)
    slice_x = []
    slice_y = []
    for x_i in range(2, x_r.size()[2] -2):
        for x_j in range(2, x_r.size()[3]-2):
            slice_y.append(x_r[:,:,x_i-2:x_i+3,x_j-2:x_j+3])
        slice_x.append(torch.cat(slice_y,dim=3))
        slice_y= []
    x_r = torch.cat(slice_x,dim=2)

    diff = torch.cat((torch.sub(x_l,x_r),diff),dim=1)

    # for x_i in range(2, x_r.size()[2] -2):
    #     for x_j in range(2, x_r.size()[3]-2):
    #         slice_y.append(x_r[:,:,x_i-2:x_i+3,x_j-2:x_j+3])
    #         print(x_i, x_j)
    #         print(x_r[0,0,x_i-2:x_i+3,x_j-2:x_j+3])
    #         print(x_l[0,0,x_i-2:x_i+3,x_j-2:x_j+3])

    return diff

def CINDLoss(input, target):
    ## NEEDS TO BE IMPLEMENTED
    # x_r = torch.tile(target,(target.size()[0],1,1,1)) # 123,123,123
    # x_l = torch.tile(target,(1,target.size()[0],1,1)).view(-1,target.size()[1],target.size()[2],target.size()[3]) #111,222,333

    no_img = target.size()[0]
    t_v = torch.transpose(target.tile(1,no_img),0,1)
    t_h = target.view(no_img,1).tile(1,no_img).view(no_img*no_img,1)
    target_mat = torch.eq(t_v, t_h).type(torch.FloatTensor).to(torch.device('cuda'))

    loss = nn.BCEWithLogitsLoss()
    return loss(input, target_mat)

# dim = 7
# ch = 128
# emb = 400
# x = torch.arange(0,emb * ch* dim * dim).view([emb, ch, dim, dim]).type(torch.float)
# y = CIND_Block()
# x =  y(x)


"""
Booking system for KSB washing rooms/ common rooms
bksjdlabsER_AGE
"""

__author__ = 'Lundh'

from bs4 import BeautifulSoup as BS
import requests
import sys
import time
import grid_logic
import datetime as dt
import logging
import pickle

headers = {'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.13) Gecko/2009073022 Firefox/3.0.13',
        'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml; q=0.9,*/*; q=0.8',
        'Content-Type': 'application/x-www-form-urlencoded'}

url_target_home = "http://booking.kistastudentbostader.se/ksb/default.aspx"

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# create a file handler
handler = logging.FileHandler('booker.log')
handler.setLevel(logging.INFO)

# create a logging format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# add the handlers to the logger
logger.addHandler(handler)

def extract_page_data(payload, session, url):
    """post validation data"""
    #print "Extracting data" sdasadas
    #global payload, session

    if "__VIEWSTATE" not in payload:
        #print "Connecting to: " + url
        t = session.post(url)
    else:
        #print "Connecting to: " + url + "\n Using: " + str(payload)
        t = session.post(url, data=payload)
    #print(t.text)

    soup = BS(t.text)
    payload["__VIEWSTATE"] = soup.find('input', {'id' : '__VIEWSTATE'})['value']
    payload["__EVENTVALIDATION"] = soup.find('input', {'id' : '__EVENTVALIDATION'})['value']
    return t.text

def book(payload, pref_time, weekday, side, room, weeknr):
    session = requests.Session()
    #first time only for viewstate and event val
    logger.info("Trying to Book: {0}, {1}, {2}, {3}, {4}, {5}".format(payload, pref_time, weekday, side, room, weeknr))
    payload["__EVENTARGUMENT"] = ""
    payload["__EVENTTARGET"] = ""
    text = extract_page_data(payload, session, url_target_home)
    #print(text)

    #getting to the booking screen
    payload["__EVENTTARGET"] = "_ctl0$ContentPlaceHolder1$btOK"
    text = extract_page_data(payload, session, url_target_home)
    #print(text)
    #time.sleep(1)
    if side == 1:
        payload["__EVENTTARGET"] = "_ctl0$ContentPlaceHolder1$dgTerminaler$_ctl3$_ctl0"
    elif side == 2:
        payload["__EVENTTARGET"] = "_ctl0$ContentPlaceHolder1$dgTerminaler$_ctl2$_ctl0"
    #andra sidan: "_ctl0$ContentPlaceHolder1$dgTerminaler$_ctl2$_ctl0"
    url = "http://booking.kistastudentbostader.se/KSB/Booking/TerminalSelector.aspx"
    text = extract_page_data(payload, session, url)
    #print text
    #time.sleep(1)

    payload["__EVENTTARGET"] = "_ctl0$LinkBooking"
    url = "http://booking.kistastudentbostader.se/KSB/Booking/BookingMain.aspx"
    text = extract_page_data(payload, session, url)
    #print text

    #time.sleep(1)
    #RUMVAL 1: "_ctl0$ContentPlaceHolder1$dgForval$_ctl2$_ctl0"
    #RUMVAL 2: "_ctl0$ContentPlaceHolder1$dgForval$_ctl3$_ctl0"
    if room == 1 or room == 2:
        payload["__EVENTTARGET"] = "_ctl0$ContentPlaceHolder1$dgForval$_ctl2$_ctl0"
    elif room == 3 or room == 4:
        payload["__EVENTTARGET"] = "_ctl0$ContentPlaceHolder1$dgForval$_ctl3$_ctl0"

    url = "http://booking.kistastudentbostader.se/KSB/Booking/Prechoices.aspx"
    text = extract_page_data(payload, session, url)
    #print text
    #you should now be at the booking screen

    for x in range(0, weeknr):
        logger.info("Changing week: %s", str(weeknr))
        payload["__EVENTTARGET"] = ""
        payload["_ctl0:ContentPlaceHolder1:btCalendarNext"] = ">>"
        url = "http://booking.kistastudentbostader.se/KSB/Booking/BookingCalendar.aspx"
        text = extract_page_data(payload, session, url)
    #print text

    #Adjust the rooms since the sizes are inverted on either side
    room_size = 0
    if (side == 1 and room == 3) or (side == 2 and room == 2):
        room_size = 1
    if (side == 1 and room == 4) or (side == 2 and room == 1):
        room_size = 2

    booked = False
    while not booked or weeknr > 4:
        grid_numbers = grid_logic.get_grid(pref_time, weekday, room_size)
        #print(grid_numbers)
        soup = BS(text)
        target_day_bookings = 0
        grid_index = None
        vacant_room = False
        #print(soup)
        for grid in grid_numbers:
            #print("_ctl0_ContentPlaceHolder1_" + grid)
            #print(soup.find("input", {'id': "_ctl0_ContentPlaceHolder1_" + grid})["title"])
            if "Vacant" in soup.find("input", {'id': "_ctl0_ContentPlaceHolder1_" + grid})["title"]:
                vacant_room = True
                target_day_bookings += 1
        if vacant_room:
            logger.info("Available washer found: %s", grid)
            payload["__EVENTTARGET"] = "BookPass"+grid
            payload["__EVENTARGUMENT"] = grid
            url = "http://booking.kistastudentbostader.se/KSB/Booking/BookingCalendar.aspx"
            text = extract_page_data(payload, session, url)

            #meny to choose washer dissapears if there is only one available
            if target_day_bookings > 1:
                payload["__EVENTARGUMENT"] = ""
                payload["__EVENTTARGET"] = "_ctl0$ContentPlaceHolder1$dgGrupptyp$_ctl2$_ctl0"
                url = "http://booking.kistastudentbostader.se/KSB/Booking/MachineGroupType.aspx"
                text = extract_page_data(payload, session, url)

            booked = True
        else:
            logger.info("No available washer found, changing week ")
            weeknr += 1
            for x in range(0, weeknr):
                payload["__EVENTTARGET"] = ""
                payload["_ctl0:ContentPlaceHolder1:btCalendarNext"] = ">>"
                url = "http://booking.kistastudentbostader.se/KSB/Booking/BookingCalendar.aspx"
                text = extract_page_data(payload, session, url)
                continue

    soup = BS(text)
    temp = str(soup.find(id="_ctl0_ContentPlaceHolder1_lbBokningsbekraftelseBokning3"))
    tempi = temp.find("You have ")
    templ = len("You have ")
    temp = temp[tempi+templ:tempi+templ+2]
    #print temp
    try:
        bookings_left = int(temp)
    except ValueError:
        bookings_left = 0
    #print bookings_left
    if bookings_left > 0:
        payload["__EVENTTARGET"] = "_ctl0$LinkLogOut"
        url = "http://booking.kistastudentbostader.se/KSB/Booking/BookingDone.aspx"
        extract_page_data(payload, session, url)
        #logg out nad redo but with next week
        logger.info("Number of bookings left was:" + str(bookings_left) + ". Booking continues")
        del payload["__VIEWSTATE"]
        del payload["__EVENTVALIDATION"]
        book(payload, pref_time, weekday, side, room, weeknr)
        return
    else:
        logger.info("No more bookings left, booking finished.")
        return 1

def check_bookings():
    try:
        with open("bookings.pkl", "rb") as myfile:
            user_data = pickle.load(myfile)
            for key in user_data.keys():
                user = user_data[key]
                payload = dict()
                payload["_ctl0:ContentPlaceHolder1:tbUsername"] = user["name"]
                payload["_ctl0:ContentPlaceHolder1:tbPassword"] = user["pw"]
                _time = int(user["time"])
                weekday = int(user["day"])
                side = int(user["side"])
                room = int(user["room"])
                print(user)
                try:
                    logger.info("Booking for: " + str(user["name"]) + " day:" + str(weekday) + " time:" + str(_time))
                    book(payload, _time+3, weekday, side, room, 0)
                except ValueError as e:
                    logger.info(str(e))
    except IOError:
        logger.error("Error opening file.")

def run():
    while 1:
        if dt.datetime.now().hour in range(0, 1) and dt.datetime.now().minute in range(0,5):
            logger.info("EXECUTING CHECK_BOOKINGS")
            check_bookings()
            time.sleep(600) # 5*60 = 300 but to be sure
        time.sleep(30)

if __name__ == "__main__":
    check_bookings()
    #payload = dict()
    #payload["_ctl0:ContentPlaceHolder1:tbUsername"] = str("834")
    #payload["_ctl0:ContentPlaceHolder1:tbPassword"] = str("ASkil!23qwe")
    #book(payload, 18+3, 6, 2, 1, 0)


import scipy
import numpy as np

def stft(x, fs, framesz, hop, noise=0):
    # framesamp = int(framesz * fs)
    # hopsamp = int(hop * fs)
    framesamp = framesz
    hopsamp = hop
    w = scipy.hanning(framesamp)
    X = scipy.array([scipy.fft(w * x[i:i + framesamp])[:(framesamp + 1) // 2]
                     / framesamp + np.ones((framesamp + 1) // 2) * noise
                     for i in range(0, len(x) - framesamp, hopsamp)])
    return X


from odoo import models, api, fields
from odoo.exceptions import ValidationError
from datetime import date

class InventoryValuation(models.TransientModel):
    _name = 'wiz.inventory.valuation'
    date = fields.Date(string='Date', default=date.today())

    def print_inventory_valuation(self):
        items = self.env['inventory.item'].search([])
        if len(items) < 1:
            raise ValidationError("There are no items to report on")
        if fields.Date.from_string(self.date) > date.today():
            raise ValidationError("You cannot select a date in the future")

        report = {
            'type': 'ir.actions.report.xml',
            'report_type': 'xlsx',
            'report_name': 'inventory.valuation.xlsx',
            'context': dict(self._context, xlsx_export=True),
            'datas': {'ids': [self.id]},
        }
        return report


import glob
import os
import shutil
import sys

import cffi

from . import coreclr, hostfxr, mono, netfx

__all__ = ["ffi", "load_coreclr", "load_hostfxr", "load_mono", "load_netfx"]

ffi = cffi.FFI()

for cdef in coreclr.cdef + hostfxr.cdef + mono.cdef + netfx.cdef:
    ffi.cdef(cdef)

def load_coreclr(runtime):
    dll_name = _get_dll_name("coreclr")
    dll_path = os.path.join(runtime.path, dll_name)
    return ffi.dlopen(dll_path)

def load_hostfxr(dotnet_root):
    hostfxr_name = _get_dll_name("hostfxr")
    hostfxr_path = os.path.join(dotnet_root, "host", "fxr", "3.*", hostfxr_name)

    for hostfxr_path in reversed(sorted(glob.glob(hostfxr_path))):
        try:
            return ffi.dlopen(hostfxr_path)
        except Exception:
            pass

    raise RuntimeError(f"Could not find a suitable hostfxr library in {dotnet_root}")

def load_mono(path=None, gc=None):
    if path is None:
        from ctypes.util import find_library

        path = find_library(f"mono{gc or ''}-2.0")
        if path is None:
            raise RuntimeError("Could not find libmono")

    return ffi.dlopen(path, ffi.RTLD_GLOBAL)

def load_netfx():
    if sys.platform != "win32":
        raise RuntimeError(".NET Framework is only supported on Windows")

    dirname = os.path.join(os.path.dirname(__file__), "dlls")
    if sys.maxsize > 2 ** 32:
        arch = "amd64"
    else:
        arch = "x86"

    path = os.path.join(dirname, arch, "ClrLoader.dll")

    return ffi.dlopen(path)

def _get_dll_name(name):
    if sys.platform == "win32":
        return f"{name}.dll"
    elif sys.platform == "darwin":
        return f"lib{name}.dylib"
    else:
        return f"lib{name}.so"


import datetime

weekday = {
    'monday' : 0,
    'tuesday' : 1,
    'wednesday' : 2,
    'thursday' : 3,
    'friday' : 4,
    'saturday' : 5
}

weeknumber = {
    '0' : 'Monday',
    '1' : 'Tuesday',
    '2' : 'Wednesday',
    '3' : 'Thursday',
    '4' : 'Friday',
    '5' : 'Saturday'
}

class Translate():
    @classmethod
    def read_string(cls, string):
        tokens = string.split(' ')
        tokenStore = {}
        dayInput = tokens[0].lower()
        now = datetime.datetime.today()

        day = ""

        if dayInput in weekday:
            day = weekday[dayInput]
        elif dayInput == 'this' or dayInput == 'today':
            # weekdays start with 0 monday + need to increase by 1
            day = now.weekday()
        elif dayInput == 'tomorrow':
            day = now.weekday() + 1
        else:
            raise ValueError('Cannot Read Input')

        tokenStore['day'] = day
        if len(tokens) > 1:
            tokenStore['time'] = tokens[1].lower()
        return tokenStore

    @classmethod
    def format_response(cls, fellows, day, time=None):
        day_string = cls.get_formatted_day(day, time)
        if len(fellows) == 0:
            return 'No fellows are on shift %s' % day_string
        elif len(fellows) == 1:
            return '%s is on shift %s' % (fellows[0], day_string)
        return '%s are on shift %s' % (', '.join(fellows), day_string)

    @classmethod
    def get_formatted_day(cls, day, time):
        if time != None:
            return '%s %s' % (weeknumber[str(day)], time)
        return '%s' % weeknumber[str(day)]


import asyncio
import calendar
import datetime
import json
import random

import jdatetime
import pytz
import requests
from asgiref.sync import async_to_sync
from django.db.models import F, Count
from django.db.models.aggregates import Sum
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _
from drf_yasg import openapi
from furl import furl
from persiantools.jdatetime import JalaliDateTime
from rest_framework import serializers
from rest_framework.exceptions import APIException
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.response import Response

from xproject import settings
from xproject.secret import DEMO
from sms.models import Operator, Message
from pydoc import locate

from django.db.models import Sum

class SumDistinctHACK(Sum):
    allow_distinct = True

def locate_from_api_v1_serializers(path):
    _from = "%s.%s" % ("xapp.api_v1.serializers",
                       path)
    c = locate(_from)
    return c

def generate_code():
    return str(random.randint(10000, 99999))

def generate_table_token():
    return str(random.randint(100000000000, 999999999999))

def get_verification_text(code):
    return _("به کافه پی خوش آمدید: %s" % code)

def send_verification_code(to, code):
    message = Message.objects.create(to=to, message=str(code))

    if DEMO:
        # Don't send actual sms if running on debug mode
        return

    return Operator.objects.get(vendor=Operator.KAVENEGAR).send_message(message)

def get_cafe_simple_json(cafe):
    return {'pk': cafe.pk, 'name': cafe.name}

class OverallRatingField(serializers.JSONField):
    class Meta:
        swagger_schema_fields = {
            "type": openapi.TYPE_OBJECT,
            "title": "Overall Rating Field",
            "properties": {
                "rate": openapi.Schema(
                    title="Overall rating",
                    type=openapi.FORMAT_FLOAT,
                ),
                "count": openapi.Schema(
                    title="Count",
                    type=openapi.TYPE_INTEGER,
                ),
            },
        }

class PaymentInfoField(serializers.JSONField):
    class Meta:
        swagger_schema_fields = {
            "type": openapi.TYPE_OBJECT,
            "title": "Payment Info field",
            "properties": {
                "total_count": openapi.Schema(
                    title="Total count",
                    type=openapi.FORMAT_FLOAT,
                ),
                "total_amount": openapi.Schema(
                    title="Total amount",
                    type=openapi.FORMAT_FLOAT,
                ),
                "payed_amount": openapi.Schema(
                    title="Payed Amount",
                    type=openapi.TYPE_INTEGER,
                ),
                "refund_amount": openapi.Schema(
                    title="Refund Amount",
                    type=openapi.TYPE_INTEGER,
                ),
                "net_amount": openapi.Schema(
                    title="Net Amount",
                    type=openapi.TYPE_INTEGER,
                ),
            },
        }

# small helper serializer

def get_payment_info(pbrs, only_invoices=False):
    """
        :param pbrs: array of product bill relation objects to calculate payment info
        :return: aggregated payment info
    """

    if not pbrs:
        return {
            'total_count': 0,
            'total_amount': 0,
            'payed_amount_pos': 0,
            'payed_amount_cash': 0,
            'payed_amount_online': 0,
            'refund_amount': 0,
            'net_payed_amount': 0,
            'net_amount': 0,
        }

    from xapp.api_v1.consts import InvoiceConsts
    from xapp.models import Invoice

    total_count = pbrs.aggregate(total_count=Sum('count'))

    total_amount = pbrs.aggregate(total_amount=Sum(F('count') * F('original_price') * (100 - F('discount')) / 100))

    payed_invoices = Invoice.objects.filter(tag=InvoiceConsts.PAYED_FOR_PRODUCT,
                                            type=InvoiceConsts.DEPOSIT,
                                            status__in=[InvoiceConsts.INTERNAL, InvoiceConsts.PAYED],
                                            pbr__in=pbrs)
    payed_invoices_pos = payed_invoices.filter(method=InvoiceConsts.POS)
    payed_invoices_cash = payed_invoices.filter(method=InvoiceConsts.CASH)
    payed_invoices_online = payed_invoices.filter(method=InvoiceConsts.ONLINE)

    agg_payed = payed_invoices.aggregate(payed_amount=Sum('amount'))
    agg_payed_pos = payed_invoices_pos.aggregate(payed_amount=Sum('amount'))
    agg_payed_cash = payed_invoices_cash.aggregate(payed_amount=Sum('amount'))
    agg_payed_online = payed_invoices_online.aggregate(payed_amount=Sum('amount'))

    refund_invoices = Invoice.objects.filter(tag=InvoiceConsts.REFUND,
                                             type=InvoiceConsts.WITHDRAW,
                                             pbr__in=pbrs)

    agg_refund = refund_invoices.aggregate(refund_amount=Sum('amount'))

    if only_invoices:
        return {
            'payed_invoices': payed_invoices,
            'refund_invoices': refund_invoices
        }

    clean_null_values(agg_payed)
    clean_null_values(agg_payed_pos)
    clean_null_values(agg_payed_cash)
    clean_null_values(agg_payed_online)
    clean_null_values(agg_refund)
    clean_null_values(total_amount)
    clean_null_values(total_count)

    total_amount = total_amount['total_amount']

    return {
        'total_count': total_count['total_count'],
        'total_amount': total_amount,

        'payed_amount': agg_payed['payed_amount'],
        'payed_amount_pos': agg_payed_pos['payed_amount'],
        'payed_amount_cash': agg_payed_cash['payed_amount'],
        'payed_amount_online': agg_payed_online['payed_amount'],

        'refund_amount': agg_refund['refund_amount'],
        'net_payed_amount': agg_payed['payed_amount'] -
                            agg_refund['refund_amount'],
        'net_amount': (total_amount -
                       agg_payed['payed_amount'] +
                       agg_refund['refund_amount'])
    }

def get_user_profile_basic_info_serializer(phone=False):
    from xapp.models import UserProfile

    class Serializer(serializers.ModelSerializer):
        class Meta:
            model = UserProfile
            fields = ['pk', 'full_name', 'email', 'first_name',
                      'last_name', 'phone_number']

    class SerializerPhone(serializers.ModelSerializer):
        class Meta:
            model = UserProfile
            fields = ['pk', 'full_name', 'email', 'phone_number', 'first_name',
                      'last_name', ]

    if not phone:
        return Serializer

    return SerializerPhone

def get_cafe_info_serializer(simple=False):
    from xapp.models import Cafe
    from xapp.api_v1.serializers.AddressSerializers import CafeRegionDetailedSerializer

    class Serializer(serializers.ModelSerializer):
        if not simple:
            overall_rating = OverallRatingField(read_only=True)
            delivery_regions = CafeRegionDetailedSerializer(many=True)

        avatar = serializers.ImageField()

        class Meta:
            model = Cafe

            if not simple:
                fields = ['pk', 'overall_rating',
                          'has_delivery',
                          'delivery_regions',
                          'name', 'is_open', 'payment_only',
                          'avatar', 'payment_first',
                          'phone',
                          'xproject_fee']
            else:
                fields = ['pk', 'name', 'xproject_fee', 'avatar',
                          'phone', 'has_delivery',
                          'payment_first', 'payment_only']

    return Serializer

def get_basic_menu_serializer():
    from xapp.models import Menu

    class Serializer(serializers.ModelSerializer):
        class Meta:
            model = Menu
            fields = ['pk', 'name', 'staff', 'is_active']

    return Serializer

def get_product_basic_info_serializer():
    from xapp.models import Product

    class _Serializer(serializers.ModelSerializer):
        class Meta:
            model = Product
            fields = ['pk', 'name', 'order']

            ref_name = "pbis"

    return _Serializer

def get_basic_char_field_serializer():
    from xapp.models import CharacterField

    class Serializer(serializers.ModelSerializer):
        class Meta:
            model = CharacterField
            fields = ['pk', 'title', 'cafe',
                      'is_delete', 'menu',
                      'staff', 'type']

    return Serializer

def get_table_simple_serializer():
    from xapp.models import Table

    class Serializer(serializers.ModelSerializer):
        class Meta:
            model = Table
            fields = ['pk', 'number', 'is_preorder']

    return Serializer

def get_table_by_token(token, user_profile):
    from xapp.models import TableToken
    table = get_object_or_404(TableToken, token=token, status=TableToken.ACTIVE).table

    return table

class APIBadRequest(APIException):
    status_code = 400

    def __init__(self, *args, **kwargs):
        self.status_code = kwargs.pop('status_code', 400)
        super(APIBadRequest, self).__init__(*args, **kwargs)

JOIN = '0'
TRANSFER = '2'

def validate_table_operation(t1, t2, op):
    if t1 == t2:
        raise APIBadRequest(detail=_("Same table operations not valid"))

    if t1.cafe != t2.cafe:
        raise APIBadRequest(detail=_("Cafe mismatch"))

    if not t1.active_join and not t2.active_join:
        raise APIBadRequest(detail=_("Empty tables operation not valid"))

    if op == TRANSFER:
        if not t1.active_join:
            raise APIBadRequest(detail=_("Cannot transfer empty table"))

def clean_null_values(aggregated_queryset):
    for key in aggregated_queryset.keys():
        if aggregated_queryset[key] is None:
            aggregated_queryset[key] = 0

def _thread_notifier(table):
    from xapp.api_v1.consumers.DispatchConsumer import DispatchConsumer
    from xapp.models import TableToken

    # todo: send to all joins
    # ----------------- socket notifications
    notify_watcher = async_to_sync(DispatchConsumer.notify_watcher_endpoint)
    _table_token = table.table_tokens.filter(status=TableToken.ACTIVE).first()
    _table_uuid = table.uuid

    notify_watcher(
        'table/%d/join/simple/by-id/' % table.pk
    )

    notify_watcher(
        'table/%d/aggregate/' % table.pk
    )

    notify_watcher(
        'cafe/%d/tables/join/simple/%s/' % (table.cafe.pk, TableToken.SELF_PICKUP)
    )

    notify_watcher(
        'cafe/%d/tables/join/simple/%s/' % (table.cafe.pk, TableToken.PAYMENT_ONLY)
    )

    notify_watcher(
        'cafe/%d/tables/join/simple/any/' % table.cafe.pk
    )

    if _table_token:
        notify_watcher(
            'table/%s/join/simple/by-token/' % _table_token.token)

    if _table_uuid:
        notify_watcher(
            'table/%s/join/simple/by-token/' % _table_uuid)

def _desktop_notification_thread(table):
    if table.is_preorder:
        print("before preorder check passed")

        cafe = table.cafe
        push_endpoints = cafe.push_endpoints.all()
        print("still here")
        push_requests = []
        payload = {
            'title': 'پیش سفارش | کافه پی',
            'body': 'پیش سفارش جدید برای شما ثبت شده است',
            'url': 'https://admin.xproject.app'
        }
        payload_text = json.dumps(payload)

        for push_endpoint in push_endpoints:
            push_requests.append({
                'text': payload_text,
                'keys': push_endpoint.keys,
                'subscription': push_endpoint.text
            })

        data = {
            'data': push_requests
        }

        print("before api call")
        print("request data")
        print(json.dumps(data))
        print("sending request")
        result = requests.post("http://cfpyqr.info:5000/api/vapid-data", json=data, verify=False)

        print("status report")
        print(result.status_code)
        print(result.text)

def _printer_thread_notifier(printer):
    from xapp.api_v1.consumers.DispatchConsumer import DispatchConsumer

    notify_watcher = async_to_sync(DispatchConsumer.notify_watcher_endpoint)

    notify_watcher(
        'cafe/%d/printer/jobs/' % printer.cafe.pk
    )

def notify_watchers(table):
    import threading

    thread1 = threading.Thread(target=_thread_notifier, args=(table,))
    thread1.start()

def notify_printers(printer):
    import threading

    thread1 = threading.Thread(target=_printer_thread_notifier, args=(printer,))
    thread1.start()

def convert_jalali_to_gregorian(date, _time):
    """
    :param date: date - either str or date object (str objects must be validated before passing to this function)
    :param _time: time - either str or time object (str objects must be validated before passing to this function)
    :return: converted and merged datetime object
    """

    if type(date) == str:
        date_data = date.split('-')
    else:
        date_data = str(date).split('-')

    if type(_time) == str:
        time_data = _time.split(':')
    else:
        time_data = str(_time).split(':')

    datetime_data = date_data + time_data
    datetime_data = [int(dt) for dt in datetime_data]

    nytz = pytz.timezone('Asia/Tehran')

    return datetime.datetime.fromtimestamp(
        calendar.timegm(nytz.localize(jdatetime.datetime(*datetime_data).togregorian()).utctimetuple()),
        tz=pytz.timezone("utc"))

def super_advanced_datetime_filter(queryset, datetime_field,
                                   start_date, start_time,
                                   end_date, end_time):
    """
    :param queryset:
    :param datetime_field:
    :param start_date:
    :param start_time:
    :param end_date:
    :param end_time:
    :return: filter a queryset across a date and time frame
    """

    # Scenario 1: start time < end time, perform a regular datetime filter
    if start_time <= end_time:
        return queryset.filter(**{
            "%s__date__gte" % datetime_field: start_date,
            "%s__date__lte" % datetime_field: end_date,
            "%s__time__gte" % datetime_field: start_time,
            "%s__time__lte" % datetime_field: end_time,
        })
    elif end_time < start_time:
        """
        converted time is like: from 01:00 until 11:00

        q1:
        ***********************************
        *  ----  ----  ----  ----  ----  *  00:00
        *  |  |  |  |  |  |  |  |  |  |  *
        *  |  |  |  |  |  |  |  |  |  |  *
        *  ----  ----  ----  ----  ----  *  21:30
        ***********************************

        q2:
                **********************************
                *  ----  ----  ----  ----  ----  *  07:30
                *  |  |  |  |  |  |  |  |  |  |  *
                *  |  |  |  |  |  |  |  |  |  |  *
                *  ----  ----  ----  ----  ----  *  00:00
                **********************************
        """
        q1 = queryset.filter(**{
            "%s__date__gte" % datetime_field: start_date,
            "%s__date__lt" % datetime_field: end_date,
            "%s__time__gte" % datetime_field: start_time
        })

        q2 = queryset.filter(**{
            "%s__date__gt" % datetime_field: start_date,
            "%s__date__lte" % datetime_field: end_date,
            "%s__time__lte" % datetime_field: end_time
        })

        return (q1 | q2).distinct()
    else:
        raise Exception("[ERROR] CPU Malfunction")

class AggregatedListAPIView(ListAPIView):
    """
    ListAPIView with aggregated data on the filtered queryset
    also supports total queryset aggregation when pagination is used
    """

    def get_extra_and_paginated_response(self, page, extra):
        """
        :param page: page of data
        :param extra: a dictionary containing extra fields to be included in the final response
        :return: paginated and extra response
        """

        serializer = self.get_serializer(page, many=True)

        if page is not None:
            response = self.get_paginated_response(serializer.data)
        else:
            response = serializer.data

        for key in extra.keys():
            response.data[key] = extra.get(key, None)

        return response

    def get_aggregated_data(self, queryset):
        """
        return a dictionary containing aggregated data of the given queryset
        """
        return {}

    def list(self, request, *args, **kwargs):
        """
        filter the given queryset
        generate some aggregate data
        return paginated data
        """
        queryset = self.filter_queryset(self.get_queryset())
        aggregated_data = self.get_aggregated_data(queryset=queryset)
        page = self.paginate_queryset(queryset)
        return self.get_extra_and_paginated_response(page, aggregated_data)

class ManagerialReport(RetrieveAPIView):
    """
        start datetime
        end datetime
        aggregation step

        **Managerial reports depend on a specific cafe
        therefore get_object must return the desired cafe
        that the reports may be generated for

    """

    class DateTimeException(Exception):
        pass

    def get_raw_report_params(self):
        """
        :return: {
            'start_datetime',
            'end_datetime',
            'step': 24 (this is default value),
        }
        """

        return {
            'start_datetime': self.request.query_params.get('start_datetime'),
            'end_datetime': self.request.query_params.get('end_datetime'),
            'step': self.request.query_params.get('step', 24)
        }

    def _validate_datetime(self, _datetime):
        """
        Convert _datetime start to actual python datetime objects

        catch any possible TypeError and ValueError exceptions and raise them as DateTimeException
        """
        try:
            return datetime.datetime.strptime(_datetime, "%Y-%m-%dT%H:%M")
        except (TypeError, ValueError) as e:
            if _datetime is None:
                raise self.DateTimeException("this field is required")
            else:
                raise self.DateTimeException(str(e))

    def validated_report_params(self):
        """
        :return: validate raw reports params and return validated data
        """
        raw_report_params = self.get_raw_report_params()
        errors = []

        # parse and validate start/end datetime s
        try:
            start_datetime = self._validate_datetime(raw_report_params.get('start_datetime'))
        except self.DateTimeException as e:
            errors.append({'start_datetime': [str(e), ]})

        try:
            end_datetime = self._validate_datetime(raw_report_params.get('end_datetime'))
        except self.DateTimeException as e:
            errors.append({'end_datetime': [str(e), ]})

        # validate step
        try:
            step = int(raw_report_params.get('step', 24))

            if step % 24 != 0:
                raise ValueError(_("step must be a multiple of 24 hours"))

            step = datetime.timedelta(hours=step)

        except (TypeError, ValueError) as e:
            errors.append({'step': [str(e), ]})

        # in report api's, start_datetime and end_datetime is required
        # and must be convertible to valid python datetime objects
        if not not errors:
            raise APIBadRequest(errors)

        # return the validate query_params data
        return {
            'start_datetime': start_datetime,
            'end_datetime': end_datetime,
            'step': step
        }

    def get_framed_queryset(self, start_datetime, end_datetime):
        """ count of items in the queryset that satisfies the given time constraints"""
        raise NotImplemented(_("Get framed queryset must be implemented"))

    def get_total_queryset_items(self):
        """Total number of items in an unbound (time wise) filter"""
        raise NotImplemented(_("Get total queryset items must be implemented"))

    def get_total_framed_items(self):
        """Total number of items in bounded (time wise) filter"""
        report_params = self.validated_report_params()

        return self.get_framed_queryset(report_params.get('start_datetime'),
                                        report_params.get('end_datetime'))

    def retrieve(self, request, *args, **kwargs):
        validated_params = self.validated_report_params()

        # extract report params
        start_datetime = validated_params.get('start_datetime')
        end_datetime = validated_params.get('end_datetime')
        step = validated_params.get('step')

        # total number of items in the given time frame
        total_bounded = self.get_total_framed_items()

        # total number of items in each step of the filter
        _start_datetime = start_datetime  # used inside the while loop that generates step by step aggregated reports

        step_results = []

        # calculate report result from start to end, excluding the last step
        while _start_datetime + step < end_datetime:
            queryset = self.get_framed_queryset(_start_datetime, _start_datetime + step)
            step_results.append(queryset)

            # increment counter start_datetime
            _start_datetime = _start_datetime + step

        # calculate the last step
        last_step = self.get_framed_queryset(_start_datetime, end_datetime)
        step_results.append(last_step)

        return Response({'total': self.get_total_queryset_items(),
                         'total_bounded': total_bounded,
                         'reports': step_results})

def kavenegar_send_sms(template, tokens, to):
    from xproject import settings
    import requests

    api_endpoint = "https://api.kavenegar.com/v1/{API-KEY}/verify/lookup.json"
    api = furl(api_endpoint.replace('{API-KEY}', settings.KAVENEGAR_API_KEY))
    api.args['receptor'] = to
    api.args['template'] = template

    for key in tokens.keys():
        api.args[key] = tokens.get(key)

    print(api.url)
    requests.get(api.url)

def datetime_to_local_str(date_time):
    asia_tehran = pytz.timezone('Asia/Tehran')
    local_now = date_time.astimezone(asia_tehran)
    return JalaliDateTime.to_jalali(local_now).strftime('%y/%m/%dساعت%H:%M:%S')

def datetime_to_asia_tehran(date_time):
    asia_tehran = pytz.timezone('Asia/Tehran')
    return date_time.astimezone(asia_tehran)


import json
import time
from datetime import datetime

from django.core.exceptions import ValidationError
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt

from crtool.models import CurriculumReviewSession

@csrf_exempt
def create_review(request):
    if request.method == 'POST':
        fd = json.loads(request.body.decode("utf-8"))

        title = fd['tdp-crt_title'] if 'tdp-crt_title' in fd else ''
        pub_date = fd['tdp-crt_pubdate'] if 'tdp-crt_pubdate' in fd else ''
        grade_range = fd['tdp-crt_grade'] if 'tdp-crt_grade' in fd else ''
        pass_code = fd['tdp-crt_pass_code'] \
            if 'tdp-crt_pass_code' in fd else ''
        review_id = CurriculumReviewSession.id_generator()
        last_updated = timezone.now()

        if not title or not grade_range:
            return HttpResponse(status=400)
        data = {
            'id': str(review_id),
            'pass_code': pass_code,
            'last_updated': str(datetime.isoformat(last_updated)),
            'curriculumTitle': title,
            'publicationDate': pub_date,
            'gradeRange': grade_range
        }

        review = CurriculumReviewSession.objects.create(
            id=review_id,
            pass_code=pass_code,
            last_updated=last_updated,
            data=data
        )

        if review:
            return JsonResponse(review.data)

    return HttpResponse(status=400)

@csrf_exempt
def get_review(request):
    data = {}
    if request.method == 'POST':
        review_id = request.POST.get('token')
        try:
            review = CurriculumReviewSession.objects.get(id=review_id)
            if review:
                data = review.data
        except (
            CurriculumReviewSession.DoesNotExist,
            ValueError,
            ValidationError
        ):
            return HttpResponse(status=404)
        return JsonResponse(data)
    return HttpResponse(status=404)

@csrf_exempt
def continue_review(request):
    if request.method == 'POST':
        review_id = request.POST.get('access_code')
        # Critical pause to prevent brute-forcing the shorter pass_code values
        time.sleep(1)
        try:
            review = CurriculumReviewSession.objects.get(id=review_id)
            if review:
                return HttpResponseRedirect('../tool/#id=' + review.id)
        except (
            CurriculumReviewSession.DoesNotExist,
            ValueError,
            ValidationError
        ):
            return HttpResponse(status=404)
    return HttpResponse(status=404)

@csrf_exempt
def update_review(request):
    if request.method == 'POST':
        data = json.loads(request.body.decode("utf-8"))
        if "id" in data:
            try:
                review = CurriculumReviewSession.objects.get(id=data["id"])
                if review:
                    # Update last_updated date
                    last_updated = timezone.now()
                    iso_last_updated = str(datetime.isoformat(last_updated))
                    data['last_updated'] = iso_last_updated
                    review.data = data
                    review.last_updated = last_updated
                    review.save()
                    return JsonResponse(review.data)
            except (
                CurriculumReviewSession.DoesNotExist,
                ValueError,
                ValidationError
            ):
                return HttpResponse(status=404)

    return HttpResponse(status=404)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by Alex on 2016/10/26

import time
import random

import requests
from prettytable import PrettyTable
from pyquery import PyQuery as pq

pt = PrettyTable()
pt.field_names=[u"编号",u"名称"]
pt.align[u"名称"]="l"
session = requests.Session()
# url = "https://movie.douban.com/top250"
# content = session.get(url).content
# text = pq(content)("ol.grid_view>li>div.item")
# code = pq(text[0])("div.pic>em").text()
# title = pq(text[0])("div.info>div.hd>a").text()
# code = u"1"
# title = u"这个".encode("utf8")
# pt.add_row((code,title))
# print(pt)
# with open("test.txt","a") as f:
#     f.write(str(pt))
# print content
for i in range(0,10):
    url = "https://movie.douban.com/top250"
    if i == 0:
        data = ""
    else:
        data = "?start={start}&filter=".format(start=i * 25)
    url += data
    content = session.get(url).content
    map(pt.add_row,[(pq(row)("div.pic>em").text(),
                     pq(row)("div.info>div.hd>a").text().encode("utf8"))
                        for row in pq(content)("ol.grid_view>li>div.item")])
    sleep = random.randrange(20)
    print("page {page},----sleep({sleep})".format(page=i,sleep=sleep))
    time.sleep(sleep)
with open("movie.txt","a") as f:
    f.write(str(pt))


from docx import Document
import dataHandle as dh
from dataHandle import maketable
from dataHandle import makefiltertable
from docx.shared import Pt
from docx.enum.style import WD_STYLE_TYPE
import os
import subprocess

#create document
document = Document()

#set style
style = document.styles['Normal']
font = style.font
font.name = 'Ubuntu'
font.size = Pt(10)

title = document.styles['Title']
T_font = title.font
T_font.name = 'Ubuntu'
T_font.size = Pt(26)

head2 = document.styles['Heading 2']
hfont = head2.font
hfont.name = 'Ubuntu'
hfont.size = Pt(14)

new_heading_style = document.styles.add_style('New Heading', WD_STYLE_TYPE.PARAGRAPH)
new_heading_style.base_style = document.styles['Heading 2']
font2 = new_heading_style.font
font2.name = 'Ubuntu'
font2.size = Pt(16)
#font2.color.ColorFormat

#user inputs for file genearation
productVers = raw_input("Please enter the Product version: ")
department = raw_input("Please enter the Client name: ")
CVSfile = "JIRA.csv"

tableData= dh.infostrip(CVSfile)
docTitle = productVers + ' Testing Results Report ' + department + '- UAT'

#generate the body of the document
document.add_heading(docTitle, 0)

document.add_heading('1 Test Summary', level=2,)
document.add_paragraph('The following tests have been run on ' + department + 's Live environment.')
t1 = document.add_table(rows=4, cols=3)
tlc = t1.rows[0].cells
tlc[0].text = 'Total JIRA tasks'
tlc[1].text = str(len(tableData))
tlc[2].text = 'No. of tasks in the release as a whole'
tlc2 = t1.rows[1].cells
tlc2[0].text = 'Verified UAT'
tlc2[1].text = str( len( tableData[tableData['Status'] == 'Verified - UAT'] ) )
tlc2[2].text = 'Issues that have been assigned over to DFT to carry out testing'
tlc3 = t1.rows[2].cells
tlc3[0].text = 'Reopened'
tlc3[1].text = str( len( tableData[tableData['Status'] == 'Reopened'] ) )
tlc3[2].text = 'Issues have gone back to the development team for investigation Refer to section 4.2'
tlc4 = t1.rows[3].cells
tlc4[0].text = 'Closed'
tlc4[1].text = str( len( tableData[tableData['Status'] == 'Closed'] ) )
tlc4[2].text = 'Issues that do not require the client to test. E.g. functionality that is disabled or ' \
               'maintenance improvements'

document.add_heading('1.1 Breakdown of JIRA tests', level=2)
document.add_paragraph('')
t2 = document.add_table(rows=1, cols=4)
t2c = t2.rows[0].cells
t2c[0].text = "Name"
t2c[1].text = "Summary"
t2c[2].text = "Status"
t2c[3].text = "Pass"
maketable(tableData, t2)

document.add_page_break()

document.add_heading('2 Regression Tests', level=2)
document.add_paragraph('The table below summarises the tests run for regression testing and the test results obtained for each regression test:')

makefiltertable(document, tableData, 'Closed')

document.add_page_break()

document.add_heading('3 Performance Testing', level=2)
document.add_paragraph('The table below summarises the tests run for performance testing and the test results obtained for each test:')

document.add_page_break()

document.add_heading('4 Test Instances', level=2)
document.add_paragraph('This sections provides information on any unexpected results, problems or defects that occurred during testing. All defects will be logged in JIRA for reference and retesting when required. ')

document.add_heading('4.1 Resolved Test Instances', level=2)
document.add_paragraph('It is known that bugs can arise from testing post deployment, this may be due to deployment issue or bugs missed during QA due to environmental differences. All defects will be logged in JIRA and assessed and progressed appropriately. ')
makefiltertable(document, tableData, 'Closed')

document.add_heading('4.2 Unresolved Test Instances', level=2)
document.add_paragraph('Unfortunately it may be the case that some defects cannot be resolved within the current release for various reasons. If this is the case,  a plan of next steps will be taken and adhered to. ')

#save the document object

dire =os.getenv("HOME") +'/Documents/Generated Reports/'

if not os.path.exists(dire):
    os.makedirs(dire)
document.save(dire + docTitle + '.docx')
subprocess.Popen(["xdg-open", dire])


import pygame,sys,random

pygame.init()

size = width,height = 600,600
screen = pygame.display.set_mode(size)
font = pygame.font.SysFont("monospace",20)

#mitu ruutu on üles-alla
boxesX = int(width/25) - 2
boxesY = int(height/25) - 2

#mitu miini on väljakul
numOfMines = 35

#2-dimensiooniline array mängu staatuse hoidmiseks
mineField = [0] * (boxesX)
for b in range(boxesY):
    mineField[b] = [0] * (boxesX)

#peamine img,kust võtan subsurfacete kaudu paar pilti
mainImg = pygame.image.load("tile.png")
imgs =  []

for a in range(4):
    imgs.append(mainImg.subsurface(a * 25,0,25,25))

#paneme random asukohtadesse miiniväljal miinid.
def populate(mineField, numOfMines):
    minePos = []
    possibleMines = [k for k in range(11,19)]

    posX,posY = random.randint(0,len(mineField[0]) - 1),random.randint(0,len(mineField[1]) - 1)

    for a in range(numOfMines):
        #while loopiga vaatan, et positsioonid oleksid kõik erinevad
        while [posX,posY] in minePos:
            posX = random.randint(0,len(mineField[0]) - 1)
            posY = random.randint(0,len(mineField[1]) - 1)
        minePos.append([posX,posY])

    for pos in minePos:
        mineField[pos[0]][pos[1]] = 5

        #siin toimub numbrite leidmise maagia
        for a in range(-1,2):
            if pos[1] + a < len(mineField[0]) - 1 and pos[0] + 1 < len(mineField) - 1:
                mPos = mineField[pos[0] + 1][pos[1] + a]
                if mPos != 5 and mPos not in possibleMines:
                    mineField[pos[0] + 1][pos[1] + a] = 11
                elif mPos in possibleMines:
                    mineField[pos[0] + 1][pos[1] + a] +=  1

        for a in range(-1,2):
            if pos[1] + a < len(mineField) - 1 and pos[0] - 1 < len(mineField[0]) - 1:
                mPos = mineField[pos[0] - 1][pos[1] + a]

                if  mPos != 5 and mPos not in possibleMines:
                    mineField[pos[0] - 1][pos[1] + a] = 11
                elif mPos in possibleMines:
                    mineField[pos[0] - 1][pos[1] + a] +=  1

        for a in range(-1,2):
            for b in range(-1,2):
                pass

        if pos[1] - 1 > 0:
            if mineField[pos[0]][pos[1] - 1] != 5 and mineField[pos[0]][pos[1] - 1] not in possibleMines:
                mineField[pos[0]][pos[1] -1] = 11
            elif mineField[pos[0]][pos[1] - 1] in possibleMines:
                mineField[pos[0]][pos[1] - 1] += 1

        if pos[1] + 1 < len(mineField[0]) - 1:
            if mineField[pos[0]][pos[1] +1] != 5 and mineField[pos[0]][pos[1]+ 1] not in possibleMines:
                mineField[pos[0]][pos[1] +1] = 11
            elif mineField[pos[0]][pos[1] + 1] in possibleMines:
                mineField[pos[0]][pos[1] + 1] += 1

def reveal(screen,mineField, x,y):

    def flood_fill(screen, mineField, x, y):

        mPos = mineField[y - 1][x - 1]

        if mPos == 0:
            mineField[y - 1][x - 1] = 1
            screen.blit(imgs[1], (x*25,y * 25))
            if x < 22:
                if mineField[y - 1][x] == 0:
                    flood_fill(screen,mineField,x + 1,y)
            if y < 22:
                if mineField[y][x - 1] == 0:
                    flood_fill(screen,mineField,x,y + 1)
            if y >= 0:
                if mineField[y - 2][x - 1] == 0:
                    flood_fill(screen,mineField,x,y - 1)
            if x >= 0:
                if mineField[y - 1][x - 2] == 0:
                    flood_fill(screen,mineField,x - 1,y)

    flood_fill(screen, mineField, x, y)

#5 - miinid
#0 - avamata tile
#1 - avatud tile
#3 - lipp
#11:18 - miinide arv ruudu läheduses

populate(mineField,numOfMines)
print(mineField)

#paneme algse miinivälja ekraanile
for a in range(boxesY):
    for b in range(boxesX):
        #if mineField[a][b] == 0:
        screen.blit(imgs[0],(25*(a+1),25*(b+1)))

#subsurface järelejäänud flagide uuendamiseks korralikult ekraanil
#muidu peaks terve ekraani koguaeg üle joonistama
screenSub = screen.subsurface((0,0,25,25))

mineFieldRect = pygame.rect.Rect(25,25, 25*boxesX, 25*boxesY)

#main loop
while True:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit()
            sys.exit(0)
        elif e.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            #kui click on minefieldi peal
            if mineFieldRect.collidepoint(pos):
                nearestX = pos[0] // 25
                nearestY = pos[1] // 25

                #y ja x telg on vahetunud praegu,mingi jama
                tileAtPos = mineField[nearestY - 1][nearestX - 1]

                if e.button == 1:
                    if tileAtPos == 5:
                        screen.blit(imgs[2], (25 * nearestX, 25 * nearestY))
                        print("Game over!")
                    elif tileAtPos > 10:
                        numOfNearbyMines = str(tileAtPos)[1:]
                        screen.blit(imgs[1], (25*nearestX,25*nearestY))
                        screen.blit(font.render(numOfNearbyMines,False, (255,0,0)), (25 * nearestX, 25 * nearestY))
                    elif tileAtPos != 3:
                        reveal(screen,mineField,nearestX,nearestY)
                        screen.blit(imgs[1],(25*nearestX,25*nearestY))
                        mineField[nearestY- 1][nearestX - 1] = 1

                elif e.button == 3:
                    if tileAtPos == 3:
                        #mineField[nearestY - 1][nearestX - 1] = 1
                        screen.blit(imgs[0],(25*nearestX,25*nearestY))
                        numOfMines += 1
                    elif tileAtPos != 1:
                        if numOfMines > 0:
                            screen.blit(imgs[3],(25*nearestX,25*nearestY))
                            mineField[nearestY - 1][nearestX - 1] = 3
                            numOfMines -= 1

    screenSub.fill((0,0,0))
    text = font.render(str(numOfMines),False, (255,255,255))
    screen.blit(text, (0,0))

    pygame.display.flip()


import bilsm_crf_model
from keras import backend as K
from tensorflow.python import debug as tfdbg
import tensorflow as tf

from keras import callbacks
import os
EPOCHS = 10
batch_size=16
USE_MULTI_INPUT = False
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
# log.info("use gpu id:" + args.gpu_id)
debug = False

def gen_callbacks():
    tb = callbacks.TensorBoard('tensorboard-logs/',
                           batch_size=batch_size, histogram_freq=int(1))
    return [tb]

def training():
    if debug:
#         sess = K.get_session()
#         sess = tfdbg.TensorBoardDebugWrapperSession(sess, "0.0.0.0:9009")
#         K.set_session(sess)
        K.set_session(
            tfdbg.TensorBoardDebugWrapperSession(tf.Session(), "chaowei-SYS-7048GR-TR:9010"))

    if USE_MULTI_INPUT:
        model, (train_x, train_y), (test_x, test_y) = bilsm_crf_model.create_model2()
        # train model
        model.fit([train_x, train_x], train_y,batch_size=batch_size,epochs=EPOCHS, validation_data=[[test_x, test_x], test_y],callbacks=gen_callbacks())
        model.save('model/crf_multi.h5')
    else:
        model, (train_x, train_y), (test_x, test_y) = bilsm_crf_model.create_model()
        # train model
        model.fit(train_x, train_y,batch_size=batch_size,epochs=EPOCHS, validation_data=[test_x, test_y],callbacks=gen_callbacks())
        model.save('model/crf.h5')

if __name__ == "__main__":
    training()


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

from setuptools import setup, find_packages

import os
import re

here = os.path.dirname(os.path.abspath(__file__))

with open(os.path.join(here, 'inferpy', '__init__.py')) as f:
    txt = f.read()

try:
    version = re.findall(r"^__version__ = '([^']+)'\r?$",
                         txt, re.M)[0]
except IndexError:
    raise RuntimeError('Unable to determine version.')

with open(os.path.join(here, 'inferpy/docs/project_description.md')) as f:
    long_description = f.read()

setup(
    name='inferpy',
    version=version,
    description='Probabilistic modeling with Tensorflow made easy',
    long_description=long_description,
    long_description_content_type="text/markdown",
    author='Andrés R. Masegosa, Rafael Cabañas',
    author_email="andresma@ual.es, rcabanas@ual.es",
    install_requires=['tensorflow >= 1.5, <1.8', 'numpy>=1.14', 'edward==1.3.5', 'pandas>0.15.0','funcsigs>=1.0.2'],
    extras_require={
        'tensorflow with gpu': ['tensorflow-gpu  >= 1.5, <1.8'],
        'visualization': ['matplotlib>=1.3',
                          'pillow>=3.4.2',
                          'seaborn>=0.3.1']},
    tests_require=['pytest', 'pytest-pep8'],
    url='http://inferpy.readthedocs.io',
    download_url='https://github.com/PGMLabSpain/InferPy/archive/' + version + '.tar.gz',
    keywords='machine learning statistics probabilistic programming tensorflow edward',
    license='Apache License 2.0',
    classifiers=['Intended Audience :: Developers',
                 'Intended Audience :: Education',
                 'Intended Audience :: Science/Research',
                 'License :: OSI Approved :: Apache Software License',
                 'Operating System :: POSIX :: Linux',
                 'Operating System :: MacOS :: MacOS X',
                 'Operating System :: Microsoft :: Windows',
                 'Programming Language :: Python :: 2.7',
                 'Programming Language :: Python :: 3.4'],
    packages=find_packages(exclude=['playground_ignored', ]),
    package_data={'inferpy': ['docs/*.md']},
)


from keras import layers, models, optimizers
from keras import backend as K
from agents.ou_noise import OUNoise
from agents.replay_buffer import ReplayBuffer
from agents.PrioritizedMemory import  Memory

class actor_params():

    def __init__(self):
        self.lr = 0.001
        self.clipvalue = 0.5

        self.optimizer = optimizers.Adadelta(decay=0.01)

    def build_nn(self, input):
        net = layers.Dense(units=32, activation='relu')(input)
        net = layers.Dense(units=64, activation='relu')(net)
        net = layers.Dense(units=32, activation='relu')(net)
        return net

class critic_params():

    def __init__(self):
        self.lr = 0.001
        self.clipvalue = 0.5

        self.optimizer = optimizers.Adadelta(decay=0.01)

    def build_nn(self, actions, states):
        # Add hidden layer(s) for state pathway
        net_states = layers.Dense(units=32, activation='relu')(states)
        net_states = layers.Dense(units=64, activation='relu')(net_states)
        # Add hidden layer(s) for action pathway
        net_actions = layers.Dense(units=32, activation='relu')(actions)
        net_actions = layers.Dense(units=64, activation='relu')(net_actions)
        # Try different layer sizes, activations, add batch normalization, regularizers, etc.
        # Combine state and action pathways
        net = layers.Add()([net_states, net_actions])
        net = layers.Activation('relu')(net)
        # Add more layers to the combined network if needed
        return net

class agent_params():

    def __init__(self, action_size):
        # Noise process
        self.exploration_mu = 0
        self.exploration_theta = 0.15  # same direction
        self.exploration_sigma = 0.001  # random noise

        self.noise = OUNoise(action_size, self.exploration_mu, self.exploration_theta, self.exploration_sigma)

        # Replay memory
        self.buffer_size = 100000
        self.batch_size = 64
        self.memory = ReplayBuffer(self.buffer_size, self.batch_size)
        #self.memory = Memory(self.buffer_size, self.batch_size)

        # Algorithm parameters
        self.gamma = 0.99  # discount factor
        self.tau = 0.1  # for soft update of target parameters


"""Incremental demo for wx support of tasks.

Multiple tasks

Note that naively subclassing SecondTask from ExampleTask, it initially used
the same menu_bar and tool_bars traits from ExampleTask.  This caused the
incorrect tying of the controls to SecondTask because the class attributes
were shared between both classes.
"""

import logging
logging.basicConfig(level=logging.DEBUG)

import wx

# Enthought library imports.
from pyface.api import GUI, ConfirmationDialog, FileDialog, \
    ImageResource, YES, OK, CANCEL
from pyface.tasks.api import Task, TaskWindow, TaskLayout, PaneItem, IEditor, \
    IEditorAreaPane, EditorAreaPane, Editor, DockPane, HSplitter, VSplitter
from pyface.tasks.action.api import DockPaneToggleGroup, SMenuBar, \
    SMenu, SToolBar, TaskAction, TaskToggleGroup
from traits.api import on_trait_change, Property, Instance, Str, List

class Pane1(DockPane):
    #### TaskPane interface ###################################################

    id = 'steps.pane1'
    name = 'Pane 1'

class Pane2(DockPane):
    #### TaskPane interface ###################################################

    id = 'steps.pane2'
    name = 'Pane 2'

    #### FileBrowserPane interface ############################################

    # The list of wildcard filters for filenames.
    filters = List(Str)

    def create_contents(self, parent):
        control = wx.GenericDirCtrl(parent, -1, size=(200,-1), style=wx.NO_BORDER)
        control.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.on_selected)
        return control

    def on_selected(self, evt):
        selected_file = self.control.GetFilePath()
        wx.CallAfter(self.task.window.application.load_file, selected_file, self.task, in_current_window=True)

class HtmlWindow(wx.html.HtmlWindow):
    def __init__(self, parent):
        print("calling HtmlWindow constructor")
        wx.html.HtmlWindow.__init__(self, parent, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE)
        print("setting HtmlWindow fonts")
        self.SetStandardFonts()

class HtmlEditor(Editor):
    def create(self, parent):
        self.control = HtmlWindow(parent)

class ExampleTask(Task):
    """ A simple task for opening a blank editor.
    """

    #### Task interface #######################################################

    id = 'example.example_task'
    name = 'Multi-Tab Editor'

    active_editor = Property(Instance(IEditor),
                             depends_on='editor_area.active_editor')

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(SMenu(TaskAction(name='New', method='new',
                                         accelerator='Ctrl+N'),
                              TaskAction(name='Add Task', method='add_task',
                                         accelerator='Ctrl+A'),
                              TaskAction(name='Remove Task', method='remove_task',
                                         accelerator='Ctrl+R'),
                              id='File', name='&File'),
                        SMenu(DockPaneToggleGroup(),
                              TaskToggleGroup(),
                              id='View', name='&View'))

    tool_bars = [ SToolBar(TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           image_size = (32, 32)), ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(
            top=VSplitter(
                HSplitter(
                    PaneItem('steps.pane1'),
                    PaneItem('steps.pane2')),
                ))

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        return [ Pane1(), Pane2() ]

    ###########################################################################
    # 'ExampleTask' interface.
    ###########################################################################

    def new(self):
        """ Opens a new empty window
        """
        editor = HtmlEditor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    def add_task(self):
        """ Opens a new empty window
        """
        task3 = ThirdTask()
        self.window.add_task(task3)
        self.window.activate_task(task3)

    def remove_task(self):
        """ Opens a new empty window
        """
        task = self.window.tasks[0]
        window = self.window
        window.remove_task(self)
        window.activate_task(task)

    #### Trait property getter/setters ########################################

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None

class SecondTask(ExampleTask):
    """ A simple task for opening a blank editor.
    """

    #### Task interface #######################################################

    id = 'example.second_task'
    name = 'Second Multi-Tab Editor'

    tool_bars = [ SToolBar(TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           image_size = (32, 32)), ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(
            left=VSplitter(
                HSplitter(
                    PaneItem('steps.pane1'),
                    PaneItem('steps.pane2')),
                ))

class ThirdTask(ExampleTask):
    """ A simple task for opening a blank editor.
    """

    #### Task interface #######################################################

    id = 'example.third_task'
    name = 'Third Multi-Tab Editor'

    tool_bars = [ SToolBar(TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           TaskAction(method='new',
                                      tooltip='New file',
                                      image=ImageResource('document_new')),
                           image_size = (32, 32)),
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(
            right=VSplitter(
                HSplitter(
                    PaneItem('steps.pane1'),
                    PaneItem('steps.pane2')),
                ))

def main(argv):
    """ A simple example of using Tasks.
    """
    # Create the GUI (this does NOT start the GUI event loop).
    gui = GUI()

    # # Create a Task and add it to a TaskWindow.
    # task1 = ExampleTask()
    # task2 = SecondTask()
    # window = TaskWindow(size=(800, 600))
    # window.add_task(task1)
    # window.add_task(task2)
    # task1.new()
    # task2.new()

    # # Show the window.
    # window.open()

    # info = wx.adv.AboutDialogInfo()

    # Start the GUI event loop.
    frame = wx.Frame(None, -1, "Test", size=(400,400))
    html = wx.html.HtmlWindow(frame, -1)
    frame.Show(True)
    gui.start_event_loop()

if __name__ == '__main__':
    import wx.html
    app = wx.App()
    import wx.adv

    import sys
    main(sys.argv)


# ref: https://adventofcode.com/2019/day/15
from typing import Dict, Tuple

def walk_maze(intcode_program: str) -> Tuple[Dict[Tuple[int, int],int], Tuple[int, int]]:
  computer = IntcodeComputer(intcode_program)
  visited = {(0,0):1}
  tail = []
  loc = (0,0)
  oxygen_loc = (0,0)
  def movable_locations():
    return {1: (loc[0],loc[1]+1), 2: (loc[0],loc[1]-1), 3: (loc[0]-1,loc[1]), 4: (loc[0]+1,loc[1])}
  def move() -> bool:
    nonlocal oxygen_loc, loc
    for direction, target_loc in movable_locations().items():
      if target_loc in visited:
        continue
      status = computer.run(direction)
      visited[target_loc] = status
      if status == 2:
        oxygen_loc = target_loc
      if status != 0:
        tail.append(direction)
        loc = target_loc
        return True
    return False
  def run():
    nonlocal loc
    if not move():
      direction = {1: 2, 2: 1, 3: 4, 4: 3}[tail.pop()]
      target_loc = movable_locations()[direction]
      if computer.run(direction) == 0:
        raise ValueError
      loc = target_loc
  run()
  while len(tail) > 0:
    run()
  return visited, oxygen_loc

def get_distance_to_furthest_loc(maze: Dict[Tuple[int, int],int], loc1: Tuple[int, int]) -> int:
  visited = set()
  queue = [(loc1, 0)]
  furthest_distance = 0
  while len(queue) > 0:
    loc, distance = queue.pop(0)
    if loc in visited:
      continue
    visited.add(loc)
    furthest_distance = max(distance, furthest_distance)
    queue.extend([(x, distance+1) for x in [(loc[0],loc[1]+1), (loc[0],loc[1]-1), (loc[0]-1,loc[1]), (loc[0]+1,loc[1])] if x in maze and maze[x] != 0])
  return furthest_distance

def main(inp):
  maze, oxygen_loc = walk_maze(inp)
  return get_distance_to_furthest_loc(maze, oxygen_loc)

class IntcodeComputer:
  def __init__(self, program: str):
    self.data = [int(x) for x in program.split(',')]
    self.index = 0
    self.offset = 0
    self.memory = {}

  def run(self, inp) -> int:
    rules = [
      {'opcode': 99, 'params': 0, 'fn': lambda args: args['halt']()},
      {'opcode': 1, 'params': 3, 'fn': lambda args: args['write'](3, args['read'](1) + args['read'](2))},
      {'opcode': 2, 'params': 3, 'fn': lambda args: args['write'](3, args['read'](1) * args['read'](2))},
      {'opcode': 3, 'params': 1, 'fn': lambda args: args['write'](1, args['input']())},
      {'opcode': 4, 'params': 1, 'fn': lambda args: args['output'](1)},
      {'opcode': 5, 'params': 2, 'fn': lambda args: args['jump'](args['read'](2)) if args['read'](1) != 0 else None},
      {'opcode': 6, 'params': 2, 'fn': lambda args: args['jump'](args['read'](2)) if args['read'](1) == 0 else None},
      {'opcode': 7, 'params': 3, 'fn': lambda args: args['write'](3, 1) if args['read'](1) < args['read'](2) else args['write'](3, 0)},
      {'opcode': 8, 'params': 3, 'fn': lambda args: args['write'](3, 1) if args['read'](1) == args['read'](2) else args['write'](3, 0)},
      {'opcode': 9, 'params': 1, 'fn': lambda args: args['offset'](args['read'](1))}
    ]
    has_read_input = False
    while True:
      opcode = self.data[self.index] % 100
      modes = list(int(x) for x in reversed(f'{self.data[self.index]:06}'))[2:]
      rule = [x for x in rules if x['opcode'] == opcode][0]
      is_jump = False
      this_output = None
      def halt():
        raise HaltError
      def read(pos):
        mode = modes[pos-1]
        i = self.data[self.index+pos] if mode == 0 else self.index+pos if mode == 1 else self.data[self.index+pos]+self.offset
        if i >= len(self.data):
          if i not in self.memory:
            return 0
          return self.memory[i]
        return self.data[i]
      def write(pos, value):
        mode = modes[pos-1]
        i = self.data[self.index+pos] if mode == 0 else self.index+pos if mode == 1 else self.data[self.index+pos]+self.offset
        if i >= len(self.data):
          self.memory[i] = value
        else:
          self.data[i] = value
      def output(pos):
        nonlocal this_output
        mode = modes[pos-1]
        i = self.data[self.index+pos] if mode == 0 else self.index+pos if mode == 1 else self.data[self.index+pos]+self.offset
        if i > len(self.data):
          this_output = self.memory[i]
        else:
          this_output = self.data[i]
      def jump(pos):
        nonlocal is_jump
        is_jump = True
        self.index = pos
      def get_next_input():
        nonlocal has_read_input
        if has_read_input or inp is None:
          raise InputError
        has_read_input = True
        return inp
      def offset(val):
        self.offset += val
      args1 = {
        'halt': halt,
        'read': read,
        'write': write,
        'input': get_next_input,
        'output': output,
        'jump': jump,
        'offset': offset,
      }
      rule['fn'](args1)
      if not is_jump:
        self.index += rule['params']+1
      if this_output is not None:
        return this_output

class InputError(ValueError):
  pass

class HaltError(ValueError):
  pass

if __name__ == '__main__':
  with open('15.txt', 'r') as f:
    contents = f.read()
  print(main(contents.strip()))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File name          :
# Author             :
# Date created       :
# Date last modified :
# Python Version     : 3.*

import os, sys
import base64

def readfile(file, binary=False):
    if binary : b_opt="b"
    else:       b_opt=""
    f = open(file, "r"+b_opt)
    data = f.readlines()
    f.close()
    return data

def writefile(file, data, binary=False):
    if binary : b_opt="b"
    else:       b_opt=""
    f = open(file, "w"+b_opt)
    for e in data:
        f.write(e)
    f.close()
    return data

chunk_size = 30

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print("Usage : python3 "+sys.argv[0]+" file")
    else :
        file = sys.argv[1]
        b64data = os.popen("cat "+file+" | base64 | tr -d \"\\n\"").read()
        print(b64data)
        print("===============")

        f = open(file, "rb")
        data = b'\n'.join(f.readlines())
        f.close()
        bd = base64.b64encode(data).decode("ISO-8859-1")
        print(bd)
        print(b64data == bd)


"""empty message

Revision ID: b2a187f85d06
Revises: 15beda253d41
Create Date: 2019-04-11 14:58:50.198086

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'b2a187f85d06'
down_revision = '15beda253d41'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_foreign_key(None, 'student_course', 'student', ['student_id'], ['id'])
    op.create_foreign_key(None, 'student_course', 'course', ['course_id'], ['id'])
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, 'student_course', type_='foreignkey')
    op.drop_constraint(None, 'student_course', type_='foreignkey')
    # ### end Alembic commands ###


#    Copyright 2018 D-Wave Systems 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.

import unittest
from random import randint
import jsonschema

from factoring.interfaces import factor
from factoring.json_schema import json_schema

class TestInterfaces(unittest.TestCase):

    def test_factor_output(self):
        P = randint(0, 2**6-1)
        output = factor(P)
        jsonschema.validate(output, json_schema)

    def test_factor_invalid(self):
        for P in [-1, 64, 'a']:
            self.assertRaises(ValueError, factor, P)

    @unittest.skip("Not really a unittest")
    def test_factor_validity(self):
        for P in [12, 21, 49]: # {a*b for a in range(2**3) for b in range(2**3)}:
            output = factor(P)
            self.assertTrue(output['results'][0]['valid'])


from models import Apartment
import requests
from main import db
import sqlalchemy

url_path = "https://devman.org/assets/ads.json"

def get_json_data(url_path):
    json_data = requests.get(url_path).json()
    return json_data

def make_old_ads_unactive(db):
    active_ads_arr = db.session.query(Apartment).filter(Apartment.active == True)
    for active_ad in active_ads_arr:
        active_ad.active = False

def insert_or_update_ads_into_db(db, json_data):
    ad_ids = [ad_obj.primary_id for ad_obj in db.session.query(Apartment).all()]
    for apartment_advert in json_data:
        changed_ad = {ad_key: ad_value for ad_key, ad_value in apartment_advert.items() if ad_key != 'id'}
        changed_ad.update({'primary_id': apartment_advert['id'], 'active': True})
        if changed_ad['primary_id'] in ad_ids:
            db.session.query(Apartment).filter(Apartment.primary_id==changed_ad['primary_id']).update(changed_ad)
        else:
            db.session.add(Apartment(**changed_ad))

if __name__ == "__main__":
    json_data = get_json_data(url_path)
    try:
        make_old_ads_unactive(db)
        insert_or_update_ads_into_db(db, json_data)
        db.session.commit()
    except sqlalchemy.exc.OperationalError as e:
        print(e)
        db.session.rollback()
    except sqlalchemy.exc.TimeoutError as e:
        print(e)
        db.session.rollback()
    db.session.close()


import cv2

imagem = cv2.imread("entrada.jpg")

#Cria um retangulo azul por toda a largura da imagem
imagem[30:50, : ] = (255,0,0)

#Cria um quadrado vermelho
imagem[100:150, 50:100] = (0,0,255)

#Cria um retangulo amarelo por toda a altura da imagem
imagem[ : , 200:220] = (0, 255, 255)

cv2.imshow("Slicing", imagem)
cv2.waitKey(0)