-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
280 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) 初版。 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pytz | ||
requests |