Skip to content

Instantly share code, notes, and snippets.

@TennyZhuang
Created September 13, 2017 14:07
Show Gist options
  • Save TennyZhuang/d367e777a7eccba3a9495ff24321527c to your computer and use it in GitHub Desktop.
Save TennyZhuang/d367e777a7eccba3a9495ff24321527c to your computer and use it in GitHub Desktop.
THU TA Learn Helper
const url = require('url');
const puppeteer = require('puppeteer');
const promisify = require('util').promisify;
const fs = require('fs');
const inquirer = require('inquirer');
const sleep = promisify(setTimeout);
const readFile = promisify(fs.readFile);
class TALearnHelper {
async open() {
this.browser = await puppeteer.launch();
}
async login() {
const page = await this.browser.newPage();
await page.goto('http://learn.tsinghua.edu.cn');
await page.evaluate(() => {
document.querySelector('input[name="userid"]').value = 'zhuangty14';
document.querySelector('input[name="userpass"]').value = 'asdfghjkl123456';
document.querySelector('form[name=form1]').submit();
});
await page.waitForNavigation();
page.close();
}
async getCourseAndAssignmentFromPage() {
const page = await this.browser.newPage();
await page.goto('http://learn.tsinghua.edu.cn/MultiLanguage/lesson/student/MyCourse.jsp');
const courses = await page.evaluate(() => {
const links = Array.from(document.querySelectorAll('#info_1 a[href^="/MultiLanguage/lesson/teacher/course_locate.jsp?"]'));
return links.map(el => ({
href: el.href,
name: el.innerText.trim(),
}));
});
courses.forEach(c => {
c.id = url.parse(c.href, true).query.course_id;
});
if (courses.length === 0) {
throw new Error('No TA Courses');
}
let course;
if (courses.length === 1) {
course = courses[0];
} else {
const res = await inquirer.prompt([{
type: 'list',
message: 'Which course?',
name: 'name',
choices: courses.map(c => c.name),
}]);
course = courses.find(c => c.name === res.name);
}
await page.goto(`http://learn.tsinghua.edu.cn/MultiLanguage/lesson/teacher/hom_wk_brw.jsp?course_id=${course.id}`);
const assignments = await page.evaluate(() => {
return Array.from(document.querySelectorAll('a[href^="hom_wk_detail.jsp"]')).map(el => ({
href: el.href,
name: el.innerText.trim(),
}));
});
assignments.forEach(a => {
a.id = url.parse(a.href, true).query.id;
});
let assignment;
if (assignments.length === 1) {
assignment = assignments[0];
} else {
const res = await inquirer.prompt([{
type: 'list',
message: 'Which assignment?',
name: 'name',
choices: assignments.map(a => a.name),
}]);
assignment = assignments.find(a => a.name === res.name);
}
return { course, assignment };
}
async getStudentList(courseId, assignmentId) {
const page = await this.browser.newPage();
await page.goto(`http://learn.tsinghua.edu.cn/MultiLanguage/lesson/teacher/hom_wk_reclist.jsp?id=${assignmentId}&course_id=${courseId}`);
const students = await page.evaluate(() => {
return Array.from(document.querySelectorAll('a[href^="hom_wk_recdetail.jsp?"]')).map(el => ({
href: el.href,
student_id: el.innerHTML,
}));
});
students.forEach(s => {
s.rec_id = url.parse(s.href, true).query.rec_id;
});
return new Map(students.map(s => {
return [s.student_id, {
rec_id: s.rec_id,
}];
}));
page.close();
}
async updateScore(courseId, recId, scoreData) {
const page = await this.browser.newPage();
await page.goto(`http://learn.tsinghua.edu.cn/MultiLanguage/lesson/teacher/hom_wk_recdetail.jsp?rec_id=${recId}&course_id=${courseId}`);
console.log(scoreData);
const { mark, remark } = scoreData;
page.on('console', (...args) => {
for (let i = 0; i < args.length; ++i)
console.log(`${i}: ${args[i]}`);
});
await page.evaluate((mark, remark) => {
document.querySelector('#post_rec_mark').value = mark;
document.querySelector('#post_rec_reply_detail').value = remark;
document.querySelector('input[name="Submit"]').click();
}, mark, remark);
await page.waitForNavigation();
}
async getScoreData() {
return JSON.parse(await readFile('score.json'));
}
async close() {
this.browser.close();
}
}
(async () => {
const helper = new TALearnHelper();
await helper.open();
try {
await helper.login();
const { course, assignment } = await helper.getCourseAndAssignmentFromPage();
const students = await helper.getStudentList(course.id, assignment.id);
const scores = await helper.getScoreData();
for (let [studentId, scoreData] of Object.entries(scores)) {
console.log(studentId);
try {
await helper.updateScore(course.id, students.get(studentId).rec_id, scoreData);
} catch (e) {
console.error(e);
}
}
// await Promise.all(Object.entries(scores).map(([studentId, scoreData]) => new Promise(async (resolve, reject) => {
// try {
// await helper.updateScore(course.id, students.get(studentId), scoreData);
// resolve();
// } catch (e) {
// console.error(e);
// reject();
// }
// })));
} catch (e) {
console.error(e);
} finally {
await helper.close();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment