Skip to content

Commit

Permalink
Update 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
pooneyy committed Jan 24, 2024
1 parent 2505fcc commit 1a98684
Show file tree
Hide file tree
Showing 3 changed files with 280 additions and 2 deletions.
69 changes: 67 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,67 @@
# CommuTrace_Monitor_TaskList
监听共迹算力平台任务列表
# 监听“算了么”平台任务列表

遵循GPL 3.0协议

### 对于不便的用户

现有一个已部署的demo,使用微信扫码,也可接收消息推送:

<img src="https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQGp8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyQ0dtTkVtMDVjWEQxTVQ1ajFCY2sAAgQ3eKtlAwQAjScA" alt="showqrcode" />

这个二维码**有效期至2024年2月20日**

### 使用说明

```bash
python index.py
```

或下载运行[index.exe](https://github.com/pooneyy/suanleme/releases/latest)

![image-20230316165557606](https://s2.loli.net/2023/03/16/tscoEFUr5X6SG2i.png)

##### 首次运行时你需要准备:

1. 平台账号、密码 [注册帐号](https://suanleme.cn/)

2. [PushPlus](http://www.pushplus.plus/)`token`用于消息推送

![image-20230316161929749](https://s2.loli.net/2023/03/16/m28Pc7BJQinXMZh.png)
- (选填)群组编码:用于PushPlus发送一对多消息(群发消息)。详见[一对多消息|pushplus(推送加)](http://www.pushplus.plus/push2.html),留空时发送一对一消息。

### 更新日志

```
1.2 (2024.01.24) 更新:现有任务增加任务点时,将会收到提醒
1.1 (2024.01.20) 更新:优化了推送消息中表格的显示。
1.0 (2024.01.20) 更新:CommuTrace共迹算力平台已升级为“算了么”平台,现已对新平台进行适配。
0.2.1 (2023.03.31) 修复:某些情况下“远程主机强迫关闭了一个现有的连接”时,报错退出的问题。
0.2 (2023.03.25) 更新:
1、登录时将Cookies保存到文件,并优先从文件载入Cookies;
2、新增检查更新。
修复:
1、修复了某些情况下订单解析失败的问题;
2、修复了Cookies失效后,重新登录失败的问题。
0.1.4 (2023.03.22) 修复:
1、当订单数=0时,重复登录的问题;
2、调整了输出的消息的格式,并做了精简,避免过多无意义内容。
0.1.3 (2023.03.20) 修复:当订单数>1时,只显示首个订单的问题。
0.1.2 (2023.03.19) 修复:
1、当无订单时崩溃的问题;
2、当订单数>1时,订单创建时间解析错误的问题;
3、修复其它错误。
0.1.1 (2023.03.16) 若干更新:
1、令当连接出错时自动重试;
2、令当验证码识别出错时自动重试;
3、处理其他报错。
0.1 (2023.03.16) 初版。
```
211 changes: 211 additions & 0 deletions index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
#!/usr/bin/env python3
# -*- coding: utf8 -*-
'''
Author : Pooneyy
Date : 2023-03-14 20:08:52
LastEditors : Pooneyy 85266337+pooneyy@users.noreply.github.com
LastEditTime : 2023-03-31 21:48:32
FilePath : /suanleme/index.py
Description : “算了么”平台 监听任务列表
Copyright (c) 2023-2024 by Pooneyy, All Rights Reserved.
'''

import json
import os
import datetime, pytz, time
import sys
import requests

VERSION = '1.2' # 2024.01.24
CONFIG_VERSION = 2
HOST = "https://api.suanleme.cn/api/v1"

def timeStamp_To_dateTime(timeStamp):return datetime.datetime.fromtimestamp(int(timeStamp), pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S')

def isoDateTime_To_dateTime(iso_date_time):return datetime.datetime.strptime(iso_date_time, "%Y-%m-%dT%H:%M:%S.%f%z").strftime('%Y-%m-%d<br />%H:%M:%S')

def saveConfig(config):
with open("config.json", "w", encoding='utf8') as file:
json.dump(config, file, ensure_ascii=False, indent = 4)

def loadConfig():
with open("config.json", "r+", encoding='utf8') as file:
config = json.load(file)
return config

def checkUpdate():
url = "https://api.github.com/repos/pooneyy/suanleme/releases/latest"
try:
response = requests.get(url)
latest = json.loads(response.text)["tag_name"]
return VERSION != latest
except:return False

def init():
print('首次运行初始化')
config = {}
config['config_version'] = CONFIG_VERSION
config['latest_id'] = 0
config['suanleme_username'] = input('请输入算了么账号:')
config['suanleme_password'] = input('请输入算了么密码:')
config['truecaptcha_userid'] = ''
config['truecaptcha_apikey'] = ''
config['pushplus_token'] = input('请输入pushplus推送加的token:')
config['pushplus_topic'] = input('(选填)输入pushplus推送加的群组编码:')
config['tasks_record'] = {}
saveConfig(config)
print('初始化完成,请重新运行')

def sendMsg(config, msg):
data = {}
url = "http://www.pushplus.plus/send"
data['token'] = config['pushplus_token']
data['title'] = '算了么来新单啦!'
data['template'] = 'markdown'
data['topic'] = config['pushplus_topic'] # 群组编码,发送群组消息。
data['content'] = msg
response = requests.post(url,data=data)
return response.text

def login(config):
url = f"{HOST}/user/token"
payload={
'username': config['suanleme_username'],
'password': config['suanleme_password'],
}
response = requests.post(url, data=payload)
print(f"{timeStamp_To_dateTime(time.time())}\t登录成功")
refresh_token = response.json()['refresh']
return refresh_token

def refresh(refresh_token):
url = f"{HOST}/user/token/refresh"
payload={'refresh': refresh_token}
response = requests.post(url, data=payload)
return response.json()["access"]

def getTasks(refresh_token):
'''获取全部订单'''
url = f"{HOST}/tasks/?page=1&data_type=all"
headers = {'Authorization': f'Bearer {refresh(refresh_token)}'}
response = requests.get(url, headers=headers)
response.close()
return response.json()

def analyzing_tasks_info(tasks):
'''分析订单页面
这是一个订单信息的数据结构
```json
{
"id": 107, //订单id
"author": 23, //发布者id?
"status": "Running", //状态 Running / Finished / Canceled / Received
"finished_points": 28, //已完成任务点
"running_points": 2, //进行中任务点
"name": "cytx", //任务名
"desc": "cytx", //任务描述
"peer_income": 1, //单位收益
"expect_time": "1", //预期单位时长
"type": "Deployment", //类型 Deployment / Job
"points": 30, //总任务点
"cpu_required": 0, //硬件要求 CPU核心数
"memory_required": 0, //硬件要求 内存 单位GB
"disk_required": 0, //硬件要求 磁盘空间要求 单位GB
"time_required": "00:00:00", //连续时长要求
"created_time": "2024-01-10T11:19:36.165607+08:00", //创建时间()
"modify_time": "2024-01-19T17:48:05.918623+08:00", //修改时间
"finished_time": "2024-01-18T07:31:00+08:00", //完成时间
"runtime": 4,
"package": "eca6bf8b-d71d-4143-b259-f7ca9294d9ff",
"joined_user": [ //参加计算成员id?
1,
22,
36,
46,
47,
50
],
"affinity": [
1,
2
],
"aversion": []
}
```
'''
taskList = []
for task in tasks['results']:
taskData = {}
taskData['id'] = task['id']
taskData['detail'] = task['desc']
taskData['created_time'] = task['created_time']
taskData['peer_income'] = task['peer_income']
taskData['points'] = task['points']
taskList.append(taskData)
return taskList

def taskList_To_Msg(taskList):
msg = r'''<html><head><style>.table-container {overflow-x: auto;}table {width: 100%;min-width: 700px;border-collapse: collapse;}th, td {border: 1px solid black;padding: 8px;text-align: left;}.detail-time {width: 50px;word-wrap: break-word;}.other-column {width: 15px;word-wrap: break-word;}</style></head><body><div class="table-container"><table><tr><th class="other-column">任务ID</th><th class="detail-time">任务细节</th><th class="detail-time">创建时间</th><th class="other-column">单位收益</th><th class="other-column">总量</th></tr>'''
for i in taskList:
msg += f'''<tr><td class="other-column">{i['id']}</td><td class="detail-time">{i['detail']}</td><td class="detail-time">{isoDateTime_To_dateTime(i['created_time'])}</td><td class="other-column">{i['peer_income']}</td><td class="other-column">{i['points']}</td></tr>'''
msg += "</tr></table></div></body></html>"
return msg

def updated_Tasks_To_Msg(tasksList,config):
msg = f'''|任务ID|任务点更新前|任务点更新后|\n|:----:|:----:|:----:|\n'''
for task in tasksList:
msg += f'''|{task['id']}|{config.get('tasks_record').get(str(task['id']),{}).get('points',0)}|{task['points']}|\n'''
return msg

def loop(config):
try:
refresh_token = login(config)
while True:
tasksList = analyzing_tasks_info(getTasks(refresh_token))
if tasksList:
i = [i['id'] for i in tasksList] # 列表,临时存储订单ID用于寻找最大的ID
latest_id = int(max(i))
msg = ''
if latest_id > config['latest_id']:
config['latest_id'] = latest_id
msg += f"#### 有新订单。当前最新是 {latest_id}\n"
msg += taskList_To_Msg(tasksList)
print(f"{taskList_To_Msg(tasksList)}")
updated_tasks = []
for task in tasksList:
if task['points'] > config.get('tasks_record').get(str(task['id']),{}).get('points',0):updated_tasks.append(task)
if updated_tasks:
msg += f"#### 有新任务点\n"
msg += updated_Tasks_To_Msg(tasksList,config)
print(f"{updated_Tasks_To_Msg(tasksList,config)}")
for task in tasksList:config['tasks_record'][str(task['id'])] = task
sendMsg(config, msg)
saveConfig(config)
print(f"{timeStamp_To_dateTime(time.time())}\t当前最新{latest_id}...\r",end='')
else:
print(f"{timeStamp_To_dateTime(time.time())}\t当前没有订单...\r",end='')
time.sleep(30)
except KeyboardInterrupt:print("\n结束")
except requests.exceptions.ConnectionError:
try:
print(f"{timeStamp_To_dateTime(time.time())}\t网络连接中断")
time.sleep(30)
loop(config)
except KeyboardInterrupt:print("结束")
except requests.exceptions.ChunkedEncodingError:
print(f"{timeStamp_To_dateTime(time.time())}\t远程主机关闭连接")
time.sleep(3)
loop(config)

def main():
if 'linux' in sys.platform: sys.stdout.write(f"\x1b]2;算了么 - 监听任务列表 - 版本 {VERSION}\x07")
elif 'win' in sys.platform: os.system(f"title 算了么 - 监听任务列表 - 版本 {VERSION}")
if checkUpdate():print("请更新到最新版本:https://github.com/pooneyy/suanleme/releases/latest \n")
try:loop(loadConfig())
except FileNotFoundError:
try:init()
except KeyboardInterrupt:print("\n退出,取消初始化")

if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pytz
requests

0 comments on commit 1a98684

Please sign in to comment.