sdu-course-bot/src/includes.ts
2022-01-04 17:34:57 +08:00

167 行
5.6 KiB
TypeScript

import axios from 'axios'
import {appConfig} from "./config"
import * as qs from "qs"
import dayjs from "dayjs"
import {ICourse, IJsonCourse, TChannel} from "./types"
import {JsonCourseList, reqBody} from "./poll"
import axiosRetry from "axios-retry"
import tough from "tough-cookie"
import axiosCookieJarSupport from "axios-cookiejar-support"
import {strEnc} from "./des"
import {scalarOptions} from "yaml"
import * as process from "process"
let sduAxios = axios.create({
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0',
},
baseURL: 'https://bkzhjx.wh.sdu.edu.cn/',
timeout: 5000,
transformResponse: data => {
try {
return JSON.parse(data)
} catch (_e) {
return data
}
},
// maxRedirects: 10
})
axiosRetry(sduAxios, {
retries: 2,
shouldResetTimeout: true,
retryCondition: (_error) => true,
})
export async function logAndNotifyUser(text: string) {
console.log(text)
// await axios.post('https://qmsg.zendee.cn/send/' + appConfig.qmsgKey, qs.stringify({
// msg: text
// }), {
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
// }
// })
await axios.post('https://' + appConfig.tgApiDomain + '/bot' + appConfig.tgApiKey + '/sendMessage', qs.stringify({
chat_id: appConfig.tgChatId,
text: text
}))
}
export function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms))
}
export function getTimeNow() {
return dayjs().format('hh:mm:ss A')
}
export function findJsonCourse(course: ICourse): IJsonCourse | undefined {
return JsonCourseList[course.channel].find(single => single.kch == course.kch && parseInt(single.kxh) == course.kxh)
}
export async function acquireCourse(course: IJsonCourse, channel: TChannel): Promise<boolean> {
let segment = ''
switch (channel) {
case 'bx':
segment = 'bxxkOper'
break
case 'xx':
segment = 'xxxkOper'
break
case 'rx':
segment = 'ggxxkxkOper'
break
}
try {
let resp = await sduAxios.get('/jsxsd/xsxkkc/' + segment + '?kcid=' + course.jx02id + '&cfbs=null&jx0404id=' + course.jx0404id + '&xkzy=&trjf=')
if (resp.data.success === true) {
return true
} else {
logAndNotifyUser(resp.data.message)
if (resp.data.message.includes('当前账号已在别处登录')) {
await resetCookie()// TODO 加锁、优化
}
return false
}
} catch (e) {
return false
}
}
export async function exitCourse(course: IJsonCourse): Promise<boolean> {
try {
let resp = await sduAxios.get('/jsxsd/xsxkjg/xstkOper?jx0404id=' + course.jx0404id)
if (resp.data.success === true) {
return true
} else {
logAndNotifyUser('[exitCourse]退课失败:' + resp.data.message)
if (resp.data.message.includes('当前账号已在别处登录')) {
await resetCookie()
}
return false
}
} catch (e) {
logAndNotifyUser('[exitCourse]网络异常,退课失败')
return false
}
}
let resetCookieLock = false
export async function resetCookie() {
if (resetCookieLock) {
console.log('resetCookie 已被锁定')
return
}
resetCookieLock = true
try {
let cookieJar = new tough.CookieJar()
let cookieAxios = axios.create({
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0'
},
timeout: 6000,
maxRedirects: 10
})
axiosCookieJarSupport(cookieAxios)
cookieAxios.defaults.jar = cookieJar
cookieAxios.defaults.withCredentials = true
await cookieAxios.get('http://bkzhjx.wh.sdu.edu.cn/sso.jsp')
let casUrl = 'https://pass.sdu.edu.cn/cas/login?service=http%3A%2F%2Fbkzhjx.wh.sdu.edu.cn%2Fsso.jsp'
let resp = await cookieAxios.get(casUrl)
let ticket = /name="lt" value="(.*?)"/.exec(resp.data)?.[1] || null
let rsa = strEnc(appConfig.username + appConfig.password + ticket, '1', '2', '3')
resp = await cookieAxios.post(casUrl, qs.stringify({
rsa,
ul: appConfig.username.length,
pl: appConfig.password.length,
lt: ticket,
execution: 'e1s1',
_eventId: 'submit'
}))
let nextUrl = 'https://bkzhjx.wh.sdu.edu.cn' + /<a href="(.*?)">进入选课/.exec(resp.data)![1]
resp = await cookieAxios.get(nextUrl)
let xkId = /jrxk\('1','(.*?)'/.exec(resp.data)![1]
nextUrl = 'https://bkzhjx.wh.sdu.edu.cn/jsxsd/xsxk/newXsxkzx?jx0502zbid=' + xkId
await cookieAxios.get(nextUrl)
await cookieAxios.get('https://bkzhjx.wh.sdu.edu.cn/jsxsd/xsxk/selectBottom?jx0502zbid=' + xkId)
let cookieString = cookieJar.getCookieStringSync('https://bkzhjx.wh.sdu.edu.cn/jsxsd/xsxk')
console.log('[cookie]取得Cookie:' + cookieString)
appConfig.cookie = cookieString
sduAxios.defaults.headers['Cookie'] = cookieString
} catch (e) {
throw e
} finally {
resetCookieLock = false
}
}
export function countStr(str: string, word: string) {
return str.split(word).length - 1
}
export {sduAxios}