#!/usr/bin/python3
#coding=utf-8
import urllib3
import json
import datetime as dt
import time
import sys
import logging
import traceback
import random
'''
特别声明:
本程序只有甜糖客户端和server酱的相关的api的访问，请仔细查阅程序安全性。
本程序仅用于测试和学习研究，禁止用于商业用途，不能保证其合法性，准确性，完整性和有效性，请根据情况自行判断.
本脚本的唯一下载地址https://www.right.com.cn/forum/thread-4048219-1-1.html  其它地方下载的可能存在危险，概不负责。
对任何脚本问题概不负责，包括但不限于由任何脚本错误导致的任何损失或损害.
请勿将本程序的任何内容用于商业或非法目的，否则后果自负.

如果任何单位或个人认为本程序可能涉嫌侵犯其权利，则应及时通知并提供身份证明，所有权证明，我们将在收到认证文件后删除相关程序.
任何以任何方式查看此程序的人或直接或间接使用该程序的使用者都应仔细阅读此声明。作者保留随时更改或补充此免责声明的权利。
一旦使用并复制了任何相关程序，则视为您已接受此免责声明.
您使用或者复制了本程序且本人制作的任何脚本，则视为已接受此声明，请仔细阅读
您必须在下载后的24小时内从计算机或手机中完全删除以上内容.
'''
def HandleException( excType, excValue, tb):
	ErrorMessage = traceback.format_exception(excType, excValue, tb)  # 异常信息
	logging.exception('ErrorMessage: %s' % ErrorMessage)  # 将异常信息记录到日志中
	str=[]
	for item in ErrorMessage:
		str.append(item)

	msg_content=[]
	msg_content.append("程序运行错误，请暂停使用程序，手动领取星愿，截图错误消息推送，并联系程序开发者！-三只松鼠")
	msg_content.append("ErrorMessage:")
	msg_content.append(str)
	msg_content.append(end)
	sendMSG("[甜糖星愿]程序错误警报",msg_content)
	return

sys.excepthook = HandleException #全局错误异常处理！

