首先,我研究了所有其他解决方案。我确保我的IDE /编辑器(Atom)不会捕获输入。我一直在查看是否我的任何代码都笨拙地阻止了Ctrl-C。我用了time.sleep,signal,threads,就给它命名。我无法弄清楚为什么发送Ctrl-C不会停止我的Python程序(但是通过Activity Monitor杀死它)。这是代码
from user_data_manager import DataManager
from get_data import SkywardDataManager
from getpass import getpass
from typing import Dict, List, Any
import time
def get_diff(new_grades: Dict[str, Any], old_grades: Dict[str, Any]) -> Dict[str, Any]:
difference = {} #type: Dict[str, List[Dict[str, str]]]
for class_name in new_grades.keys():
if class_name in old_grades.keys():
new_grade_list = new_grades[class_name]
old_grade_list = old_grades[class_name]
diff = [
item
for item in new_grade_list if item not in old_grade_list
]
difference[class_name] = diff
return difference
def print_grade_diff(grades: SkywardDataManager, student: DataManager) -> None:
new_grades = grades.get_grades()
old_grades = student.load()
diff = get_diff(new_grades, old_grades)
student.write(new_grades)
print(diff)
def main() -> None:
default_conf = {
"username": "",
"password": ""
}
dm = DataManager("./conf.json", def_obj=default_conf)
data = dm.load()
username = data["username"]
password = data["password"]
GDM = None
while True:
try:
if username == "" or password == "":
username = input("Skyward username: ")
password = getpass("Skyward password: ")
GDM = SkywardDataManager(username, password)
break
except ValueError:
print("Incorrect username or password, please try again.")
username = input("Skyward username: ")
password = getpass("Skyward password: ")
except KeyboardInterrupt:
print("Hellow")
sdm = DataManager("./grades/{0}.json".format(username))
print_grade_diff(GDM, sdm)
old_time = 0
while True:
try:
new_time = time.time()
if new_time - old_time > 5*60:
print("running")
old_time = time.time()
main()
except KeyboardInterrupt:
print("Hello")
still_going = False
exit
user_data_manager只是我用于连接JSON文件的一段代码,而get_data.py看起来像这样
from requests_html import HTMLSession, HTML
import getpass
import os
from user_data_manager import DataManager
from typing import Dict, List, Any
session = HTMLSession()
base_url = "https://skyward.iscorp.com/scripts/wsisa.dll/WService=wseduoakparkrfil"
login_url = base_url + "/skyporthttp.w"
def parse_login_text(text: str) -> Dict[str, Any]:
text = text.replace("<li>", "").replace("</li>", "")
values = text.split("^")
new_url = base_url + "/" + values[7]
encses = values[14]
data = {
"params": {
"dwd": values[0],
"web-data-recid": values[1],
"wfaacl-recid": values[2],
"wfaacl": values[3],
"nameid": values[4],
"duserid": values[5],
"User-Type": values[6],
"enc": values[13],
"encses": encses
},
"new_url": new_url,
"encses": values[14]
}
return data
class SkywardDataManager():
def __init__(self, usern: str, passw: str) -> None:
self.username = usern
self.password = passw
data = self.login()
self.login_data = data
def login(self) -> Dict[str, Any]:
req_dm = DataManager("./default_request_conf.json")
params = req_dm.load()
params["codeValue"] = self.username
params["login"] = self.username
params["password"] = self.password
req = session.post(login_url, data=params)
text = req.text
if "Invalid" in text:
raise ValueError("Incorrect username or password")
return parse_login_text(text)
def get_session_params(self) -> Dict[str, str]:
ldata = self.login_data
req2 = session.post(ldata["new_url"], data=ldata["params"])
page = req2.html
sessid = page.find("#sessionid", first=True).attrs["value"]
encses = page.find("#encses", first=True).attrs["value"]
return {
"sessid": sessid,
"encses": encses
}
def get_grades(self) -> Dict[str, List[Dict[str, str]]]:
grade_url = base_url + "/sfgradebook001.w"
sessionp = self.get_session_params()
req3 = session.post(grade_url, data={
"encses": sessionp["encses"],
"sessionid": sessionp["sessid"]
})
new_text = req3.text
new_text = new_text.replace(
"src='",
"src='{0}/".format(base_url)
).replace(
"href='",
"href='{0}/".format(base_url)
)
'''
Replacing values here to make sure that all requests
are being made to the skyward site and not the local
computer.
'''
new_html = HTML(html=new_text)
with open("./page.html", "w") as f:
f.write(new_html.html)
new_html.render()
i = 1
grades = {} # type: Dict[str, List[Dict[str, str]]]
tr_with_rownum = list(
filter(
lambda elem: "data-rownum" in elem.attrs.keys(),
new_html.find("tr")
)
)
current_class = ""
while True:
elems = list(
filter(
lambda elem: elem.attrs["data-rownum"] == str(i),
tr_with_rownum
)
)
if elems == []:
break # No more assignments/classes
i += 1
elems_text = list(
map(
lambda elem: elem.text,
elems
)
)
if "Period" in elems_text[1] and "Due:" not in elems_text[1]:
# This represents a class row
current_class = elems_text[1].split("\n")[0]
overall_grades = elems_text[0].split("\n")
grades[current_class] = []
semester1_grades = overall_grades[0:4]
# Semester 1 is the first 4 Grades
# Q1, Q2, EX1, SM1
semester2_grades = overall_grades[4:]
#Semester 2 is the last 4 Grades
# Q3, Q4, EX2, SM2
quarter_grades = [] # type: List[str]
exam_grades = [] # type: List[str]
semester_grades = [] # type: List[str]
if len(semester1_grades) == 4:
quarter_grades += semester1_grades[:-2]
exam_grades += semester1_grades[-2]
semester1_grades += semester1_grades[-1]
else:
quarter_grades += semester1_grades[:-1]
exam_grades = None
semester_grades += semester1_grades[-1]
if len(semester2_grades) == 4:
quarter_grades += semester2_grades[:-2]
exam_grades += semester2_grades[-2]
semester1_grades += semester2_grades[-1]
elif len(semester2_grades) > 0:
quarter_grades += semester2_grades[:-1]
semester_grades += semester2_grades[-1]
for num, grade in enumerate(quarter_grades):
grades[current_class].append({
"Quarter {0}".format(num+1): grade
})
for num, grade in enumerate(semester_grades):
grades[current_class].append({
"Semester {0}".format(num+1): grade
})
if exam_grades != None:
for num, grade in enumerate(exam_grades):
grades[current_class].append({
"Exam {0}".format(num+1): grade
})
else:
# This represents an assignment
assignment_name = elems_text[1].split("\n")[0]
grade = elems_text[0]
if assignment_name != "Next 4...":
grades[current_class].append({
assignment_name: grade
})
return grades
我不明白为什么get_data或main中的某些内容会干扰捕获SIGINT的行为,但是我不是专家。为什么我不能退出代码?
编辑:如果有帮助,我可以在main()打印之前完全退出,但是在退出之前不能退出。
答案 0 :(得分:0)
我尝试用IDLE中的KeyboardInterrput测试,它完美地引发了KeyboardInterrupt。如果确实不适合您,建议您使用其他方法来管理热键。
编辑:KeyboardInterrpu出现时出现,但用except语句无法检测到。 可能的最可能的原因是KeyboardInterrupt没有继承自BaseException,后者具有允许捕获错误的编码。希望这可以帮助!