-
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
0 parents
commit d18da6a
Showing
17 changed files
with
440 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
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,31 @@ | ||
name: BUPT ncov auto-report Python+Actions V3.0 | ||
|
||
on: | ||
schedule: | ||
- cron: "*/15 0,23 * * *" | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: [3.7] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | ||
- name: Run BUPT ncov Auto-report Script | ||
run: | | ||
python3 main.py | ||
env: | ||
USERS: ${{ secrets.USERS }} | ||
SERVER_KEY: ${{ secrets.SERVER_KEY }} |
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,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 zzp-seeker | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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,111 @@ | ||
<h2 align="center">:helicopter:北邮疫情自动填报(Python+Github Actions)长期维护</h2> | ||
<p align="center"> | ||
<a href="https://github.com/zzp-seeker/bupt-ncov-auto-report/actions/workflows/main.yml"> | ||
<img src="https://github.com/zzp-seeker/bupt-ncov-auto-report/actions/workflows/main.yml/badge.svg?branch=master" alt="Action Badge"> | ||
</a> | ||
<img src="https://img.shields.io/badge/python-%3d%203.7-blue" alt="Python Version"> | ||
</p> | ||
|
||
|
||
|
||
## 特点: | ||
|
||
- 每天7-8点自动多次填报(可通过main.yml修改) | ||
- 运行失败会自动往邮箱(注册github所用邮箱)发送邮件 | ||
- 可以多人同时填报(可以帮小伙伴一起打卡哦) | ||
- 填报情况可以使用上一次打卡数据(如需更换请于当日脚本运行前手动打卡),也可以使用固定数据(地点始终位于北邮) | ||
- **(可选)** 填报结果通过Server酱推送至微信 | ||
| ||
|
||
<div align="center"> | ||
<img src='img/0.png' width=55%/> | ||
</div> | ||
|
||
|
||
|
||
|
||
## 使用详解 | ||
|
||
1. 点击右上角的 **Use this template** <img src="img/2.png" width="50%">然后给仓库随便起一个名字,点击 **Create repository from template** | ||
2. 点击 **Settings** ,进入 **Secrets** 页面,点击右上角的 **New repository secret**,流程如下图所示 | ||
<div align="center"> | ||
<img src="img/3.png" width="90%"> | ||
</div> | ||
|
||
3. 一共有**两**个secret,第一个Name填**USERS**,Value按照如下格式填写: | ||
|
||
```python | ||
[ | ||
(学号:str,密码:str,用户名:str,0 or 1), | ||
(学号:str,密码:str,用户名:str,0 or 1), | ||
(学号:str,密码:str,用户名:str,0 or 1), | ||
... 如果还有则继续往后面加 | ||
] | ||
``` | ||
|
||
相当于**列表**里面有很多**元组**,每个元组代表一个用户,可以有任意多个。每个元组有**四个元素**,前两个分别为**学号**和**密码**,字符串格式(可自行通过 [https://app.bupt.edu.cn/ncov/wap/default/index](https://app.bupt.edu.cn/ncov/wap/default/index) 登陆验证账号密码正确性,密码一般为身份证后8位),第三个为**用户名**(随便填,用于控制台与Server显示),第四个为是否用上一次打卡数据,**0或者1**,0代表使用上一次打卡数据(**某一次自己在脚本运行前打卡之后都采用这次打卡数据**),1代表使用固定数据(固定数据的地点始终位于北邮),以下是一个样例: | ||
|
||
<div align="center"> | ||
<img src="img/4.png" width="55%"> | ||
</div> | ||
|
||
|
||
4. 第二个secret的Name填写**SERVER_KEY**,如果不配置Server酱微信推送,那么Value里填写**0**即可,如果想配置的话看下一点 | ||
5. **(可选)** Value填写Server酱的SendKey(在这里查看 [https://sct.ftqq.com/sendkey](https://sct.ftqq.com/sendkey)),在此之前需要微信注册企业号,并加入Server酱内部应用,具体流程见 [https://sct.ftqq.com/forward](https://sct.ftqq.com/forward),看起来比较多,但也不是很麻烦,一步步照做即可 | ||
|
||
最后Actions secrets效果: | ||
|
||
<div align="center"> | ||
<img src="img/5.png" width="100%"> | ||
</div> | ||
|
||
6. 点击上方**Actions**按钮: | ||
|
||
<img src="img/6.png" width="100%"> | ||
|
||
点击左侧的**BUPT ncov auto-report Python**,再点击右侧的**Run workflow**,如下图所示: | ||
|
||
<div align="center"> | ||
<img src="img/7.png" width="100%"> | ||
</div> | ||
|
||
点击这个workflow(没看到的话请刷新一下),然后再次点进去jobs查看执行情况 | ||
|
||
<div align="center"> | ||
<img src="img/8.png" > | ||
</div> | ||
|
||
7. 如果准确按照上述步骤执行,你应该会看到类似的如下输出: | ||
|
||
<div align="center"> | ||
<img src="img/9.png" width="95%"> | ||
</div> | ||
|
||
若想查看上图一样具体填报信息需要取消注释main.py的75行 | ||
|
||
**恭喜你,你还有你的小伙伴不用为被催打卡而烦恼了~** | ||
|
||
|
||
## 参数更改: | ||
### 更改每日打卡时间 | ||
在 .github/workflows/main.yml 中来设置每天运行的时间: | ||
```python | ||
on: | ||
schedule: | ||
- cron: "*/20 16,23 * * *" | ||
``` | ||
cron里的"\*/20 16,23 * * \*"代表 at every 20th minute past hour 16 and 23,然而这是UTC,北京时间为UTC+8,代表0点与7点之后每隔20分钟 | ||
[https://crontab.guru/#*/10_16,23_*_*_*](https://crontab.guru/#*/10_16,23_*_*_*) 用这个网站来选取你想要的时间 | ||
### 更改打卡的固定数据 | ||
在 [https://app.bupt.edu.cn/ncov/wap/default/index](https://app.bupt.edu.cn/ncov/wap/default/index) 进行填报,全部填完后最后不要提交,f12打开控制台,在Console页面下输入代码vm.info回车得到填报数据,替换掉 constant.py 里的INFO变量 | ||
|
||
|
||
## Credit | ||
参考了[ipid/bupt-ncov-report](https://github.com/ipid/bupt-ncov-report) 与 [imtsuki/bupt-ncov-report-action](https://github.com/imtsuki/bupt-ncov-report-action), 十分感谢 | ||
|
||
## License | ||
MIT © [zzp-seeker](https://github.com/zzp-seeker) | ||
|
||
### 好用的话别忘了:star:哦 :wink: | ||
|
||
|
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,114 @@ | ||
import os | ||
|
||
USERS = eval(os.environ['USERS']) | ||
SERVER_KEY = os.environ['SERVER_KEY'] | ||
|
||
|
||
LOGIN_API = 'https://app.bupt.edu.cn/uc/wap/login/check' | ||
GET_API = 'https://app.bupt.edu.cn/ncov/wap/default/index' | ||
REPORT_API = 'https://app.bupt.edu.cn/ncov/wap/default/save' | ||
|
||
# 当今日没有填报时,在https://app.bupt.edu.cn/ncov/wap/default/index下进行填报, | ||
# 全部填完,不要提交,f12打开控制台,在Console页面下输入代码 console.log(vm.info) 就会得到以下信息,之后每天就默认填以下信息 | ||
INFO = r"""{ | ||
"address":"北京市海淀区北太平庄街道北京邮电大学计算机学院北京邮电大学海淀校区", | ||
"area":"北京市 海淀区", | ||
"bztcyy":"", | ||
"city":"北京市", | ||
"csmjry":"0", | ||
"fjqszgjdq":"", | ||
"geo_api_info":"{\"type\":\"complete\",\"position\":{\"Q\":39.960390625,\"R\":116.356397569445,\"lng\":116.356398,\"lat\":39.960391},\"location_type\":\"html5\",\"message\":\"Get ipLocation failed.Get geolocation success.Convert Success.Get address success.\",\"accuracy\":23,\"isConverted\":true,\"status\":1,\"addressComponent\":{\"citycode\":\"010\",\"adcode\":\"110108\",\"businessAreas\":[{\"name\":\"北下关\",\"id\":\"110108\",\"location\":{\"Q\":39.955976,\"R\":116.33873,\"lng\":116.33873,\"lat\":39.955976}},{\"name\":\"西直门\",\"id\":\"110102\",\"location\":{\"Q\":39.942856,\"R\":116.34666099999998,\"lng\":116.346661,\"lat\":39.942856}},{\"name\":\"小西天\",\"id\":\"110108\",\"location\":{\"Q\":39.957147,\"R\":116.364058,\"lng\":116.364058,\"lat\":39.957147}}],\"neighborhoodType\":\"科教文化服务;学校;高等院校\",\"neighborhood\":\"北京邮电大学\",\"building\":\"北京邮电大学计算机学院\",\"buildingType\":\"科教文化服务;学校;高等院校\",\"street\":\"西土城路\",\"streetNumber\":\"10号\",\"country\":\"中国\",\"province\":\"北京市\",\"city\":\"\",\"district\":\"海淀区\",\"township\":\"北太平庄街道\"},\"formattedAddress\":\"北京市海淀区北太平庄街道北京邮电大学计算机学院北京邮电大学海淀校区\",\"roads\":[],\"crosses\":[],\"pois\":[],\"info\":\"SUCCESS\"}", | ||
"glksrq":"", | ||
"gllx":"", | ||
"gtjzzchdfh":"", | ||
"gtjzzfjsj":"", | ||
"ismoved":"0", | ||
"jcbhlx":"", | ||
"jcbhrq":"", | ||
"jchbryfs":"", | ||
"jcjgqr":"0", | ||
"jcwhryfs":"", | ||
"jhfjhbcc":"", | ||
"jhfjjtgj":"", | ||
"jhfjrq":"", | ||
"mjry":"0", | ||
"province":"北京市", | ||
"qksm":"", | ||
"remark":"", | ||
"sfcxtz":"0", | ||
"sfcxzysx":"0", | ||
"sfcyglq":"0", | ||
"sfjcbh":"0", | ||
"sfjchbry":"0", | ||
"sfjcwhry":"0", | ||
"sfjzdezxgym":"1", | ||
"sfjzxgym":"1", | ||
"sfsfbh":"0", | ||
"sftjhb":"0", | ||
"sftjwh":"0", | ||
"sfxk":"0", | ||
"sfygtjzzfj":"", | ||
"sfyyjc":"0", | ||
"sfzx":1, | ||
"szcs":"", | ||
"szgj":"", | ||
"szsqsfybl":"0", | ||
"tw":"2", | ||
"xjzd":"", | ||
"xkqq":"", | ||
"xwxgymjzqk":"3", | ||
"ymjzxgqk":"已接种", | ||
"zgfxdq":"0" | ||
}""" | ||
|
||
REASONABLE_LENGTH = 24 | ||
TIMEOUT_SECOND = 25 | ||
|
||
class HEADERS: | ||
REFERER_LOGIN_API = 'https://app.bupt.edu.cn/uc/wap/login' | ||
REFERER_POST_API = 'https://app.bupt.edu.cn/ncov/wap/default/index' | ||
ORIGIN_BUPTAPP = 'https://app.bupt.edu.cn' | ||
|
||
UA = ('Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) ' | ||
'Mobile/15E148 MicroMessenger/7.0.11(0x17000b21) NetType/4G Language/zh_CN') | ||
ACCEPT_JSON = 'application/json' | ||
ACCEPT_HTML = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' | ||
REQUEST_WITH_XHR = 'XMLHttpRequest' | ||
ACCEPT_LANG = 'zh-cn' | ||
CONTENT_TYPE_UTF8 = 'application/x-www-form-urlencoded; charset=UTF-8' | ||
|
||
def __init__(self) -> None: | ||
raise NotImplementedError | ||
|
||
COMMON_HEADERS = { | ||
'User-Agent': HEADERS.UA, | ||
'Accept-Language': HEADERS.ACCEPT_LANG, | ||
} | ||
COMMON_POST_HEADERS = { | ||
'Accept': HEADERS.ACCEPT_JSON, | ||
'Origin': HEADERS.ORIGIN_BUPTAPP, | ||
'X-Requested-With': HEADERS.REQUEST_WITH_XHR, | ||
'Content-Type': HEADERS.CONTENT_TYPE_UTF8, | ||
} | ||
|
||
from typing import Optional | ||
from abc import ABCMeta, abstractmethod | ||
|
||
class INotifier(metaclass=ABCMeta): | ||
@property | ||
@abstractmethod | ||
def PLATFORM_NAME(self) -> str: | ||
""" | ||
将 PLATFORM_NAME 设为类的 Class Variable,内容是通知平台的名字(用于打日志)。 | ||
如:PLATFORM_NAME = 'Telegram 机器人' | ||
:return: 通知平台名 | ||
""" | ||
@abstractmethod | ||
def notify(self, *, success, msg, data,username, name) -> None: | ||
""" | ||
通过该平台通知用户操作成功的消息。失败时将抛出各种异常。 | ||
:param success: 表示是否成功 | ||
:param msg: 成功时表示服务器的返回值,失败时表示失败原因;None 表示没有上述内容 | ||
:return: None | ||
""" | ||
|
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,93 @@ | ||
from serverJiang import * | ||
from constant import * | ||
|
||
import requests, re, json, copy, traceback | ||
|
||
|
||
session = requests.Session() | ||
|
||
|
||
def ncov_report(username, password, name, is_useold): | ||
print('登录北邮 nCoV 上报网站') | ||
login_res = session.post( | ||
LOGIN_API, | ||
data={'username': username, 'password': password, }, | ||
headers={**COMMON_HEADERS, **COMMON_POST_HEADERS, 'Referer': HEADERS.REFERER_LOGIN_API, | ||
}) | ||
if login_res.status_code != 200: | ||
raise RuntimeError('login_res 状态码不是 200') | ||
get_res = session.get( | ||
GET_API, | ||
headers={**COMMON_HEADERS, 'Accept': HEADERS.ACCEPT_HTML}, | ||
) | ||
if get_res.status_code != 200: | ||
raise RuntimeError('get_res 状态码不是 200') | ||
try: | ||
old_data = json.loads('{' + re.search(r'(?<=oldInfo: {).+(?=})', get_res.text)[0] + '}') | ||
except: | ||
raise RuntimeError('未获取到昨日打卡数据,请今日手动打卡明日再执行脚本或使用固定打卡数据') | ||
post_data = json.loads(copy.deepcopy(INFO).replace("\n", "").replace(" ", "")) | ||
if is_useold: | ||
try: | ||
for k, v in old_data.items(): | ||
if k in post_data: | ||
post_data[k] = v | ||
geo = json.loads(old_data['geo_api_info']) | ||
|
||
province = geo['addressComponent']['province'] | ||
city = geo['addressComponent']['city'] | ||
if geo['addressComponent']['city'].strip() == "" and len(re.findall(r'北京市|上海市|重庆市|天津市', province)) != 0: | ||
city = geo['addressComponent']['province'] | ||
area = province + " " + city + " " + geo['addressComponent']['district'] | ||
address = geo['formattedAddress'] | ||
post_data['province'] = province | ||
post_data['city'] = city | ||
post_data['area'] = area | ||
post_data['address'] = address | ||
|
||
# 强行覆盖一些字段 | ||
post_data['ismoved'] = 0 # 是否移动了位置?否 | ||
post_data['bztcyy'] = '' # 不在同城原因?空 | ||
post_data['sfsfbh'] = 0 # 是否省份不合?否 | ||
except: | ||
print("加载昨日数据错误,采用固定数据") | ||
post_data = json.loads(copy.deepcopy(INFO).replace("\n", "").replace(" ", "")) | ||
report_res = session.post( | ||
REPORT_API, | ||
data=post_data, | ||
headers={**COMMON_HEADERS,**COMMON_POST_HEADERS,'Referer': HEADERS.REFERER_POST_API,}, | ||
) | ||
if report_res.status_code != 200: | ||
raise RuntimeError('report_res 状态码不是 200') | ||
return post_data,report_res.text | ||
|
||
successs,ress,usernames,names,datas = [],[],[],[],[] | ||
for user in USERS: | ||
success=True | ||
username,password,name,useold=user | ||
try: | ||
data,res = ncov_report(username=username,password=password,name=name,is_useold=(useold==0)) | ||
except: | ||
success = False | ||
data,res = '',traceback.format_exc() | ||
|
||
print(f'{name}填报成功!服务器返回数据:\n{res}' if success else f'{name}填报失败!发生如下异常:\n{res}') | ||
# print(f'填报数据:\n{data}\n') | ||
|
||
successs+=[success] | ||
ress+=[res] | ||
datas+=[data] | ||
usernames+=[username] | ||
names+=[name] | ||
|
||
try: | ||
notifier = ServerJiangNotifier( | ||
sckey=SERVER_KEY, | ||
sess=requests.Session() | ||
) | ||
print(f'通过「{notifier.PLATFORM_NAME}」给用户发送通知') | ||
notifier.notify(success=successs, msg=ress,data=datas,username=usernames,name=names) | ||
except: | ||
print(r"可能由于 「SERVER_KEY未设置」 或 「SERVER_KEY不正确」 或 「网络波动」 ,SERVER酱发送失败") | ||
|
||
|
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 @@ | ||
requests |
Oops, something went wrong.