path=sys.path[0] #脚本所在目录
logging.basicConfig(filename=path + '/AutoTTnodeClient.log',format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s', level=logging.DEBUG)
logging.debug("日志开始")
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
####################以下内容请不要乱动，程序写得很菜，望大佬手下留情#########################################
devices=''
inactivedPromoteScore=0
total=0
accountScore=0
msgTitle="[甜糖星愿]星愿日结详细"
msg="\n"

def sendPlusPlus(text,desp):#发送PlusPlus代码
    url="http://pushplus.hxtrip.com/send"
    header={"Content-Type":"application/json"}
    body_json={"token":plusplus_token,"title":text,"content":desp,"template":"html"}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=200:
       print("sendPlusPlus方法请求失败，结束程序")
       logging.debug("sendPlusPlus方法请求失败，结束程序")
       exit()
    data=response.data.decode('utf-8')
    data=json.loads(data)
    return

def sendTelegram(desp):#发送Telegram代码
    url="https://api.telegram.org/bot"+tg_bot_token+"/sendMessage"
    header={"Content-Type":"application/json"}
    body_json={"chat_id":chat_id,"text":desp}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=200:
       print("sendPlusPlus方法请求失败，结束程序，请确保连接了外国网络！")
       logging.debug("sendPlusPlus方法请求失败，结束程序，请确保连接了外国网络！")
       exit()
    data=response.data.decode('utf-8')
    data=json.loads(data)
    return

def getInitInfo():#甜糖用户初始化信息，可以获取待收取的推广信息数，可以获取账户星星数
    url="http://tiantang.mogencloud.com/web/api/account/message/loading"
    header={"Content-Type":"application/json","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('POST', url,headers=header)
    if response.status!=200:
       print("getInitInfo方法请求失败，结束程序")
       logging.debug("getInitInfo方法请求失败，结束程序")
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']!=0:
        print("发送推送微信，authorization已经失效")
        msg_content=[]
        msg_content.append("甜糖登录状态已经失效，请通过手机号码和验证码进行重新生成配置")
        msg_content.append("docker版运行下面命令：")
        item=[]
        item.append("docker exec  autottnode python3 /root/ttnode/TTnodeLogin.py")
        msg_content.append(item)
        msg_content.append("源码版运行下面命令：")
        item=[]
        item.append("python3 /你文件的路径/TTnodeLogin.py")
        msg_content.append(item)
        msg_content.append(end)
        sendMSG("[甜糖星愿]-Auth失效通知",msg_content)
        exit()
    data=data['data']

    return data

def getDevices():#获取当前设备列表，可以获取待收的星星数
    url="http://tiantang.mogencloud.com/api/v1/devices?page=1&type=2&per_page=200"
    header={"Content-Type":"application/json","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('GET', url,headers=header)
    if response.status!=200:
        print("getDevices方法请求失败，结束程序")
        logging.debug("getDevices方法请求失败，结束程序")
        raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']!=0:
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API可能已经变更，请暂停使用程序！")

    data=data['data']['data']
    if len(data)==0:
        msg_content=[]
        msg_content.append("该账号尚未绑定设备，请绑定设备后再运行！")
        msg_content.append(end)
        sendMSG("[甜糖星愿]获取设备失败通知",msg_content)
        exit()
    return data

def promote_score_logs(score):#收取推广奖励星星
    global msg
    if score==0:

        return "[推广奖励]0-🌟"
    url="http://tiantang.mogencloud.com/api/v1/promote/score_logs"
    header={"Content-Type":"application/json","authorization":authorization}
    body_json={'score':score}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
       print("promote_score_logs方法请求失败，结束程序")
       logging.debug("promote_score_logs方法请求失败，结束程序")
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)

    if data['errCode']!=0:

        return "[推广奖励]0-🌟(收取异常)"

    global total
    total=total+score
    data=data['data']
    #发送微信推送，啥设备，获取了啥星星数
    return "[推广奖励]"+str(score)+"-🌟"

def score_logs(device_id,score,name):#收取设备奖励
    global msg
    if score==0:

        return "["+name+"]0-🌟"
    url="http://tiantang.mogencloud.com/api/v1/score_logs"
    header={"Content-Type":"application/json","authorization":authorization}
    body_json={'device_id':device_id,'score':score}
    encoded_body=json.dumps(body_json).encode('utf-8')
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
       print("score_logs方法请求失败，结束程序")
       logging.debug("score_logs方法请求失败，结束程序")
       raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
    data=response.data.decode('utf-8')
    data=json.loads(data)

    if data['errCode']!=0:
        return "["+name+"]0-🌟(收取异常)"

    global total
    total=total+int(score)
    data=data['data']
    #发送微信推送，啥设备，获取了啥星星数
    return "["+name+"]"+str(score)+"-🌟"

def sign_in():#签到功能
	url="http://tiantang.mogencloud.com/web/api/account/sign_in"
	header={"Content-Type":"application/json","authorization":authorization}
	http = urllib3.PoolManager()
	response= http.request('POST', url,headers=header)
	if response.status!=201 and response.status!=200:
		print("sign_in方法请求失败，结束程序")
		logging.debug("sign_in方法请求失败，结束程序")
		raise Exception("响应状态码:"+str(response.status)+"\n请求url:"+url+"\n消息:API出现异常，请暂停使用程序！")
	data=response.data.decode('utf-8')
	data=json.loads(data)
	global msg

	if data['errCode']!=0:

		return "[签到奖励]0-🌟(失败:"+data['msg']+")"

	global total
	total=total+data['data']
	return "[签到奖励]"+str(data['data'])+"-🌟"

def readConfig(filePath):#读取配置文件
	try:
		file=open(filePath,"a+",encoding="utf-8",errors="ignore")
		file.seek(0)
		result=file.read()
	finally:
		if file:
			file.close()
			print("文件流已经关闭")

	return result
def zfb_withdraw(bean):#支付宝提现
    url="http://tiantang.mogencloud.com/api/v1/withdraw_logs"
    score=bean["score"]
    score=score-score%100
    real_name=bean["real_name"]
    card_id=bean["card_id"]
    bank_name="支付宝"
    sub_bank_name=""
    type="zfb"

    if score<1000:
        return "[自动提现]支付宝提现失败，星愿数不足1000",""
    if score>=10000:
        score=9900
    body_json="score="+str(score)+"&real_name="+real_name+"&card_id="+card_id+"&bank_name="+bank_name+"&sub_bank_name="+sub_bank_name+"&type="+type
    encoded_body=body_json.encode('utf-8')
    header={"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
        logging.debug("withdraw_logs方法请求失败")
        return "[自动提现]支付宝提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']==403002:
        logging.debug("[自动提现]支付宝提现失败，"+data['msg'])
        return "[自动提现]支付宝提现失败，"+data['msg'],""
    if data['errCode']!=0:
        print(""+data['msg']+str(score))
        logging.debug(""+data['msg']+str(score))
        return "[自动提现]支付宝提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=data['data']
    zfbID=data['card_id']
    pre=zfbID[0:4]
    end=zfbID[len(zfbID)-4:len(zfbID)]
    zfbID=pre+"***"+end
    item=[]
    item.append("-------提现方式：支付宝")
    item.append("-------支付宝号："+zfbID)
    return "[自动提现]扣除"+str(score)+"-🌟",item

def yhk_withdraw(bean):#银行卡提现
    url="http://tiantang.mogencloud.com/api/v2/withdraw_logs"
    score=bean["score"]
    score=score-score%100
    real_name=bean["real_name"]
    card_id=bean["card_id"]
    bank_name=bean["bank_name"]
    sub_bank_name=bean["sub_bank_name"]
    type="bank_card"

    if score<1000:
        return "[自动提现]银行卡提现失败，星愿数不足1000",""
    body_json="score="+str(score)+"&real_name="+real_name+"&card_id="+card_id+"&bank_name="+bank_name+"&sub_bank_name="+sub_bank_name+"&type="+type
    encoded_body=body_json.encode('utf-8')
    header={"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8","authorization":authorization}
    http = urllib3.PoolManager()
    response= http.request('POST', url,body=encoded_body,headers=header)
    if response.status!=201 and response.status!=200:
        logging.debug("withdraw_logs方法请求失败")
        return "[自动提现]银行卡提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=response.data.decode('utf-8')
    data=json.loads(data)
    if data['errCode']==403002:
        logging.debug("[自动提现]银行卡提现失败，"+data['msg'])
        return "[自动提现]银行卡提现失败，"+data['msg'],""
    if data['errCode']!=0:
        print(""+data['msg']+str(score))
        logging.debug(""+data['msg']+str(score))
        return "[自动提现]银行卡提现失败，请关闭自动提现等待更新并及时查看甜糖客户端app的账目",""

    data=data['data']
    yhkID=data['card_id']
    pre=yhkID[0:4]
    end=yhkID[len(yhkID)-4:len(yhkID)]
    yhkID=pre+"****"+end
    item=[]
    item.append("-------提现方式：银行卡")
    item.append("-------银行卡号："+yhkID)
    return "[自动提现]扣除"+str(score)+"-🌟",item

def withdraw_type(userInfo):#根据用户是否签约来决定提现方式
	isEContract=userInfo['isEContract']
	bean={}
	if isEContract:
		#已经实名签约的采用银行卡提现
		bankCardList=userInfo['bankCardList']#获取支付宝列表
		if len(bankCardList)==0:
			withdraw_str="[自动提现]银行卡提现失败，原因是未绑定银行卡，请绑定一张银行卡"
			return withdraw_str,""
		else:
			bean["score"]=userInfo['score']
			bean["real_name"]=bankCardList[0]['name']
			bean["card_id"]=bankCardList[0]['bankCardNum']
			bean["bank_name"]=bankCardList[0]['bankName']
			bean["sub_bank_name"]=bankCardList[0]['subBankName']
			withdraw_str,item=yhk_withdraw(bean)
			return withdraw_str,item
	else:
		#未实名签约采用支付宝提现
		zfbList=userInfo['zfbList']#获取支付宝列表
		if len(zfbList)==0:
			withdraw_str="[自动提现]支付提现失败，原因是未绑定支付宝号，请绑定支付宝账户"
			return withdraw_str,""
		else:
			bean["score"]=userInfo['score']
			bean["real_name"]=zfbList[0]['name']
			bean["card_id"]=zfbList[0]['account']
			withdraw_str,item=zfb_withdraw(bean)
			return withdraw_str,item

def sendMSG(title,content):

    if len(plusplus_token)>10:
        msgContent=""
        num=0
        for item in content:
            num=num+1
            if len(content)==num:
                msgContent=msgContent+"
"
            if isinstance(item,list):
                msgContent=msgContent+"

"
                for i in item:
                    msgContent=msgContent+""+i+"
"
                msgContent=msgContent+"

"
            else:
                msgContent=msgContent+""+item+"
"
        sendPlusPlus(title,msgContent)
    if len(tg_bot_token)>10 and len(chat_id)!=0:
        msgContent=title+"\n\n"
        num=0
        for item in content:
            num=num+1
            if len(content)==num:
                msgContent=msgContent+"\n"
            if isinstance(item,list):
                for i in item:
                    msgContent=msgContent+"    "+i+"\n"
            else:
                msgContent=msgContent+""+item+"\n"
        sendTelegram(msgContent)

#*********************************main***********************************************************************************
#*********************************读取配置*************************************
end="注意:以上统计仅供参考，一切请以甜糖客户端APP为准。填写邀请码123463支持作者！"
config=readConfig(path+"/ttnodeConfig.config")
print("config:"+config)

if len(config)==0:
	print("错误提示ttnodeConfig.config为空，请重新运行ttnodeconfig.py")
	logging.debug("错误提示ttnodeConfig.config为空，请重新运行ttnodeconfig.py")
	exit()

config=eval(config)#转成字典
#获取甜糖授权码
authorization=config.get("authorization","")
#获取Plus+推送授权码
plusplus_token=config.get("plusplus_token","")
#获取Telegram机器人推送授权码
tg_bot_token=config.get("tg_bot_token","")
chat_id=config.get("chat_id","")

#提现配置参数
week=config.get("week",0)
if len(authorization)==0:
	print("错误提示authorization为空，请重新运行ttnodeconfig.py")
	exit()

week=int(week)

#*********************************错峰延时执行*************************************
sleep_time=random.randint(1,300)
print("错峰延时执行"+str(sleep_time)+"秒，请耐心等待")
logging.debug("错峰延时执行"+str(sleep_time)+"秒，请耐心等待")
#time.sleep(sleep_time)
#*********************************获取用户信息*************************************
content=[]
data=getInitInfo()
inactivedPromoteScore=data['inactivedPromoteScore']
accountScore=data['score']

devices=getDevices()#获取设备列表信息
#*********************************收取星星*************************************
score_info=[]
sign_in_msg=sign_in()#收取签到收益
score_info.append(sign_in_msg)
promote_score_msg=promote_score_logs(inactivedPromoteScore)#收取推广收益
score_info.append(promote_score_msg)
for device in devices:
    string=score_logs(device['hardware_id'],device['inactived_score'],device['alias'])#收取设备收益
    score_info.append(string)
    time.sleep(1)

#*********************************自动提现*************************************
withdraw=""
now_week=dt.datetime.now().isoweekday()#获取今天是星期几返回1-7
now_week=int(now_week)
items=[]
if week==now_week:
    userInfo=getInitInfo()
    withdraw,items=withdraw_type(userInfo)

#*********************************收益统计并发送微信消息*************************************
total_str="[总共收取]"+str(total)+"-🌟"
nowdata=getInitInfo()
accountScore=nowdata['score']
nickName="[账户昵称]"+nowdata['nickName']
accountScore_str="[账户星愿]"+str(accountScore)+"-🌟"
now_time = dt.datetime.now().strftime('%F %T')
now_time_str="[当前时间]"+now_time

content.append(now_time_str)
content.append(nickName)
content.append(accountScore_str)
content.append(total_str)

if week==now_week:
    content.append(withdraw)
    if len(items)!=0:
        content.append(items)

content.append("[收益详细]：")
content.append(score_info)
content.append(end)
sendMSG(msgTitle,content)

print("微信消息已推送。请注意查看。")
title="[甜糖星愿]"
content="####"

exit()


from bots.abstract_bot import AbstractBot
from bots.action import Action
import sendgrid
from sendgrid.helpers.mail import *
import settings

class MailBot(AbstractBot):
    def __init__(self, id):
        actions = ['send']
        super().__init__(id, actions)
        # REQUIRED
        self.mail_from = None
        self.mail_to = None
        self.subject = None
        self.body = None

    def extract_attr(self, intent):
        if intent.parameters['from']:
            self.mail_from = intent.parameters['from']
        if intent.parameters['to']:
            self.mail_to = intent.parameters['to']
        if intent.parameters['subject']:
            self.subject = intent.parameters['subject']
        if intent.parameters['body']:
            self.body = intent.parameters['body']

    def execute(self):
        sg = sendgrid.SendGridAPIClient(apikey=settings.SENDGRID_ACCESS_TOKEN)
        from_email = Email(self.mail_from)
        to_email = Email(self.mail_to)
        subject = self.subject
        content = Content("text/plain",self.body)
        mail = Mail(from_email, subject, to_email, content)
        response = sg.client.mail.send.post(request_body=mail.get())
        print(response.status_code)
        print(response.body)
        print(response.headers)
        return Action(
            action_type='message',
            body='email sent successfully',
            bot=self.id,
            keep_context=False)

    def is_long_running(self):
        return False

    def has_missing_attr(self):
        return (self.mail_from == None or self.mail_to == None or self.subject == None or self.body == None)

    def request_missing_attr(self):
        if self.mail_from == None:
            return Action(
                action_type='inquiry',
                body='Please specify the sender email address',
                bot=self.id,
                keep_context=True)

        if self.mail_to == None:
            return Action(
                action_type='inquiry',
                body='Please specify the recipient email address',
                bot=self.id,
                keep_context=True)

        if self.subject == None:
            return Action(
                action_type='inquiry',
                body='What is the mail subject?',
                bot=self.id,
                keep_context=True)

        if self.body == None:
            return Action(
                action_type='inquiry',
                body='What is the mail body ?',
                bot=self.id,
                keep_context=True)


import torch as th
from torch.utils.tensorboard import SummaryWriter

class learning_loop():
    def __init__(self, N_EPOCH,model,device,train_data,val_data,test_data,optimizer,criterion, directory,mode ) -> None:
        self.N_EPOCH = N_EPOCH
        self.model = model
        self.device = device
        self.train_data = train_data
        self.val_data = val_data
        self.test_data = test_data
        self.optimizer = optimizer
        self.criterion = criterion
        self.mode = mode
        self.writer1=SummaryWriter('logs/'+directory+'/train',flush_secs=60)
        self.writer2=SummaryWriter('logs/'+directory+'/val',flush_secs=60)

    def train(self):
        for epoch in range(1, self.N_EPOCH+1):
            for (_,train) , (_,test) in zip(enumerate(self.train_data, 0),enumerate(self.val_data, 0)):
                self.model.train()
                X_train_ts, y_train_ts = train
                X_val_ts, y_val_ts = test

                X_train_ts, y_train_ts = X_train_ts.to(self.device), y_train_ts.to(self.device)
                X_val_ts, y_val_ts = X_val_ts.to(self.device), y_val_ts.to(self.device)

                out = self.model(X_train_ts.to(th.float32))
                loss = self.criterion(out, y_train_ts)

                self.optimizer.zero_grad()
                loss.backward()
                self.optimizer.step()

                if self.mode == 'classification':
                    acc = (th.argmax(out, dim=1) == y_train_ts).float().mean().item()

                self.model.eval()
                with th.no_grad():
                    out_val = self.model(X_val_ts.to(th.float32))
                    loss_val = self.criterion(out_val, y_val_ts)
                    if self.mode == 'classification':
                        acc_val = (th.argmax(out_val, dim=1) == y_val_ts).float().mean().item()

            self.writer1.add_scalar('Loss', loss.item(), epoch)
            self.writer2.add_scalar('Loss', loss_val.item(), epoch)

            if self.mode == 'classification':
                self.writer1.add_scalar('Accuracy', acc*100 , epoch)
                self.writer2.add_scalar('Accuracy', acc_val*100, epoch)

            if epoch % 20 == 0:
                    if self.mode == 'classification':
                        print('Epoch : {:3d} / {}, Loss : {:.4f}, Accuracy : {:.2f} %, Val Loss : {:.4f}, Val Accuracy : {:.2f} %'.format(
                            epoch, self.N_EPOCH, loss.item(), acc*100, loss_val.item(), acc_val*100))
                    else:
                        print('Epoch : {:3d} / {}, Loss : {:.4f},  Val Loss : {:.4f}'.format(
                            epoch, self.N_EPOCH, loss.item(), loss_val.item()))

        self.writer1.close()
        self.writer2.close()

    def test(self):
        acc_avg = 0
        loss_avg = 0
        y_list = [] # i,y_test,y_pred

        for (i,test) in enumerate(self.test_data, 0):

            X_test_ts, y_test_ts = test
            X_test_ts, y_test_ts = X_test_ts.to(self.device), y_test_ts.to(self.device)

            self.model.eval()
            with th.no_grad():
                out_test = self.model(X_test_ts.to(th.float32))
                loss_test = self.criterion(out_test, y_test_ts)
                if self.mode == 'classification':
                    acc_test = (th.argmax(out_test, dim=1) == y_test_ts).float().mean().item()

            if self.mode == 'classification':
                acc_avg += acc_test
            else:
                y_list.append([i,y_test_ts.cpu().numpy(),out_test.cpu().numpy()])

            loss_avg += loss_test
        if self.mode == 'classification':
            print('Val avg Loss : {:.4f}, Val avg Accuracy : {:.2f} %'.format(
                loss_avg/i,acc_avg/i*100))
        else:
            print('Val avg Loss : {:.4f}'.format(
                loss_avg/i))
            return y_list


# -*- coding: utf-8 -*-
# @Time    : 2017-12-12 20:50
# @Author  : Storm
# @File    : chapter05-05.py
# variables_to_restore函数的使用样例

import tensorflow as tf

v = tf.Variable(0, dtype=tf.float32, name="v")
ema = tf.train.ExponentialMovingAverage(0.99)
print(ema.variables_to_restore())
# {'v/ExponentialMovingAverage': <tf.Variable 'v:0' shape=() dtype=float32_ref>}

saver = tf.train.Saver({"v/ExponentialMovingAverage": v})
with tf.Session() as sess:
    saver.restore(sess, "Saved_model/model2.ckpt")
    print(sess.run(v))
# 0.0999999


import re
import sys
import time
from re import Pattern

from comm_support_lib.comm_interfaces.debug_cli import DebugCLI
from tests.common.common_const import CommonConst
from tests.common.common_regex import CommonRegex
from utils.cli_common_util import CliCommonUtil
from utils.common.cli_command_consts import CliCommandConsts
from utils.common.cli_regex_consts import CliRegexConsts

class CommonHelper:
    __debug_cli = DebugCLI()
    __cli_common_util = CliCommonUtil(__debug_cli)

    assert __debug_cli is not None
    assert __cli_common_util is not None

    @staticmethod
    def copy_file(source_file, target_path):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_CP + source_file + " " + target_path)
        while True:
            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC)
            if not message:
                continue
            if CommonRegex.PATH_FILE_NOT_FOUND.search(message):
                print("copy_file(). No file/path found on the storage device", file=sys.stderr)
                return False
            if CliRegexConsts.REGEX_LOGGED_IN2.search(message):
                print("copy_file() done for " + source_file)
                return True

    @staticmethod
    def remove_file(filename, forced=False, recursive=False, timeout=CommonConst.TIMEOUT_10_SEC):
        command = CommonConst.COMMAND_RM
        if forced:
            command += CommonConst.RM_ARGUMENT_FORCED
        if recursive:
            command += CommonConst.RM_ARGUMENT_RECURSIVE
        command += filename

        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(command)
        while True:
            message = CommonHelper.__debug_cli.get_message(timeout)
            if not message:
                continue
            if CommonRegex.PATH_FILE_NOT_FOUND.search(message):
                print(f"Cannot remove '{filename}': no such file", file=sys.stderr)
                return False
            if CliRegexConsts.REGEX_LOGGED_IN.search(message):
                print(f"File '{filename}' removed successfully")
                return True

    # Check the file for presence in current or alternating partition
    @staticmethod
    def check_file(partition, filename, timeout=CommonConst.TIMEOUT_2_SEC):
        if partition == 'A':
            cmd_tmp = CommonConst.PARTITION_A + filename
        elif partition == 'B':
            cmd_tmp = CommonConst.PARTITION_B + filename
        else:
            print("Undefine partition")
            return False
        CommonHelper.__debug_cli.flush_incoming_data()
        command = f"[ -f '{cmd_tmp}' ] && echo {CommonConst.FOUND_FILE}"
        CommonHelper.__debug_cli.send_message(command)
        while True:
            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC)
            if not message:
                continue
            if CliRegexConsts.REGEX_LOGGED_IN2.search(message):
                print(f"Cannot find file '{filename}'", file=sys.stderr)
                return False
            if CliRegexConsts.REGEX_FOUND_FILE.search(message):
                print(f"File '{filename}' found successfully")
                return True

    @staticmethod
    def check_file(partition, filename, timeout=CommonConst.TIMEOUT_2_SEC):
        if partition == 'A':
            cmd_tmp = CommonConst.PARTITION_A + filename
        elif partition == 'B':
            cmd_tmp = CommonConst.PARTITION_B + filename
        else:
            print("Undefine partition")
            return False
        CommonHelper.__debug_cli.flush_incoming_data()
        command = f"[ -f '{cmd_tmp}' ] && echo {CommonConst.FOUND_FILE}"
        CommonHelper.__debug_cli.send_message(command)
        while True:
            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC)
            if not message:
                continue
            if CliRegexConsts.REGEX_LOGGED_IN2.search(message):
                print(f"Cannot find file '{filename}'", file=sys.stderr)
                return False
            if CliRegexConsts.REGEX_FOUND_FILE.search(message):
                print(f"File '{filename}' found successfully")
                return True

    @staticmethod
    def list_directory(directory):
        command = f'{CommonConst.COMMAND_LS}{directory}'
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(command)
        start_time = time.time()
        while True:
            if time.time() - start_time > CommonConst.TIMEOUT_60_SEC:
                return None

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC,
                                                           CommonRegex.LIST_DIR_COMMAND_RESULT)
            if not message:
                continue
            else:
                return message

    @staticmethod
    def package_remove(package_name):
        command = f'{CommonConst.COMMAND_PACKAGE_REMOVE}{package_name}'
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(command)
        start_time = time.time()
        while True:
            if time.time() - start_time > CommonConst.TIMEOUT_30_SEC:
                return None

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC)
            if not message:
                continue

            if CliRegexConsts.REGEX_LOGGED_IN2.search(message):
                print(f"'{package_name}' removed ")
                return True

    @staticmethod
    def switch_ethernet(state: bool):
        CommonHelper.__debug_cli.flush_incoming_data()

        if state:
            CommonHelper.__debug_cli.send_message("ifconfig eth0 up")
            assert CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, CommonRegex.ETH0_READY)
        else:
            CommonHelper.__debug_cli.send_message("ifconfig eth0 down")
            assert CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, CliRegexConsts.REGEX_LOGGED_IN)

    @staticmethod
    def wifi_radio_on():
        CommonHelper.__debug_cli.flush_incoming_data()

        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_WIFI_RADIO_ON)
        assert CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, CliRegexConsts.REGEX_LOGGED_IN)

    @staticmethod
    def switch_wifi(state: bool):
        CommonHelper.__debug_cli.flush_incoming_data()

        if state:
            CommonHelper.__debug_cli.send_message(
                CommonConst.COMMAND_IFCONFIG + f"{CommonConst.IFACE_WIFI} {CommonConst.IFACE_STATE_UP}")
            # If wlan0 has no suitable AP configurations, "wlan0: link becomes ready" will not be occurred.
            # Any way, checking of "wlan0: link becomes ready" is required to be sure that the system is
            # completely configured the wlan device
            CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, CommonRegex.WLAN0_READY)
        else:
            CommonHelper.__debug_cli.send_message(
                CommonConst.COMMAND_IFCONFIG + f"{CommonConst.IFACE_WIFI} {CommonConst.IFACE_STATE_DOWN}")
            CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, CliRegexConsts.REGEX_LOGGED_IN)

    @staticmethod
    def wifi_connect(ssid, password, timeout):
        CommonHelper.__debug_cli.flush_incoming_data()

        test_start_time = time.time()
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_WIFI_CONNECT + f"{ssid} password \"{password}\"")
        while True:
            if time.time() - test_start_time > timeout:
                print("wifi_connect() timeout occurred", file=sys.stderr)
                return False

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC)
            if message is None:
                continue

            if CommonRegex.WLAN_ACTIVATED.search(message):
                print("wifi_connect() successfully connected to: " + ssid)
                return True
            if CommonRegex.WLAN_SSID_NOT_FOUND.search(message):
                print("wifi_connect() ssid is not found: " + ssid, file=sys.stderr)
                return False
            if CommonRegex.WLAN_CONN_FAILED.search(message):
                print("wifi_connect() connection failed with : " + message, file=sys.stderr)
                return False

    @staticmethod
    def wifi_disconnect(ssid):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_WIFI_DISCONNECT + ssid)
        assert CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, CliRegexConsts.REGEX_LOGGED_IN)

    @staticmethod
    def set_wlan_tx_power(power):
        output_command = f"{CommonConst.COMMAND_IW}{CommonConst.IFACE_WIFI} {CommonConst.IW_SET_TXPOWER}{power}"

        start_time = time.time()
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(output_command)
        while True:
            if time.time() - start_time > CommonConst.TIMEOUT_30_SEC:
                print("__set_wlan_tx_power() timeout occurred", file=sys.stderr)
                return False

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC)

            if CommonRegex.IW_ERROR.search(message):
                print("__set_wlan_tx_power() execution error", file=sys.stderr)
                return False
            if CliRegexConsts.REGEX_LOGGED_IN.search(message):
                return True

    @staticmethod
    def wifi_check_connection():
        connection_ssid = None

        CommonHelper.__debug_cli.flush_incoming_data()
        result_searching_start_time = time.time()
        CommonHelper.__debug_cli.send_message(
            f"{CommonConst.COMMAND_IW}{CommonConst.IW_DEV}{CommonConst.IFACE_WIFI} {CommonConst.IW_LINK}")
        while True:
            if time.time() - result_searching_start_time > CommonConst.TIMEOUT_20_SEC:
                print("__wifi_check_connection() unknown ping result, timeout occurred", file=sys.stderr)
                return None

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC)
            if message is None:
                continue

            if CommonRegex.IW_LINK_SSID.search(message):
                connection_ssid = message.split(": ")[1]
            if connection_ssid is not None and CliRegexConsts.REGEX_LOGGED_IN.search(message):
                break

        return connection_ssid

    @staticmethod
    def ping(host, ping_time):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_PING + host)
        time.sleep(ping_time)

        result_searching_start_time = time.time()
        CommonHelper.__debug_cli.send_message(CliCommandConsts.COMMAND_CTRL_C)
        while True:
            if time.time() - result_searching_start_time > CommonConst.TIMEOUT_20_SEC:
                print("ping() unknown ping result, timeout occurred", file=sys.stderr)
                return False

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC)
            if message is None:
                continue

            if CommonRegex.BAD_PING.search(message):
                print("ping() return state False")
                return False
            if CommonRegex.GOOD_PING.search(message):
                print("ping() return state True")
                return True

    @staticmethod
    def check_package_presence(package: str):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_TYPE + package)
        type_result = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, re.compile(f"{package} {CommonConst.TYPE_PACKAGE_IS}"))

        if type_result is None:
            print("__check_package_presence() unsuccessful. No response on \'type\' command", file=sys.stderr)
            return False
        else:
            return True

    @staticmethod
    def check_package_help(package: str, help_argument: str):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(package + help_argument)
        if CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC, CommonRegex.COMMAND_NOT_FOUND) is None:
            return True
        else:
            print("__check_package_help() unsuccessful. \'Command not found\' occurred", file=sys.stderr)
            return False

    @staticmethod
    def check_package_version(package: str, version_argument: str, result_regex: Pattern):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(package + version_argument)
        if CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC, result_regex) is not None:
            return True
        else:
            print("__check_package_version() unsuccessful", file=sys.stderr)
            return False

    @staticmethod
    def perform_ethtool(device: str, speed: str, duplex: str, auto_negotiation: str):
        check_speed = False
        check_duplex = False
        check_autoneg = False

        ethtool_command = f"{CommonConst.COMMAND_ETHTOOL}-s {device} speed {speed} duplex {duplex} autoneg {auto_negotiation}"

        CommonHelper.__debug_cli.flush_incoming_data()

        test_start_time = time.time()
        CommonHelper.__debug_cli.send_message(ethtool_command)
        # wait some time ensure that the function is done and the device is completely reconfigured
        time.sleep(CommonConst.TIMEOUT_10_SEC)

        ethtool_check_command = f"{CommonConst.COMMAND_ETHTOOL}{device}"
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(ethtool_check_command)
        while True:
            if time.time() - test_start_time > CommonConst.TIMEOUT_60_SEC:
                return False

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC)
            if message is None:
                continue

            result = CommonRegex.ETHTOOL_SPEED.search(message)
            if result:
                if speed in result.group(0):
                    check_speed = True
                else:
                    print("__perform_ethtool() failed to set speed: " + speed, file=sys.stderr)
                    return False

            result = CommonRegex.ETHTOOL_DUPLEX.search(message)
            if result:
                if duplex in result.group(0).lower():
                    check_duplex = True
                else:
                    print("__perform_ethtool() failed to set duplex: " + duplex, file=sys.stderr)
                    return False

            result = CommonRegex.ETHTOOL_AUTONEG.search(message)
            if result:
                if auto_negotiation in result.group(0):
                    check_autoneg = True
                else:
                    print("__perform_ethtool() failed to set autoneg: " + auto_negotiation, file=sys.stderr)
                    return False

            if check_speed and check_duplex and check_autoneg:
                return True

    @staticmethod
    def find_matches(command_to_perform: str, matches_regex: Pattern, timeout: int):
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(command_to_perform)
        found_list = []
        test_start_time = time.time()
        while True:
            if time.time() - test_start_time > timeout:
                break

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC)
            if message is None:
                continue
            elif matches_regex.search(message):
                found_list.append(message)

        return found_list

    @staticmethod
    def configure_can(iface: str, enable: bool, bit_rate: int = 20000):
        CommonHelper.__debug_cli.flush_incoming_data()
        if enable:
            CommonHelper.__debug_cli.send_message(
                f"{CommonConst.COMMAND_IP_LINK}{CommonConst.IP_LINK_SET}{iface} {CommonConst.IFACE_STATE_UP} {CommonConst.IP_LINK_TYPE_CAN}{CommonConst.IP_LINK_BITRATE}{bit_rate}")
        else:
            CommonHelper.__debug_cli.send_message(
                f"{CommonConst.COMMAND_IP_LINK}{CommonConst.IP_LINK_SET}{iface} {CommonConst.IFACE_STATE_DOWN}")

        return_state = True
        test_start_time = time.time()
        while True:
            if time.time() - test_start_time > CommonConst.TIMEOUT_30_SEC:
                print("__configure_can() timeout occurred", file=sys.stderr)
                return False

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_5_SEC)
            if message is None:
                continue
            elif CliRegexConsts.REGEX_LOGGED_IN.search(message):
                return return_state
            elif CommonRegex.CAN_DEV_BUSY.search(message):
                print("__configure_can() Device or resource busy", file=sys.stderr)
                return_state = False

    @staticmethod
    def perform_cangen(iface: str, extended_id: bool, data: bytes, id: int, delay_msec: int, generation_time_sec: int,
                       additional_arguments: str = None):
        output_command = f"{CommonConst.COMMAND_CANGEN} {iface} "

        if extended_id:
            output_command += CommonConst.CANGEN_EXTENDED

        data_len = len(data)
        if data_len == 0 or data_len > CommonConst.CAN_MAX_PAYLOAD:
            return False

        output_command += f"{CommonConst.CANGEN_DATA_LEN}{data_len} {CommonConst.CANGEN_DATA}{data.hex().upper()} "
        output_command += f"{CommonConst.CANGEN_ID}{hex(id).upper()} "
        output_command += f"{CommonConst.CANGEN_INTERVAL} {delay_msec} "

        if additional_arguments:
            output_command += additional_arguments

        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(output_command)
        time.sleep(generation_time_sec)

        CommonHelper.__debug_cli.send_message(CliCommandConsts.COMMAND_CTRL_C)
        return CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_20_SEC,
                                                    CliRegexConsts.REGEX_LOGGED_IN) is not None

    @staticmethod
    def create_folder(folder: str, with_patents: bool = False):
        CommonHelper.__debug_cli.flush_incoming_data()

        command = CommonConst.COMMAND_MKDIR
        if with_patents:
            command += CommonConst.MKDIR_ARGUMENT_P
        command += folder

        return_state = True
        test_start_time = time.time()
        CommonHelper.__debug_cli.send_message(command)
        while True:
            if time.time() - test_start_time > CommonConst.TIMEOUT_60_SEC:
                print("create_folder() timeout occurred", file=sys.stderr)
                return False

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC)
            if message is None:
                continue

            if CommonRegex.MKDIR_ERROR.search(message):
                print(f"create_folder() error while creating {folder}", file=sys.stderr)
                return_state = False
            if CliRegexConsts.REGEX_LOGGED_IN.search(message):
                print(f"create_folder() done for {folder}")
                return return_state

    @staticmethod
    def get_md5_checksum(file):
        command = f'{CommonConst.COMMAND_MD5_CHECKSUM} {file}'
        CommonHelper.__debug_cli.flush_incoming_data()
        CommonHelper.__debug_cli.send_message(command)

        start_time = time.time()
        while True:
            if time.time() - start_time > CommonConst.TIMEOUT_60_SEC:
                return None

            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC,
                                                           CommonRegex.MD5_CHECKSUM_COMMAND_RESULT)
            if not message:
                continue
            else:
                return message.split(" ")[0]

    @staticmethod
    def hard_reset(boot_from_emmc=False):
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_ECHO + CommonConst.SET_SYSRQ)
        CommonHelper.__debug_cli.send_message(CommonConst.COMMAND_ECHO + CommonConst.SET_SYSRQ_TRIGG)

        if boot_from_emmc:
            command_start_time = time.time()
            CommonHelper.__debug_cli.flush_incoming_data()
            while True:
                if time.time() - command_start_time > CommonConst.TIMEOUT_60_SEC:
                    print("Boot system after hard reset failed. Timeout occurred", file=sys.stderr)
                    return False
                CommonHelper.__debug_cli.send_message(CliCommandConsts.COMMAND_EMPTY)
                if CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_500_MSEC, CliRegexConsts.REGEX_UBOOT_CLI):
                    break
            CommonHelper.__debug_cli.send_message(CliCommandConsts.COMMAND_BOOT_FROM_EMMC)

        command_start_time = time.time()
        CommonHelper.__debug_cli.flush_incoming_data()
        while True:  # Wait system to boot after hard reset
            if time.time() - command_start_time > CommonConst.TIMEOUT_60_SEC:
                print("Boot system after hard reset failed. Timeout occurred", file=sys.stderr)
                return False
            message = CommonHelper.__debug_cli.get_message(CommonConst.TIMEOUT_10_SEC, CliRegexConsts.REGEX_LOGIN)
            if message:
                print("Boot system after hard reset succeeded.")
                return True


