mirror of
https://github.com/lifegpc/pythonscript.git
synced 2026-06-06 11:28:58 +08:00
add zyys
This commit is contained in:
397
zyys.py
Normal file
397
zyys.py
Normal file
@@ -0,0 +1,397 @@
|
||||
from argparse import ArgumentParser
|
||||
from getpass import getpass
|
||||
from hashlib import sha1 as _sha1
|
||||
from json import dumps as _dumps, load
|
||||
from math import ceil
|
||||
from random import random
|
||||
from urllib.parse import urlencode
|
||||
from requests import Session
|
||||
|
||||
|
||||
def stringify(json):
|
||||
return _dumps(json, ensure_ascii=False, separators=(",", ":"))
|
||||
|
||||
|
||||
def sha1(data: str):
|
||||
f = _sha1()
|
||||
f.update(data.encode())
|
||||
return f.hexdigest()
|
||||
|
||||
|
||||
class Client():
|
||||
MYSHOP_FORAPP_KEY = "987654321"
|
||||
SOFTWARE = "0"
|
||||
LOGINDEVICETYPE = "android"
|
||||
FROMANDROID = "1"
|
||||
VERSION = "131"
|
||||
DEVICEID = "设备Id获取失败,null值!版本\u003d131"
|
||||
|
||||
def __init__(self):
|
||||
self._ses = Session()
|
||||
self._ses.headers.update({
|
||||
"User-Agent": "okhttp/3.6.0",
|
||||
"Accept-Encoding": "gzip",
|
||||
})
|
||||
self._baseUrl = "http://39.104.60.22:6023/"
|
||||
self._token = ""
|
||||
self._fromteacher = False
|
||||
self._portalUrl = None
|
||||
|
||||
def check_in(self, longitude: float, latitude: float, localname, note):
|
||||
if self._portalUrl is None:
|
||||
raise Exception("请先选择医院")
|
||||
if not self._token:
|
||||
raise Exception("请先登录")
|
||||
url = self._portalUrl + "doctor_train/rest/ningboschedule/signstudent.do" # noqa: E501
|
||||
url += f"?{self.get_base_params()}"
|
||||
d = stringify({
|
||||
"logindevicetype": self.LOGINDEVICETYPE,
|
||||
"longitude": f"{longitude:.06f}",
|
||||
"latitude": f"{latitude:.06f}",
|
||||
"fromandroid": self.FROMANDROID,
|
||||
"note": note,
|
||||
"fromteacher": "1" if self._fromteacher else "0",
|
||||
"localname": localname,
|
||||
})
|
||||
re = self._ses.post(url, data={"data": d})
|
||||
if re.status_code != 200:
|
||||
raise Exception(f"HTTP {re.status_code} {re.reason}")
|
||||
return self.check_error2(re.json())
|
||||
|
||||
def check_error(self, r):
|
||||
if r["code"] != "1" or "data" not in r or r["data"] is None:
|
||||
raise Exception(f"Error: {r['msg']}")
|
||||
return r["data"]
|
||||
|
||||
def check_error2(self, r):
|
||||
if r["code"] != "1":
|
||||
raise Exception(f"Error: {r['msg']}")
|
||||
return r
|
||||
|
||||
def get_base_params(self):
|
||||
d = {
|
||||
"token": self._token,
|
||||
"myshop_app_key": self.MYSHOP_FORAPP_KEY,
|
||||
"software": self.SOFTWARE,
|
||||
}
|
||||
return urlencode(d)
|
||||
|
||||
def get_ningbo_schedule_init_data(self):
|
||||
if self._portalUrl is None:
|
||||
raise Exception("请先选择医院")
|
||||
if not self._token:
|
||||
raise Exception("请先登录")
|
||||
url = self._portalUrl + "doctor_train/rest/ningboschedule/getInitData.do" # noqa: E501
|
||||
url += f"?{self.get_base_params()}"
|
||||
d = stringify({
|
||||
"logindevicetype": self.LOGINDEVICETYPE,
|
||||
"fromteacher": "1" if self._fromteacher else "0",
|
||||
"fromandroid": self.FROMANDROID,
|
||||
})
|
||||
re = self._ses.post(url, data={"data": d})
|
||||
if re.status_code != 200:
|
||||
raise Exception(f"HTTP {re.status_code} {re.reason}")
|
||||
return self.check_error2(re.json())
|
||||
|
||||
def login_check(self, loginid: str, password: str):
|
||||
if self._portalUrl is None:
|
||||
raise Exception("请先选择医院")
|
||||
url = self._portalUrl + "doctor_portal/rest/loginCheck.do"
|
||||
url += f"?{self.get_base_params()}"
|
||||
d = stringify({
|
||||
"logindevicetype": self.LOGINDEVICETYPE,
|
||||
"password": sha1(password),
|
||||
"fromandroid": self.FROMANDROID,
|
||||
"devicetype": self.LOGINDEVICETYPE,
|
||||
"deviceid": self.DEVICEID,
|
||||
"fromteacher": "1" if self._fromteacher else "0",
|
||||
"loginid": loginid,
|
||||
"mac": self.DEVICEID,
|
||||
})
|
||||
re = self._ses.post(url, data={"data": d})
|
||||
if re.status_code != 200:
|
||||
raise Exception(f"HTTP {re.status_code} {re.reason}")
|
||||
return self.check_error2(re.json())
|
||||
|
||||
def init_with_hospital(self, hospital):
|
||||
self._portalUrl = f'http://{hospital["portalurl"]}/'
|
||||
|
||||
def init_with_user(self, user):
|
||||
self._token = user["token"]
|
||||
|
||||
def query_train_hospital(self):
|
||||
url = self._baseUrl + "cloud_doctor_train/rest/trainHospital/query.do"
|
||||
url += f"?{self.get_base_params()}"
|
||||
d = stringify({
|
||||
"logindevicetype": self.LOGINDEVICETYPE,
|
||||
"fromteacher": "1" if self._fromteacher else "0",
|
||||
"fromandroid": self.FROMANDROID,
|
||||
})
|
||||
re = self._ses.post(url, data={"data": d})
|
||||
if re.status_code != 200:
|
||||
raise Exception(f"HTTP {re.status_code} {re.reason}")
|
||||
return self.check_error(re.json())
|
||||
|
||||
|
||||
class Main():
|
||||
def __init__(self, config, arg):
|
||||
self._config = config
|
||||
self._arg = arg
|
||||
self._client = Client()
|
||||
|
||||
def ask_choice(self, choices: list, prompt="请选择:", fn=None, extra=None):
|
||||
count = len(choices)
|
||||
total_pages = ceil(count / self._arg.page_size)
|
||||
page = 1
|
||||
|
||||
def show_page():
|
||||
nonlocal page
|
||||
base = (page - 1) * self._arg.page_size
|
||||
if total_pages > 1:
|
||||
print(f"第{page}/{total_pages}页")
|
||||
for i in range(self._arg.page_size):
|
||||
index = base + i
|
||||
if index >= count:
|
||||
break
|
||||
s = fn(choices[index]) if fn else choices[index]
|
||||
print(f"{i}. {s}")
|
||||
if page > 1:
|
||||
print("f. 第一页")
|
||||
print("p. 上一页")
|
||||
if page < total_pages:
|
||||
print("n. 下一页")
|
||||
print("l. 最后一页")
|
||||
if extra is not None:
|
||||
for t in extra:
|
||||
print(f"{t[0]}. {t[1]}")
|
||||
|
||||
while True:
|
||||
show_page()
|
||||
s = input(prompt)
|
||||
if s == "f":
|
||||
page = 1
|
||||
elif s == "p":
|
||||
page = max(1, page - 1)
|
||||
elif s == "n":
|
||||
page = min(total_pages, page + 1)
|
||||
elif s == "l":
|
||||
page = total_pages
|
||||
else:
|
||||
if extra is not None:
|
||||
for t in extra:
|
||||
if t[0] == s:
|
||||
return t[2]
|
||||
try:
|
||||
index = int(s)
|
||||
except Exception:
|
||||
continue
|
||||
base = (page - 1) * self._arg.page_size
|
||||
index += base
|
||||
if index < 0 or index >= count:
|
||||
continue
|
||||
return choices[index]
|
||||
|
||||
def checkIn(self):
|
||||
self.init_client()
|
||||
if "location" not in self._config:
|
||||
self._config["location"] = []
|
||||
location = self.ask_choice(self._config["location"], "请选择位置:", lambda x: f'{x["name"]} ({x["longitude"]},{x["latitude"]},{x["localname"]})', [("a", "添加位置", "add")]) # noqa: E501
|
||||
if location == "add":
|
||||
name = input("请输入位置名称(仅用作标识,不会上传到服务器):")
|
||||
longitude = float(input("请输入经度:"))
|
||||
latitude = float(input("请输入纬度:"))
|
||||
localname = input("请输入地名(会在签到时上传到服务器):")
|
||||
location = {
|
||||
"name": name,
|
||||
"longitude": longitude,
|
||||
"latitude": latitude,
|
||||
"localname": localname,
|
||||
"longitude_radius": 0.00001,
|
||||
"latitude_radius": 0.00001,
|
||||
}
|
||||
while True:
|
||||
self.show_location(location)
|
||||
s = input("是否需要进行调整?(y/n)")
|
||||
if s == "n":
|
||||
break
|
||||
elif s == "y":
|
||||
t = {
|
||||
"name": "位置名称",
|
||||
"longitude": "经度",
|
||||
"latitude": "纬度",
|
||||
"localname": "地名",
|
||||
"longitude_radius": "随机化经度半径",
|
||||
"latitude_radius": "随机化纬度半径",
|
||||
}
|
||||
c = self.ask_choice(["name", "longitude", "latitude",
|
||||
"localname", "longitude_radius",
|
||||
"latitude_radius"], "请选择要修改的内容:",
|
||||
lambda x: t[x])
|
||||
if c == "name":
|
||||
location["name"] = input("请输入位置名称:")
|
||||
elif c == "longitude":
|
||||
location["longitude"] = float(input("请输入经度:"))
|
||||
elif c == "latitude":
|
||||
location["latitude"] = float(input("请输入纬度:"))
|
||||
elif c == "localname":
|
||||
location["localname"] = input("请输入地名:")
|
||||
elif c == "longitude_radius":
|
||||
location["longitude_radius"] = float(
|
||||
input("请输入随机化经度半径:"))
|
||||
elif c == "latitude_radius":
|
||||
location["latitude_radius"] = float(
|
||||
input("请输入随机化纬度半径:"))
|
||||
else:
|
||||
continue
|
||||
self._config["location"].append(location)
|
||||
print("获取签到信息...")
|
||||
data = self._client.get_ningbo_schedule_init_data()
|
||||
print("已签到列表:")
|
||||
for x in data["signlist"]:
|
||||
print(x)
|
||||
prompt = f"要进行{data['buttonname']}吗?(y/n)"
|
||||
while True:
|
||||
s = input(prompt)
|
||||
if s == "y":
|
||||
break
|
||||
elif s == "n":
|
||||
return
|
||||
localname = location["localname"]
|
||||
longitude = round(location["longitude"] + (random() - 0.5) * location["longitude_radius"], 6) # noqa: E501
|
||||
latitude = round(location["latitude"] + (random() - 0.5) * location["latitude_radius"], 6) # noqa: E501
|
||||
note = ""
|
||||
if self._arg.note:
|
||||
note = self._arg.note
|
||||
while True:
|
||||
print("经度:", longitude)
|
||||
print("纬度:", latitude)
|
||||
print("地名:", localname)
|
||||
print("备注:", note)
|
||||
s = input("是否需要进行调整?(y/n)")
|
||||
if s == "n":
|
||||
break
|
||||
elif s == "y":
|
||||
t = {
|
||||
"longitude": "经度",
|
||||
"latitude": "纬度",
|
||||
"localname": "地名",
|
||||
"note": "备注",
|
||||
}
|
||||
c = self.ask_choice(["longitude", "latitude", "localname",
|
||||
"note"], "请选择要修改的内容:", lambda x: t[x])
|
||||
if c == "longitude":
|
||||
longitude = float(input("请输入经度:"))
|
||||
elif c == "latitude":
|
||||
latitude = float(input("请输入纬度:"))
|
||||
elif c == "localname":
|
||||
localname = input("请输入地名:")
|
||||
elif c == "note":
|
||||
note = input("请输入备注:")
|
||||
print("签到中...")
|
||||
self._client.check_in(longitude, latitude, localname, note)
|
||||
print("签到成功")
|
||||
|
||||
def get_hospital(self):
|
||||
print("获取医院列表...")
|
||||
data = self._client.query_train_hospital()
|
||||
if self._arg.hospital_id:
|
||||
for x in data:
|
||||
if x["trainhospitalid"] == self._arg.hospital_id:
|
||||
return x
|
||||
raise Exception(f"医院ID {self._arg.hospital_id} 不存在")
|
||||
if self._arg.hospital_name:
|
||||
for x in data:
|
||||
if x["name"] == self._arg.hospital_name:
|
||||
return x
|
||||
raise Exception(f"医院名称 {self._arg.hospital_name} 不存在")
|
||||
if self._arg.hospital_code:
|
||||
for x in data:
|
||||
if x["hospitalcode"] == self._arg.hospital_code:
|
||||
return x
|
||||
raise Exception(f"医院编码 {self._arg.hospital_code} 不存在")
|
||||
return self.ask_choice(data, "请选择医院:", lambda x: x["name"])
|
||||
|
||||
def init_client(self):
|
||||
if "hospital" not in self._config or "user" not in self._config:
|
||||
self.login()
|
||||
else:
|
||||
self._client.init_with_hospital(self._config["hospital"])
|
||||
self._client.init_with_user(self._config["user"])
|
||||
|
||||
def login(self):
|
||||
if "hospital" not in self._config or self._arg.change_hospital:
|
||||
self._config["hospital"] = self.get_hospital()
|
||||
self._client.init_with_hospital(self._config["hospital"])
|
||||
if self._arg.login_id is None:
|
||||
self._arg.login_id = input("请输入登录ID:")
|
||||
if self._arg.password is None:
|
||||
if self._arg.no_getpass:
|
||||
self._arg.password = input("请输入密码:")
|
||||
else:
|
||||
self._arg.password = getpass("请输入密码:")
|
||||
print("登录中...")
|
||||
self._config["user"] = self._client.login_check(
|
||||
self._arg.login_id, self._arg.password)
|
||||
self._client.init_with_user(self._config["user"])
|
||||
print("登录成功")
|
||||
|
||||
def show_location(self, loc):
|
||||
print("位置名称:", loc["name"])
|
||||
print("经度:", loc["longitude"])
|
||||
print("纬度:", loc["latitude"])
|
||||
print("地名:", loc["localname"])
|
||||
print("随机化经度半径:", loc["longitude_radius"])
|
||||
print("随机化纬度半径:", loc["latitude_radius"])
|
||||
|
||||
|
||||
ACTIONS = ["login", "checkin"]
|
||||
EACTIONS = ["login2"]
|
||||
|
||||
|
||||
def get_action_str(action):
|
||||
if action == "login":
|
||||
return "登录"
|
||||
elif action == "login2":
|
||||
return "登录(重新选择医院)"
|
||||
elif action == "checkin":
|
||||
return "签到"
|
||||
|
||||
|
||||
def main(args=None):
|
||||
p = ArgumentParser()
|
||||
p.add_argument("-c", "--config", default="zyys.json", help="配置文件")
|
||||
p.add_argument("-l", "--login-id", help="登录ID")
|
||||
p.add_argument("-p", "--password", help="密码")
|
||||
p.add_argument("--hospital-id", help="医院ID", type=int)
|
||||
p.add_argument("--hospital-name", help="医院名称")
|
||||
p.add_argument("--hospital-code", help="医院编码")
|
||||
p.add_argument("-P", "--page-size", default=10, help="每页数量", type=int)
|
||||
p.add_argument("-C", "--change-hospital", action="store_true",
|
||||
help="重新选择医院")
|
||||
p.add_argument("--no-getpass", action="store_true", help="不使用getpass")
|
||||
p.add_argument("-n", "--note", help="备注")
|
||||
p.add_argument("action", choices=ACTIONS, help="操作", nargs="?")
|
||||
arg = p.parse_args(args)
|
||||
try:
|
||||
with open(arg.config) as f:
|
||||
config = load(f)
|
||||
except Exception:
|
||||
config = {}
|
||||
m = Main(config, arg)
|
||||
if arg.action is None:
|
||||
arg.action = m.ask_choice(ACTIONS + EACTIONS, "请选择操作:", get_action_str)
|
||||
try:
|
||||
if arg.action == "login":
|
||||
m.login()
|
||||
elif arg.action == "login2":
|
||||
arg.change_hospital = True
|
||||
m.login()
|
||||
elif arg.action == "checkin":
|
||||
m.checkIn()
|
||||
finally:
|
||||
with open(arg.config, "w") as f:
|
||||
f.write(stringify(config))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user