diff --git a/cqwu/enums/webvpn.py b/cqwu/enums/webvpn.py index b700ffb..ea4e975 100644 --- a/cqwu/enums/webvpn.py +++ b/cqwu/enums/webvpn.py @@ -1,17 +1,9 @@ from enum import Enum -class ExamRound(str, Enum): - Supplementation = "1" - """ 开学补缓考 """ - Scattered = "2" - """ 分散考试 """ - Concentration = "3" - """ 集中考试 """ - - class ScoreSearchType(str, Enum): - """ 成绩查询类型 """ + """成绩查询类型""" + All = "1" """入学以来""" XUENIAN = "2" diff --git a/cqwu/errors/auth.py b/cqwu/errors/auth.py index 47baddd..3bce8c5 100644 --- a/cqwu/errors/auth.py +++ b/cqwu/errors/auth.py @@ -6,14 +6,15 @@ class AuthError(CQWUEhallError): class UsernameOrPasswordError(AuthError): - """ 用户名或密码错误 """ + """用户名或密码错误""" class CookieError(AuthError): - """ Cookie 失效 """ + """Cookie 失效""" class NeedCaptchaError(AuthError): - """ 需要验证码才能登录 """ + """需要验证码才能登录""" + def __init__(self, captcha: bytes): self.captcha = captcha diff --git a/cqwu/errors/base.py b/cqwu/errors/base.py index 515b9e3..be3456a 100644 --- a/cqwu/errors/base.py +++ b/cqwu/errors/base.py @@ -1,3 +1,4 @@ class CQWUEhallError(Exception): """Base class for exceptions in this module.""" + pass diff --git a/cqwu/errors/webvpn.py b/cqwu/errors/webvpn.py index fe1fca5..4a46d34 100644 --- a/cqwu/errors/webvpn.py +++ b/cqwu/errors/webvpn.py @@ -6,8 +6,8 @@ class CQWUWebVPNError(CQWUEhallError): class NoExamData(CQWUWebVPNError): - """ 没有检索到对应的考试记录 """ + """没有检索到对应的考试记录""" class NoScoreDetailData(CQWUWebVPNError): - """ 没有检索到对应的成绩明细记录 """ + """没有检索到对应的成绩明细记录""" diff --git a/cqwu/methods/auth/__init__.py b/cqwu/methods/auth/__init__.py index 8e76dad..83f9442 100644 --- a/cqwu/methods/auth/__init__.py +++ b/cqwu/methods/auth/__init__.py @@ -14,6 +14,6 @@ class Auth( LoginWithCookie, LoginWithCookieFile, LoginWithPassword, - Oauth + Oauth, ): pass diff --git a/cqwu/methods/auth/check_captcha.py b/cqwu/methods/auth/check_captcha.py index b88a4a0..31fdd6f 100644 --- a/cqwu/methods/auth/check_captcha.py +++ b/cqwu/methods/auth/check_captcha.py @@ -10,21 +10,23 @@ class CheckCaptcha: username: int = None, show_qrcode: bool = True, ): - """ 检查是否需要验证码 """ + """检查是否需要验证码""" username = username or self.username params = { "username": username, "pwdEncrypt2": "pwdEncryptSalt", - "_": str(round(time.time() * 1000)) + "_": str(round(time.time() * 1000)), } url = f"{self.auth_host}/authserver/needCaptcha.html" - captcha_html = await self.request.get(url, params=params, follow_redirects=False) - if captcha_html.text == 'true': - params = { - "ts": str(round(time.time())) - } + captcha_html = await self.request.get( + url, params=params, follow_redirects=False + ) + if captcha_html.text == "true": + params = {"ts": str(round(time.time()))} captcha_url = f"{self.auth_host}/authserver/captcha.html" - res = await self.request.get(captcha_url, params=params, follow_redirects=False) + res = await self.request.get( + captcha_url, params=params, follow_redirects=False + ) if not show_qrcode: raise NeedCaptchaError(res.content) with open("captcha.jpg", mode="wb") as f: diff --git a/cqwu/methods/auth/login.py b/cqwu/methods/auth/login.py index 2b706de..50a7524 100644 --- a/cqwu/methods/auth/login.py +++ b/cqwu/methods/auth/login.py @@ -9,7 +9,7 @@ class Login: async def login( self: "cqwu.Client", ): - """ 登录 """ + """登录""" with contextlib.suppress(CookieError): if self.cookie: await self.login_with_cookie() diff --git a/cqwu/methods/auth/login_with_password.py b/cqwu/methods/auth/login_with_password.py index 950eebb..cf70891 100644 --- a/cqwu/methods/auth/login_with_password.py +++ b/cqwu/methods/auth/login_with_password.py @@ -17,47 +17,51 @@ class LoginWithPassword: """ auth_host = auth_host or self.auth_host headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Cache-Control': 'max-age=0', - 'Connection': 'keep-alive', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9", + "Cache-Control": "max-age=0", + "Connection": "keep-alive", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63", } - html = await self.request.get(f"{auth_host}/authserver/login", headers=headers, follow_redirects=True) + html = await self.request.get( + f"{auth_host}/authserver/login", headers=headers, follow_redirects=True + ) self.cookies.update(html.cookies) tree = etree.HTML(html.text) try: - pwd_default_encrypt_salt = tree.xpath('//*[@id="pwdDefaultEncryptSalt"]/@value')[0] + pwd_default_encrypt_salt = tree.xpath( + '//*[@id="pwdDefaultEncryptSalt"]/@value' + )[0] except IndexError: if auth_host == self.auth_host: self._use_password_login = True # noqa self.me = await self.get_me() # noqa return form_data = { - 'username': str(self.username), - 'password': encode_password(self.password, pwd_default_encrypt_salt), - 'lt': tree.xpath('//*[@id="casLoginForm"]/input[1]/@value')[0], - 'dllt': tree.xpath('//*[@id="casLoginForm"]/input[2]/@value')[0], - 'execution': tree.xpath('//*[@id="casLoginForm"]/input[3]/@value')[0], - '_eventId': tree.xpath('//*[@id="casLoginForm"]/input[4]/@value')[0], - 'rmShown': tree.xpath('//*[@id="casLoginForm"]/input[5]/@value')[0] + "username": str(self.username), + "password": encode_password(self.password, pwd_default_encrypt_salt), + "lt": tree.xpath('//*[@id="casLoginForm"]/input[1]/@value')[0], + "dllt": tree.xpath('//*[@id="casLoginForm"]/input[2]/@value')[0], + "execution": tree.xpath('//*[@id="casLoginForm"]/input[3]/@value')[0], + "_eventId": tree.xpath('//*[@id="casLoginForm"]/input[4]/@value')[0], + "rmShown": tree.xpath('//*[@id="casLoginForm"]/input[5]/@value')[0], } # 是否需要验证码 if not captcha_code: captcha_code = await self.check_captcha(show_qrcode=show_qrcode) if captcha_code: - form_data['captchaResponse'] = captcha_code + form_data["captchaResponse"] = captcha_code # 登录 headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Cache-Control': 'max-age=0', - 'Connection': 'keep-alive', - 'Origin': auth_host, - 'Referer': f'{auth_host}/authserver/login', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9", + "Cache-Control": "max-age=0", + "Connection": "keep-alive", + "Origin": auth_host, + "Referer": f"{auth_host}/authserver/login", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63", } html = await self.request.post( f"{auth_host}/authserver/login", @@ -66,7 +70,7 @@ class LoginWithPassword: follow_redirects=False, ) if auth_host == self.auth_host: - if 'CASTGC' not in html.cookies.keys(): + if "CASTGC" not in html.cookies.keys(): raise UsernameOrPasswordError self.cookies.update(html.cookies) self._use_password_login = True # noqa diff --git a/cqwu/methods/epay/get_pay_bill.py b/cqwu/methods/epay/get_pay_bill.py index 3b27583..2e2a6b6 100644 --- a/cqwu/methods/epay/get_pay_bill.py +++ b/cqwu/methods/epay/get_pay_bill.py @@ -22,6 +22,6 @@ class GetPayBill: raise CookieError() data = await self.request.post( "http://218.194.176.214:8382/epay/thirdapp/loadbill.json", - data={"pageno": page_number} + data={"pageno": page_number}, ) return PayBillPage(**data.json()) diff --git a/cqwu/methods/pay/__init__.py b/cqwu/methods/pay/__init__.py index c08a204..183b7a3 100644 --- a/cqwu/methods/pay/__init__.py +++ b/cqwu/methods/pay/__init__.py @@ -19,7 +19,10 @@ class Pay( html = await self.request.get(url, follow_redirects=False) if html.status_code == 302: location = html.headers["location"] - params = {i.split("=")[0]: i.split("=")[1] for i in location.split("?")[1].split("&")} + params = { + i.split("=")[0]: i.split("=")[1] + for i in location.split("?")[1].split("&") + } self._pay_x_token = params["token"] @property diff --git a/cqwu/methods/pay/get_pay_project_detail.py b/cqwu/methods/pay/get_pay_project_detail.py index 7c5b209..5993ce6 100644 --- a/cqwu/methods/pay/get_pay_project_detail.py +++ b/cqwu/methods/pay/get_pay_project_detail.py @@ -18,8 +18,10 @@ class GetPayProjectDetail: """ if not self._pay_x_token: await self._oauth_pay() - url = (f"https://pay.cqwu.edu.cn/api/pay/web/tuitionAndDorm/getTuitionAndDormList/" - f"{self.username}/{project_id}") + url = ( + f"https://pay.cqwu.edu.cn/api/pay/web/tuitionAndDorm/getTuitionAndDormList/" + f"{self.username}/{project_id}" + ) html = await self.request.get(url, headers=self.pay_headers) if html.status_code != 200: raise CookieError() diff --git a/cqwu/methods/users/__init__.py b/cqwu/methods/users/__init__.py index 2795c61..831f0ab 100644 --- a/cqwu/methods/users/__init__.py +++ b/cqwu/methods/users/__init__.py @@ -1,7 +1,5 @@ from .get_me import GetMe -class Users( - GetMe -): +class Users(GetMe): pass diff --git a/cqwu/methods/users/get_me.py b/cqwu/methods/users/get_me.py index 61b4696..904410c 100644 --- a/cqwu/methods/users/get_me.py +++ b/cqwu/methods/users/get_me.py @@ -6,7 +6,9 @@ from cqwu import types from cqwu.errors.auth import CookieError -def get_value_from_soup(soup: BeautifulSoup, attr_id: str) -> Union[type(None), str, int]: +def get_value_from_soup( + soup: BeautifulSoup, attr_id: str +) -> Union[type(None), str, int]: try: data = soup.find("input", attrs={"id": attr_id})["value"] try: @@ -53,7 +55,9 @@ class GetMe: temp = {key: get_value_from_soup(soup, value) for key, value in data.items()} temp["password"] = self.password try: - temp["specialty"] = soup.find_all("input", attrs={"id": "detail_xy"})[1]["value"] + temp["specialty"] = soup.find_all("input", attrs={"id": "detail_xy"})[1][ + "value" + ] except (ValueError, TypeError, KeyError, IndexError): temp["specialty"] = None return types.User(**temp) diff --git a/cqwu/methods/webvpn/__init__.py b/cqwu/methods/webvpn/__init__.py index e05cfee..8ebf93b 100644 --- a/cqwu/methods/webvpn/__init__.py +++ b/cqwu/methods/webvpn/__init__.py @@ -3,6 +3,7 @@ from httpx import URL from .get_calendar import GetCalendar from .get_calendar_change import GetCalendarChange from .get_exam_calendar import GetExamCalendar +from .get_exam_calendar_action import GetExamCalendarAction from .get_score_detail import GetScoreDetail from .get_selected_courses import GetSelectedCourses from .login_jwmis import LoginJwmis @@ -13,6 +14,7 @@ class WebVPN( GetCalendar, GetCalendarChange, GetExamCalendar, + GetExamCalendarAction, GetScoreDetail, GetSelectedCourses, LoginJwmis, diff --git a/cqwu/methods/webvpn/get_calendar.py b/cqwu/methods/webvpn/get_calendar.py index 405ae96..f9a52a6 100644 --- a/cqwu/methods/webvpn/get_calendar.py +++ b/cqwu/methods/webvpn/get_calendar.py @@ -14,7 +14,7 @@ class GetCalendar: xue_qi: int = None, use_model: bool = False, ) -> Union[str, List[AiCourse]]: - """ 获取课程表 """ + """获取课程表""" xue_nian = xue_nian or self.xue_nian xue_qi = xue_qi or self.xue_qi jw_html = await self.login_jwmis() @@ -24,22 +24,27 @@ class GetCalendar: "params": base64.b64encode(f"xn={xue_nian}&xq={xue_qi}".encode()).decode(), } headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Connection': 'keep-alive', - 'Referer': f'{jw_host}/cqwljw/student/xkjg.wdkb.jsp?menucode=S20301', - 'Sec-Fetch-Dest': 'iframe', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Fetch-User': '?1', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41', - 'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9", + "Connection": "keep-alive", + "Referer": f"{jw_host}/cqwljw/student/xkjg.wdkb.jsp?menucode=S20301", + "Sec-Fetch-Dest": "iframe", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41", + "sec-ch-ua": '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', } - jw_html = await self.request.get(jw_url, params=params, headers=headers, timeout=60, follow_redirects=True) - jw_html = jw_html.text.replace("""""", "") + jw_html = await self.request.get( + jw_url, params=params, headers=headers, timeout=60, follow_redirects=True + ) + jw_html = jw_html.text.replace( + """""", + "", + ) return ( parse_courses(jw_html) if use_model diff --git a/cqwu/methods/webvpn/get_calendar_change.py b/cqwu/methods/webvpn/get_calendar_change.py index 0f28ed2..9ddcb71 100644 --- a/cqwu/methods/webvpn/get_calendar_change.py +++ b/cqwu/methods/webvpn/get_calendar_change.py @@ -11,7 +11,7 @@ class GetCalendarChange: xue_nian: int = None, xue_qi: int = None, ) -> str: - """ 获取课程表 """ + """获取课程表""" xue_nian = xue_nian or self.xue_nian xue_qi = xue_qi or self.xue_qi jw_html = await self.login_jwmis() @@ -19,50 +19,60 @@ class GetCalendarChange: jw_url = f"{jw_host}/cqwljw/student/jxap.jxaptzxx_rpt.jsp" jw_sg_url = f"{jw_host}/cqwljw/STU_DynamicInitDataAction.do" headers = { - 'Accept': '*/*', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Connection': 'keep-alive', - 'Origin': 'https://clientvpn.cqwu.edu.cn', - 'Referer': f'{jw_host}/cqwljw/student/jxap.jxaptzxx.html?menucode=S20302', - 'Sec-Fetch-Dest': 'empty', - 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Site': 'same-origin', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41', - 'content-type': 'application/x-www-form-urlencoded', - 'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', + "Accept": "*/*", + "Accept-Language": "zh-CN,zh;q=0.9", + "Connection": "keep-alive", + "Origin": "https://clientvpn.cqwu.edu.cn", + "Referer": f"{jw_host}/cqwljw/student/jxap.jxaptzxx.html?menucode=S20302", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41", + "content-type": "application/x-www-form-urlencoded", + "sec-ch-ua": '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', } params = { "classPath": "C73E288D0DEA8D7F772BBD7F8FDC7E66F44C9E3992261989ECBAC5A3D722B306C6354658E0F25121E24CED075326C19885F263F369E5CD668E2EEE7CFB7EB5788F202FC6FD7DB0C96FB6995C1DD96ADE84BE3E72CFFBE9EC74FA044498BD2D21EA0439F9DC625F0EF61B7159924C542D577F814848F27128" } - res = await self.request.post(jw_sg_url, params=params, headers=headers, timeout=60, follow_redirects=True) + res = await self.request.post( + jw_sg_url, params=params, headers=headers, timeout=60, follow_redirects=True + ) data = { - 'xh': get_in_middle(res.text, '', ''), - 'xn': str(xue_nian), - 'xq': str(xue_qi), - 'xnxq': f'{xue_nian},{xue_qi}', - 'menucode_current': 'S20302', + "xh": get_in_middle(res.text, "", ""), + "xn": str(xue_nian), + "xq": str(xue_qi), + "xnxq": f"{xue_nian},{xue_qi}", + "menucode_current": "S20302", } headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Cache-Control': 'max-age=0', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded', - 'Origin': 'https://clientvpn.cqwu.edu.cn', - 'Referer': f'{jw_host}/cqwljw/student/jxap.jxaptzxx.html?menucode=S20302', - 'Sec-Fetch-Dest': 'iframe', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Fetch-User': '?1', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41', - 'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9", + "Cache-Control": "max-age=0", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Origin": "https://clientvpn.cqwu.edu.cn", + "Referer": f"{jw_host}/cqwljw/student/jxap.jxaptzxx.html?menucode=S20302", + "Sec-Fetch-Dest": "iframe", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41", + "sec-ch-ua": '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', } - jw_html = await self.request.post(jw_url, data=data, headers=headers, timeout=60, follow_redirects=True) - jw_html = jw_html.text.replace("""""", "") - jw_html = jw_html.replace("""""", "") + jw_html = await self.request.post( + jw_url, data=data, headers=headers, timeout=60, follow_redirects=True + ) + jw_html = jw_html.text.replace( + """""", + "", + ) + jw_html = jw_html.replace( + """""", + "", + ) return jw_html.replace("", '') diff --git a/cqwu/methods/webvpn/get_exam_calendar.py b/cqwu/methods/webvpn/get_exam_calendar.py index fcbaefd..c5c1495 100644 --- a/cqwu/methods/webvpn/get_exam_calendar.py +++ b/cqwu/methods/webvpn/get_exam_calendar.py @@ -3,7 +3,6 @@ from typing import Union, List from bs4 import BeautifulSoup import cqwu -from cqwu.enums import ExamRound from cqwu.errors import NoExamData from cqwu.types import AiExam @@ -11,56 +10,63 @@ from cqwu.types import AiExam class GetExamCalendar: async def get_exam_calendar( self: "cqwu.Client", - exam_round: Union[str, ExamRound] = ExamRound.Supplementation, + exam_round: str = "1", xue_nian: int = None, xue_qi: int = None, use_model: bool = False, ) -> Union[str, List[AiExam]]: - """ 获取考试安排表 """ + """获取考试安排表""" xue_nian = xue_nian or self.xue_nian xue_qi = xue_qi or self.xue_qi - exam_round = ExamRound(exam_round) jw_html = await self.login_jwmis() jw_host = self.get_web_vpn_host(jw_html.url, https=True) jw_url = f"{jw_host}/cqwljw/student/ksap.ksapb_date.jsp" headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4', - 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded', - 'DNT': '1', - 'Pragma': 'no-cache', - 'Referer': f'{jw_host}/cqwljw/student/ksap.ksapb.html?menucode=S20403', - 'Sec-Fetch-Dest': 'iframe', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Fetch-User': '?1', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36', - 'sec-ch-ua': '"Chromium";v="112", "Not:A-Brand";v="99"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4", + "Cache-Control": "no-cache", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "DNT": "1", + "Pragma": "no-cache", + "Referer": f"{jw_host}/cqwljw/student/ksap.ksapb.html?menucode=S20403", + "Sec-Fetch-Dest": "iframe", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "sec-ch-ua": '"Chromium";v="112", "Not:A-Brand";v="99"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', } data = { - 'xn': str(xue_nian), - 'xq': str(xue_qi), - 'title': '', - 'xnxq': f'{xue_nian}{xue_qi}', - 'kslc': exam_round.value, + "xn": str(xue_nian), + "xq": str(xue_qi), + "title": "", + "xnxq": f"{xue_nian}{xue_qi}", + "kslc": exam_round, } - jw_html = await self.request.post(jw_url, data=data, headers=headers, timeout=60, follow_redirects=True) + jw_html = await self.request.post( + jw_url, data=data, headers=headers, timeout=60, follow_redirects=True + ) if "没有检索到记录!" in jw_html.text: raise NoExamData("没有检索到记录!") - jw_html = jw_html.text.replace("""""", "") - jw_html = jw_html.replace("""""", "") - jw_html = jw_html.replace("charset=GBK", 'charset=UTF-8') + jw_html = jw_html.text.replace( + """""", + "", + ) + jw_html = jw_html.replace( + """""", + "", + ) + jw_html = jw_html.replace("charset=GBK", "charset=UTF-8") if not use_model: return jw_html return parse_html(jw_html, exam_round) -def parse_html(html: str, exam_round: ExamRound) -> List[AiExam]: +def parse_html(html: str, exam_round: str) -> List[AiExam]: data: List[AiExam] = [] soup = BeautifulSoup(html, "html.parser") trs = soup.find_all("tr")[1:] diff --git a/cqwu/methods/webvpn/get_exam_calendar_action.py b/cqwu/methods/webvpn/get_exam_calendar_action.py new file mode 100644 index 0000000..2958e71 --- /dev/null +++ b/cqwu/methods/webvpn/get_exam_calendar_action.py @@ -0,0 +1,64 @@ +from json import JSONDecodeError + +import cqwu +from cqwu.types.exam import ExamType + + +class GetExamCalendarAction: + async def get_exam_calendar_action( + self: "cqwu.Client", + xue_nian: int = None, + xue_qi: int = None, + ) -> ExamType: + """获取考试安排可用类型""" + xue_nian = xue_nian or self.xue_nian + xue_qi = xue_qi or self.xue_qi + jw_html = await self.login_jwmis() + jw_host = self.get_web_vpn_host(jw_html.url, https=True) + jw_url = f"{jw_host}/cqwljw/frame/droplist/getDropLists.action" + headers = { + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4", + "Cache-Control": "no-cache", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "DNT": "1", + "Pragma": "no-cache", + "Referer": f"{jw_host}/cqwljw/student/ksap.ksapb.html?menucode=S20403", + "Sec-Fetch-Dest": "iframe", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "sec-ch-ua": '"Chromium";v="112", "Not:A-Brand";v="99"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', + } + data = { + "comboBoxName": "Ms_KSSW_FBKSLC", + "paramValue": f"xtdm=jw&zxtdm=7&kgmc=kw_fbksap&xnxq={xue_nian}{xue_qi}", + "isYXB": "0", + "isCDDW": "0", + "isXQ": "0", + "isDJKSLB": "0", + "isZY": "0", + } + jw_html = await self.request.post( + jw_url, data=data, headers=headers, timeout=60, follow_redirects=True + ) + data = ExamType() + try: + jw_data = jw_html.json() + for i in jw_data: + if "开学补缓考" in i["name"]: + data.supplementation = i["code"] + elif "毕业年级考试" in i["name"]: + data.graduate = i["code"] + elif "分散考试" in i["name"]: + data.scattered = i["code"] + elif "集中考试" in i["name"]: + data.concentration = i["code"] + except JSONDecodeError: + pass + return data diff --git a/cqwu/methods/webvpn/get_score_detail.py b/cqwu/methods/webvpn/get_score_detail.py index 394ed78..d606547 100644 --- a/cqwu/methods/webvpn/get_score_detail.py +++ b/cqwu/methods/webvpn/get_score_detail.py @@ -16,7 +16,7 @@ class GetScoreDetail: xue_qi: int = None, use_model: bool = False, ) -> Union[str, ScoreDetail]: - """ 获取学业成绩 """ + """获取学业成绩""" xue_nian = xue_nian or self.xue_nian xue_qi = xue_qi or self.xue_qi search_type = ScoreSearchType(search_type) @@ -24,23 +24,23 @@ class GetScoreDetail: jw_host = self.get_web_vpn_host(jw_html.url, https=True) jw_url = f"{jw_host}/cqwljw/student/xscj.stuckcj_data.jsp" headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4', - 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded', - 'DNT': '1', - 'Pragma': 'no-cache', - 'Referer': f'{jw_host}/cqwljw/student/ksap.ksapb.html?menucode=S20403', - 'Sec-Fetch-Dest': 'iframe', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Fetch-User': '?1', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36', - 'sec-ch-ua': '"Chromium";v="112", "Not:A-Brand";v="99"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9,zh-Hans;q=0.8,und;q=0.7,en;q=0.6,zh-Hant;q=0.5,ja;q=0.4", + "Cache-Control": "no-cache", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "DNT": "1", + "Pragma": "no-cache", + "Referer": f"{jw_host}/cqwljw/student/ksap.ksapb.html?menucode=S20403", + "Sec-Fetch-Dest": "iframe", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", + "sec-ch-ua": '"Chromium";v="112", "Not:A-Brand";v="99"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', } data = { "sjxz": f"sjxz{search_type.value}", @@ -50,7 +50,7 @@ class GetScoreDetail: "btnExport": "%B5%BC%B3%F6", "rxnj": str(xue_nian), "xn": str(xue_nian), - 'xn1': str(xue_nian + 1), + "xn1": str(xue_nian + 1), "xq": str(xue_qi), "ysyxS": "on", "sjxzS": "on", @@ -58,12 +58,20 @@ class GetScoreDetail: "fxC": "on", "xsjd": "1", } - jw_html = await self.request.post(jw_url, data=data, headers=headers, timeout=60, follow_redirects=True) + jw_html = await self.request.post( + jw_url, data=data, headers=headers, timeout=60, follow_redirects=True + ) if "没有检索到记录!" in jw_html.text: raise NoScoreDetailData("没有检索到记录!") - jw_html = jw_html.text.replace("""""", "") - jw_html = jw_html.replace("""""", "") - jw_html = jw_html.replace("charset=GBK", 'charset=UTF-8') + jw_html = jw_html.text.replace( + """""", + "", + ) + jw_html = jw_html.replace( + """""", + "", + ) + jw_html = jw_html.replace("charset=GBK", "charset=UTF-8") if not use_model: return jw_html return parse_html(jw_html) diff --git a/cqwu/methods/webvpn/get_selected_courses.py b/cqwu/methods/webvpn/get_selected_courses.py index 79ade16..2546de4 100644 --- a/cqwu/methods/webvpn/get_selected_courses.py +++ b/cqwu/methods/webvpn/get_selected_courses.py @@ -12,27 +12,32 @@ class GetSelectedCourses: self: "cqwu.Client", use_model: bool = False, ) -> Union[str, List[AiCourse]]: - """ 获取选课结果 """ + """获取选课结果""" jw_html = await self.login_jwmis() jw_host = self.get_web_vpn_host(jw_html.url) jw_url = f"{jw_host}/cqwljw/student/wsxk.zxjg.jsp" headers = { - 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Connection': 'keep-alive', - 'Referer': f'{jw_host}/cqwljw/frame/homes.html', - 'Sec-Fetch-Dest': 'iframe', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Fetch-User': '?1', - 'Upgrade-Insecure-Requests': '1', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41', - 'sec-ch-ua': '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", + "Accept-Language": "zh-CN,zh;q=0.9", + "Connection": "keep-alive", + "Referer": f"{jw_host}/cqwljw/frame/homes.html", + "Sec-Fetch-Dest": "iframe", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-User": "?1", + "Upgrade-Insecure-Requests": "1", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.41", + "sec-ch-ua": '"Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"', } - jw_html = await self.request.get(jw_url, headers=headers, timeout=60, follow_redirects=True) - jw_html = jw_html.text.replace("""""", "") + jw_html = await self.request.get( + jw_url, headers=headers, timeout=60, follow_redirects=True + ) + jw_html = jw_html.text.replace( + """""", + "", + ) return ( parse_courses(jw_html) if use_model @@ -57,7 +62,9 @@ def parse_courses(jw_html: str) -> List[AiCourse]: for calendar in calendars: text = (BeautifulSoup(calendar, "lxml")).text.strip() try: - position, weeks, day, start_num, sections = parse_weeks_and_sections(text) + position, weeks, day, start_num, sections = parse_weeks_and_sections( + text + ) except Exception: continue item = AiCourse( diff --git a/cqwu/methods/webvpn/login_jwmis.py b/cqwu/methods/webvpn/login_jwmis.py index 3bbfb87..a326719 100644 --- a/cqwu/methods/webvpn/login_jwmis.py +++ b/cqwu/methods/webvpn/login_jwmis.py @@ -8,9 +8,10 @@ class LoginJwmis: async def login_jwmis( self: "cqwu.Client", ) -> Response: - """ 登录教学管理平台 """ + """登录教学管理平台""" jw_html = await self.request.get( - f"{self.web_ehall_path}/appShow?appId=5299144291521305", follow_redirects=True + f"{self.web_ehall_path}/appShow?appId=5299144291521305", + follow_redirects=True, ) if "教学管理服务平台" not in jw_html.text: raise CookieError diff --git a/cqwu/methods/webvpn/login_webvpn.py b/cqwu/methods/webvpn/login_webvpn.py index 554fdf5..f9c69f7 100644 --- a/cqwu/methods/webvpn/login_webvpn.py +++ b/cqwu/methods/webvpn/login_webvpn.py @@ -13,7 +13,9 @@ class LoginWebVPN: url = "https://webvpn.cqwu.edu.cn" ehall_html = await self.request.get(url, follow_redirects=True) self.web_ehall_path = self.get_web_vpn_host(ehall_html.url) # noqa - await self.oauth("https://authserver.cqwu.edu.cn/authserver/login?service=https://clientvpn.cqwu.edu.cn/enlink/api/client/callback/cas") + await self.oauth( + "https://authserver.cqwu.edu.cn/authserver/login?service=https://clientvpn.cqwu.edu.cn/enlink/api/client/callback/cas" + ) auth_html = await self.request.get( f"{self.web_ehall_path}/login", follow_redirects=True ) diff --git a/cqwu/methods/xg/__init__.py b/cqwu/methods/xg/__init__.py index 66a9ee9..4dd1282 100644 --- a/cqwu/methods/xg/__init__.py +++ b/cqwu/methods/xg/__init__.py @@ -22,15 +22,15 @@ class XG( raise CookieError() url = "http://xg.cqwu.edu.cn/xsfw/sys/swpubapp/indexmenu/getAppConfig.do" headers = { - 'Accept': '*/*', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,hu;q=0.5', - 'Connection': 'keep-alive', - 'Referer': 'http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51', + "Accept": "*/*", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,hu;q=0.5", + "Connection": "keep-alive", + "Referer": "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51", } params = { - 'appId': '5275772372599202', - 'appName': 'zhcptybbapp', - 'v': '021534151969418724', + "appId": "5275772372599202", + "appName": "zhcptybbapp", + "v": "021534151969418724", } await self.request.get(url, headers=headers, params=params) diff --git a/cqwu/methods/xg/get_cp.py b/cqwu/methods/xg/get_cp.py index 3644b46..4989b22 100644 --- a/cqwu/methods/xg/get_cp.py +++ b/cqwu/methods/xg/get_cp.py @@ -13,33 +13,33 @@ class GetCP: year: int = None, semester: int = None, ) -> CP: - """ 获取综合测评结果 """ + """获取综合测评结果""" xue_nian = year or self.xue_nian xue_qi = semester or self.xue_qi await self.oauth_xg() url = "http://xg.cqwu.edu.cn/xsfw/sys/emapcomponent/imexport/export.do" headers = { - 'Accept': 'application/json, text/javascript, */*; q=0.01', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,hu;q=0.5', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'Origin': 'http://xg.cqwu.edu.cn', - 'Referer': 'http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51', - 'X-Requested-With': 'XMLHttpRequest', + "Accept": "application/json, text/javascript, */*; q=0.01", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,hu;q=0.5", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "Origin": "http://xg.cqwu.edu.cn", + "Referer": "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51", + "X-Requested-With": "XMLHttpRequest", } data = { - 'app': 'zhcptybbapp', - 'contextPath': 'http://xg.cqwu.edu.cn/xsfw', - 'module': 'modules', - 'page': 'cpjgcx', - 'action': 'cpjgcxbgdz', - 'containerId': 'cpjg_grid', - 'CPXN': str(xue_nian), - 'CPXQ': str(xue_qi), - 'filename': '综合测评结果', - 'colnames': 'XH,XM,CPXN,CPXQ,DWDM,DZ_ZYFX,BJDM,ZCJ,BJPM,BJRS,ZYNJPM,ZYNJRS,FS1,FS10,FS11,FS12,' - 'XZNJ,DZ_BJPM,DZ_ZYPM', + "app": "zhcptybbapp", + "contextPath": "http://xg.cqwu.edu.cn/xsfw", + "module": "modules", + "page": "cpjgcx", + "action": "cpjgcxbgdz", + "containerId": "cpjg_grid", + "CPXN": str(xue_nian), + "CPXQ": str(xue_qi), + "filename": "综合测评结果", + "colnames": "XH,XM,CPXN,CPXQ,DWDM,DZ_ZYFX,BJDM,ZCJ,BJPM,BJRS,ZYNJPM,ZYNJRS,FS1,FS10,FS11,FS12," + "XZNJ,DZ_BJPM,DZ_ZYPM", } html = await self.request.post(url, headers=headers, data=data) if html.status_code != 200: diff --git a/cqwu/methods/xg/get_public_cp.py b/cqwu/methods/xg/get_public_cp.py index 785b83b..4691111 100644 --- a/cqwu/methods/xg/get_public_cp.py +++ b/cqwu/methods/xg/get_public_cp.py @@ -12,25 +12,27 @@ class GetPublicCP: page_number: int = 1, total: bool = True, ) -> List[PublicCPRaw]: - """ 获取综合测评公示结果 """ + """获取综合测评公示结果""" await self.oauth_xg() async def get_public_cp_raw(page_size_: int, page_number_: int) -> CPGS: - url = "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/modules/cpgs/cpgs_cpgsbg.do" + url = ( + "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/modules/cpgs/cpgs_cpgsbg.do" + ) headers = { - 'Accept': 'application/json, text/javascript, */*; q=0.01', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,hu;q=0.5', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'Origin': 'http://xg.cqwu.edu.cn', - 'Referer': 'http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51', - 'X-Requested-With': 'XMLHttpRequest', + "Accept": "application/json, text/javascript, */*; q=0.01", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,hu;q=0.5", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "Origin": "http://xg.cqwu.edu.cn", + "Referer": "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51", + "X-Requested-With": "XMLHttpRequest", } data = { - 'querySetting': '[]', - 'pageSize': str(page_size_), - 'pageNumber': str(page_number_), + "querySetting": "[]", + "pageSize": str(page_size_), + "pageNumber": str(page_number_), } html = await self.request.post(url, headers=headers, data=data) if html.status_code != 200: @@ -59,7 +61,10 @@ class GetPublicCP: return_datas.extend(html_raw_datas.rows) if html_raw_datas.totalSize == 0: break - elif html_raw_datas.pageNumber * html_raw_datas.pageSize >= html_raw_datas.totalSize: + elif ( + html_raw_datas.pageNumber * html_raw_datas.pageSize + >= html_raw_datas.totalSize + ): break else: page_number += 1 diff --git a/cqwu/methods/xg/get_score.py b/cqwu/methods/xg/get_score.py index fdbcbb5..0930999 100644 --- a/cqwu/methods/xg/get_score.py +++ b/cqwu/methods/xg/get_score.py @@ -7,9 +7,9 @@ from cqwu import types class GetScore: async def get_score( - self: "cqwu.Client", - year: int = None, - semester: int = None, + self: "cqwu.Client", + year: int = None, + semester: int = None, ) -> List["types.Score"]: """ 获取期末成绩 @@ -20,16 +20,18 @@ class GetScore: year = year or self.xue_nian semester = semester or (self.xue_qi + 1) await self.oauth_xg() - query_url = "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/modules/cjcx/cjcxbgdz.do" + query_url = ( + "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/modules/cjcx/cjcxbgdz.do" + ) headers = { - 'Accept': 'application/json, text/javascript, */*; q=0.01', - 'Accept-Language': 'zh-CN,zh;q=0.9', - 'Connection': 'keep-alive', - 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - 'Origin': 'http://xg.cqwu.edu.cn', - 'Referer': 'http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do', - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63', - 'X-Requested-With': 'XMLHttpRequest', + "Accept": "application/json, text/javascript, */*; q=0.01", + "Accept-Language": "zh-CN,zh;q=0.9", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "Origin": "http://xg.cqwu.edu.cn", + "Referer": "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63", + "X-Requested-With": "XMLHttpRequest", } query_data = [ { @@ -47,12 +49,12 @@ class GetScore: "builderList": "cbl_m_List", "builder": "m_value_equal", "value": str(semester), - } + }, ] data = { - 'querySetting': json.dumps(query_data), - 'pageSize': '100', - 'pageNumber': '1', + "querySetting": json.dumps(query_data), + "pageSize": "100", + "pageNumber": "1", } html = await self.request.post(query_url, headers=headers, data=data) data = [types.Score(**i) for i in html.json()["datas"]["cjcxbgdz"]["rows"]] diff --git a/cqwu/types/__init__.py b/cqwu/types/__init__.py index a2d5139..fb032f2 100644 --- a/cqwu/types/__init__.py +++ b/cqwu/types/__init__.py @@ -4,5 +4,10 @@ from .epay import PayBill, PayBillPage from .exam import AiExam from .pay import PayProject, PayProjectDetail, PayUser from .score import Score -from .score_detail import ScoreDetail, ScoreDetailInfo, ScoreDetailCourse, ScoreDetailTotal +from .score_detail import ( + ScoreDetail, + ScoreDetailInfo, + ScoreDetailCourse, + ScoreDetailTotal, +) from .user import User diff --git a/cqwu/types/calendar.py b/cqwu/types/calendar.py index 3e4aea1..02d4a3f 100644 --- a/cqwu/types/calendar.py +++ b/cqwu/types/calendar.py @@ -29,5 +29,11 @@ class AiCourse(BaseModel): "weeks": ",".join(list(map(str, self.weeks))), "day": self.day, "style": "", - "sections": ",".join(list(map(str, list(range(self.start_num, self.start_num + self.sections))))) + "sections": ",".join( + list( + map( + str, list(range(self.start_num, self.start_num + self.sections)) + ) + ) + ), } diff --git a/cqwu/types/cp.py b/cqwu/types/cp.py index 7975559..c657cc7 100644 --- a/cqwu/types/cp.py +++ b/cqwu/types/cp.py @@ -40,77 +40,77 @@ class PublicCPRaw(BaseModel): @property def id(self) -> int: - """ 学号 """ + """学号""" return int(self.XH) @property def name(self) -> str: - """ 姓名 """ + """姓名""" return self.XM @property def yuan_xi(self) -> str: - """ 院系 """ + """院系""" return self.DWDM_DISPLAY @property def zhuan_ye(self) -> str: - """ 专业 """ + """专业""" return self.ZYDM_DISPLAY @property def class_name(self) -> str: - """ 班级 """ + """班级""" return self.BJDM_DISPLAY @property def total_score(self) -> float: - """ 总成绩 """ + """总成绩""" return float(self.ZCJ) @property def class_rank(self) -> int: - """ 班级排名 """ + """班级排名""" return int(self.BJPM) @property def grade_rank(self) -> int: - """ 专业年级排名 """ + """专业年级排名""" return int(self.ZYNJPM) @property def dysz(self) -> float: - """ 德育素质分 """ + """德育素质分""" return float(self.FS1) @property def zysz(self) -> float: - """ 智育素质测评 """ + """智育素质测评""" return float(self.FS10) @property def cxsz(self) -> float: - """ 创新素质测评 """ + """创新素质测评""" return float(self.FS11) @property def wtsz(self) -> float: - """ 文体素质 """ + """文体素质""" return float(self.FS12) @property def dysz_raw(self) -> float: - """ 德育原始成绩 """ + """德育原始成绩""" return float(self.DYYSCJ) @property def wtsz_raw(self) -> float: - """ 文体原始成绩 """ + """文体原始成绩""" return float(self.WTYSCJ) @property def cxsz_raw(self) -> float: - """ 创新原始成绩 """ + """创新原始成绩""" return float(self.CXYSCJ) diff --git a/cqwu/types/exam.py b/cqwu/types/exam.py index c991265..76e5f63 100644 --- a/cqwu/types/exam.py +++ b/cqwu/types/exam.py @@ -3,7 +3,28 @@ from typing import Tuple from pydantic import BaseModel -from cqwu.enums import ExamRound + +class ExamType: + supplementation: str + """ 开学补缓考 """ + graduate: str + """ 毕业年级考试 """ + scattered: str + """ 分散考试 """ + concentration: str + """ 集中考试 """ + + def __init__( + self, + supplementation: str = "", + graduate: str = "", + scattered: str = "", + concentration: str = "", + ): + self.supplementation = supplementation + self.graduate = graduate + self.scattered = scattered + self.concentration = concentration class AiExam(BaseModel): @@ -17,25 +38,33 @@ class AiExam(BaseModel): """ 考试地点 """ seat: str """ 座位号 """ - exam_round: ExamRound + exam_round: str """ 考试轮次 """ @property def name_no_id(self) -> str: - """ 获取课程名称(去除课程编号) """ + """获取课程名称(去除课程编号)""" return self.name.split("]")[-1] @property def days_left(self) -> int: - """ 获取距离考试的天数 """ + """获取距离考试的天数""" return (self.get_time()[0] - datetime.datetime.now()).days def get_time(self) -> Tuple[datetime.datetime, datetime.datetime]: - """ 获取格式化后的考试时间 """ + """获取格式化后的考试时间""" # 2023-06-25(18周 星期日)09:00-11:00 day = datetime.datetime.strptime(self.time.split("(")[0], "%Y-%m-%d") - start_time = datetime.datetime.strptime(self.time.split(")")[1].split("-")[0], "%H:%M") - start_time = datetime.datetime(day.year, day.month, day.day, start_time.hour, start_time.minute) - end_time = datetime.datetime.strptime(self.time.split(")")[1].split("-")[1], "%H:%M") - end_time = datetime.datetime(day.year, day.month, day.day, end_time.hour, end_time.minute) + start_time = datetime.datetime.strptime( + self.time.split(")")[1].split("-")[0], "%H:%M" + ) + start_time = datetime.datetime( + day.year, day.month, day.day, start_time.hour, start_time.minute + ) + end_time = datetime.datetime.strptime( + self.time.split(")")[1].split("-")[1], "%H:%M" + ) + end_time = datetime.datetime( + day.year, day.month, day.day, end_time.hour, end_time.minute + ) return start_time, end_time diff --git a/cqwu/types/score.py b/cqwu/types/score.py index 713c4a2..95388ab 100644 --- a/cqwu/types/score.py +++ b/cqwu/types/score.py @@ -2,7 +2,8 @@ from pydantic import BaseModel class Score(BaseModel): - """ 成绩类 """ + """成绩类""" + KCMC: str XF: float ZCJ: float @@ -14,30 +15,30 @@ class Score(BaseModel): @property def name(self) -> str: - """ 课程名称 """ + """课程名称""" return self.KCMC @property def credit(self) -> float: - """ 学分 """ + """学分""" return self.XF @property def score(self) -> float: - """ 成绩 """ + """成绩""" return self.ZCJ @property def grade_point(self) -> float: - """ 绩点 """ + """绩点""" return float(self.JD) @property def year(self) -> int: - """ 学年 """ + """学年""" return int(self.XN) @property def semester(self) -> int: - """ 学期 """ + """学期""" return int(self.XQ) diff --git a/setup.py b/setup.py index ccaef98..fccf988 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh: setuptools.setup( name="cqwu", # 用自己的名替换其中的YOUR_USERNAME_ - version="0.0.17", # 包版本号,便于维护版本 + version="0.0.18", # 包版本号,便于维护版本 author="omg-xtao", # 作者,可以写自己的姓名 author_email="xtao@xtaolink.cn", # 作者联系方式,可写自己的邮箱地址 description="A cqwu ehall client.", # 包的简述 @@ -18,7 +18,7 @@ setuptools.setup( "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], - python_requires='>=3.8', # 对python的最低版本要求 + python_requires=">=3.8", # 对python的最低版本要求 install_requires=[ "httpx", "lxml",