diff --git a/.gitignore b/.gitignore index 55be276..d6e4e00 100644 --- a/.gitignore +++ b/.gitignore @@ -150,5 +150,7 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +.idea/ +*.xlsx +config.py diff --git a/config.gen.py b/config.gen.py new file mode 100644 index 0000000..ed6c3f4 --- /dev/null +++ b/config.gen.py @@ -0,0 +1,3 @@ +username = "111" +password = "xxx" +sid = "xxx" diff --git a/defs/api_url.py b/defs/api_url.py new file mode 100644 index 0000000..4465d88 --- /dev/null +++ b/defs/api_url.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +import time + + +class ApiUrl: + @staticmethod + def __get_ts() -> int: + return int(time.time() * 1000) + + def id_api(self, xsid: str) -> str: + return f"http://www.cqooc.com/user/session?xsid={xsid}&ts={self.__get_ts()}" + + def info_api(self) -> str: + return f"http://www.cqooc.com/account/session/api/profile/get?ts={self.__get_ts()}" + + def get_nonce_api(self): + return f"http://www.cqooc.com/user/login?ts={self.__get_ts()}" + + @staticmethod + def login_api(username: str, hash_str: str, nonce: str, cn: str) -> str: + return ( + "http://www.cqooc.com/user/login" + + f"?username={username}&password={hash_str}" + + f"&nonce={nonce}&cnonce={cn}" + ) + + def course_api(self, ownerId: str, limit: int) -> str: + return ( + "http://www.cqooc.com/json/mcs?sortby=id&reverse=true&del=2" + + f"&courseType=2&ownerId={ownerId}&limit={limit}" + + f"&ts={self.__get_ts()}" + ) + + def lessons_api( + self, course_id: str, start: int = 0, limit: int = 100 + ) -> str: + return ( + "http://www.cqooc.com/json/mooc/lessons" + + f"?limit={limit}&start={start}&sortby=selfId&reverse=false" + + f"&courseId={course_id}&ts={self.__get_ts()}" + ) + + def lessons_status_api( + self, course_id: str, username: str, start: int = 0, limit: int = 100 + ) -> str: + return ( + "http://www.cqooc.com/json/learnLogs" + + f"?limit={limit}&start={start}&courseId={course_id}" + + f"&select=sectionId&username={username}&ts={self.__get_ts()}" + ) + + def mcs_id_api(self, owner_id: str, course_id: str) -> str: + return ( + "http://www.cqooc.com/json/mcs" + + f"?ownerId={owner_id}&courseId={course_id}" + + f"&ts={self.__get_ts()}" + ) + + def learn_log_api(self, section_id: str, username: str) -> str: + return ( + "http://www.cqooc.com/json/learnLogs" + + f"?sectionId={section_id}&username={username}" + + f"&ts={self.__get_ts()}" + ) + + def exam_list_api(self, course_id: str) -> str: + return ( + "http://www.cqooc.com/json/exam/papers" + + f"?limit=200&start=1&courseId={course_id}&select=id,title,parentId,submitEnd" + f"&ts={self.__get_ts()}" + ) + + def task_list_api(self, course_id: str) -> str: + return ( + "http://www.cqooc.com/json/tasks" + + f"?limit=200&start=1&isPublish=1&courseId={course_id}&select=id,title,pubClass,submitEnd" + + f"&ts={self.__get_ts()}" + ) + + def chapters_api(self, course_id: str) -> str: + return ( + "http://www.cqooc.com/json/chapters" + + f"?limit=200&start=1&isPublish=1&courseId={course_id}&select=id,title,parentId" + + f"&ts={self.__get_ts()}" + ) + + @staticmethod + def skip_section_api() -> str: + return "http://www.cqooc.com/learnLog/api/add" diff --git a/defs/core.py b/defs/core.py new file mode 100644 index 0000000..65f8e88 --- /dev/null +++ b/defs/core.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +from defs.request import Request +from defs.user import User +from defs.msg import Msg +from defs.test import test +from defs.processer import Processer +from defs.api_url import ApiUrl + + +class Core: + def __init__(self, username: str, pwd: str) -> None: + self.__processer = Processer() + self.__request = Request() + self.__api_url = ApiUrl() + self.__user = User(username, pwd) + + def __process_user_info(self) -> None: + id_res = self.__request.do_get( + self.__api_url.id_api(self.__user.get_xsid()) + ) + id_data = id_res.json() + self.__user.set_id(id_data["id"]) + + info_res = self.__request.do_get(self.__api_url.info_api()) + info_data = info_res.json() + self.__user.set_name(info_data["name"]) + self.__user.set_avatar( + self.__request.get_host() + info_data["headimgurl"] + ) + + def login(self) -> dict: + api = self.__api_url.get_nonce_api() + nonce_res = self.__request.do_get( + api, + { + "Referer": "http://www.cqooc.com/login", + }, + ) + data = nonce_res.json() + cn = test.cnonce() + hash_str = test.getEncodePwd( + data["nonce"] + test.getEncodePwd(self.__user.get_pwd()) + cn + ) + login_res = self.__request.do_post( + self.__api_url.login_api( + self.__user.get_username(), hash_str, data["nonce"], cn + ), + headers={ + "Referer": "http://www.cqooc.com/login", + }, + ) + data = login_res.json() + login_success = data["code"] == 0 + if login_success: + self.__user.set_xsid(data["xsid"]) + self.__request.set_headers("Cookie", f'xsid={data["xsid"]}') + self.__process_user_info() + return Msg().processing("登录成功", 200, data) + else: + return Msg().processing("登录失败,可能需要官网登录后重试", 400, data) + + def login_use_sid(self, sid: str): + self.__user.set_xsid(sid) + self.__request.set_headers("Cookie", f'xsid={sid}') + self.__process_user_info() + return Msg().processing("设置成功", 200) + + def get_user_info(self) -> dict: + return Msg().processing("登录成功", 200, self.__user.get_info()) + + def get_course(self, limit: int = 20) -> dict: + course_res = self.__request.do_get( + self.__api_url.course_api(str(self.__user.get_id()), limit), + headers={ + "Referer": "http://www.cqooc.com/my/learn", + "Host": "www.cqooc.com", + }, + ) + course_data = self.__processer.process_course_data(course_res) + self.__user.set_course_data(course_data.copy()) + return Msg().processing("获取课程成功", 200, self.__user.get_course_data()) + + def get_course_lessons(self, course_id: str) -> dict: + mcs_id_res = self.__request.do_get( + self.__api_url.mcs_id_api(str(self.__user.get_id()), course_id), + headers={ + "Referer": "http://www.cqooc.com/my/learn", + "Host": "www.cqooc.com", + }, + ) + mcs_id_data = mcs_id_res.json() + self.__user.set_mcs_id(mcs_id_data["data"][0]["id"]) + lessons_res = self.__request.do_get( + self.__api_url.lessons_api(course_id), + headers={ + "Referer": "http://www.cqooc.com/learn" + + f"/mooc/structure?id={course_id}", + "host": "www.cqooc.com", + }, + ) + lessons_status_res = self.__request.do_get( + self.__api_url.lessons_status_api( + course_id, self.__user.get_username() + ), + headers={ + "Referer": ( + "http://www.cqooc.com/learn/mooc/progress" + + f"?id={course_id}" + ), + "host": "www.cqooc.com", + }, + ) + lessons_data = self.__processer.process_lessons_data( + self.__user.get_username(), lessons_res, lessons_status_res + ) + self.__user.set_lessons_data(lessons_data.copy()) + return Msg().processing( + "获取课程课时成功", 200, self.__user.get_lessons_data() + ) + + def skip_section(self, section_id: str) -> dict: + section_data = list( + filter( + lambda d: d["id"] == section_id, + self.__user.get_lessons_data()["data"], + ) + )[0] + post_data = self.__processer.process_section_data( + section_data, self.__user.get_mcs_id() + ) + skip_res = self.__request.do_post( + self.__api_url.skip_section_api(), + data=post_data, + headers={ + "Referer": "http://www.cqooc.com/learn/mooc/structure?id=" + + section_data["courseId"], + "Host": "www.cqooc.com", + }, + ) + status_code = skip_res.json()["code"] + if status_code == 2: + return Msg().processing("已经跳过该课程", 200) + elif status_code == 0: + return Msg().processing("跳过课程成功", 200) + elif status_code == 1: + return Msg().processing("非法操作", 400) + else: + return Msg().processing("跳过课程失败", 400) + + def get_exam_info(self, course_id: str) -> dict: + exam_list_res = self.__request.do_get( + self.__api_url.exam_list_api(course_id), + headers={ + "Referer": "http://www.cqooc.com/my/learn", + "Host": "www.cqooc.com", + }, + ) + return Msg().processing( + "获取测验列表成功", 200, exam_list_res.json() + ) + + def get_task_info(self, course_id: str) -> dict: + task_list_res = self.__request.do_get( + self.__api_url.task_list_api(course_id), + headers={ + "Referer": "http://www.cqooc.com/my/learn", + "Host": "www.cqooc.com", + }, + ) + return Msg().processing( + "获取作业列表成功", 200, task_list_res.json() + ) + + def get_chapters_info(self, course_id: str) -> dict: + chapter_list_res = self.__request.do_get( + self.__api_url.chapters_api(course_id), + headers={ + "Referer": f"http://www.cqooc.com/learn/mooc/progress?id={course_id}", + "Host": "www.cqooc.com", + }, + ) + return Msg().processing( + "获取章节列表成功", 200, chapter_list_res.json() + ) diff --git a/defs/export.py b/defs/export.py new file mode 100644 index 0000000..1cce710 --- /dev/null +++ b/defs/export.py @@ -0,0 +1,44 @@ +from typing import List, Optional + +from openpyxl import Workbook, load_workbook +from os.path import isfile + +from model.course import Course +from model.exam import Exam +from model.task import Task + + +def export_exam_list(course: Course, exam_list: List[Exam], task_list: List[Task]) -> None: + if isfile("exams.xlsx"): + wb = load_workbook('exams.xlsx') + else: + # 创建一个工作簿对象 + wb = Workbook() + # 创建一个名为 课程名称 的 sheet 页 + ws = wb.create_sheet(course.title) + if "Sheet" in wb.get_sheet_names(): + wb.remove_sheet(wb["Sheet"]) + # 标题 + ws["A1"] = "课程名称" + ws["B1"] = "章节名称" + ws["C1"] = "测验名称" + ws["D1"] = "测验结束时间" + ws["E1"] = "测验结束时间戳" + # 写入 exam_list + for i, exam in enumerate(exam_list): + ws.cell(row=i + 2, column=1, value=course.title) + ws.cell(row=i + 2, column=2, value=exam.chapter) + ws.cell(row=i + 2, column=3, value=exam.title) + ws.cell(row=i + 2, column=4, value=exam.end_time) + ws.cell(row=i + 2, column=5, value=exam.submitEnd) + # 写入 task_list + for i, task in enumerate(task_list): + ws.cell(row=i + 2 + len(exam_list), column=1, value=course.title) + ws.cell(row=i + 2 + len(exam_list), column=2, value=task.chapter) + ws.cell(row=i + 2 + len(exam_list), column=3, value=task.title) + ws.cell(row=i + 2 + len(exam_list), column=4, value=task.end_time) + ws.cell(row=i + 2 + len(exam_list), column=5, value=task.submitEnd) + # 将创建的工作簿保存为 exams.xlsx + wb.save("exams.xlsx") + # 最后关闭文件 + wb.close() diff --git a/defs/msg.py b/defs/msg.py new file mode 100644 index 0000000..8b41c0a --- /dev/null +++ b/defs/msg.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +class Msg: + def __init__(self): + self.__sussess = { + "code": 200, + "status": "ok", + } + self.__fail = { + "code": 400, + "status": "fail", + } + + def processing(self, msg: str, code: int, res=None) -> dict: + if res is None: + res = {} + if code == 200: + res["code"] = self.__sussess["code"] + res["status"] = self.__sussess["status"] + res["msg"] = msg + else: + res["code"] = self.__fail["code"] + res["status"] = self.__fail["status"] + res["msg"] = msg + res["data"] = None + + return res diff --git a/defs/processer.py b/defs/processer.py new file mode 100644 index 0000000..154ece7 --- /dev/null +++ b/defs/processer.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +import json +import httpx + + +class Processer: + @staticmethod + def process_course_data(course_res: httpx.Response) -> dict: + res_course_data = json.loads(course_res.text) + course_data = {"meta": res_course_data["meta"], "data": []} + for course in res_course_data["data"]: + course_data["data"].append( + { + "courseId": course["courseId"], + "ownerId": course["ownerId"], + "title": course["course"]["title"], + } + ) + return course_data + + @staticmethod + def process_lessons_data( + username: str, + lessons_res: httpx.Response, + lessons_status_res: httpx.Response, + ) -> dict: + lessons_res_data = json.loads(lessons_res.text) + lessons_status_res_data = json.loads(lessons_status_res.text) + lessons_data = {"meta": lessons_res_data["meta"], "data": []} + for lesson in lessons_res_data["data"]: + lessons_data["data"].append( + { + "title": lesson["title"], + "sectionId": lesson["id"], + "category": lesson["category"], + "chapterId": lesson["chapterId"], + "courseId": lesson["courseId"], + "ownerId": lesson["ownerId"], + "parentId": lesson["parentId"], + "id": lesson["id"], + "username": username, + } + ) + # add status + lesson_status = [ + i["sectionId"] for i in lessons_status_res_data["data"] + ] + for lesson in lessons_data["data"]: + if lesson["sectionId"] in lesson_status: + lesson["status"] = 1 + else: + lesson["status"] = 0 + # sort by sectionId + lessons_data["data"] = sorted( + lessons_data["data"], key=lambda x: x["sectionId"] + ) + return lessons_data + + @staticmethod + def process_section_data(section_data: dict, mcs_id: str) -> dict: + post_data = {} + post_data["action"] = 0 + post_data["category"] = 2 + post_data["chapterId"] = section_data["chapterId"] + post_data["courseId"] = section_data["courseId"] + post_data["ownerId"] = int(section_data["ownerId"]) + post_data["parentId"] = mcs_id + post_data["sectionId"] = section_data["sectionId"] + post_data["username"] = section_data["username"] + return post_data diff --git a/defs/request.py b/defs/request.py new file mode 100644 index 0000000..14cb71f --- /dev/null +++ b/defs/request.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +import httpx + + +class Request: + + __host = "http://www.cqooc.com" + + def __init__(self): + self.__headers = { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" + + " AppleWebKit/537.36 (KHTML, like Gecko)" + + " Chrome/101.0.0.0 Safari/537.36", + } + self.__proxies = {} + + def set_headers(self, name: str, value: str) -> None: + self.__headers[name] = value + + def del_headers(self, name: str) -> None: + del self.__headers[name] + + def get_headers(self) -> dict: + return self.__headers + + def set_proxies(self, name: str, value: str) -> None: + self.__proxies[name] = value + + def get_proxies(self) -> dict: + return self.__proxies + + def get_host(self) -> str: + return self.__host + + def do_get( + self, url: str, headers: dict = None, proxies: dict = None + ) -> httpx.Response: + self_headers = self.__headers.copy() + if headers is not None: + for key in headers: + self_headers[key] = headers[key] + self_proxies = self.__proxies.copy() + if proxies is not None: + for key in proxies: + self_proxies[key] = proxies[key] + return httpx.get(url, headers=self_headers, proxies=self_proxies) + + def do_post( + self, + url: str, + data: dict = None, + headers: dict = None, + proxies: dict = None, + ) -> httpx.Response: + self_headers = self.__headers.copy() + if headers is not None: + for key in headers: + self_headers[key] = headers[key] + self_proxies = self.__proxies.copy() + if proxies is not None: + for key in proxies: + self_proxies[key] = proxies[key] + return httpx.post( + url, data=data, headers=self_headers, proxies=self_proxies + ) diff --git a/defs/test.py b/defs/test.py new file mode 100644 index 0000000..812d857 --- /dev/null +++ b/defs/test.py @@ -0,0 +1,1207 @@ +# -*- coding: utf-8 -*- +# flake8: noqa +__all__ = ["test"] + +# Don't look below, you will not understand this Python code :) I don't. + +from js2py.pyjs import * + +# setting scope +var = Scope(JS_BUILTINS) +set_global_object(var) + +# Code follows: +var.registers(["cnonce", "CryptoJS", "getEncodePwd"]) + + +@Js +def PyJsHoisted_cnonce_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["toHEX", "INT2HEX"]) + + @Js + def PyJsHoisted_toHEX_(v, this, arguments, var=var): + var = Scope({"v": v, "this": this, "arguments": arguments}, var) + var.registers(["h", "v"]) + var.put("h", Js("")) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(28.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(24.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(20.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(16.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(12.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(8.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(4.0)) & Js(15)) + ), + "+", + ) + var.put( + "h", + var.get("INT2HEX").get( + (PyJsBshift(var.get("v"), Js(0.0)) & Js(15)) + ), + "+", + ) + return var.get("h") + + PyJsHoisted_toHEX_.func_name = "toHEX" + var.put("toHEX", PyJsHoisted_toHEX_) + var.put( + "INT2HEX", + Js( + [ + Js("0"), + Js("1"), + Js("2"), + Js("3"), + Js("4"), + Js("5"), + Js("6"), + Js("7"), + Js("8"), + Js("9"), + Js("A"), + Js("B"), + Js("C"), + Js("D"), + Js("E"), + Js("F"), + ] + ), + ) + pass + return var.get("toHEX")( + var.get("Math").callprop( + "floor", + ( + var.get("Math").callprop("random") + * var.get("Math").callprop("pow", Js(2.0), Js(32.0)) + ), + ) + ) + var.get("toHEX")( + var.get("Math").callprop( + "floor", + ( + var.get("Math").callprop("random") + * var.get("Math").callprop("pow", Js(2.0), Js(32.0)) + ), + ) + ) + + +PyJsHoisted_cnonce_.func_name = "cnonce" +var.put("cnonce", PyJsHoisted_cnonce_) + + +@Js +def PyJsHoisted_getEncodePwd_(pwd, this, arguments, var=var): + var = Scope({"pwd": pwd, "this": this, "arguments": arguments}, var) + var.registers(["pwd", "encodePwd"]) + var.put( + "encodePwd", + var.get("CryptoJS") + .callprop("SHA256", var.get("pwd")) + .callprop("toString") + .callprop("toUpperCase"), + ) + return var.get("encodePwd") + + +PyJsHoisted_getEncodePwd_.func_name = "getEncodePwd" +var.put("getEncodePwd", PyJsHoisted_getEncodePwd_) + + +@Js +def PyJs_anonymous_0_(h, s, this, arguments, var=var): + var = Scope({"h": h, "s": s, "this": this, "arguments": arguments}, var) + var.registers( + ["t", "g", "k", "l", "s", "v", "f", "w", "h", "q", "u", "j", "x"] + ) + var.put("f", Js({})) + var.put("t", var.get("f").put("lib", Js({}))) + + @Js + def PyJs_anonymous_1_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + pass + + PyJs_anonymous_1_._set_name("anonymous") + var.put("g", PyJs_anonymous_1_) + + @Js + def PyJs_anonymous_2_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a", "c"]) + var.get("g").put("prototype", var.get("this")) + var.put("c", var.get("g").create()) + (var.get("a") and var.get("c").callprop("mixIn", var.get("a"))) + + @Js + def PyJs_anonymous_3_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + var.get("c").get("$super").get("init").callprop( + "apply", var.get("this"), var.get("arguments") + ) + + PyJs_anonymous_3_._set_name("anonymous") + ( + var.get("c").callprop("hasOwnProperty", Js("init")) + or var.get("c").put("init", PyJs_anonymous_3_) + ) + var.get("c").get("init").put("prototype", var.get("c")) + var.get("c").put("$super", var.get("this")) + return var.get("c") + + PyJs_anonymous_2_._set_name("anonymous") + + @Js + def PyJs_anonymous_4_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["a"]) + var.put("a", var.get("this").callprop("extend")) + var.get("a").get("init").callprop( + "apply", var.get("a"), var.get("arguments") + ) + return var.get("a") + + PyJs_anonymous_4_._set_name("anonymous") + + @Js + def PyJs_anonymous_5_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + pass + + PyJs_anonymous_5_._set_name("anonymous") + + @Js + def PyJs_anonymous_6_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a", "c"]) + for PyJsTemp in var.get("a"): + var.put("c", PyJsTemp) + ( + var.get("a").callprop("hasOwnProperty", var.get("c")) + and var.get("this").put( + var.get("c"), var.get("a").get(var.get("c")) + ) + ) + ( + var.get("a").callprop("hasOwnProperty", Js("toString")) + and var.get("this").put("toString", var.get("a").get("toString")) + ) + + PyJs_anonymous_6_._set_name("anonymous") + + @Js + def PyJs_anonymous_7_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + return ( + var.get("this") + .get("init") + .get("prototype") + .callprop("extend", var.get("this")) + ) + + PyJs_anonymous_7_._set_name("anonymous") + var.put( + "j", + var.get("t").put( + "Base", + Js( + { + "extend": PyJs_anonymous_2_, + "create": PyJs_anonymous_4_, + "init": PyJs_anonymous_5_, + "mixIn": PyJs_anonymous_6_, + "clone": PyJs_anonymous_7_, + } + ), + ), + ) + + @Js + def PyJs_anonymous_8_(a, c, this, arguments, var=var): + var = Scope( + {"a": a, "c": c, "this": this, "arguments": arguments}, var + ) + var.registers(["a", "c"]) + var.put("a", var.get("this").put("words", (var.get("a") or Js([])))) + var.get("this").put( + "sigBytes", + ( + var.get("c") + if (var.get("c") != var.get("s")) + else (Js(4.0) * var.get("a").get("length")) + ), + ) + + PyJs_anonymous_8_._set_name("anonymous") + + @Js + def PyJs_anonymous_9_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + return (var.get("a") or var.get("u")).callprop( + "stringify", var.get("this") + ) + + PyJs_anonymous_9_._set_name("anonymous") + + @Js + def PyJs_anonymous_10_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a", "b", "c", "d", "e"]) + var.put("c", var.get("this").get("words")) + var.put("d", var.get("a").get("words")) + var.put("b", var.get("this").get("sigBytes")) + var.put("a", var.get("a").get("sigBytes")) + var.get("this").callprop("clamp") + if var.get("b") % Js(4.0): + # for JS loop + var.put("e", Js(0.0)) + while var.get("e") < var.get("a"): + try: + var.get("c").put( + PyJsBshift((var.get("b") + var.get("e")), Js(2.0)), + ( + ( + PyJsBshift( + var.get("d").get( + PyJsBshift(var.get("e"), Js(2.0)) + ), + ( + Js(24.0) + - (Js(8.0) * (var.get("e") % Js(4.0))) + ), + ) + & Js(255.0) + ) + << ( + Js(24.0) + - ( + Js(8.0) + * ((var.get("b") + var.get("e")) % Js(4.0)) + ) + ) + ), + "|", + ) + finally: + ( + var.put("e", Js(var.get("e").to_number()) + Js(1)) + - Js(1) + ) + else: + if Js(65535.0) < var.get("d").get("length"): + # for JS loop + var.put("e", Js(0.0)) + while var.get("e") < var.get("a"): + try: + var.get("c").put( + PyJsBshift((var.get("b") + var.get("e")), Js(2.0)), + var.get("d").get( + PyJsBshift(var.get("e"), Js(2.0)) + ), + ) + finally: + var.put("e", Js(4.0), "+") + else: + var.get("c").get("push").callprop( + "apply", var.get("c"), var.get("d") + ) + var.get("this").put("sigBytes", var.get("a"), "+") + return var.get("this") + + PyJs_anonymous_10_._set_name("anonymous") + + @Js + def PyJs_anonymous_11_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["a", "c"]) + var.put("a", var.get("this").get("words")) + var.put("c", var.get("this").get("sigBytes")) + var.get("a").put( + PyJsBshift(var.get("c"), Js(2.0)), + ( + Js(4294967295.0) + << (Js(32.0) - (Js(8.0) * (var.get("c") % Js(4.0)))) + ), + "&", + ) + var.get("a").put( + "length", var.get("h").callprop("ceil", (var.get("c") / Js(4.0))) + ) + + PyJs_anonymous_11_._set_name("anonymous") + + @Js + def PyJs_anonymous_12_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["a"]) + var.put( + "a", var.get("j").get("clone").callprop("call", var.get("this")) + ) + var.get("a").put( + "words", var.get("this").get("words").callprop("slice", Js(0.0)) + ) + return var.get("a") + + PyJs_anonymous_12_._set_name("anonymous") + + @Js + def PyJs_anonymous_13_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["d", "a", "c"]) + # for JS loop + var.put("c", Js([])) + var.put("d", Js(0.0)) + while var.get("d") < var.get("a"): + try: + var.get("c").callprop( + "push", + ( + (Js(4294967296.0) * var.get("h").callprop("random")) + | Js(0.0) + ), + ) + finally: + var.put("d", Js(4.0), "+") + return var.get("q").get("init").create(var.get("c"), var.get("a")) + + PyJs_anonymous_13_._set_name("anonymous") + var.put( + "q", + var.get("t").put( + "WordArray", + var.get("j").callprop( + "extend", + Js( + { + "init": PyJs_anonymous_8_, + "toString": PyJs_anonymous_9_, + "concat": PyJs_anonymous_10_, + "clamp": PyJs_anonymous_11_, + "clone": PyJs_anonymous_12_, + "random": PyJs_anonymous_13_, + } + ), + ), + ), + ) + var.put("v", var.get("f").put("enc", Js({}))) + + @Js + def PyJs_anonymous_14_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a", "b", "c", "d", "e"]) + var.put("c", var.get("a").get("words")) + var.put("a", var.get("a").get("sigBytes")) + # for JS loop + var.put("d", Js([])) + var.put("b", Js(0.0)) + while var.get("b") < var.get("a"): + try: + var.put( + "e", + ( + PyJsBshift( + var.get("c").get( + PyJsBshift(var.get("b"), Js(2.0)) + ), + (Js(24.0) - (Js(8.0) * (var.get("b") % Js(4.0)))), + ) + & Js(255.0) + ), + ) + var.get("d").callprop( + "push", + PyJsBshift(var.get("e"), Js(4.0)).callprop( + "toString", Js(16.0) + ), + ) + var.get("d").callprop( + "push", + (var.get("e") & Js(15.0)).callprop("toString", Js(16.0)), + ) + finally: + (var.put("b", Js(var.get("b").to_number()) + Js(1)) - Js(1)) + return var.get("d").callprop("join", Js("")) + + PyJs_anonymous_14_._set_name("anonymous") + + @Js + def PyJs_anonymous_15_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["d", "a", "c", "b"]) + # for JS loop + var.put("c", var.get("a").get("length")) + var.put("d", Js([])) + var.put("b", Js(0.0)) + while var.get("b") < var.get("c"): + try: + var.get("d").put( + PyJsBshift(var.get("b"), Js(3.0)), + ( + var.get("parseInt")( + var.get("a").callprop( + "substr", var.get("b"), Js(2.0) + ), + Js(16.0), + ) + << (Js(24.0) - (Js(4.0) * (var.get("b") % Js(8.0)))) + ), + "|", + ) + finally: + var.put("b", Js(2.0), "+") + return ( + var.get("q") + .get("init") + .create(var.get("d"), (var.get("c") / Js(2.0))) + ) + + PyJs_anonymous_15_._set_name("anonymous") + var.put( + "u", + var.get("v").put( + "Hex", + Js({"stringify": PyJs_anonymous_14_, "parse": PyJs_anonymous_15_}), + ), + ) + + @Js + def PyJs_anonymous_16_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["d", "a", "c", "b"]) + var.put("c", var.get("a").get("words")) + var.put("a", var.get("a").get("sigBytes")) + # for JS loop + var.put("d", Js([])) + var.put("b", Js(0.0)) + while var.get("b") < var.get("a"): + try: + var.get("d").callprop( + "push", + var.get("String").callprop( + "fromCharCode", + ( + PyJsBshift( + var.get("c").get( + PyJsBshift(var.get("b"), Js(2.0)) + ), + ( + Js(24.0) + - (Js(8.0) * (var.get("b") % Js(4.0))) + ), + ) + & Js(255.0) + ), + ), + ) + finally: + (var.put("b", Js(var.get("b").to_number()) + Js(1)) - Js(1)) + return var.get("d").callprop("join", Js("")) + + PyJs_anonymous_16_._set_name("anonymous") + + @Js + def PyJs_anonymous_17_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["d", "a", "c", "b"]) + # for JS loop + var.put("c", var.get("a").get("length")) + var.put("d", Js([])) + var.put("b", Js(0.0)) + while var.get("b") < var.get("c"): + try: + var.get("d").put( + PyJsBshift(var.get("b"), Js(2.0)), + ( + ( + var.get("a").callprop("charCodeAt", var.get("b")) + & Js(255.0) + ) + << (Js(24.0) - (Js(8.0) * (var.get("b") % Js(4.0)))) + ), + "|", + ) + finally: + (var.put("b", Js(var.get("b").to_number()) + Js(1)) - Js(1)) + return var.get("q").get("init").create(var.get("d"), var.get("c")) + + PyJs_anonymous_17_._set_name("anonymous") + var.put( + "k", + var.get("v").put( + "Latin1", + Js({"stringify": PyJs_anonymous_16_, "parse": PyJs_anonymous_17_}), + ), + ) + + @Js + def PyJs_anonymous_18_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + try: + return var.get("decodeURIComponent")( + var.get("escape")( + var.get("k").callprop("stringify", var.get("a")) + ) + ) + except PyJsException as PyJsTempException: + PyJsHolder_63_93562790 = var.own.get("c") + var.force_own_put("c", PyExceptionToJs(PyJsTempException)) + try: + PyJsTempException = JsToPyException( + var.get("Error")(Js("Malformed UTF-8 data")) + ) + raise PyJsTempException + finally: + if PyJsHolder_63_93562790 is not None: + var.own["c"] = PyJsHolder_63_93562790 + else: + del var.own["c"] + del PyJsHolder_63_93562790 + + PyJs_anonymous_18_._set_name("anonymous") + + @Js + def PyJs_anonymous_19_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + return var.get("k").callprop( + "parse", + var.get("unescape")(var.get("encodeURIComponent")(var.get("a"))), + ) + + PyJs_anonymous_19_._set_name("anonymous") + var.put( + "l", + var.get("v").put( + "Utf8", + Js({"stringify": PyJs_anonymous_18_, "parse": PyJs_anonymous_19_}), + ), + ) + + @Js + def PyJs_anonymous_20_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + var.get("this").put("_data", var.get("q").get("init").create()) + var.get("this").put("_nDataBytes", Js(0.0)) + + PyJs_anonymous_20_._set_name("anonymous") + + @Js + def PyJs_anonymous_21_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + ( + (Js("string") == var.get("a", throw=False).typeof()) + and var.put("a", var.get("l").callprop("parse", var.get("a"))) + ) + var.get("this").get("_data").callprop("concat", var.get("a")) + var.get("this").put("_nDataBytes", var.get("a").get("sigBytes"), "+") + + PyJs_anonymous_21_._set_name("anonymous") + + @Js + def PyJs_anonymous_22_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a", "m", "b", "f", "c", "d", "e"]) + var.put("c", var.get("this").get("_data")) + var.put("d", var.get("c").get("words")) + var.put("b", var.get("c").get("sigBytes")) + var.put("e", var.get("this").get("blockSize")) + var.put("f", (var.get("b") / (Js(4.0) * var.get("e")))) + var.put( + "f", + ( + var.get("h").callprop("ceil", var.get("f")) + if var.get("a") + else var.get("h").callprop( + "max", + ( + (var.get("f") | Js(0.0)) + - var.get("this").get("_minBufferSize") + ), + Js(0.0), + ) + ), + ) + var.put("a", (var.get("f") * var.get("e"))) + var.put( + "b", + var.get("h").callprop( + "min", (Js(4.0) * var.get("a")), var.get("b") + ), + ) + if var.get("a"): + # for JS loop + var.put("m", Js(0.0)) + while var.get("m") < var.get("a"): + try: + var.get("this").callprop( + "_doProcessBlock", var.get("d"), var.get("m") + ) + finally: + var.put("m", var.get("e"), "+") + var.put( + "m", var.get("d").callprop("splice", Js(0.0), var.get("a")) + ) + var.get("c").put("sigBytes", var.get("b"), "-") + return var.get("q").get("init").create(var.get("m"), var.get("b")) + + PyJs_anonymous_22_._set_name("anonymous") + + @Js + def PyJs_anonymous_23_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["a"]) + var.put( + "a", var.get("j").get("clone").callprop("call", var.get("this")) + ) + var.get("a").put( + "_data", var.get("this").get("_data").callprop("clone") + ) + return var.get("a") + + PyJs_anonymous_23_._set_name("anonymous") + var.put( + "x", + var.get("t").put( + "BufferedBlockAlgorithm", + var.get("j").callprop( + "extend", + Js( + { + "reset": PyJs_anonymous_20_, + "_append": PyJs_anonymous_21_, + "_process": PyJs_anonymous_22_, + "clone": PyJs_anonymous_23_, + "_minBufferSize": Js(0.0), + } + ), + ), + ), + ) + + @Js + def PyJs_anonymous_24_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + var.get("this").put( + "cfg", var.get("this").get("cfg").callprop("extend", var.get("a")) + ) + var.get("this").callprop("reset") + + PyJs_anonymous_24_._set_name("anonymous") + + @Js + def PyJs_anonymous_25_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + var.get("x").get("reset").callprop("call", var.get("this")) + var.get("this").callprop("_doReset") + + PyJs_anonymous_25_._set_name("anonymous") + + @Js + def PyJs_anonymous_26_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + var.get("this").callprop("_append", var.get("a")) + var.get("this").callprop("_process") + return var.get("this") + + PyJs_anonymous_26_._set_name("anonymous") + + @Js + def PyJs_anonymous_27_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + (var.get("a") and var.get("this").callprop("_append", var.get("a"))) + return var.get("this").callprop("_doFinalize") + + PyJs_anonymous_27_._set_name("anonymous") + + @Js + def PyJs_anonymous_28_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + + @Js + def PyJs_anonymous_29_(c, d, this, arguments, var=var): + var = Scope( + {"c": c, "d": d, "this": this, "arguments": arguments}, var + ) + var.registers(["d", "c"]) + return ( + var.get("a") + .get("init") + .create(var.get("d")) + .callprop("finalize", var.get("c")) + ) + + PyJs_anonymous_29_._set_name("anonymous") + return PyJs_anonymous_29_ + + PyJs_anonymous_28_._set_name("anonymous") + + @Js + def PyJs_anonymous_30_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + + @Js + def PyJs_anonymous_31_(c, d, this, arguments, var=var): + var = Scope( + {"c": c, "d": d, "this": this, "arguments": arguments}, var + ) + var.registers(["d", "c"]) + return ( + var.get("w") + .get("HMAC") + .get("init") + .create(var.get("a"), var.get("d")) + .callprop("finalize", var.get("c")) + ) + + PyJs_anonymous_31_._set_name("anonymous") + return PyJs_anonymous_31_ + + PyJs_anonymous_30_._set_name("anonymous") + var.get("t").put( + "Hasher", + var.get("x").callprop( + "extend", + Js( + { + "cfg": var.get("j").callprop("extend"), + "init": PyJs_anonymous_24_, + "reset": PyJs_anonymous_25_, + "update": PyJs_anonymous_26_, + "finalize": PyJs_anonymous_27_, + "blockSize": Js(16.0), + "_createHelper": PyJs_anonymous_28_, + "_createHmacHelper": PyJs_anonymous_30_, + } + ), + ), + ) + var.put("w", var.get("f").put("algo", Js({}))) + return var.get("f") + + +PyJs_anonymous_0_._set_name("anonymous") +var.put( + "CryptoJS", (var.get("CryptoJS") or PyJs_anonymous_0_(var.get("Math"))) +) + + +@Js +def PyJs_anonymous_32_(h, this, arguments, var=var): + var = Scope({"h": h, "this": this, "arguments": arguments}, var) + var.registers( + ["t", "a", "g", "u", "k", "l", "v", "f", "w", "h", "q", "s", "j", "x"] + ) + # for JS loop + var.put("s", var.get("CryptoJS")) + var.put("f", var.get("s").get("lib")) + var.put("t", var.get("f").get("WordArray")) + var.put("g", var.get("f").get("Hasher")) + var.put("f", var.get("s").get("algo")) + var.put("j", Js([])) + var.put("q", Js([])) + + @Js + def PyJs_anonymous_33_(a, this, arguments, var=var): + var = Scope({"a": a, "this": this, "arguments": arguments}, var) + var.registers(["a"]) + return ( + Js(4294967296.0) * (var.get("a") - (var.get("a") | Js(0.0))) + ) | Js(0.0) + + PyJs_anonymous_33_._set_name("anonymous") + var.put("v", PyJs_anonymous_33_) + var.put("u", Js(2.0)) + var.put("k", Js(0.0)) + while Js(64.0) > var.get("k"): + pass + + class JS_BREAK_LABEL_61(Exception): + pass + + try: + var.put("l", var.get("u")) + # for JS loop + var.put("x", var.get("h").callprop("sqrt", var.get("l"))) + var.put("w", Js(2.0)) + while var.get("w") <= var.get("x"): + try: + if (var.get("l") % var.get("w")).neg(): + var.put("l", Js(1.0).neg()) + raise JS_BREAK_LABEL_61("Breaked") + finally: + ( + var.put("w", Js(var.get("w").to_number()) + Js(1)) + - Js(1) + ) + var.put("l", Js(0.0).neg()) + except JS_BREAK_LABEL_61: + pass + ( + var.get("l") + and PyJsComma( + PyJsComma( + ( + (Js(8.0) > var.get("k")) + and var.get("j").put( + var.get("k"), + var.get("v")( + var.get("h").callprop( + "pow", var.get("u"), Js(0.5) + ) + ), + ) + ), + var.get("q").put( + var.get("k"), + var.get("v")( + var.get("h").callprop( + "pow", var.get("u"), (Js(1.0) / Js(3.0)) + ) + ), + ), + ), + (var.put("k", Js(var.get("k").to_number()) + Js(1)) - Js(1)), + ) + ) + (var.put("u", Js(var.get("u").to_number()) + Js(1)) - Js(1)) + + var.put("a", Js([])) + + @Js + def PyJs_anonymous_34_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers([]) + var.get("this").put( + "_hash", + var.get("t") + .get("init") + .create(var.get("j").callprop("slice", Js(0.0))), + ) + + PyJs_anonymous_34_._set_name("anonymous") + + @Js + def PyJs_anonymous_35_(c, d, this, arguments, var=var): + var = Scope( + {"c": c, "d": d, "this": this, "arguments": arguments}, var + ) + var.registers( + [ + "p", + "n", + "k", + "l", + "g", + "m", + "b", + "f", + "c", + "h", + "d", + "r", + "e", + "j", + ] + ) + # for JS loop + var.put("b", var.get("this").get("_hash").get("words")) + var.put("e", var.get("b").get("0")) + var.put("f", var.get("b").get("1")) + var.put("m", var.get("b").get("2")) + var.put("h", var.get("b").get("3")) + var.put("p", var.get("b").get("4")) + var.put("j", var.get("b").get("5")) + var.put("k", var.get("b").get("6")) + var.put("l", var.get("b").get("7")) + var.put("n", Js(0.0)) + while Js(64.0) > var.get("n"): + try: + if Js(16.0) > var.get("n"): + var.get("a").put( + var.get("n"), + ( + var.get("c").get((var.get("d") + var.get("n"))) + | Js(0.0) + ), + ) + else: + var.put("r", var.get("a").get((var.get("n") - Js(15.0)))) + var.put("g", var.get("a").get((var.get("n") - Js(2.0)))) + + def PyJs_LONG_36_(var=var): + return ( + ( + ( + ( + ( + (var.get("r") << Js(25.0)) + | PyJsBshift(var.get("r"), Js(7.0)) + ) + ^ ( + (var.get("r") << Js(14.0)) + | PyJsBshift( + var.get("r"), Js(18.0) + ) + ) + ) + ^ PyJsBshift(var.get("r"), Js(3.0)) + ) + + var.get("a").get((var.get("n") - Js(7.0))) + ) + + ( + ( + ( + (var.get("g") << Js(15.0)) + | PyJsBshift(var.get("g"), Js(17.0)) + ) + ^ ( + (var.get("g") << Js(13.0)) + | PyJsBshift(var.get("g"), Js(19.0)) + ) + ) + ^ PyJsBshift(var.get("g"), Js(10.0)) + ) + ) + var.get("a").get((var.get("n") - Js(16.0))) + + var.get("a").put(var.get("n"), PyJs_LONG_36_()) + var.put( + "r", + ( + ( + ( + ( + var.get("l") + + ( + ( + ( + (var.get("p") << Js(26.0)) + | PyJsBshift( + var.get("p"), Js(6.0) + ) + ) + ^ ( + (var.get("p") << Js(21.0)) + | PyJsBshift( + var.get("p"), Js(11.0) + ) + ) + ) + ^ ( + (var.get("p") << Js(7.0)) + | PyJsBshift( + var.get("p"), Js(25.0) + ) + ) + ) + ) + + ( + (var.get("p") & var.get("j")) + ^ ((~var.get("p")) & var.get("k")) + ) + ) + + var.get("q").get(var.get("n")) + ) + + var.get("a").get(var.get("n")) + ), + ) + var.put( + "g", + ( + ( + ( + ( + (var.get("e") << Js(30.0)) + | PyJsBshift(var.get("e"), Js(2.0)) + ) + ^ ( + (var.get("e") << Js(19.0)) + | PyJsBshift(var.get("e"), Js(13.0)) + ) + ) + ^ ( + (var.get("e") << Js(10.0)) + | PyJsBshift(var.get("e"), Js(22.0)) + ) + ) + + ( + ( + (var.get("e") & var.get("f")) + ^ (var.get("e") & var.get("m")) + ) + ^ (var.get("f") & var.get("m")) + ) + ), + ) + var.put("l", var.get("k")) + var.put("k", var.get("j")) + var.put("j", var.get("p")) + var.put("p", ((var.get("h") + var.get("r")) | Js(0.0))) + var.put("h", var.get("m")) + var.put("m", var.get("f")) + var.put("f", var.get("e")) + var.put("e", ((var.get("r") + var.get("g")) | Js(0.0))) + finally: + (var.put("n", Js(var.get("n").to_number()) + Js(1)) - Js(1)) + var.get("b").put( + "0", ((var.get("b").get("0") + var.get("e")) | Js(0.0)) + ) + var.get("b").put( + "1", ((var.get("b").get("1") + var.get("f")) | Js(0.0)) + ) + var.get("b").put( + "2", ((var.get("b").get("2") + var.get("m")) | Js(0.0)) + ) + var.get("b").put( + "3", ((var.get("b").get("3") + var.get("h")) | Js(0.0)) + ) + var.get("b").put( + "4", ((var.get("b").get("4") + var.get("p")) | Js(0.0)) + ) + var.get("b").put( + "5", ((var.get("b").get("5") + var.get("j")) | Js(0.0)) + ) + var.get("b").put( + "6", ((var.get("b").get("6") + var.get("k")) | Js(0.0)) + ) + var.get("b").put( + "7", ((var.get("b").get("7") + var.get("l")) | Js(0.0)) + ) + + PyJs_anonymous_35_._set_name("anonymous") + + @Js + def PyJs_anonymous_37_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["d", "a", "e", "b"]) + var.put("a", var.get("this").get("_data")) + var.put("d", var.get("a").get("words")) + var.put("b", (Js(8.0) * var.get("this").get("_nDataBytes"))) + var.put("e", (Js(8.0) * var.get("a").get("sigBytes"))) + var.get("d").put( + PyJsBshift(var.get("e"), Js(5.0)), + (Js(128.0) << (Js(24.0) - (var.get("e") % Js(32.0)))), + "|", + ) + var.get("d").put( + ( + (PyJsBshift((var.get("e") + Js(64.0)), Js(9.0)) << Js(4.0)) + + Js(14.0) + ), + var.get("h").callprop("floor", (var.get("b") / Js(4294967296.0))), + ) + var.get("d").put( + ( + (PyJsBshift((var.get("e") + Js(64.0)), Js(9.0)) << Js(4.0)) + + Js(15.0) + ), + var.get("b"), + ) + var.get("a").put("sigBytes", (Js(4.0) * var.get("d").get("length"))) + var.get("this").callprop("_process") + return var.get("this").get("_hash") + + PyJs_anonymous_37_._set_name("anonymous") + + @Js + def PyJs_anonymous_38_(this, arguments, var=var): + var = Scope({"this": this, "arguments": arguments}, var) + var.registers(["a"]) + var.put( + "a", var.get("g").get("clone").callprop("call", var.get("this")) + ) + var.get("a").put( + "_hash", var.get("this").get("_hash").callprop("clone") + ) + var.get("returna") + + PyJs_anonymous_38_._set_name("anonymous") + var.put( + "f", + var.get("f").put( + "SHA256", + var.get("g").callprop( + "extend", + Js( + { + "_doReset": PyJs_anonymous_34_, + "_doProcessBlock": PyJs_anonymous_35_, + "_doFinalize": PyJs_anonymous_37_, + "clone": PyJs_anonymous_38_, + } + ), + ), + ), + ) + var.get("s").put( + "SHA256", var.get("g").callprop("_createHelper", var.get("f")) + ) + var.get("s").put( + "HmacSHA256", var.get("g").callprop("_createHmacHelper", var.get("f")) + ) + + +PyJs_anonymous_32_._set_name("anonymous") +PyJs_anonymous_32_(var.get("Math")) +pass +pass +pass + + +# Add lib to the module scope +test = var.to_python() diff --git a/defs/user.py b/defs/user.py new file mode 100644 index 0000000..850cd2d --- /dev/null +++ b/defs/user.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- +class User: + + __xsid = None + __id = None + __username = None + __pwd = None + __name = None + __avatar = None + __course_data = None + __lessons_data = None + __mcs_id = None + + def __init__(self, username: str, pwd: str) -> None: + self.__username = username + self.__pwd = pwd + + def set_xsid(self, xsid: str) -> None: + self.__xsid = xsid + + def get_xsid(self) -> str: + return self.__xsid + + def set_id(self, id_: int) -> None: + self.__id = id_ + + def get_id(self) -> int: + return self.__id + + def set_username(self, username: str) -> None: + self.__username = username + + def get_username(self) -> str: + return self.__username + + def set_pwd(self, pwd: str) -> None: + self.__pwd = pwd + + def get_pwd(self) -> str: + return self.__pwd + + def set_name(self, name: str) -> None: + self.__name = name + + def get_name(self) -> str: + return self.__name + + def set_avatar(self, avatar: str) -> None: + self.__avatar = avatar + + def get_avatar(self) -> str: + return self.__avatar + + def set_course_data(self, course_data: dict) -> None: + self.__course_data = course_data + + def get_course_data(self) -> dict: + return self.__course_data + + def set_lessons_data(self, lessons_data: dict) -> None: + self.__lessons_data = lessons_data + + def get_lessons_data(self) -> dict: + return self.__lessons_data + + def set_mcs_id(self, mcs_id: str) -> None: + self.__mcs_id = mcs_id + + def get_mcs_id(self) -> str: + return self.__mcs_id + + def get_info(self) -> dict: + return { + "xsid": self.__xsid, + "id": self.__id, + "username": self.__username, + "pwd": self.__pwd, + "name": self.__name, + "avatar": self.__avatar, + "mcs_id": self.__mcs_id, + "course_data": self.__course_data, + "lessons_data": self.__lessons_data, + } diff --git a/main.py b/main.py new file mode 100644 index 0000000..c81418c --- /dev/null +++ b/main.py @@ -0,0 +1,58 @@ +from coloredlogs import ColoredFormatter +from logging import getLogger, StreamHandler, CRITICAL, INFO, basicConfig +from sys import exit + +from defs.core import Core +from defs.export import export_exam_list +from model.course import get_course_list, print_course_list +from model.exam import get_exam_list +from model.task import get_task_list + +from config import username, password, sid + +logs = getLogger(__name__) +logging_format = "%(levelname)s [%(asctime)s] [%(name)s] %(message)s" +logging_handler = StreamHandler() +logging_handler.setFormatter(ColoredFormatter(logging_format)) +root_logger = getLogger() +root_logger.setLevel(CRITICAL) +root_logger.addHandler(logging_handler) +basicConfig(level=INFO) +logs.setLevel(INFO) + +core = Core(username, password) +core.login_use_sid(sid) +# 获取课程列表 +courses = core.get_course() +if courses.get("code", 0) != 200: + logs.error("获取课程列表失败") + exit(1) +course_list = get_course_list(courses.get("data", [])) +print_course_list(course_list) +if not course_list: + logs.warning("无课程") + exit(0) +# 输入需要输出的课程 +while 1: + try: + course_id = input("请输入课程ID:") + except KeyboardInterrupt: + break + course = None + for i in course_list: + if course_id == i.course_id: + course = i + break + if not course: + logs.error("课程 id 错误,请重新输入") + else: + # 获取章节列表 + chapters = core.get_chapters_info(course_id) + # 获取测验列表 + exams = core.get_exam_info(course_id) + exam_list = get_exam_list(exams.get("data", []), chapters.get("data", [])) + tasks = core.get_task_info(course_id) + task_list = get_task_list(tasks.get("data", [])) + # 导出 + export_exam_list(course, exam_list, task_list) + logs.info(f"{course.title} | 导出成功") diff --git a/model/course.py b/model/course.py new file mode 100644 index 0000000..aa5df9f --- /dev/null +++ b/model/course.py @@ -0,0 +1,28 @@ +from typing import List + + +class Course: + course_id: str = "0" + title: str = "" + owner_id: str = "0" + + def __init__(self, data: dict): + self.course_id = data.get("courseId", "0") + self.title = data.get("title", "") + self.owner_id = data.get("ownerId", "0") + + +def get_course_list(courses: List[dict]) -> List[Course]: + course_list = [] + for course in courses: + try: + course_list.append(Course(course)) + except Exception as e: + print(e) + continue + return course_list + + +def print_course_list(course_list: List[Course]) -> None: + for course in course_list: + print(f"{course.title} | {course.course_id}") diff --git a/model/exam.py b/model/exam.py new file mode 100644 index 0000000..533a92d --- /dev/null +++ b/model/exam.py @@ -0,0 +1,42 @@ +import traceback +from datetime import datetime +from typing import List + + +class Exam: + id: str = "0" + chapter: str = "" + title: str = "" + parentId: str = "0" + submitEnd: int = 0 + end_time: str = "" + + def __init__(self, data: dict): + self.id = data.get("id", "0") + self.title = data.get("title", "") + self.parentId = data.get("parentId", "0") + self.submitEnd = data.get("submitEnd", 0) / 1000 + self.end_time = datetime.strftime(datetime.fromtimestamp(self.submitEnd), '%Y-%m-%d %H:%M:%S') + + +def get_title(chapter_id: str, chapters: List[dict]) -> str: + for chapter in chapters: + if chapter.get("id", "0") == chapter_id and chapter.get("title", None) is not None: + if chapter.get("parentId", None) is None: + return chapter.get("title", "") + else: + return get_title(chapter.get("parentId"), chapters) + return "" + + +def get_exam_list(exams: List[dict], chapters: List[dict]) -> List[Exam]: + exam_list = [] + for exam in exams: + try: + exam_ = Exam(exam) + exam_.chapter = get_title(exam_.parentId, chapters) + exam_list.append(exam_) + except Exception as e: # noqa + print(traceback.format_exc()) + continue + return exam_list diff --git a/model/task.py b/model/task.py new file mode 100644 index 0000000..96787e6 --- /dev/null +++ b/model/task.py @@ -0,0 +1,29 @@ +import traceback +from datetime import datetime +from typing import List + + +class Task: + id: str = "0" + title: str = "" + chapter: str = "" + submitEnd: int = 0 + end_time: str = "" + + def __init__(self, data: dict): + self.id = data.get("id", "0") + self.chapter = data.get("chapter", {}).get("title", "") + self.title = data.get("title", "") + self.submitEnd = data.get("submitEnd", 0) / 1000 + self.end_time = datetime.strftime(datetime.fromtimestamp(self.submitEnd), '%Y-%m-%d %H:%M:%S') + + +def get_task_list(tasks: List[dict], ) -> List[Task]: + task_list = [] + for task in tasks: + try: + task_list.append(Task(task)) + except Exception as e: # noqa + print(traceback.format_exc()) + continue + return task_list diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..48b45d0 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +httpx==0.23.0 +coloredlogs==15.0.1 +Js2Py==0.71 +openpyxl==3.0.10