UNPKG

watch12306

Version:

检测12306网站,并在有余票时候通知

166 lines (157 loc) 5.12 kB
'use strict'; const path = require('path'); const fs = require('fs'); const fileExistSync = fs.existsSync || path.existsSync; const Type = require('./lib/util/typeOf');//这里不适用node-util检查,因为官方提示很多isXXX方法会过时 const STATIONS = require('./lib/station'); const Watcher = require('./lib/watcher'); const gaze = require('gaze'); const colors = require('./lib/util/colorful'); /** * 通过中文站名获取到对应key * @param name * @returns {*|string} */ function getKeyByStationName(name){ if(!STATIONS[name||'']){ throw new Error(`没有找到名字叫'${name}'的车站!`); } return STATIONS[name||''] || name || 'undefined'; } /** * 转换中文配置中的‘包含票种’字段 * @param includeArr * @returns {*} */ function getInclude(includeArr){ let res = { resArr: [], resArrCN: [] }; if(Type.isArray(includeArr) && includeArr.length > 0){ let tkMap = { "商务座": "swz_num", "特等座": "tz_num", "一等座": "zy_num", "二等座": "ze_num", "高铁软卧": "gr_num" , "软卧": "rw_num", "硬卧": "yw_num", "软座": "rz_num", "硬座": "yz_num", "无座": "wz_num", "其他": "qt_num" }; includeArr.forEach(k=>{ if(!!tkMap[k]){ res.resArr.push(tkMap[k]); res.resArrCN.push(k); delete tkMap[k];//为了去重 } }); } // console.log(res); return res; } /** * 将中文配置转换为配置 * @param config * @returns {Object} */ function cvtConfig(config){ config = config || {}; let pollInt = parseInt(config["监控频率(分钟)"]) || 0; pollInt = pollInt < 1 ? 1 : pollInt; let includeObj = getInclude(config['包含票种']); return { name: config.name || "未命名", from: getKeyByStationName(config['出发站']), to: getKeyByStationName(config['到达站']), date: config['出发时间'], condition:{ purposeCode: config['成人票'] ? 'ADULT' : '0X00', showPrice: !!config['显示票价'], onlyShowHighSpeedRail: !!config['仅显示高铁'], include: includeObj.resArr }, pollinterval: pollInt * 60 * 1000, info:{ from: config["出发站"], to: config["到达站"], date: config['出发时间'], purposeCode: config['成人票'] ? '成人票' : '学生票', onlyShowHighSpeedRail: config['仅显示高铁']?"高铁":"普通", include: includeObj.resArrCN } }; } /** * 通过 * @param dir directory path * @returns {Array} */ function getConfigs(dir){ dir = Type.isString(dir) ? path.normalize(dir) : "./targets/"; if(!fileExistSync(dir)){ console.warn(`The directory '${dir}' is not existed!`); return []; } let configs = []; let dirs = fs.readdirSync(dir); dirs.forEach((item)=>{ let curPath = path.join(dir,item); let stat = fs.statSync(curPath); if(stat.isFile() && curPath.match(/(\.json[3,5]?)$/)){ console.log(`Watch-json: ${colors.gray(curPath.replace(/\\/g,"/"))}`); try{ let config = JSON.parse(fs.readFileSync(curPath), 'utf8'); config.name = path.basename(curPath); configs.push(cvtConfig(config)); }catch(e){ console.warn(`Get config via '${curPath}' failed!`); console.error(e); } } }); return configs; } let WTS = {}; /** * 开始监视工作 * @param configs * @param dir */ function watch(configs,dir){ if(configs.length==0){ console.log("启动失败!"); return; } configs.forEach((it)=>{ WTS[it.name] = new Watcher(it); WTS[it.name].start(); }); gaze(path.join(dir,"*.json"),null, function(err,watcher){ this.on('all', function(event, filepath) { let target = path.basename(filepath); // console.log(`${target} is ${event}`); try{ let newConfig = JSON.parse(fs.readFileSync(filepath), 'utf8'); try{ WTS[target].restart(cvtConfig(newConfig)); }catch(e2){ console.error(`重启监视器'${target}'失败!配置的json文件有问题\r\n:`,e2); } }catch(e1){ console.error(`获取配置'${target}'失败!配置的json文件有问题\r\n:`,e1); } }); }); } module.exports = { start: (dir) => { dir = dir||"./targets"; console.log(`Watch-dir: ${colors.gray(dir.replace(/\\/g,"/"))}`); watch(getConfigs(dir),dir); } }; // watch(getConfigs());