forked from hnu202311020126/iSmartAuto
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.9 KiB
123 lines
3.9 KiB
import json
|
|
import os
|
|
import pickle
|
|
import urllib.parse as parser
|
|
|
|
from bs4 import BeautifulSoup
|
|
from loguru import logger
|
|
from random import random, randint
|
|
|
|
from configs import configs
|
|
from .devtools import Browser
|
|
from .markdown import generate_md
|
|
from .spider import Spider
|
|
|
|
random_args = { # 不同题型对应的随机时长和分数范围
|
|
'1': { # 单选题
|
|
'time': (20, 60), # 完成时长 / 秒
|
|
'score': 1 # 得分 (归一化, 向上随机取至满分)
|
|
},
|
|
'2': { # 多选题
|
|
'time': (40, 120),
|
|
'score': 0.9
|
|
},
|
|
'3': { # 判断题
|
|
'time': (20, 50),
|
|
'score': 1
|
|
},
|
|
'4': { # 填空题
|
|
'time': (60, 180),
|
|
'score': 1
|
|
},
|
|
'6': { # 连线题
|
|
'time': (60, 180),
|
|
'score': 0.8
|
|
},
|
|
'8': { # 匹配题
|
|
'time': (30, 90),
|
|
'score': 1
|
|
},
|
|
'9': { # 口语跟读
|
|
'time': (15, 30),
|
|
'score': 0.8
|
|
},
|
|
'10': { # 短文改错
|
|
'time': (120, 180),
|
|
'score': 0.7
|
|
},
|
|
'11': { # 选词填空
|
|
'time': (30, 90),
|
|
'score': 0.9
|
|
}
|
|
}
|
|
|
|
|
|
def _random_progress(paper):
|
|
paper = BeautifulSoup(paper, 'lxml-xml')
|
|
questions = paper.select('element[knowledge]:has(> question_type)')
|
|
if questions:
|
|
total_score = 0
|
|
my_score, my_time = 0, 0
|
|
for que in questions:
|
|
qt_type = que.select_one('question_type').text
|
|
qt_score = int(que.select_one('question_score').text)
|
|
total_score += qt_score
|
|
|
|
rate = 1 - (1 - random_args[qt_type]['score']) * random()
|
|
my_score += qt_score * rate
|
|
my_time += randint(*random_args[qt_type]['time'])
|
|
return int(100 * my_score / total_score), my_time
|
|
return 100, 5
|
|
|
|
|
|
async def export(): # 导出某书籍的答案
|
|
browser = Browser.connect()
|
|
page = await browser.wait_for_book()
|
|
params = dict(parser.parse_qsl(parser.urlsplit(page.url).query))
|
|
# noinspection PyTypeChecker
|
|
book_id, course_id = params['bookId'], params['courseId']
|
|
if not os.path.exists(f'.cache/books/{book_id}'):
|
|
async with Spider() as spider:
|
|
await spider.login(**configs['user'])
|
|
book = await spider.book_info(book_id)
|
|
book['courseId'] = course_id
|
|
tasks = await spider.get_tasks(book, tree=True)
|
|
await spider.download_tree(tasks)
|
|
with open(f'.cache/books/{book_id}/Tree.pck', 'rb') as fp:
|
|
generate_md(pickle.load(fp))
|
|
|
|
|
|
async def finish(): # 直接完成某书籍的任务
|
|
browser = Browser.connect()
|
|
page = await browser.wait_for_book()
|
|
params = dict(parser.parse_qsl(parser.urlsplit(page.url).query))
|
|
# noinspection PyTypeChecker
|
|
book_id, course_id = params['bookId'], params['courseId']
|
|
async with Spider() as spider:
|
|
await spider.login(**configs['user'])
|
|
if not os.path.exists(f'.cache/books/{book_id}'):
|
|
book = await spider.book_info(book_id)
|
|
book['courseId'] = course_id
|
|
tasks = await spider.get_tasks(book, tree=True)
|
|
await spider.download_tree(tasks)
|
|
user_id = (await spider.get_user())['data']['uid']
|
|
logger.info('正在提交任务...')
|
|
for file in os.listdir(f'.cache/books/{book_id}'):
|
|
paper_id, ext = os.path.splitext(file)
|
|
if ext != '.json':
|
|
continue
|
|
|
|
with open(f'.cache/books/{book_id}/{file}') as fp:
|
|
data = json.load(fp)
|
|
task = data['task']
|
|
paper = data['paperData']
|
|
score, time = _random_progress(paper)
|
|
result = await page.submit(book_id, task['chapterId'], task['id'], score, time, 100, user_id)
|
|
if result['wasThrown'] or not result['result']['value']:
|
|
logger.warning(f'任务 {task["name"]} [paperId: {paper_id}] 可能提交失败,请留意最终结果!')
|
|
logger.info('全部提交完成!')
|
|
|
|
|
|
async def finish_all(): # Todo: 全刷了?
|
|
pass
|