import serial
import time
ser = serial.Serial('COM5', baudrate = 9600, timeout = 5, xonxoff=True)

if ser.isOpen():
    #do nothing
    print("Serial is open")
else:
    try:
            ser.open()
    except Exception as e:
            print("error opening Serial Port: " + str(e))
            exit()

if ser.isOpen():
    o = "hello serial port\n\r"
    o_out = o.encode()
    ser.write(o_out)
    for x in range(10):
       ser.write(b'\x06')
    ser.write(o_out)
    youcan = "you can stop\n\r"
    ser.write(youcan.encode())
else:
    print("Serial is not open")
ser.close()
print("End")


#!/usr/bin/env python3

import os # for os.path.plittext (remove .png from filename)
import PIL
import numpy as np
import scipy.ndimage
from scipy.spatial import Delaunay
from matplotlib import pyplot
import math
import argparse

PIL.Image.MAX_IMAGE_PIXELS = None # disable decompression bomb error

# empty config: (False, (r,g,b))
#               (True,  alpha)

# global vars, get set by command line parser
file_name = "Ansicht Ost_0.25.tif"
empty_config = (True, 0) #empty_config = (False, (255, 0, 255))

# still not changeable by command line argumets
max_distance = 10 # in pixels
chunk_size = 1000 # chunk_size² (output) pixels per chunk

