def handle_library_search_by_isbn(isbn: str): page = request.args.get('page', '1') if len(isbn) != 13 and len(isbn) != 10: custom_abort(-6, '无效的 ISBN 编号') if len(isbn) == 10: isbn = isbn[:1] + '-' + isbn[1:5] + '-' + isbn[5:9] + '-' + isbn[9:] else: isbn = isbn[:3] + '-' + isbn[3:4] + '-' + isbn[4:8] + '-' + isbn[ 8:12] + '-' + isbn[12:] url = 'http://222-31-39-3-8080-p.vpn.nuc1941.top:8118//pft/wxjs/bk_s_Q_fillpage.asp?q=标准编号=[[%s*]]' \ '&nmaxcount=&nSetPageSize=10&orderby=&Research=1&page=%s&opt=1' % (quote(isbn), page) content = session.get(url, headers={ 'Cookie': global_values.get_value('vpn_cookie') }).content.decode('utf-8') re_book_ids = re.findall(r"ShowItem\('([0-9]*)'\)", content) records_group = re.search('共([0-9]*)条记录', content) if not records_group: custom_abort(-6, '无结果') records = records_group.group(1) pool = Pool(10) book_list = pool.map(book_detail, re_book_ids) return { 'code': 0, 'data': { 'records': records, 'page': page, 'recordsPerPage': len(book_list), 'list': book_list } }
def handle_list_grade(user_id: int): post_data = {'userId': user_id, 'timestamp': int(time.time() * 1000)} post_data['sign'] = sign(post_data) res_json = session.post(config.grade_list_url, data=post_data).json() if res_json['returnCode'] != '200': custom_abort(-1, res_json['returnMsg']) return {'code': 0, 'data': res_json['data']}
def handle_library_search_by_name(keyword: str): book_type = request.args.get('type', '正题名') page = request.args.get('page', '1') url = 'http://222-31-39-3-8080-p.vpn.nuc1941.top:8118//pft/wxjs/bk_s_Q_fillpage.asp?q=%s=[[*%s*]]' \ '&nmaxcount=&nSetPageSize=10&orderby=&Research=1&page=%s&opt=1' % (quote(book_type), quote(keyword), page) content = session.get(url, headers={ 'Cookie': global_values.get_value('vpn_cookie') }).content.decode('utf-8') re_book_ids = re.findall(r"ShowItem\('([0-9]*)'\)", content) records_group = re.search('共([0-9]*)条记录', content) if not records_group: custom_abort(-6, '无结果') records = records_group.group(1) pool = Pool(10) book_list = pool.map(book_detail, re_book_ids) return { 'code': 0, 'data': { 'records': records, 'page': page, 'recordsPerPage': len(book_list), 'list': book_list } }
def handle_export_grade(): name = request.args.get('name', type=str) passwd = request.args.get('passwd', type=str) file_type = request.args.get('type', 'pdf') cookies = login(name, passwd) if file_type == 'pdf': post_data1 = {'gsdygx': '10353-zw-mrgs1'} pdf_message = session.post(config.pdf_url1, data=post_data1, cookies=cookies).content.decode() if pdf_message.find('可打印') == -1: custom_abort(-3, pdf_message) pdf_url = session.post(config.pdf_url2, data=post_data1, cookies=cookies).content.decode().replace( '\\', '').replace('\"', '') if pdf_url.find('成功') != -1: pdf_content = session.get('http://222.31.49.139' + pdf_url.split('#')[0], cookies=cookies).content file_name = 'files/%s-grade-%s.pdf' % \ (name, hashlib.md5((name + app_secret).encode('utf-8')).hexdigest()[:5]) with open(file_name, 'wb') as pdf_file: pdf_file.write(pdf_content) upload_to_qiniu(file_name) return { 'code': 0, 'data': { 'url': 'https://blog-cdn.dreace.top/' + file_name } } custom_abort(-3, pdf_url) else: xls_content = session.post(config.excel_url, data=config.post_data, cookies=cookies).content file_name = 'files/%s-grade-%s.xls' % \ (name, hashlib.md5((name + app_secret).encode('utf-8')).hexdigest()[:5]) with open(file_name, 'wb') as xls_file: xls_file.write(xls_content) upload_to_qiniu(file_name) return { 'code': 0, 'message': { 'url': 'https://blog-cdn.dreace.top/' + file_name } }
def decorated_function(*args, **kwargs) -> dict: user_key = request.args['key'] + request.path if redis_request_limit.llen(user_key) < limit_per_minute: redis_request_limit.lpush(user_key, time.time()) else: first_time = redis_request_limit.lindex(user_key, -1) if time.time() - float(first_time) < 60: logging.warning("{} 达到请求限制({}次/分钟)".format( request.args['key'], 10)) custom_abort(-5, '操作过频繁') else: redis_request_limit.lpush(user_key, time.time()) redis_request_limit.ltrim(user_key, 0, limit_per_minute - 1) redis_request_limit.expire(user_key, 60) return f(*args, **kwargs)
def handle_balance(name: str): session = requests.session() session.proxies = proxies session.get(config.url1) time_now = datetime.now(cst_tz) local_time_hour = time_now.timetuple()[3] if local_time_hour >= 22 or local_time_hour <= 1: custom_abort(-6, '非服务时间') post_data = { 'pageMark': '3', 'paymentContent': 'busiCode=%s' % name, 'queryPageinfo': '1', 'netType': '181', 'IEVersionFlag': 'ANDROID-CHROME-0', 'ComputID': '98', 'PlatFlag': '8', 'areaCodeTmp': '0502', 'areaNameTmp': '̫ԭ', 'dse_menuid': 'PM002', 'IN_PAYITEMCODE': 'PJ120012021000010048', 'cmd': '', 'isShortpay': '', 'maskFlag': '0', 'isP3bank': '0' } content = session.post(config.url2, data=post_data).content soups = bs4.BeautifulSoup(content, 'html.parser') balance = soups.find(id='item37') name = soups.find(id='item31') if not balance: custom_abort(-6, '没有数据') return { 'code': 0, 'data': { 'balance': balance.text, 'name': name.text, 'time': time_now.strftime('%Y-%m-%d %H:%M') } }
def handle_login(): name = request.args.get('name', type=str) passwd = request.args.get('passwd', type=str) if not name or not passwd: custom_abort(-2, '账号密码不能为空') post_data = { 'uname': base64.b64encode(key.encrypt(pad(name))).decode(), 'pwd': base64.b64encode(key.encrypt(pad(passwd))).decode(), 'code': request.args.get('captcha', type=str), 'timestamp': int(time.time() * 1000) } post_data['sign'] = sign(post_data) login_resp = session.post( config.login_url, data=post_data, allow_redirects=False, cookies={'JSESSIONID': request.args.get('JSESSIONID', type=str)}) login_res = login_resp.json() if login_res['returnMsg']: custom_abort(1, login_res['returnMsg']) info_res = session.post(config.info_url, cookies=login_resp.cookies.get_dict()).json() return {'code': 0, 'data': {'id': info_res['data'][0]['sysUser']['id']}}
def login(name: str, passwd: str, disable_cache=False) -> dict: """ 使用用户名和密码登录教务系统 :param name: 用户名(学号) :param passwd: 密码 :param disable_cache: 是否禁用缓存的 cookie,首次登录时应当禁用,防止错误密码也能“登录成功” :return 成功登录后的 cookies """ if not name or not passwd: custom_abort(-3, '账号密码不能为空') if name.strip() != name: custom_abort(-3, '用户名包含空字符') if not disable_cache: cookie_json = redis_session.get("cookie" + name) if cookie_json: cookies = json.loads(cookie_json) r = session.get(config.test_url, allow_redirects=False, cookies=cookies) if r.status_code == 200: redis_session.expire("cookie" + name, 43200) return cookies else: redis_session.delete("cookie" + name) index_response = session.get(config.index_url) csrf_token = re.search('name="csrftoken" value="(.*?)"', index_response.content.decode()).group(1) cookies = index_response.cookies.get_dict() public_key_dict = session.get(config.public_key_url, cookies=cookies).json() public_key = rsa.PublicKey(base_64_to_int(public_key_dict["modulus"]), base_64_to_int(public_key_dict["exponent"])) post_data = { 'csrftoken': csrf_token, 'yhm': name, 'mm': base64.b64encode(rsa.encrypt(passwd.encode(), public_key)) } login_response = session.post(config.index_url, data=post_data, allow_redirects=False, cookies=cookies) if login_response.content.decode().find("不正确") != -1: custom_abort(-3, '账号或密码错误') cookies['JSESSIONID'] = login_response.cookies.get('JSESSIONID') redis_session.set("cookie" + name, json.dumps(cookies), ex=43200) return cookies
def decorated_function(*args, **kwargs) -> dict: if "sign" not in request.args.keys() or \ "ts" not in request.args.keys() or \ "key" not in request.args.keys(): logging.warning('缺少参数') custom_abort(-2, '请求签名校验失败') if int(request.args["ts"]) + 3e5 < int(time.time() * 1000): logging.warning('{} 参数签名过期'.format(request.args['key'])) custom_abort(-2, '参数签名过期') need_check_args = check_args.union({'ts', 'key'}) arg_list = [] for k in sorted(dict(request.args)): if k in need_check_args: arg_list.append(k + "=" + quote(request.args[k], safe="~()*!.\'")) url_args = quote(request.path) + "&".join(arg_list) # print(url_args) # print(hashlib.md5((url_args + app_secret).encode("utf-8")).hexdigest()) if request.args["sign"] != hashlib.md5( (url_args + app_secret).encode("utf-8")).hexdigest(): logging.warning('{} 请求签名校验失败'.format(request.args['key'])) custom_abort(-2, '请求签名校验失败') return f(*args, **kwargs)
def decorated_function(): custom_abort(-4, '未开发查询')
def handle_class_timetable(class_name: str): if not class_name: custom_abort(-6, '空关键词') cookies = {} try: cookies = login(NAME, PASSWD) except CustomHTTPException: logging.warning('全局账号登录失败') custom_abort(-6, '查询失败') post_data = { 'xnm': '2020', 'xqm': '3', 'xqh_id': '01', 'njdm_id': '', 'jg_id': '', 'zyh_id': '', 'zyfx_id': '', 'bh_id': class_name, '_search': 'false', 'queryModel.showCount': '1', } pre_data_json = session.post(config.pre_class_timetable_url, data=post_data, cookies=cookies).json() if not pre_data_json['items']: custom_abort(-6, '无效的班级号') post_data = { 'xnm': '2020', 'xqm': '3', 'xnmc': '2020-2021', 'xqmmc': '1', 'xqh_id': '01', 'njdm_id': pre_data_json['items'][0]['njdm_id'], 'zyh_id': pre_data_json['items'][0]['zyh_id'], 'bh_id': class_name, 'tjkbzdm': '1', 'tjkbzxsdm': '0', # 'zxszjjs': True } timetable = session.post(config.class_timetable_url, data=post_data, cookies=cookies).json() timetable_items = [] cnt = 0 name_dict = {} for index, table in enumerate(timetable['kbList']): spited = table['jcor'].split('-') if table['kcmc'] not in name_dict: name_dict[table['kcmc']] = cnt cnt += 1 timetable_items.append({ 'name': table.get('kcmc', ''), 'teacher': table.get('xm'), # 哪几周上课,形如”9-14周“ 'weeks': table.get('zcd', ''), 'color': name_dict[table['kcmc']], # 星期几 'dayOfWeek': table.get('xqj', ''), # 第几小节开始 'start': int(spited[0]), # 上几小节 'length': int(spited[1]) - int(spited[0]) + 1, 'building': table.get('xqmc'), 'classroom': table.get('cdmc') }) for d in timetable['sjkList']: timetable_items.append({'name': d['sjkcgs']}) return {'code': 0, 'data': timetable_items}
def decorated_function(*args, **kwargs) -> dict: if not global_values.get_value("proxy_status_ok"): custom_abort(-2, '无法连接学校网络') return f(*args, **kwargs)