Created
September 13, 2017 14:07
-
-
Save TennyZhuang/d367e777a7eccba3a9495ff24321527c to your computer and use it in GitHub Desktop.
THU TA Learn Helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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