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.

122 lines
4.2 KiB

from random import uniform, randint
from bs4 import BeautifulSoup
from loguru import logger
3 years ago
from configs import configs
from .devtools import Browser
from .spider import Spider
PLACEHOLDER = '. '
_paper_config = configs['paper']
async def list_books(detail):
async with Spider() as spider:
await spider.login(**configs['user'])
courses = await spider.get_courses()
for cr in courses:
if detail:
hint = f'{cr["courseName"]} ({cr["teacherName"]})'
else:
hint = cr['courseName']
print(hint)
books = await spider.get_books(cr["courseId"])
for book in books:
if detail:
hint = f'> [{cr["courseId"]}#{book["bookId"]}] {book["bookName"]} ({book["percent"]}%)'
else:
hint = f'> {book["bookName"]}'
print(PLACEHOLDER + hint)
async def _random(spider, paper_id): # 随机的分数和学习时长
paper = BeautifulSoup((await spider.get_paper(paper_id))['paperData'], 'lxml-xml')
questions = paper.select('element[knowledge]:has(> question_type)')
if not questions:
return 100, 5
total = 0
score, time = 0, 0
for q in questions:
q_type = int(q.select_one('question_type').text)
q_score = float(q.select_one('question_score').text)
total += q_score
ranges = _paper_config['random-score']
if q_type <= len(ranges) and (r := ranges[q_type-1]) is not None:
if not isinstance(ranges[q_type-1], list):
r = [r, r]
score += q_score * uniform(*r)
else:
q_no = q.select_one('question_no').text
logger.warning(f'T{q_no}:未知的题型!')
if (r := _paper_config['defaults']) == 'pause':
score += float(input('请手动输入该题得分 [0-1]'))
else: # defaults
score += q_score * uniform(*r)
3 years ago
time += randint(*_paper_config['random-time'])
3 years ago
return int(100 * score / total), time
3 years ago
async def _flash(course_id, book_id, spider):
async def dfs(node, depth=0):
task = node.task
print(PLACEHOLDER * depth + task['name'])
if _paper_config['skip-finished'] and task['unitStudyPercent'] == 100:
print(PLACEHOLDER * depth + '# Skipped')
return
if 'paperId' in task: # 如果有任务则提交
chapter_id = task['chapterId']
task_id = task['id']
score, time = await _random(spider, task['paperId'])
result = await page.submit(book_id, chapter_id, task_id, score, time, 100, user_id)
if result['wasThrown'] or not result['result']['value']:
logger.warning(f'任务 {task["name"]} 可能提交失败,请留意最终结果!')
for ch in node.child:
await dfs(ch, depth + 1)
browser = await Browser.connect()
page = await browser.wait_for_page(r'https?://pc\.ismartin\.com.*')
# With Spider
await spider.login(**configs['user'])
user_id = (await spider.user_info())['data']['uid']
book_type = (await spider.book_info(book_id))['bookType']
root = await spider.get_tasks(book_id, book_type, course_id)
await dfs(root)
async def flash_by_id(identity):
async with Spider() as spider:
await _flash(*identity.split('#'), spider)
async def flash_current(): # 对当前课程或书籍执行刷课
browser = await Browser.connect()
course_id, book_id = await browser.get_current()
async with Spider() as spider:
if book_id:
await _flash(course_id, book_id, spider)
else:
await spider.login(**configs['user'])
books = await spider.get_books(course_id)
for book in books:
await _flash(course_id, book['bookId'], spider)
3 years ago
async def flash_all():
3 years ago
async with Spider() as spider:
await spider.login(**configs['user'])
courses = await spider.get_courses()
for course in courses:
course_id = course['courseId']
books = await spider.get_books(course_id)
for book in books:
await _flash(course_id, book['bookId'], spider)