Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

Commit

Permalink
fix: move cli interface to entry point
Browse files Browse the repository at this point in the history
  • Loading branch information
beetcb committed Feb 17, 2021
1 parent 39cb286 commit d6978c7
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 319 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Init school and users
run: |
npm i
node ./init.js
node ./index.js
env: # Or as an environment variable
users: ${{ secrets.users }}
school: ${{ secrets.school }}
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pipeline {
stage('签到') {
steps {
sh 'npm i'
sh 'node ./init.js'
sh 'node ./index.js'
sh 'date'
}
}
Expand Down
9 changes: 5 additions & 4 deletions TEST/dcampus.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,28 @@ const school = conf.get('school')
// wait * minute for signing
await sleep(0)
// Sign in
await signIn()
const logs = await signIn()
// Log out config path
console.table({ 'config-path': conf.path })
console.table(logs)
})()

async function sleep(timeout) {
return new Promise(r => setTimeout(r, timeout * 1000 * 60))
}

async function signIn() {
const logs = {}
// sign in asynchronizedly with promise all and diff instance of signApp class
await Promise.all(
users.map(async i => {
const cookie = i.cookie
? { campusphere: i.cookie }
: conf.get(`cookie.${i.alias || i.username}`)

const sign = new signApp(school, i)

await sign.signInfo(cookie)
await sign.signWithForm()
logs[i.alias || i.id] = sign.result
})
)
return logs
}
13 changes: 9 additions & 4 deletions campusphere/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,21 @@ exports.signApp = class signApp extends campusphereApp {
extraFieldItems,
}
headers['Cpdaily-Extension'] = this.extention(form)
console.log(form)
res = await fetch(signApi.sign, {
headers,
method: 'POST',
body: JSON.stringify(form),
})
res = await res.json()
console.log(
`${this.user.alias || this.user.username} 的签到结果: ${res.message}`
)

const logInfo = {
签到结果: res.message,
签到地址: form.position,
签到时间: new Date().toTimeString(),
真实信息: signedStuInfo.userName
}
// store result
this.result = logInfo
}

signAtHomePos() {
Expand Down
301 changes: 289 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const conf = require('./init')

const login = require('./crawler/casLogIn')
#!/usr/bin/env node
const Conf = require('conf')
const fetch = require('node-fetch')
const yaml = require('js-yaml')
const fs = require('fs')
const log = require('./interface/colorLog')

const login = require('./crawler/casLogIn')
const { prompt } = require('inquirer')
const { signApp } = require('./campusphere/app')

const conf = new Conf()

const school = conf.get('school')
const users = conf.get('users')

if (!users) {
log.error('未找到用户,请运行 ./init.js -u 配置')
process.exit(1)
}

/**
* Keys of this cookie Object:
* YOU CAN USE THIS COOKIE FOR EVERYTHING
Expand Down Expand Up @@ -58,8 +58,6 @@ async function handleLogin(i, storedCookie) {
}
}



function storeCookie(path, i, set) {
const name = i.alias || i.username
if (set) {
Expand All @@ -70,5 +68,284 @@ function storeCookie(path, i, set) {
log.success(`${name}: Using stored cookie`)
}
}

module.exports = { handleCookie, conf }

// Below creates CLI interface
class User {
constructor() {
this.selectType = null
}

storeUsers(loadedUsers) {
const users = users || []
const storedUsers = users.map(e => e.username)
loadedUsers = loadedUsers.filter(e => !storedUsers.includes(e.username))
conf.set('users', [...loadedUsers, ...users])
}

loadUserFromFile(path) {
let loadedUsers
if (fs.existsSync(path)) {
const doc = yaml.load(fs.readFileSync(path, 'utf8'))
if (!doc) return
loadedUsers = doc
} else {
return
}
this.storeUsers(loadedUsers)
}

loadUserFromEnv({ users }) {
if (users) {
const loadedUsers = users.split('\n').map(user => {
const [username, password, alias] = user.split(' ')
let addr = user.split('home ')[1]
addr = addr ? addr.split(' ') : null
return { username, password, alias, addr }
})
this.storeUsers(loadedUsers)
}
}

async load() {
const questions = [
{
type: 'list',
name: 'type',
message: `用户编辑: ${
conf.get('school') ? ' 学校信息已成功配置' : ' 学校信息未配置'
}\n 已有用户:${users.reduce((s, e) => {
const userInfo = e.alias || e.username
return s + ' ' + userInfo
}, '')}`,
choices: [
{
value: 1,
name: '添加用户',
},
{
value: 2,
name: '删除用户',
},
{
value: -1,
name: '取消',
},
],
},
]

const res = await prompt(questions)
this.selectType = res.type
}

async createUser() {
const users = users || []
const questions = [
{
type: 'input',
name: 'username',
message: '请输入用户名',
},
{
type: 'input',
name: 'password',
message: '请输入密码',
},
{
type: 'input',
name: 'alias',
message: '(可选)请输入用户别名',
},
{
type: 'input',
name: 'cookie',
message: '(可选,将省去登录操作)抓包到的 Cookie',
},
]

const res = await prompt(questions)

if (!users.some(e => e.username === res.username)) {
const addUser = {
username: res.username,
password: res.password,
alias: res.alias || null,
cookie: res.cookie,
}
conf.set('users', [addUser, ...users])
log.success('🎉 成功添加用户', addUser)
} else {
log.error('🙃 用户已存在')
}
}

async deleteUser() {
const users = users
const questions = [
{
type: 'list',
name: 'selection',
message: '请选择删除对象:',
choices: [
...users.map((e, idx) => ({
value: idx,
name: `${e.alias || e.user.name}`,
})),
{
value: -1,
name: '取消',
},
],
},
]

const res = await prompt(questions)
const neoUsers = users.filter((el, index) => index !== res.selection)
conf.set('users', neoUsers)

log.success('🎉 成功删除用户')
}
}

class School {
async init() {
if (!conf.get('school')) {
const questions = [
{
type: 'input',
name: 'ids',
message: '请输入学校英文简称',
},
{
type: 'list',
name: 'isSignAtHome',
message: '是否在家签到(若是,会避开学校随机选点)',
choices: [
{
value: 1,
name: '是',
},
{
value: 0,
name: '否',
},
],
},
]

let res = await prompt(questions)
const isSignAtHome = res.isSignAtHome
const school = await this.schoolApi(res.ids, isSignAtHome)

if (!isSignAtHome) school.addr = await this.schoolAddr(school.name)
conf.set('school', school)
log.success(`您的学校 ${school.name} 已完成设定`)
} else {
log.warning('学校信息已配置')
}
}

/**
* Grab school info from environment
* @param {string} name school
*/
async loadSchoolFromEnv({ school: name, users }) {
if (!conf.get('school')) {
const isSignAtHome = users.includes('home')
const school = await this.schoolApi(name, isSignAtHome)
if (!isSignAtHome) school.addr = await this.schoolAddr(name)
conf.set('school', school)
log.success(`您的学校 ${school.name} 已完成设定`)
} else {
log.warning('学校信息已配置')
}
}

/**
* Get school address & coordinates(with baidu website's ak)
* @param {string} name school
*/
async schoolAddr(name) {
let res = await fetch(
`https://api.map.baidu.com/?qt=s&wd=${encodeURIComponent(
name
)}&ak=E4805d16520de693a3fe707cdc962045&rn=10&ie=utf-8&oue=1&fromproduct=jsapi&res=api`
)
res = await res.json()
const { addr } = res.content[0]
return addr
}

/**
* Grab school endpoint from campushoy API
* @param {string} name school name
* @param {boolean} isSignAtHome
*/
async schoolApi(name, isSignAtHome) {
let res = await fetch(
`https://mobile.campushoy.com/v6/config/guest/tenant/info?ids=${name}`
).catch(err => err)
res = await JSON.parse(await res.text())

const origin = new URL(res.data[0].ampUrl).origin
const casOrigin = res.data[0].idsUrl
const schoolName = res.data[0].name
return {
name: schoolName,
casOrigin,
origin,
isSignAtHome,
login: `${casOrigin}/login?service=${encodeURIComponent(
origin
)}/portal/login`,
campusphere: `${origin}/portal/login`,
checkCaptcha: `${casOrigin}/checkNeedCaptcha.htl`,
getCaptcha: `${casOrigin}/getCaptcha.htl`,
}
}
}

;(async () => {
const argv = process.argv[2] || ''
const argv2 = process.argv[3]

switch (argv) {
case '-u':
case '--user': {
const userUlti = new User()
userUlti.loadUserFromFile('./userConf.yml')
userUlti.loadUserFromEnv(process.env)
await userUlti.load()
const type = userUlti.selectType
if (type === 1) userUlti.createUser()
if (type === 2) userUlti.deleteUser()
break
}
case '-s':
case '--school': {
new School().init()
break
}
case 'rm':
case '--remove': {
if (argv2 === 'all') conf.clear()
conf.delete(argv2)
break
}
case 'sign': {
require('./TEST/dcampus')
break
}
default: {
const env = process.env
if (env.users && env.school) {
log.warning('Loading from env!')
const userUlti = new User()
userUlti.loadUserFromEnv(env)
await new School().loadSchoolFromEnv(env)
require('./TEST/dcampus')
}
}
}
})()
Loading

0 comments on commit d6978c7

Please sign in to comment.