성준영

커멘드라인에서 불릴때와 모듈료 불러졌을 때 분리 / function 에 대한 주석 추가

......@@ -5,7 +5,7 @@
var request = require('request');
var cheerio = require('cheerio');
var Promise = require('promise');
const readline = require('readline');
var readline = require('readline');
var https = require('https');
var querystring = require('querystring');
var fs = require('fs');
......@@ -14,6 +14,16 @@ var fs = require('fs');
var j = request.jar();
request = request.defaults({jar: j});
/**
* @author sungjunyoung
* @description klas에 로그인해서 세션을 받습니다.
* 3초가 넘게 응답이 없으면 klas 서버 오류,
* 쿠키를 받지 못했을 경우 로그인 에러를 반환합니다.
* @param id
* @param pw
* @returns {*|Promise}
*/
exports.login = function (id, pw) {
return new Promise(function (resolve, reject) {
request({
......@@ -23,17 +33,22 @@ exports.login = function (id, pw) {
timeout: 3000
}, function (err, res, body) {
if (err) {
reject('timeout');
reject('클라스 요청 응답시간이 너무 길어요.');
} else if (j.getCookies("https://klas.khu.ac.kr").length === 0) {
reject('login_error');
reject('로그인에 실패했습니다!');
} else {
resolve(body);
resolve('success');
}
})
});
};
/**
* @author sungjunyoung
* @description login 세션을 가지고 현재 수강중인 강의 리스트를 보여주는 페이지에 접근합니다.
* 해당 페이지의 html 소스를 반환합니다.
* @returns {*|Promise}
*/
exports.getLecture = function () {
return new Promise(function (resolve, reject) {
......@@ -42,7 +57,8 @@ exports.getLecture = function () {
method: "GET"
}, function (err, res, body) {
if (err) {
reject(err);
console.log(err);
reject('파싱 중 에러가 발생했어요!');
} else {
resolve(body);
}
......@@ -50,6 +66,13 @@ exports.getLecture = function () {
})
};
/**
* @author sungjunyoung
* @description getLecture 에서 받은 페이지 소스에서 강의 이름과 강의실로 가는 링크를 파싱합니다.
* lectureLinkList 에 오브젝트 리스트 형태로 결과를 반환합니다.
* @param getLectureBody
* @returns {*|Promise}
*/
exports.getLectureLink = function (getLectureBody) {
return new Promise(function (resolve, reject) {
......@@ -71,11 +94,20 @@ exports.getLectureLink = function (getLectureBody) {
lectureLinkList[i].link = 'https://klas.khu.ac.kr' + $(this).attr('href')
});
console.log(lectureLinkList);
resolve(lectureLinkList);
})
};
/**
* @author sungjunyoung
* @description lectureLinkList [{lectureName (string), link (string)}] 를 받고 강의를 선택합니다. 그에대한 강의실 link (string) 를 리턴합니다.
* @param {Object[]} lectureLinkList - 강좌명, 강의실을 포함하는 리스트들
* @param lectureLinkList[].lectureName - 강의명 [강의코드]
* @param lectureLinkList[].link - 강의실 link
* @returns {*|Promise}
*/
exports.selectLecture = function (lectureLinkList) {
const rl = readline.createInterface({
......@@ -129,8 +161,8 @@ exports.getClassPageBody = function (lectureLink) {
} else {
resolve(body);
}
})
})
});
});
};
exports.findFiles = function (classPageBody) {
......@@ -152,7 +184,7 @@ exports.findFiles = function (classPageBody) {
});
resolve(fileArr);
})
});
};
exports.getSelectedFiles = function (fileArr, lb) {
......@@ -169,11 +201,11 @@ exports.getSelectedFiles = function (fileArr, lb) {
var downloadIndex = fileArr.length - lectureBefore - 1;
if (downloadIndex < 0) {
reject('no reference files');
reject('이 날에는 강의자료가 없네요!');
}
resolve(fileArr[downloadIndex]);
})
});
};
exports.downloadSelectedFile = function (selectedFile, path) {
......@@ -203,6 +235,6 @@ exports.downloadSelectedFile = function (selectedFile, path) {
});
})
})
};
\ No newline at end of file
});
});
};
......
......@@ -2,39 +2,62 @@
var args = require('args');
var functions = require('./functions');
var os = require('os');
args
.option('id', '[필수] 학번을 입력합니다.')
.option('pw', '[필수] 비밀번호를 입력합니다. 절대 악용되지 않습니다.')
.option('lectureBefore', '[선택] 몇번째 전 강좌의 자료를 다운받을지 선택합니다. Default 는 0 입니다.')
.option('downloadPath', '[선택] 자료를 다운받을 경로를 선택합니다.');
const flags = args.parse(process.argv);
if (!flags.id) {
console.log('id is required!');
return;
} else if (!flags.pw) {
console.log('pw is required!');
return;
}
// var os = require('os');
if(require.main === module){
// 커멘드 라인 상에서 직접적으로 불려졌을 때
args
.option('id', '[필수] 학번을 입력합니다.')
.option('pw', '[필수] 비밀번호를 입력합니다. 로컬 PC 에서만 사용하기 때문에 안전합니다 ^^.')
.option('downloadPath', '[선택] 자료를 다운받을 경로를 입력합니다. (default 는 ~/Downloads 입니다.)');
const flags = args.parse(process.argv);
if (!flags.id) {
console.log('학번(id) 가 필요해요!');
return;
} else if (!flags.pw) {
console.log('비밀번호(pw) 가 필요해요!');
return;
} else {
functions.login(flags.id, flags.pw)
.then(functions.getLecture)
.then(functions.getLectureLink)
.then(functions.selectLecture)
.then(functions.getClassPageBody)
.then(functions.findFiles)
.then(function (fileArr) {
return functions.getSelectedFiles(fileArr, flags.lectureBefore);
})
.then(function (selectedFile) {
// console.log(selectedFile);
functions.downloadSelectedFile(selectedFile);
})
.catch(function (err) {
console.log(err);
});
}
} else {
// 모듈로 불려졌을때 (준비중)
// module.exports = {
//
// getLectureList: function (id, pw, callback) {
// functions.login(id, pw)
// .then(functions.getLecture)
// .then(functions.getLectureLink)
// .then(function(lectureList){
// callback(lectureList);
// })
// }
//
// };
}
functions.login(flags.id, flags.pw)
.then(functions.getLecture)
.then(functions.getLectureLink)
.then(functions.selectLecture)
.then(functions.getClassPageBody)
.then(functions.findFiles)
.then(function (fileArr) {
return functions.getSelectedFiles(fileArr, flags.lectureBefore);
})
.then(function (selectedFile) {
functions.downloadSelectedFile(selectedFile, flags.downloadPath);
})
.catch(function (err) {
console.log(err);
});
......
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/7.3.0/bin/node',
1 verbose cli '/usr/local/bin/npm',
1 verbose cli 'publish' ]
2 info using npm@3.10.10
3 info using node@v7.3.0
4 verbose publish [ '.' ]
5 silly cache add args [ '.', null ]
6 verbose cache add spec .
7 silly cache add parsed spec Result {
7 silly cache add raw: '.',
7 silly cache add scope: null,
7 silly cache add escapedName: null,
7 silly cache add name: null,
7 silly cache add rawSpec: '.',
7 silly cache add spec: '/Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader',
7 silly cache add type: 'directory' }
8 verbose addLocalDirectory /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz not in flight; packing
9 verbose correctMkdir /Users/junyoung/.npm correctMkdir not in flight; initializing
10 info lifecycle klas-file-downloader@0.0.3~prepublish: klas-file-downloader@0.0.3
11 silly lifecycle klas-file-downloader@0.0.3~prepublish: no script for prepublish, continuing
12 verbose tar pack [ '/Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz',
12 verbose tar pack '/Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader' ]
13 verbose tarball /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz
14 verbose folder /Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader
15 verbose addLocalTarball adding from inside cache /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz
16 verbose correctMkdir /Users/junyoung/.npm correctMkdir not in flight; initializing
17 silly cache afterAdd klas-file-downloader@0.0.3
18 verbose afterAdd /Users/junyoung/.npm/klas-file-downloader/0.0.3/package/package.json not in flight; writing
19 verbose correctMkdir /Users/junyoung/.npm correctMkdir not in flight; initializing
20 verbose afterAdd /Users/junyoung/.npm/klas-file-downloader/0.0.3/package/package.json written
21 silly publish { name: 'klas-file-downloader',
21 silly publish version: '0.0.3',
21 silly publish description: 'Project that download lecture reference files from Klas',
21 silly publish main: 'index.js',
21 silly publish scripts: { test: 'echo "Error: no test specified" && exit 1' },
21 silly publish repository:
21 silly publish { type: 'git',
21 silly publish url: 'git+https://github.com/sungjunyoung/klas-file-downloader.git' },
21 silly publish keywords: [ 'klas', 'file', 'download', 'lecture' ],
21 silly publish author: { name: 'sungjunyoung' },
21 silly publish license: 'MIT',
21 silly publish bugs: { url: 'https://github.com/sungjunyoung/klas-file-downloader/issues' },
21 silly publish bin: { klasFileDownloader: './index.js' },
21 silly publish homepage: 'https://sungjunyoung.github.io',
21 silly publish dependencies:
21 silly publish { args: '^2.4.1',
21 silly publish cheerio: '^0.22.0',
21 silly publish fs: '0.0.1-security',
21 silly publish promise: '^7.1.1',
21 silly publish querystring: '^0.2.0',
21 silly publish request: '^2.81.0' },
21 silly publish readme: '\n> # **IN-DEVELOPING**\n\n# klas-file-downloader\n\n경희대학교 클라스의 강의실 페이지에서 강의자료를 다운받는 npm 패키지입니다.\n\n\n## INSTALL\n\n```\nnpm install -g klasFileDownloader \n```\n\n## USAGE\n\n> **WARNING!!** 패스워드가 @ 이외의 특수문자를 포함하고 있다면, 패스워드 앞에 \\ 를 붙여주어야 합니다. \n\n```\nklasFileDownloader -i 2012104095 -p \\!123123\\*123\n```\n\n\n---\nMIT License\n\nCopyright (c) 2017 Junyoung, Sung\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the "Software"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n',
21 silly publish readmeFilename: 'README.md',
21 silly publish gitHead: 'f63d4d6214ea2d6abbdf2787afa1b9261b9009ff',
21 silly publish _id: 'klas-file-downloader@0.0.3',
21 silly publish _shasum: 'caee90301dde3dc1d87971fb49149ab4276c4871',
21 silly publish _from: '.' }
22 verbose getPublishConfig undefined
23 silly mapToRegistry name klas-file-downloader
24 silly mapToRegistry using default registry
25 silly mapToRegistry registry https://registry.npmjs.org/
26 silly mapToRegistry data Result {
26 silly mapToRegistry raw: 'klas-file-downloader',
26 silly mapToRegistry scope: null,
26 silly mapToRegistry escapedName: 'klas-file-downloader',
26 silly mapToRegistry name: 'klas-file-downloader',
26 silly mapToRegistry rawSpec: '',
26 silly mapToRegistry spec: 'latest',
26 silly mapToRegistry type: 'tag' }
27 silly mapToRegistry uri https://registry.npmjs.org/klas-file-downloader
28 verbose publish registryBase https://registry.npmjs.org/
29 silly publish uploading /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz
30 verbose request uri https://registry.npmjs.org/klas-file-downloader
31 verbose request sending authorization for write operation
32 info attempt registry request try #1 at 8:57:26 PM
33 verbose request using bearer token for auth
34 verbose request id d6c4649ba2332349
35 http request PUT https://registry.npmjs.org/klas-file-downloader
36 http 403 https://registry.npmjs.org/klas-file-downloader
37 verbose headers { 'content-type': 'application/json',
37 verbose headers 'cache-control': 'max-age=300',
37 verbose headers 'content-length': '95',
37 verbose headers 'accept-ranges': 'bytes',
37 verbose headers date: 'Tue, 09 May 2017 11:57:26 GMT',
37 verbose headers via: '1.1 varnish',
37 verbose headers connection: 'keep-alive',
37 verbose headers 'x-served-by': 'cache-nrt6129-NRT',
37 verbose headers 'x-cache': 'MISS',
37 verbose headers 'x-cache-hits': '0',
37 verbose headers 'x-timer': 'S1494331047.662517,VS0,VE285',
37 verbose headers vary: 'Accept-Encoding' }
38 verbose request invalidating /Users/junyoung/.npm/registry.npmjs.org/klas-file-downloader on PUT
39 error publish Failed PUT 403
40 verbose stack Error: "You cannot publish over the previously published version 0.0.3." : klas-file-downloader
40 verbose stack at makeError (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:302:12)
40 verbose stack at CachingRegistryClient.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:290:14)
40 verbose stack at Request._callback (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:210:14)
40 verbose stack at Request.self.callback (/usr/local/lib/node_modules/npm/node_modules/request/request.js:187:22)
40 verbose stack at emitTwo (events.js:106:13)
40 verbose stack at Request.emit (events.js:191:7)
40 verbose stack at Request.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/request/request.js:1048:10)
40 verbose stack at emitOne (events.js:96:13)
40 verbose stack at Request.emit (events.js:188:7)
40 verbose stack at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/request/request.js:969:12)
41 verbose statusCode 403
42 verbose pkgid klas-file-downloader
43 verbose cwd /Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader
44 error Darwin 16.5.0
45 error argv "/usr/local/Cellar/node/7.3.0/bin/node" "/usr/local/bin/npm" "publish"
46 error node v7.3.0
47 error npm v3.10.10
48 error code E403
49 error "You cannot publish over the previously published version 0.0.3." : klas-file-downloader
50 error If you need help, you may report this error at:
50 error <https://github.com/npm/npm/issues>
51 verbose exit [ 1, true ]
{
"name": "klas-file-downloader",
"version": "0.0.1",
"version": "0.0.3",
"description": "Project that download lecture reference files from Klas",
"main": "index.js",
"scripts": {
......