From 127fcf2df99b17bb7bfe6ad352cf2b0efdb64da6 Mon Sep 17 00:00:00 2001 From: brian <90851827+wobeitaoleshigexuruo@users.noreply.github.com> Date: Thu, 23 Mar 2023 22:31:05 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Support=20ZHCP=20(#8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: brian --- cqwu/client.py | 3 +- cqwu/methods/epay/__init__.py | 2 + cqwu/methods/epay/get_pay_bill.py | 27 ++++++++++ cqwu/methods/xg/__init__.py | 2 + cqwu/methods/xg/get_cp.py | 88 +++++++++++++++++++++++++++++++ cqwu/types/cp.py | 19 +++++++ cqwu/types/epay.py | 20 +++++++ requirements.txt | 1 + setup.py | 3 +- 9 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 cqwu/methods/epay/get_pay_bill.py create mode 100644 cqwu/methods/xg/get_cp.py create mode 100644 cqwu/types/cp.py create mode 100644 cqwu/types/epay.py diff --git a/cqwu/client.py b/cqwu/client.py index 1f563e1..bc7d09d 100644 --- a/cqwu/client.py +++ b/cqwu/client.py @@ -15,6 +15,7 @@ class Client(Methods): password: str = None, cookie: str = None, cookie_file_path: str = "cookie.txt", + timeout: int = 10, ): self.username = username self.password = password @@ -24,7 +25,7 @@ class Client(Methods): self.auth_host = "http://authserver.cqwu.edu.cn" self.web_ehall_path = "" self.cookies = Cookies() - self.request = AsyncClient() + self.request = AsyncClient(timeout=timeout) self.loop = asyncio.get_event_loop() self.me: Optional[User] = None self._use_password_login = False diff --git a/cqwu/methods/epay/__init__.py b/cqwu/methods/epay/__init__.py index 892af47..efa1be1 100644 --- a/cqwu/methods/epay/__init__.py +++ b/cqwu/methods/epay/__init__.py @@ -1,9 +1,11 @@ from .gen_pay_qrcode import GenPayQrcode from .get_balance import GetBalance +from .get_pay_bill import GetPayBill class EPay( GenPayQrcode, GetBalance, + GetPayBill, ): pass diff --git a/cqwu/methods/epay/get_pay_bill.py b/cqwu/methods/epay/get_pay_bill.py new file mode 100644 index 0000000..3b27583 --- /dev/null +++ b/cqwu/methods/epay/get_pay_bill.py @@ -0,0 +1,27 @@ +import cqwu +from cqwu.errors.auth import CookieError +from cqwu.types.epay import PayBillPage + + +class GetPayBill: + async def get_pay_bill( + self: "cqwu.Client", + page_number: int = 1, + ) -> PayBillPage: + """ + 获取校园卡消费账单 + + Returns: + PayBillPage: 消费账单 + """ + url = "http://218.194.176.214:8382/epay/thirdapp/bill" + html = await self.oauth(url) + if not html: + raise CookieError() + if html.url != url: + raise CookieError() + data = await self.request.post( + "http://218.194.176.214:8382/epay/thirdapp/loadbill.json", + data={"pageno": page_number} + ) + return PayBillPage(**data.json()) diff --git a/cqwu/methods/xg/__init__.py b/cqwu/methods/xg/__init__.py index cb0af5c..fbc3092 100644 --- a/cqwu/methods/xg/__init__.py +++ b/cqwu/methods/xg/__init__.py @@ -1,7 +1,9 @@ +from .get_cp import GetCP from .get_score import GetScore class XG( + GetCP, GetScore, ): pass diff --git a/cqwu/methods/xg/get_cp.py b/cqwu/methods/xg/get_cp.py new file mode 100644 index 0000000..1b7564e --- /dev/null +++ b/cqwu/methods/xg/get_cp.py @@ -0,0 +1,88 @@ +from io import BytesIO + +import openpyxl + +import cqwu +from cqwu.errors import CookieError +from cqwu.types.cp import CP + + +class GetCP: + async def get_cp( + self: "cqwu.Client", + year: int = None, + semester: int = None, + ) -> CP: + """ 获取综合测评结果 """ + xue_nian = year or self.xue_nian + xue_qi = semester or self.xue_qi + url = "http://xg.cqwu.edu.cn/xsfw/sys/zhcptybbapp/*default/index.do#/cjcx" + html = await self.oauth(url) + if not html: + raise CookieError() + if html.url != url: + 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', + } + params = { + 'appId': '5275772372599202', + 'appName': 'zhcptybbapp', + 'v': '021534151969418724', + } + await self.request.get(url, headers=headers, params=params) + 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', + } + 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', + } + html = await self.request.post(url, headers=headers, data=data) + if html.status_code != 200: + raise CookieError() + html_data = html.json() + url = f"http://xg.cqwu.edu.cn/xsfw/sys/emapcomponent/file/getAttachmentFile/{html_data['attachment']}.do" + xlsx_file = await self.request.get(url, headers=headers) + wb = openpyxl.load_workbook(filename=BytesIO(xlsx_file.content)) + ws = wb.active + wz = ws[2] + return CP( + id=int(wz[0].value), + name=wz[1].value, + xue_nian=wz[2].value, + xue_qi=wz[3].value, + score=float(wz[7].value), + class_rank=int(wz[8].value), + class_member=int(wz[9].value), + grade_rank=int(wz[10].value), + grade_member=int(wz[11].value), + dysz=float(wz[12].value), + zysz=float(wz[13].value), + cxsz=float(wz[14].value), + wtsz=float(wz[15].value), + zysz_class_rank=int(wz[17].value), + zysz_grade_rank=int(wz[18].value), + ) diff --git a/cqwu/types/cp.py b/cqwu/types/cp.py new file mode 100644 index 0000000..59c6385 --- /dev/null +++ b/cqwu/types/cp.py @@ -0,0 +1,19 @@ +from pydantic import BaseModel + + +class CP(BaseModel): + id: int + name: str + xue_nian: str + xue_qi: str + score: float + class_rank: int + class_member: int + grade_rank: int + grade_member: int + dysz: float + zysz: float + cxsz: float + wtsz: float + zysz_class_rank: int + zysz_grade_rank: int diff --git a/cqwu/types/epay.py b/cqwu/types/epay.py new file mode 100644 index 0000000..8e1dd0b --- /dev/null +++ b/cqwu/types/epay.py @@ -0,0 +1,20 @@ +from typing import List + +from pydantic import BaseModel + + +class PayBill(BaseModel): + id: str + amount: float + tradename: str + shopname: str + paytime: int + status: int + + +class PayBillPage(BaseModel): + pageno: int + totalpage: int + retcode: int + retmsg: str + dtls: List[PayBill] diff --git a/requirements.txt b/requirements.txt index dfa27c0..3254fe3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,4 @@ beautifulsoup4==4.11.2 qrcode==7.4.2 pillow pydantic==1.10.5 +openpyxl diff --git a/setup.py b/setup.py index 4f3e864..975d861 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.8", # 包版本号,便于维护版本 + version="0.0.9", # 包版本号,便于维护版本 author="omg-xtao", # 作者,可以写自己的姓名 author_email="xtao@xtaolink.cn", # 作者联系方式,可写自己的邮箱地址 description="A cqwu ehall client.", # 包的简述 @@ -27,5 +27,6 @@ setuptools.setup( "qrcode", "pillow", "pydantic", + "openpyxl", ], )