def compute_is_empty(img):
	(use_alpha, value) = empty_config
	if use_alpha:
		print(f"Compute empty pixels using alpha = {value} ...")
		is_empty = img[:,:,3] == value
	else:
		print(f"Compute empty pixels using rgb = {value} ...")
		(r,g,b) = value
		is_empty = (img[:,:,0] == r) & (img[:,:,1] == g) & (img[:,:,2] == b)
	print(f"is_empty uses {humansize(is_empty.nbytes)}.")
	return is_empty

def compute_is_vertex(img, is_empty):
	print(f"Compute is_vertex pixels without optimization")

	is_vertex = ~is_empty
	# TODO: optimize away points inside filled surface

	print(f"is_vertex uses {humansize(is_vertex.nbytes)}.")
	return is_vertex

def encode_image(img):
	""" return (vertices, is_empty, is_vertex, colors) as numpy arrays """

	print("in encode_image:")

	#(h,w) = img.shape[:2]
	(use_alpha, value) = empty_config

	# compute is_empty numpy array
	is_empty = compute_is_empty(img)

	# compute is_vertex numpy array
	is_vertex = compute_is_vertex(img, is_empty)

	print("compute number of vertices...")
	vertex_count = np.sum(is_vertex)
	if vertex_count == 0:
		print("Warning: no vertices in this chunk, leave empty.")
		return (None, None, None, None)

	print(f"image contains {vertex_count} vertices.")

	print(f"compute vertex coordinates...")
	# [y,x] arrays
	vertices = np.argwhere(is_vertex).astype(np.uint16)
	print(f"vertices uses {humansize(vertices.nbytes)}.")

	print(f"extract vertex colors...")

	colors = np.zeros((vertex_count, 3), dtype=np.uint8)
	colors[:,0] = np.extract(is_vertex, img[:,:,0])
	colors[:,1] = np.extract(is_vertex, img[:,:,1])
	colors[:,2] = np.extract(is_vertex, img[:,:,2])

	print(f"colors uses {humansize(colors.nbytes)}.")

	return (vertices, is_empty, is_vertex, colors)

def fill_image(src_img, dst_img, colors, triangulation, is_empty, is_vertex, dst_offset):
	(dst_h, dst_w) = dst_img.shape[:2]
	should_interpolate = is_empty[
		dst_offset[0] : dst_h + dst_offset[0],
		dst_offset[1] : dst_w + dst_offset[1]]

	print("Search for triangles to interpolate from...")
	interpolation_coords = np.argwhere(should_interpolate)
	simplex_ids = triangulation.find_simplex(interpolation_coords + dst_offset)

	print("compute output colors")
	for i in range(len(interpolation_coords)):
		(y,x) = interpolation_coords[i]
		simplex_id = simplex_ids[i]

		# skip points outside of triangulation
		if simplex_id == -1:
			should_interpolate[y,x] = False
			continue

		# read triangle values
		simplex_vertexids = triangulation.simplices[simplex_id]
		simplex_vertices = triangulation.points[simplex_vertexids]

		(p1, p2, p3) = simplex_vertices

		v1 = p2 - p1
		v2 = p3 - p2
		v3 = p1 - p3

		# skip if triangle is too large
		if max(	np.linalg.norm(v1),
				np.linalg.norm(v1),
				np.linalg.norm(v3) ) > max_distance:
			should_interpolate[y,x] = False
			continue

		# compute barycentric coordinates using affine transformation
		# provided by scipy Delaunay
		barycentric = np.dot(
			triangulation.transform[simplex_id,:2],
			np.array([y,x]) + dst_offset - triangulation.transform[simplex_id,2])

		# interpolate final color
		v1i = (int(p1[0]), int(p1[1]))
		v2i = (int(p2[0]), int(p2[1]))
		v3i = (int(p3[0]), int(p3[1]))

		dst_img[y,x] =	barycentric[0] * src_img[v1i] \
			+			barycentric[1] * src_img[v2i] \
			+ (1 - barycentric[0] - barycentric[1]) * src_img[v3i]

def parse_args():
	parser = argparse.ArgumentParser(description='Fill holes in Images using delaunay triangulation. This program splits work into smaller chunks to be able to parallelize the workload and overcome memory limitations.')
	parser.add_argument('-a','--use-alpha', help='use alpha color to specify empty regions')
	parser.add_argument('-r','--use-rgb', nargs=3, help='use alpha color to specify empty regions')
	parser.add_argument('-c','--chunk-size', help='set size of blocks in which the image is computed. smaller chunks reduce memory usage and triangulation work, but increases overhead due to smaller arrays')
	parser.add_argument('-d','--max-distance', help='maximal distance between two points for interpolation')
	parser.add_argument('filename', help="the image to fill the holes")
	args = parser.parse_args()

	global empty_config
	if args.use_alpha is not None:
		empty_config = (True, int(args.use_alpha))
	elif args.use_rgb is not None:
		empty_config = (False, (int(args.use_rgb[0]), int(args.use_rgb[1]), int(args.use_rgb[2])))
	else:
		if input("Use alpha channel to decide if points are empty? (y/n)").lower() == 'y':
			empty_config = (True, int(input("Enter alpha value for empty cells (probably 0)")))
		else:
			empty_config = (False, (
				int(input("Enter red value")),
				int(input("Enter green value")),
				int(input("Enter blue value"))
			))
	global file_name
	file_name = args.filename

	if args.chunk_size is not None:
		global chunk_size
		chunk_size = int(args.chunk_size)
		print(f"use chunk size {chunk_size}")
	if args.max_distance is not None:
		global max_distance
		max_distance = int(args.max_distance)
		print(f"use max distance {max_distance}")

def process_chunk(in_img, out_img, dst_offset):
	print(f"dst_offset: {dst_offset}, in_img.shape: {in_img.shape}, out_img.shape: {out_img.shape}")

	(vertices, is_empty, is_vertex, colors) = encode_image(in_img)
	if vertices is None:
		return

	print("Compute delaunay triangulation...")
	triangulation = Delaunay(vertices)
	fill_image(in_img, out_img, colors, triangulation, is_empty, is_vertex, dst_offset)

def main():
	parse_args()

	print(f"load image {file_name}...")
	img = np.array(PIL.Image.open(file_name))
	(h,w,channels) = img.shape
	print(f"Image size: w={w}, h={h}, channels={channels}, dtype={img.dtype}, memory={humansize(img.nbytes)}")

	dst_img = img.copy()
	chunk_count_x = math.ceil(w / chunk_size)
	chunk_count_y = math.ceil(h / chunk_size)

	for chunk_y in range(chunk_count_y):
		for chunk_x in range(chunk_count_x):
			print(f"= {int(100.0*(chunk_y * chunk_count_x + chunk_x) / (chunk_count_x * chunk_count_y))}% ===============================")
			print(f"=== fill chunk x:{chunk_x+1}/{chunk_count_x} y:{chunk_y+1}/{chunk_count_y} ===")

			src_img_chunk =     img[max(chunk_y * chunk_size - max_distance, 0) : (chunk_y + 1) * chunk_size + max_distance,
									max(chunk_x * chunk_size - max_distance, 0) : (chunk_x + 1) * chunk_size + max_distance]
			dst_img_chunk = dst_img[chunk_y * chunk_size                        : (chunk_y + 1) * chunk_size,
									chunk_x * chunk_size                        : (chunk_x + 1) * chunk_size]
			dst_offset = (chunk_y * chunk_size - max(chunk_y * chunk_size - max_distance, 0),
			              chunk_x * chunk_size - max(chunk_x * chunk_size - max_distance, 0))

			process_chunk(src_img_chunk, dst_img_chunk, dst_offset)

		#print("Show graph..")
		#pyplot.imshow(dst_img)
		#pyplot.show()
		#print("done.")

	dst_img_pil = PIL.Image.fromarray(dst_img)
	dst_img_pil.save(os.path.splitext(file_name)[0] + "_interpolated.png", "PNG")

	pyplot.imshow(dst_img)
	pyplot.show()

# ------- other stuff

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
def humansize(nbytes):
    i = 0
    while nbytes >= 1024 and i < len(suffixes)-1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])

if __name__ == "__main__":
	main()


n = int(input())
tap_guests = []
space_guests = []
stay_days_of_the_longest_stay_guest = 0

for _ in range(366):
    tap_guests.append(0)
    space_guests.append(0)

for _ in range(n):
    c, s, e = input().split()
    s, e = int(s) - 1, int(e)
    if c == 'T':
        for i in range(s, e):
            tap_guests[i] += 1
    else:
        for i in range(s, e):
            space_guests[i] += 1
    stay_days = e - s
    if stay_days > stay_days_of_the_longest_stay_guest:
        stay_days_of_the_longest_stay_guest = stay_days

days_when_only_one_guest = 0
max_guests = 0
no_fights_days = 0
max_guests_when_no_fights = 0

for i in range(366):
    guests = tap_guests[i] + space_guests[i]
    if guests > 0:
        days_when_only_one_guest += 1
        if guests > max_guests:
            max_guests = guests
        if tap_guests[i] == space_guests[i]:
            no_fights_days += 1
            if guests > max_guests_when_no_fights:
                max_guests_when_no_fights = guests

print(days_when_only_one_guest)
print(max_guests)
print(no_fights_days)
print(max_guests_when_no_fights)
print(stay_days_of_the_longest_stay_guest)


# Convert COG metadata into possible (aligned) base sequence that would produce these mutations and ambiguities.
# It will choose some plausible triple of bases for each AA name, which will often not be the actual triple used.
# Output in GISAID-style format with hCoV-19/ prefix and |collection date.

from stuff import *
import sys,argparse

parser=argparse.ArgumentParser()
parser.add_argument('-f', '--mindate',       default="2019-01-01",  help="Minimum date used from input")
parser.add_argument('-s', '--sorted',     action="store_true",      help="Whether input is sorted into reverse date order")
args=parser.parse_args()

stats={}
for geneloc in genes.values():
  for p in range(geneloc[0],geneloc[1],3):
    c=refgenome[p:p+3]
    x=codontable.get(c,'?')
    if x not in stats: stats[x]={}
    stats[x][c]=stats[x].get(c,0)+1

# Find most likely triple of bases for each AA
# AA2bases[ new AA name, refgenome triple ] = best guess for new triple
AA2bases={}
w0,w1,w2=0.4,0.7,0.75# Weights that work reasonably well
for x in stats:
  y=stats[x]
  s=sum(stats[x].values())
  for old3 in codontable:
    best=(-1e30,)
    for new3 in y:
      # Mutation from old3 -> new3
      score=y[new3]/s-w0*(old3[0]!=new3[0])-w1*(old3[1]!=new3[1])-w2*(old3[2]!=new3[2])
      if score>best[0]: best=(score,new3)
    AA2bases[x,old3]=best[1]

for (name,date,ml,am) in csvrows_it(sys.stdin,["sequence_name","sample_date","mutations","ambiguities"]):
  if date<args.mindate:
    if args.sorted: break
    continue

  ml=ml.split('|')
  am=am.split('|')

  output=list(refgenome)

  for mut in ml:
    (gene,m)=mut.split(':')
    x=m[0]
    p1=int(m[1:-1])
    y=m[-1]
    if gene=='synSNP':
      p=p1-1
      output[p]=y
    else:
      if gene=='orf1ab':
        if p1<=4401: gene='ORF1a'
        else: gene='ORF1b';p1-=4401
      p0=genes[gene]
      p=p0[0]+(p1-1)*3-1
      output[p:p+3]=list(AA2bases[y,refgenome[p:p+3]])

  for ar in am:
    x=[int(p)-1 for p in ar.split('-')]
    if len(x)==1: output[x[0]]='N'
    else: output[x[0]:x[1]+1]=['N']*(x[1]+1-x[0])

  print(">hCoV-19/"+name+"|"+date)
  print("".join(output))


import tkinter
import customtkinter
from pytube import YouTube

def startDownloadHigh():
    try:
        youtubeLink = link.get()
        youtubeObject = YouTube(youtubeLink, on_progress_callback=onProgress)
        title.configure(text=youtubeObject.title, text_color="white")
        author.configure(text="Uploaded by " + youtubeObject.author, text_color="white")
        length.configure(text=str(youtubeObject.length) + " seconds", text_color="white")
        finishLabel.configure(text="")
        video = youtubeObject.streams.get_highest_resolution()
        video.download()
        finishLabel.configure(text="Downloaded", text_color="green")
    except:
        finishLabel.configure(text="Download Error!", text_color="red")

def startDownloadAudio():
    try:
        youtubeLink = link.get()
        youtubeObject = YouTube(youtubeLink, on_progress_callback=onProgress)
        title.configure(text=youtubeObject.title, text_color="white")
        author.configure(text="Uploaded by " + youtubeObject.author, text_color="white")
        length.configure(text=str(youtubeObject.length) + " seconds", text_color="white")
        finishLabel.configure(text="")
        audio = youtubeObject.streams.get_audio_only()
        audio.download()
        finishLabel.configure(text="Downloaded", text_color="green")
    except:
        finishLabel.configure(text="Download Error!", text_color="red")

def onProgress(stream, chunk, bytes_remaining):
    total_size = stream.filesize
    bytes_downloaded = total_size - bytes_remaining
    percentage_of_completion = bytes_downloaded / total_size * 100
    per = str(int(percentage_of_completion))
    pPercentage.configure(text=per+"%")
    pPercentage.update()

    # Update progress bar
    progressBar.set(float(percentage_of_completion / 100))

# System settings
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("blue")

# App frame
app = customtkinter.CTk()
app.geometry("720x480")
app.title("Youtube Downloader")

# UI elements
title = customtkinter.CTkLabel(app, text="Insert Youtube link")
title.pack(padx = 10, pady = 10)
author = customtkinter.CTkLabel(app, text="")
author.pack(padx = 10, pady = 10)
length = customtkinter.CTkLabel(app, text="")
length.pack(padx = 10, pady = 10)

# Link input
url = tkinter.StringVar()
link = customtkinter.CTkEntry(app, width=350, height=40, textvariable=url)
link.pack()

# Finished Downloading
finishLabel = customtkinter.CTkLabel(app, text="")
finishLabel.pack()

# Progress percentage
pPercentage = customtkinter.CTkLabel(app, text="0%")
pPercentage.pack()

progressBar = customtkinter.CTkProgressBar(app, width=400)
progressBar.set(0)
progressBar.pack()

# Download button

## Button for high resolution download
download_high_resolution = customtkinter.CTkButton(app, text="Download Highest Resolution", command=startDownloadHigh, height=40, width=150)
download_high_resolution.pack(padx=10, pady=15)

## Button for mp4 download
download_audio = customtkinter.CTkButton(app, text=" Download Audio Only (MP4) ", command=startDownloadAudio, height=40, width=150)
download_audio.pack(padx=10, pady=15)

# Footer
footer = customtkinter.CTkLabel(app, text="RegusAl ©2023")
footer.pack(pady=30)

# Run app
app.mainloop()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='NewsPost',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=200, verbose_name='Titel')),
                ('posted', models.DateTimeField(verbose_name='Dato')),
                ('body', models.TextField(verbose_name='Indhold')),
                ('group_handle', models.CharField(max_length=20)),
                ('year', models.IntegerField(default=0)),
                ('author', models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Forfatter', on_delete=models.CASCADE)),
            ],
            options={
                'verbose_name_plural': 'nyheder',
                'verbose_name': 'nyhed',
            },
        ),
    ]


from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, get_object_or_404
from django.urls import reverse_lazy
from chat.utils import login_required
from .utils import *
from .forms import *
from django.views.generic.list import ListView, View
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, FormMixin
from MagrasBox.settings import BASE_DIR
import os
from authsys.forms import SignInFormSecurity, SignUpForm

# Create your views here.
from django.http import HttpResponse, Http404, HttpResponseRedirect, JsonResponse
from .models import *

from django.shortcuts import redirect

class Main(ListView):
    paginate_by = 10
    model = Rooms
    context_object_name = 'rooms'
    template_name = 'mainapp/showrooms.html'
    extra_context = {'title': 'Main', 'form_login': SignInFormSecurity, 'form_signup': SignUpForm}

    def get(self, request, *args, **kwargs):
        self.query = {}
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.query = {}
        if 'search_inp' in self.request.POST:
            self.query['room_name__contains'] = request.POST.get('search_inp')
        else:
            del self.query['room_name__contains']
        self.object_list = self.get_queryset()
        context = self.get_context_data()
        return self.render_to_response(context)

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()
        context['types'] = RoomType.objects.all()
        if 'search_inp' in self.request.POST:
            context['search_init'] = self.request.POST.get('search_inp')
        context['pk'] = 0
        return context

    def get_queryset(self):
        if 'typid' in self.request.GET.keys() and self.request.GET['typid'].isdigit():
            self.query['type_id'] = int(self.request.GET['typid'])
        if self.query != {}:
            queryset = Rooms.objects.filter(**self.query).select_related('author', 'type').order_by('-create_date')
        else:
            queryset = Rooms.objects.all().select_related('author', 'type').order_by('-create_date')
        return queryset

class ShowRoom(LoginRequiredMixin, DetailView):
    model = Rooms
    pk_url_kwarg = 'roomid'
    template_name = 'mainapp/room.html'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data()
        context = super().get_context_data()
        context['title'] = self.object.room_name
        return context

def show_user(request, userid):
    return HttpResponse('User')

def delete_room(request, room_id):
    room =  get_object_or_404(Rooms, pk = room_id)
    if request.user != room.author:
        raise PermissionError('You are not author of this room')
    else:
        room.delete()
        return redirect('get_to_main')

class CreateRoomView(LoginRequiredMixin, CreateView):
    model = Rooms
    template_name = 'mainapp/create_room.html'
    login_url = 'login'
    form_class = CreateRoom
    extra_context = {'title': 'Create room page'}

    def create_data(self, room):
        path_t = f"{BASE_DIR}/chat/chats_data/"
        path_a = f"{BASE_DIR}/chat/actions_data/"

        if not os.path.exists(path_t):
            os.makedirs(path_t)
        if not os.path.exists(path_a):
            os.makedirs(path_a)

        with open(f'{path_t}{room.pk}.txt', "w") as f:
            f.write("Welcome\n")
        with open(f'{path_a}{room.pk}.txt', "w") as f:
            f.write("")

    def form_valid(self, form):
        room = form.save(commit=False)
        room.author = self.request.user
        room.save()
        Membership.objects.create(room = room, user = self.request.user, can_write=True)
        self.success_url = reverse_lazy('get_to_main')
        self.create_data(room)
        return super(CreateRoomView, self).form_valid(form)

@login_required
def rate(request, room_id, type):
    value = 1
    if type == 'down':
        value = -1
    elif type == 'up':
        pass
    else:
        raise ValueError('Invalid rate type')
    room = Rooms.objects.get(pk=int(room_id))
    blue_button = True
    if request.user in room.rated_persons.all():
        rating = Rating.objects.get(room_id = room.pk, user_id = request.user.pk)
        if (rating.is_positive and value > 0) or (not rating.is_positive and value < 0):
            if value > 0:
                room.rate -= 1
            else:
                room.rate += 1
            blue_button = False
            rating.delete()
        else:
            rating.is_positive = not rating.is_positive
            room.rate += 2*value
            rating.save()

    else:
        room.rate+=value
        Rating.objects.create(user_id = request.user, room_id = room, is_positive = value>0)
    room.save()
    if blue_button:
        if value > 0:
            blue_button = 'r'
        else:
            blue_button = 'l'
    ans = f'<b id="rate" style="color: {room.get_rate_color()}">{room.rate}</b>'
    return JsonResponse({'rate': ans, 'pk': room.pk, 'blue_button': blue_button})


import os
import re
import time
import httpretty
import unittest
import socket

from app_fixture import app

test_iri = "/us/judgment/us/1986-06-30/05-179/eng@published#test/2014-01-01/main.xml"
test_transform = "mayer-to-akx"
test_xml_file = "./test/data/0b3e349463dcdd20.xml"
test_file = ""
with open(test_xml_file, 'r') as f:
    test_file = f.read()
full_iri = test_iri + "?transform=%s" % test_transform

test_forwarding_headers = {
    "Content-Type": "text/xml",
    "X-Forward-Id": "550e8400-e29b-41d4-a716-446655440000",
    "X-Forward-To": "http://example.com,http://2example.com",
    "X-Forward-Query-Params": "foo=bar&baz=quux,testing=true",
    "X-Forward-Method": "POST,PUT",
    "X-Forward-Errors-To": "errors.com:7070",
    "X-Forward-Referer": "ORIGIN"
}

test_unforwardable_headers = {
    "Content-Type": "application/xml",
    "X-Forward-Id": "550e8400-e29b-41d4-a716-446655440000",
    "X-Forward-Errors-To": "errors.com:7070",
    "X-Forward-Referer": "ORIGIN"
}

fail_forwarding_headers = {
    "Content-Type": "text/xml",
    "X-Forward-Id": "550e8400-e29b-41d4-a716-446655440000",
    "X-Forward-To": "http://err-gen.com",
    "X-Forward-Query-Params": "foo=bar&baz=quux",
    "X-Forward-Method": "POST",
    "X-Forward-Errors-To": "asherah.int.casetext.com:7099",
    "X-Forward-Referer": "ORIGIN"
}

timeout_forwarding_headers = {
    "Content-Type": "text/xml",
    "X-Forward-Id": "550e8400-e29b-41d4-a716-446655440000",
    "X-Forward-To": "http://timeout.com",
    "X-Forward-Query-Params": "foo=bar&baz=quux",
    "X-Forward-Method": "POST",
    "X-Forward-Errors-To": "errors.com:7070",
    "X-Forward-Referer": "ORIGIN"
}

expected_forwarding_headers = {
    "Content-Type": "text/xml",
    "X-Forward-Id": "550e8400-e29b-41d4-a716-446655440000",
    "X-Forward-To": "http://2example.com",
    "X-Forward-Query-Params": "testing=true",
    "X-Forward-Method": "PUT",
    "X-Forward-Errors-To": "errors.com:7070",
    "X-Forward-Referer": "http://localhost" + full_iri
}

class TestForwarding(unittest.TestCase):
    def setUp(self):
        self.flask_app_obj = app
        self.app = self.flask_app_obj.test_client()
        httpretty.enable()
        self.response_count = 0
        self.error_count = 0
        def callback(request, uri, headers):
            self.assertEqual(request.body.decode('utf8'), test_file)
            for expected_header, value in expected_forwarding_headers.items():
                self.assertIn(expected_header, request.headers)
                self.assertEqual(request.headers[expected_header], value)

            self.response_count += 1
            return (202, headers, "")
        def err_callback(request, uri, headers):
            self.error_count += 1
            return (200, headers, "")

        httpretty.register_uri(httpretty.POST,
                               re.compile("example.com/(.*)$"),
                               body=callback)
        httpretty.register_uri(httpretty.POST,
                               re.compile("errors.com/(.*)$"),
                               body=callback)

    def tearDown(self):
        httpretty.disable()
        httpretty.reset()

    def test_without_forwarding(self):
        """ Not setting forwarding headers should trigger a 200. """
        full_iri = test_iri + "?transform=%s" % test_transform
        with open(test_xml_file, 'r') as f:
            r = self.app.post(full_iri, data=f.read(), headers=test_unforwardable_headers)
            self.assertEqual(r.status_code, 200)

    def test_with_bad_headers(self):
        """ Failing to set any one of the forwarding headers should trigger a 400. """
        for i in range(0, len(test_forwarding_headers)):
            items = list(test_forwarding_headers.items())
            missing_header = items.pop(i)

            # we can't not set the Content-Type, so skip that one
            if missing_header[0] == "Content-Type":
                continue

            shortened_headers = dict(items)
            for header, value in shortened_headers.items():
                with open(test_xml_file, 'r') as f:
                    r = self.app.post(full_iri, data=f.read(), headers=shortened_headers)
                    self.assertEqual(r.status, "400 Missing header %s" % missing_header[0])

    def test_with_valid_forwarding_scheme(self):
        """ With a valid forwarding scheme in place, we should get a 202.
            We should also expect the dummy HTTP server to get hit correctly. """
        with open(test_xml_file, 'r') as f:
            r = self.app.post(full_iri, data=f.read(), headers=test_forwarding_headers)
            self.assertEqual(r.status_code, 202, r.status)
            time.sleep(0.5)
            self.assertEqual(self.error_count, 0)
            self.assertEqual(self.response_count, 1)

class TestForwardingErrors(unittest.TestCase):
    def setUp(self):
        self.flask_app_obj = app
        self.app = self.flask_app_obj.test_client()
        httpretty.enable()
        self.error_provocation_count = 0
        self.error_response_count = 0

        def provoke_timeout_error(request, uri, headers):
            raise socket.timeout('timeout')
            return (200, headers, "OK")

        def provoke_error_callback(request, uri, headers):
            self.error_provocation_count += 1
            return (500, headers, "ERROR!")

        def handle_error_callback(request, uri, headers):
            self.error_response_count += 1
            return (200, headers, "OK")

        httpretty.register_uri(httpretty.POST,
                               re.compile("err-gen.com/(.*)$"),
                               body=provoke_error_callback)
        httpretty.register_uri(httpretty.POST,
                               re.compile("errors.com/(.*)$"),
                               body=handle_error_callback)
        httpretty.register_uri(httpretty.POST,
                               re.compile("timeout.com/(.*)$"),
                               body=provoke_timeout_error)

    # We should set up a udp listener to verify the changed error handling here, but
    # probably only if we actually continue using this library.
    '''def test_error_handling(self):
        """ If a forward fails, we should see a message to the error-handling server. """
        with open(test_xml_file, 'r') as f:
            r = self.app.post(full_iri, data=f.read(), headers=fail_forwarding_headers)
            self.assertEqual(r.status_code, 202, r.status)
            time.sleep(0.5)
            self.assertEqual(self.error_provocation_count, 1)
            self.assertEqual(self.error_response_count, 1)
    def test_timeout_handling(self):
        """ If a forwarding times out, we should see a message to the error-handling server. """
        with open(test_xml_file, 'r') as f:
            r = self.app.post(full_iri, data=f.read(), headers=timeout_forwarding_headers)
            self.assertEqual(r.status_code, 202, r.status)
            time.sleep(0.5)
            self.assertEqual(self.error_response_count, 1)
    '''


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
@Time       :2019-05-13 下午 2:16
@Author     : 罗林
@File       : total_line.py
@desc       : 统计代码行数
"""

import os

# 指定想要统计的文件类型
whitelist = ['.py']

# 遍历文件, 递归遍历文件夹中的所有
def getFile(basedir):
    filelists = list()
    for parent, dirnames, filenames in os.walk(basedir):
        for filename in filenames:
            name, suf = os.path.splitext(filename)
            # 只统计指定的文件类型，略过一些log和cache文件
            if suf in whitelist:
                filelists.append(os.path.join(parent, filename))
    return filelists

def countLine(fname):
    # 统计一个文件的行数
    count = 0
    for file_line in open(fname, 'r', encoding='utf-8').readlines():
        if file_line != '' and file_line != '\n':  # 过滤掉空行和注释行
            count += 1
    return count

def total_line(basedir):
    filelists = getFile(basedir)
    totalline = 0
    for filelist in filelists:
        totalline += countLine(filelist)
    return totalline

if __name__ == '__main__':
    dir_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
    dir_path = os.path.join(dir_path, 'xqkj')
    print(dir_path)
    print(total_line(dir_path))


"""
This is an image viewer application
"""

import sys
import signal
# pylint: disable=no-name-in-module
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtWidgets import QWidget, QApplication, QTableWidget

signal.signal(signal.SIGINT, signal.SIG_DFL)

class ImageWidget(QWidget):

    def __init__(self, image_path, parent):
        super().__init__(parent)
        self.picture = QPixmap(image_path)

    def paintEvent(self, _event):
        painter = QPainter(self)
        painter.drawPixmap(0, 0, self.picture)

class TableWidget(QTableWidget):

    def setImage(self, row, col, image_path):
        image = ImageWidget(image_path, self)
        self.setCellWidget(row, col, image)

def main():
    app = QApplication([])
    table_widget = TableWidget(10, 2)
    table_widget.setImage(0, 1, "data/jpg/image0000.jpg")
    table_widget.show()
    sys.exit(app.exec_())

main()


from flask import Flask, render_template
import sqlite3
app = Flask(__name__)

@app.route('/')
def index():
    return render_template("index.html")

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

@app.route('/rank')
def rank():
    datalist = []
    con = sqlite3.connect("movie.db")
    cur = con.cursor()
    sql = "select * from movie250"
    data = cur.execute(sql)
    for item in data:
        datalist.append(item)
    cur.close()
    con.close()
    return render_template("rank.html", movies=datalist)

@app.route('/score')
def score():
    score = []
    num = []
    con = sqlite3.connect("movie.db")
    cur = con.cursor()
    sql = "select score,count(score) from movie250 group by score"
    data = cur.execute(sql)
    for item in data:
        score.append(item[0])
        num.append(item[1])
    cur.close()
    con.close()
    return render_template("score.html", score=score, num=num,)

# def score_2():
#     name = []
#     score2 = []
#     people = []
#     con2 = sqlite3.connect("movie.db")
#     cur2 = con2.cursor()
#     sql2 = "select cname,score,rated from movie250"
#     data2 = cur2.execute(sql2)
#     for item2 in data2:
#         name.append(item2[0])
#         score2.append(item2[1])
#         people.append(item2[2])
#     cur2.close()
#     con2.close()
#     return render_template("score.html", name=name, score2=score2, people=people)

@app.route('/wordcloud')
def wordcloud():
    return render_template("wordcloud.html")

@app.route('/other')
def other():
    return render_template("other.html")

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


class Solution(object):
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if not nums:
            return None
        mydict = {}
        for i in nums:
            if i in mydict:
                mydict[i]+=1
            else:
                mydict[i]=1

        mylist = [i for i in mydict]
        mylist.sort()
        # print mylist
        output = []
        for num in mylist:
            lenth = 0
            if output:
                lenth = len(output)
            for i in range(1, mydict[num]+1):
                output.append([num]*i)
                for j in range(lenth):
                    output.append(output[j]+[num]*i)
        output.append([])
        return output


"""Represents the machine that picks numbers"""

import random

import pygame as pg

from data.components import common
from data.components import loggable
from .settings import SETTINGS as S
from . import statemachine

class Ball(object):
    """A ball representing a number in the game"""

    def __init__(self, number):
        """Initialise the ball"""
        self.number = number
        #
        # Get the name for this ball (eg B1, I20)
        number_lookup = S['card-numbers']
        for letter, col in zip('BINGO', sorted(number_lookup.keys())):
            numbers = number_lookup[col]
            if number in numbers:
                self.letter = letter
                self.col = col
                break
        else:
            raise ValueError('Could not locate details for {0}'.format(number))
        #
        self.full_name = '{0}{1}'.format(self.letter, self.number)

class BallMachine(common.Drawable, loggable.Loggable):
    """A machine to pick balls at random"""

    def __init__(self, name, state):
        """Initialise the machine"""
        self.addLogger()
        self.name = name
        self.state = state
        #
        self.all_balls = [Ball(n) for n in S['machine-balls']]
        self.balls = []
        self.called_balls = []
        self.speed_buttons = common.DrawableGroup()
        self.buttons = common.ClickableGroup()
        self.current_ball = None
        self.interval = self.initial_interval = S['machine-speeds'][0][1] * 1000
        self.running = False
        self.timer = None
        self.speed_transitions = {}
        #
        self.ui = self.create_ui()
        self.reset_machine()

    def create_ui(self):
        """Create the UI components"""
        components = common.DrawableGroup()
        #
        # The display of all the balls that have been called
        self.called_balls_ui = CalledBallTray(S['called-balls-position'], self.state)
        components.append(self.called_balls_ui)
        #
        # Speed increases based on the number of balls called
        for idx, (name, interval, number_balls) in enumerate(S['machine-speeds']):
            self.speed_transitions[number_balls] = (idx, interval)
        #
        self.cog = CogWheel(self)
        components.append(self.cog)
        #
        # The spout showing progress towards a new ball
        self.spout_sprites = [
            common.NamedSprite('bingo-spout-{0}'.format(i), S['spout-position']) for i in range(S['spout-number'])
        ]
        #
        return components

    def change_speed(self, obj,  arg, silent=False):
        """Change the speed of the ball machine"""
        selected_idx, interval = arg
        self.log.info('Changing machine speed to index {0}, {1}s'.format(selected_idx, interval))
        #
        # Play appropriate sound
        if not silent:
            if interval < self.interval / 1000:
                self.state.play_sound('bingo-speed-up')
            else:
                self.state.play_sound('bingo-slow-down')
        #
        # Set cog
        self.cog.set_speed(selected_idx)
        #
        # Set speed of the machine
        self.reset_timer(interval * 1000)

    def start_machine(self):
        """Start the machine"""
        self.running = True
        if self.timer:
            try:
                self.state.stop_generator('ball-machine')
            except statemachine.NotFound:
                # OK, must have already completed
                pass

        self.timer = self.state.add_generator('ball-machine', self.pick_balls())

    def stop_machine(self):
        """Stop the machine"""
        self.running = False

    def reset_timer(self, interval):
        """Reset the timer on the machine"""
        self.interval = interval
        if self.timer:
            self.timer.update_interval(interval)

    def reset_machine(self, interval=None):
        """Reset the machine"""
        self.balls = list(self.all_balls)
        self.called_balls = []
        random.shuffle(self.balls)
        self.called_balls_ui.reset_display()
        self.change_speed(None, (0, S['machine-speeds'][0][1]), silent=True)
        self.start_machine()

    def pick_balls(self):
        """Pick the balls"""
        for idx, ball in enumerate(self.balls):
            #
            # Under some circumstances we will restart this iterator so this
            # makes sure we don't repeat balls
            if ball.number in self.called_balls:
                continue
            #
            self.called_balls.append(ball.number)
            self.set_current_ball(ball)
            self.state.play_sound('bingo-ball-chosen')
            #
            # Watch for speed transition
            try:
                button_idx, new_interval = self.speed_transitions[idx]
            except KeyError:
                # No transition
                pass
            else:
                self.change_speed(None, (button_idx, new_interval))
            #
            # Wait for next ball
            yield self.interval

    def set_current_ball(self, ball):
        """Set the current ball"""
        self.log.info('Current ball is {0}'.format(ball.full_name))
        #
        self.current_ball = ball
        self.state.ball_picked(ball)
        self.called_balls_ui.call_ball(ball)

    def draw(self, surface):
        """Draw the machine"""
        self.ui.draw(surface)
        if not self.timer.paused:
            self.called_balls_ui.update(self.state.dt * S['conveyor-speed'] / self.interval)
            self.cog.update(self.state.dt * S['machine-cog-speed'] / self.interval)
        #
        # Calculate how close we are to choosing a new ball
        fraction = 1.0 - self.timer.get_fraction_to_go()
        if fraction > 0.95:
            self.spout_sprites[-1].draw(surface)
        else:
            self.spout_sprites[int(fraction * (S['spout-number'] - 1))].draw(surface)

    def call_next_ball(self):
        """Immediately call the next ball"""
        self.timer.next_step()

    def pause(self):
        """Pause the machine"""
        self.timer.paused = True

    def unpause(self):
        """Unpause the machine"""
        self.timer.paused = False

class CalledBallTray(common.Drawable, loggable.Loggable):
    """A display of the balls that have been called"""

    def __init__(self, position, state):
        """Initialise the display"""
        self.addLogger()
        self.state = state
        #
        self.x, self.y = position
        self.called_balls = []
        #
        self.conveyor = common.NamedSprite(
            'bingo-conveyor',
            S['conveyor-position'],
        )
        self.initial_x = S['conveyor-position'][0]
        self.current_x = 0
        #
        self.background = common.NamedSprite('bingo-grill', S['machine-background-position'])
        self.dropping_balls = common.DrawableGroup()
        self.moving_balls = common.DrawableGroup()

    def call_ball(self, ball):
        """Call a particular ball"""
        self.called_balls.append(ball)
        ball_ui = SingleBallDisplay('ball', S['machine-ball-position'], ball, self)
        self.dropping_balls.append(ball_ui)
        self.state.add_generator('ball-falling', self.ball_falling(ball_ui))

    def draw(self, surface):
        """Draw the tray"""
        self.background.draw(surface)
        self.moving_balls.draw(surface)
        self.dropping_balls.draw(surface)
        self.conveyor.draw(surface)

    def reset_display(self):
        """Reset the display of the balls"""
        self.called_balls = []
        self.dropping_balls.clear()
        self.moving_balls.clear()

    def update(self, increment):
        """Update the display of the tray"""
        self.current_x += increment
        if self.current_x > S['conveyor-repeat']:
            self.current_x -= S['conveyor-repeat']
        self.conveyor.rect.x = self.initial_x + self.current_x
        self.move_balls(increment)

    def ball_falling(self, ball):
        """Cause a ball to fall down to the conveyor"""
        drop_speed = S['machine-ball-drop-initial-speed']
        while ball.y < S['conveyor-ball-position']:
            ball.y += drop_speed
            drop_speed += S['machine-ball-drop-acceleration']
            yield 10
        self.moving_balls.append(ball)
        #
        # Remove from the list - note that we have to check the ball is still there
        # because the machine may have been reset between the 'yield' and here
        if ball in self.dropping_balls:
            self.dropping_balls.remove(ball)

    def move_balls(self, increment):
        """Move the balls"""
        for ball in reversed(self.moving_balls):
            ball.x += increment
            if ball.x >= S['conveyor-ball-drop-off']:
                self.moving_balls.remove(ball)

class SingleBallDisplay(common.Drawable, loggable.Loggable):
    """A ball displayed on the screen"""

    def __init__(self, name, position, ball, state):
        """Initialise the ball"""
        self.addLogger()
        #
        self.name = name
        self.state = state
        #
        # Create the background chip
        self.background = common.NamedSprite.from_sprite_sheet(
            'chips', (2, 5),
            S['called-ball-sprite-lookup'][ball.col], position,
            scale=S['machine-ball-sprite-scale']
        )
        #
        # And the text for the number
        self.text = common.getLabel(
            'machine-ball',
            (self.background.rect.width / 2, self.background.rect.height / 2), str(ball.number), S
        )
        self.text.color = pg.Color(S['called-ball-font-color'][ball.col])
        self.text.update_text()
        #
        # Write the number on the background
        self.text.draw(self.background.sprite)
        #
        # And rotate a bit
        self.background.rotate_to(random.uniform(*S['machine-ball-angle-range']))
        #
        self._x, self._y = self.background.rect.x, self.background.rect.y

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = value
        self.background.rect.y = value

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value
        self.background.rect.x = value

    def draw(self, surface):
        """Draw the ball"""
        self.background.draw(surface)

class CogWheel(common.Drawable):
    """Visual display of the cog"""

    def __init__(self, state):
        """Initialise the cog"""
        self.state = state
        #
        self.sprites = [
            common.NamedSprite(
                'bingo-cog-{0}'.format(i),
                S['machine-cog-position'],
            ) for i in range(len(S['machine-speeds']))
        ]
        self.speed = 0
        self.angle = 0
        self.set_speed(0)
        self.current_sprite = self.sprites[0].sprite
        self.x, self.y = S['machine-cog-position']

    def set_speed(self, speed):
        """Set the current speed"""
        self.speed = speed

    def draw(self, surface):
        """Draw the cog"""
        w, h = self.current_sprite.get_size()
        rect = pg.Rect(self.x - w / 2, self.y - h / 2, w, h)
        surface.blit(self.current_sprite, rect)

    def update(self, increment):
        """Update the display of the cog"""
        self.angle = (self.angle + increment) % 360
        # TODO: refactor the rotation logic - should be built into sprite
        surface = self.sprites[self.speed].sprite.copy()
        self.current_sprite = pg.transform.rotozoom(surface, self.angle, 1.0)


import random
import operator
import matplotlib.pyplot
import time
import agentframework
import csv

#a = agentframework.Agent(environment, agents)
#a.o_agents

#input agent from agentframework
start = time.clock()

##################################################################
#####                DISTANCE CALC                           #####
##################################################################
def distance_between(agents_row_a, agents_row_b):
    return (((agents_row_a.x - agents_row_b.x)**2) + ((agents_row_a.y - agents_row_b.y)**2))**0.5

##################################################################
#####                    PARAMETERS                          #####
##################################################################
num_of_agents = 5
num_of_iterations = 1
neighbourhood = 20

##################################################################
#####                INITIALISE VARIABLES                    #####
##################################################################
agents = []
data = []
processed_data = []

##################################################################
#####                GETTING THE ENVIRONMENT                 #####
##################################################################
#initialising environment
environment = []
#initialising the csv reader to convert .txt to .csv
f = open('in.txt', newline='')
reader = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC)
for row in reader: # A list of rows
    rowlist = []
    #append the environment in a loop
    environment.append(rowlist)
    for value in row:
        rowlist.append(value)
        #print(value) # Floats
f.close()
# Fill with random data.
for i in (range(1,98)):
    datarow = []
    for j in (range(1,98)):
        datarow.append(random.randint(0,99))
    data.append(datarow)

# =============================================================================
# #ensuring dataset is rectangular i.e. col value for every row value
# nrows = len(environment)
# print (nrows)
# ncols = len(environment[0])
# print (ncols)
# #show the 299th by 299th value for ref
# #print(environment[299][299])
#total = 0
#for row in nrows
    #for col in cols:
        #total += environment[row][col]
# =============================================================================

#random.seed(10) #uncomment for testing purposes

##################################################################
#####                CREATE AGENTS                           #####
##################################################################
for i in range(num_of_agents):
    y = random.randint(0,299)
    x = random.randint(0,299)
    agents.append(agentframework.Agent(environment, agents, y, x))

#shuffle the agent list
random.shuffle(agents)
#Commence movement & mastication
for j in range(num_of_iterations):
    for i in range(num_of_agents):
        agents[i].move()
        agents[i].eat()
        agents[i].share_with_neighbours(neighbourhood)

#plot the data
matplotlib.pyplot.ylim(299, 0)
matplotlib.pyplot.xlim(0, 299)
matplotlib.pyplot.imshow(environment)
for i in range (num_of_agents):
    matplotlib.pyplot.scatter(agents[i].x,agents[i].y)

#identify the left and rightmost agents
# =============================================================================
# ## Agents do not support indexing so this section ##
# ## cannot be executed                             ##
# leftmostagent = min(agents, key=operator.itemgetter(0))
# rightmostagent = max(agents, key=operator.itemgetter(0))
# matplotlib.pyplot.scatter(leftmostagent[0],leftmostagent[1], color='green')
# matplotlib.pyplot.scatter(rightmostagent[0],rightmostagent[1], color='red')
# =============================================================================

matplotlib.pyplot.show()

#calculate the maximum distance
#max_distance = distance_between(agents[1], agents[0])
print("*"*20)
for i in range (0,num_of_agents):
    for j in range (i+1 ,num_of_agents):
        distance = distance_between(agents[i], agents[j])
        #max_distance = max(max_distance, distance)
        print("distance between agent", i, "and", j, distance)
        #print(max_distance)

f2 = open('dataout.csv', 'w', newline='')
writer = csv.writer(f2, delimiter=' ')
for row in data:
    writer.writerow(row) # List of values.
f2.close()

end=time.clock()

print("time=",str(end-start))
print(agents[i])


import os, glob
import re

def open_file_in_path(path, filename_in_path, mode='w'):
    """
    Automatically creates path if the path doesn't exist,
    then open filename_in_path with mode,
    and write content
    """
    filepath = os.path.join(path, filename_in_path)
    if not os.path.exists(filepath):
        if not os.path.exists(path):
            os.makedirs(path)
    return open(filepath, mode)

def tf_open_file_in_path(path, filename_in_path, mode='w'):
    """
    Automatically creates path if the path doesn't exist,
    then open filename_in_path with mode,
    and write content
    """
    import tensorflow as tf
    filepath = os.path.join(path, filename_in_path)
    if not tf.io.gfile.exists(filepath):
        if not tf.io.gfile.exists(path):
            tf.io.gfile.makedirs(path)
    return tf.io.gfile.GFile(filepath, mode)

def get_filename(file: str, remove_ext=True):
    if file.endswith('/'):
        file = file[:-1]
    name = os.path.split(file)[1]
    if remove_ext:
        return rm_ext(name)
    return name

def get_folderpath(file):
    name = os.path.split(file)[0]
    return name

def rm_ext(filename):
    filename = os.path.splitext(filename)[0]
    return filename

# copied and modified from https://github.com/huggingface/transformers/blob/cd56f3fe7eae4a53a9880e3f5e8f91877a78271c/src/transformers/trainer_utils.py#L96
PREFIX_CHECKPOINT_DIR = "check"
_re_checkpoint = re.compile(r"^" + PREFIX_CHECKPOINT_DIR + r"\-(\d+)[/]?$")

def get_checkpoint_subdir_name(steps):
    return f'{PREFIX_CHECKPOINT_DIR}-{steps}'

def get_checkpoint_dirs_from(folder):
    return glob.glob(os.path.join(folder, f"{PREFIX_CHECKPOINT_DIR}-*"))

def get_last_checkpoint(folder):
    """Supports google cloud bucket also"""
    import tensorflow as tf
    content = tf.io.gfile.listdir(folder)
    # content = ['check-789/']
    checkpoints = [
        path
        for path in content
        if _re_checkpoint.search(path) is not None and tf.io.gfile.isdir(os.path.join(folder, path))
    ]
    if len(checkpoints) == 0:
        return
    return os.path.join(folder, max(checkpoints, key=lambda x: int(_re_checkpoint.search(x).groups()[0])))

def get_step_from_checkpoint(ckpt_dir):
    return int(_re_checkpoint.search(ckpt_dir).groups()[0])