성준영

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

...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
5 var request = require('request'); 5 var request = require('request');
6 var cheerio = require('cheerio'); 6 var cheerio = require('cheerio');
7 var Promise = require('promise'); 7 var Promise = require('promise');
8 -const readline = require('readline'); 8 +var readline = require('readline');
9 var https = require('https'); 9 var https = require('https');
10 var querystring = require('querystring'); 10 var querystring = require('querystring');
11 var fs = require('fs'); 11 var fs = require('fs');
...@@ -14,6 +14,16 @@ var fs = require('fs'); ...@@ -14,6 +14,16 @@ var fs = require('fs');
14 var j = request.jar(); 14 var j = request.jar();
15 request = request.defaults({jar: j}); 15 request = request.defaults({jar: j});
16 16
17 +
18 +/**
19 + * @author sungjunyoung
20 + * @description klas에 로그인해서 세션을 받습니다.
21 + * 3초가 넘게 응답이 없으면 klas 서버 오류,
22 + * 쿠키를 받지 못했을 경우 로그인 에러를 반환합니다.
23 + * @param id
24 + * @param pw
25 + * @returns {*|Promise}
26 + */
17 exports.login = function (id, pw) { 27 exports.login = function (id, pw) {
18 return new Promise(function (resolve, reject) { 28 return new Promise(function (resolve, reject) {
19 request({ 29 request({
...@@ -23,17 +33,22 @@ exports.login = function (id, pw) { ...@@ -23,17 +33,22 @@ exports.login = function (id, pw) {
23 timeout: 3000 33 timeout: 3000
24 }, function (err, res, body) { 34 }, function (err, res, body) {
25 if (err) { 35 if (err) {
26 - reject('timeout'); 36 + reject('클라스 요청 응답시간이 너무 길어요.');
27 } else if (j.getCookies("https://klas.khu.ac.kr").length === 0) { 37 } else if (j.getCookies("https://klas.khu.ac.kr").length === 0) {
28 - reject('login_error'); 38 + reject('로그인에 실패했습니다!');
29 } else { 39 } else {
30 - resolve(body); 40 + resolve('success');
31 } 41 }
32 }) 42 })
33 }); 43 });
34 }; 44 };
35 45
36 - 46 +/**
47 + * @author sungjunyoung
48 + * @description login 세션을 가지고 현재 수강중인 강의 리스트를 보여주는 페이지에 접근합니다.
49 + * 해당 페이지의 html 소스를 반환합니다.
50 + * @returns {*|Promise}
51 + */
37 exports.getLecture = function () { 52 exports.getLecture = function () {
38 53
39 return new Promise(function (resolve, reject) { 54 return new Promise(function (resolve, reject) {
...@@ -42,7 +57,8 @@ exports.getLecture = function () { ...@@ -42,7 +57,8 @@ exports.getLecture = function () {
42 method: "GET" 57 method: "GET"
43 }, function (err, res, body) { 58 }, function (err, res, body) {
44 if (err) { 59 if (err) {
45 - reject(err); 60 + console.log(err);
61 + reject('파싱 중 에러가 발생했어요!');
46 } else { 62 } else {
47 resolve(body); 63 resolve(body);
48 } 64 }
...@@ -50,6 +66,13 @@ exports.getLecture = function () { ...@@ -50,6 +66,13 @@ exports.getLecture = function () {
50 }) 66 })
51 }; 67 };
52 68
69 +/**
70 + * @author sungjunyoung
71 + * @description getLecture 에서 받은 페이지 소스에서 강의 이름과 강의실로 가는 링크를 파싱합니다.
72 + * lectureLinkList 에 오브젝트 리스트 형태로 결과를 반환합니다.
73 + * @param getLectureBody
74 + * @returns {*|Promise}
75 + */
53 exports.getLectureLink = function (getLectureBody) { 76 exports.getLectureLink = function (getLectureBody) {
54 77
55 return new Promise(function (resolve, reject) { 78 return new Promise(function (resolve, reject) {
...@@ -71,11 +94,20 @@ exports.getLectureLink = function (getLectureBody) { ...@@ -71,11 +94,20 @@ exports.getLectureLink = function (getLectureBody) {
71 lectureLinkList[i].link = 'https://klas.khu.ac.kr' + $(this).attr('href') 94 lectureLinkList[i].link = 'https://klas.khu.ac.kr' + $(this).attr('href')
72 }); 95 });
73 96
97 + console.log(lectureLinkList);
74 resolve(lectureLinkList); 98 resolve(lectureLinkList);
75 99
76 }) 100 })
77 }; 101 };
78 102
103 +/**
104 + * @author sungjunyoung
105 + * @description lectureLinkList [{lectureName (string), link (string)}] 를 받고 강의를 선택합니다. 그에대한 강의실 link (string) 를 리턴합니다.
106 + * @param {Object[]} lectureLinkList - 강좌명, 강의실을 포함하는 리스트들
107 + * @param lectureLinkList[].lectureName - 강의명 [강의코드]
108 + * @param lectureLinkList[].link - 강의실 link
109 + * @returns {*|Promise}
110 + */
79 exports.selectLecture = function (lectureLinkList) { 111 exports.selectLecture = function (lectureLinkList) {
80 112
81 const rl = readline.createInterface({ 113 const rl = readline.createInterface({
...@@ -129,8 +161,8 @@ exports.getClassPageBody = function (lectureLink) { ...@@ -129,8 +161,8 @@ exports.getClassPageBody = function (lectureLink) {
129 } else { 161 } else {
130 resolve(body); 162 resolve(body);
131 } 163 }
132 - }) 164 + });
133 - }) 165 + });
134 }; 166 };
135 167
136 exports.findFiles = function (classPageBody) { 168 exports.findFiles = function (classPageBody) {
...@@ -152,7 +184,7 @@ exports.findFiles = function (classPageBody) { ...@@ -152,7 +184,7 @@ exports.findFiles = function (classPageBody) {
152 }); 184 });
153 185
154 resolve(fileArr); 186 resolve(fileArr);
155 - }) 187 + });
156 }; 188 };
157 189
158 exports.getSelectedFiles = function (fileArr, lb) { 190 exports.getSelectedFiles = function (fileArr, lb) {
...@@ -169,11 +201,11 @@ exports.getSelectedFiles = function (fileArr, lb) { ...@@ -169,11 +201,11 @@ exports.getSelectedFiles = function (fileArr, lb) {
169 var downloadIndex = fileArr.length - lectureBefore - 1; 201 var downloadIndex = fileArr.length - lectureBefore - 1;
170 202
171 if (downloadIndex < 0) { 203 if (downloadIndex < 0) {
172 - reject('no reference files'); 204 + reject('이 날에는 강의자료가 없네요!');
173 } 205 }
174 206
175 resolve(fileArr[downloadIndex]); 207 resolve(fileArr[downloadIndex]);
176 - }) 208 + });
177 }; 209 };
178 210
179 exports.downloadSelectedFile = function (selectedFile, path) { 211 exports.downloadSelectedFile = function (selectedFile, path) {
...@@ -203,6 +235,6 @@ exports.downloadSelectedFile = function (selectedFile, path) { ...@@ -203,6 +235,6 @@ exports.downloadSelectedFile = function (selectedFile, path) {
203 235
204 }); 236 });
205 237
206 - })
207 - })
208 -};
...\ No newline at end of file ...\ No newline at end of file
238 + });
239 + });
240 +};
......
...@@ -2,39 +2,62 @@ ...@@ -2,39 +2,62 @@
2 2
3 var args = require('args'); 3 var args = require('args');
4 var functions = require('./functions'); 4 var functions = require('./functions');
5 -var os = require('os'); 5 +// var os = require('os');
6 - 6 +
7 -args 7 +
8 - .option('id', '[필수] 학번을 입력합니다.') 8 +
9 - .option('pw', '[필수] 비밀번호를 입력합니다. 절대 악용되지 않습니다.') 9 +if(require.main === module){
10 - .option('lectureBefore', '[선택] 몇번째 전 강좌의 자료를 다운받을지 선택합니다. Default 는 0 입니다.') 10 + // 커멘드 라인 상에서 직접적으로 불려졌을 때
11 - .option('downloadPath', '[선택] 자료를 다운받을 경로를 선택합니다.'); 11 +
12 - 12 + args
13 -const flags = args.parse(process.argv); 13 + .option('id', '[필수] 학번을 입력합니다.')
14 - 14 + .option('pw', '[필수] 비밀번호를 입력합니다. 로컬 PC 에서만 사용하기 때문에 안전합니다 ^^.')
15 -if (!flags.id) { 15 + .option('downloadPath', '[선택] 자료를 다운받을 경로를 입력합니다. (default 는 ~/Downloads 입니다.)');
16 - console.log('id is required!'); 16 +
17 - return; 17 + const flags = args.parse(process.argv);
18 -} else if (!flags.pw) { 18 +
19 - console.log('pw is required!'); 19 + if (!flags.id) {
20 - return; 20 + console.log('학번(id) 가 필요해요!');
21 -} 21 + return;
22 + } else if (!flags.pw) {
23 + console.log('비밀번호(pw) 가 필요해요!');
24 + return;
25 + } else {
26 + functions.login(flags.id, flags.pw)
27 + .then(functions.getLecture)
28 + .then(functions.getLectureLink)
29 + .then(functions.selectLecture)
30 + .then(functions.getClassPageBody)
31 + .then(functions.findFiles)
32 + .then(function (fileArr) {
33 + return functions.getSelectedFiles(fileArr, flags.lectureBefore);
34 + })
35 + .then(function (selectedFile) {
36 + // console.log(selectedFile);
37 + functions.downloadSelectedFile(selectedFile);
38 + })
39 + .catch(function (err) {
40 + console.log(err);
41 + });
42 + }
43 +
44 +} else {
45 + // 모듈로 불려졌을때 (준비중)
46 +
47 + // module.exports = {
48 + //
49 + // getLectureList: function (id, pw, callback) {
50 + // functions.login(id, pw)
51 + // .then(functions.getLecture)
52 + // .then(functions.getLectureLink)
53 + // .then(function(lectureList){
54 + // callback(lectureList);
55 + // })
56 + // }
57 + //
58 + // };
22 59
60 +}
23 61
24 -functions.login(flags.id, flags.pw)
25 - .then(functions.getLecture)
26 - .then(functions.getLectureLink)
27 - .then(functions.selectLecture)
28 - .then(functions.getClassPageBody)
29 - .then(functions.findFiles)
30 - .then(function (fileArr) {
31 - return functions.getSelectedFiles(fileArr, flags.lectureBefore);
32 - })
33 - .then(function (selectedFile) {
34 - functions.downloadSelectedFile(selectedFile, flags.downloadPath);
35 - })
36 - .catch(function (err) {
37 - console.log(err);
38 - });
39 62
40 63
......
1 +0 info it worked if it ends with ok
2 +1 verbose cli [ '/usr/local/Cellar/node/7.3.0/bin/node',
3 +1 verbose cli '/usr/local/bin/npm',
4 +1 verbose cli 'publish' ]
5 +2 info using npm@3.10.10
6 +3 info using node@v7.3.0
7 +4 verbose publish [ '.' ]
8 +5 silly cache add args [ '.', null ]
9 +6 verbose cache add spec .
10 +7 silly cache add parsed spec Result {
11 +7 silly cache add raw: '.',
12 +7 silly cache add scope: null,
13 +7 silly cache add escapedName: null,
14 +7 silly cache add name: null,
15 +7 silly cache add rawSpec: '.',
16 +7 silly cache add spec: '/Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader',
17 +7 silly cache add type: 'directory' }
18 +8 verbose addLocalDirectory /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz not in flight; packing
19 +9 verbose correctMkdir /Users/junyoung/.npm correctMkdir not in flight; initializing
20 +10 info lifecycle klas-file-downloader@0.0.3~prepublish: klas-file-downloader@0.0.3
21 +11 silly lifecycle klas-file-downloader@0.0.3~prepublish: no script for prepublish, continuing
22 +12 verbose tar pack [ '/Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz',
23 +12 verbose tar pack '/Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader' ]
24 +13 verbose tarball /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz
25 +14 verbose folder /Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader
26 +15 verbose addLocalTarball adding from inside cache /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz
27 +16 verbose correctMkdir /Users/junyoung/.npm correctMkdir not in flight; initializing
28 +17 silly cache afterAdd klas-file-downloader@0.0.3
29 +18 verbose afterAdd /Users/junyoung/.npm/klas-file-downloader/0.0.3/package/package.json not in flight; writing
30 +19 verbose correctMkdir /Users/junyoung/.npm correctMkdir not in flight; initializing
31 +20 verbose afterAdd /Users/junyoung/.npm/klas-file-downloader/0.0.3/package/package.json written
32 +21 silly publish { name: 'klas-file-downloader',
33 +21 silly publish version: '0.0.3',
34 +21 silly publish description: 'Project that download lecture reference files from Klas',
35 +21 silly publish main: 'index.js',
36 +21 silly publish scripts: { test: 'echo "Error: no test specified" && exit 1' },
37 +21 silly publish repository:
38 +21 silly publish { type: 'git',
39 +21 silly publish url: 'git+https://github.com/sungjunyoung/klas-file-downloader.git' },
40 +21 silly publish keywords: [ 'klas', 'file', 'download', 'lecture' ],
41 +21 silly publish author: { name: 'sungjunyoung' },
42 +21 silly publish license: 'MIT',
43 +21 silly publish bugs: { url: 'https://github.com/sungjunyoung/klas-file-downloader/issues' },
44 +21 silly publish bin: { klasFileDownloader: './index.js' },
45 +21 silly publish homepage: 'https://sungjunyoung.github.io',
46 +21 silly publish dependencies:
47 +21 silly publish { args: '^2.4.1',
48 +21 silly publish cheerio: '^0.22.0',
49 +21 silly publish fs: '0.0.1-security',
50 +21 silly publish promise: '^7.1.1',
51 +21 silly publish querystring: '^0.2.0',
52 +21 silly publish request: '^2.81.0' },
53 +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',
54 +21 silly publish readmeFilename: 'README.md',
55 +21 silly publish gitHead: 'f63d4d6214ea2d6abbdf2787afa1b9261b9009ff',
56 +21 silly publish _id: 'klas-file-downloader@0.0.3',
57 +21 silly publish _shasum: 'caee90301dde3dc1d87971fb49149ab4276c4871',
58 +21 silly publish _from: '.' }
59 +22 verbose getPublishConfig undefined
60 +23 silly mapToRegistry name klas-file-downloader
61 +24 silly mapToRegistry using default registry
62 +25 silly mapToRegistry registry https://registry.npmjs.org/
63 +26 silly mapToRegistry data Result {
64 +26 silly mapToRegistry raw: 'klas-file-downloader',
65 +26 silly mapToRegistry scope: null,
66 +26 silly mapToRegistry escapedName: 'klas-file-downloader',
67 +26 silly mapToRegistry name: 'klas-file-downloader',
68 +26 silly mapToRegistry rawSpec: '',
69 +26 silly mapToRegistry spec: 'latest',
70 +26 silly mapToRegistry type: 'tag' }
71 +27 silly mapToRegistry uri https://registry.npmjs.org/klas-file-downloader
72 +28 verbose publish registryBase https://registry.npmjs.org/
73 +29 silly publish uploading /Users/junyoung/.npm/klas-file-downloader/0.0.3/package.tgz
74 +30 verbose request uri https://registry.npmjs.org/klas-file-downloader
75 +31 verbose request sending authorization for write operation
76 +32 info attempt registry request try #1 at 8:57:26 PM
77 +33 verbose request using bearer token for auth
78 +34 verbose request id d6c4649ba2332349
79 +35 http request PUT https://registry.npmjs.org/klas-file-downloader
80 +36 http 403 https://registry.npmjs.org/klas-file-downloader
81 +37 verbose headers { 'content-type': 'application/json',
82 +37 verbose headers 'cache-control': 'max-age=300',
83 +37 verbose headers 'content-length': '95',
84 +37 verbose headers 'accept-ranges': 'bytes',
85 +37 verbose headers date: 'Tue, 09 May 2017 11:57:26 GMT',
86 +37 verbose headers via: '1.1 varnish',
87 +37 verbose headers connection: 'keep-alive',
88 +37 verbose headers 'x-served-by': 'cache-nrt6129-NRT',
89 +37 verbose headers 'x-cache': 'MISS',
90 +37 verbose headers 'x-cache-hits': '0',
91 +37 verbose headers 'x-timer': 'S1494331047.662517,VS0,VE285',
92 +37 verbose headers vary: 'Accept-Encoding' }
93 +38 verbose request invalidating /Users/junyoung/.npm/registry.npmjs.org/klas-file-downloader on PUT
94 +39 error publish Failed PUT 403
95 +40 verbose stack Error: "You cannot publish over the previously published version 0.0.3." : klas-file-downloader
96 +40 verbose stack at makeError (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:302:12)
97 +40 verbose stack at CachingRegistryClient.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:290:14)
98 +40 verbose stack at Request._callback (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/request.js:210:14)
99 +40 verbose stack at Request.self.callback (/usr/local/lib/node_modules/npm/node_modules/request/request.js:187:22)
100 +40 verbose stack at emitTwo (events.js:106:13)
101 +40 verbose stack at Request.emit (events.js:191:7)
102 +40 verbose stack at Request.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/request/request.js:1048:10)
103 +40 verbose stack at emitOne (events.js:96:13)
104 +40 verbose stack at Request.emit (events.js:188:7)
105 +40 verbose stack at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/npm/node_modules/request/request.js:969:12)
106 +41 verbose statusCode 403
107 +42 verbose pkgid klas-file-downloader
108 +43 verbose cwd /Users/junyoung/Library/Mobile Documents/com~apple~CloudDocs/Junyoung/Opensource/klas-file-downloader
109 +44 error Darwin 16.5.0
110 +45 error argv "/usr/local/Cellar/node/7.3.0/bin/node" "/usr/local/bin/npm" "publish"
111 +46 error node v7.3.0
112 +47 error npm v3.10.10
113 +48 error code E403
114 +49 error "You cannot publish over the previously published version 0.0.3." : klas-file-downloader
115 +50 error If you need help, you may report this error at:
116 +50 error <https://github.com/npm/npm/issues>
117 +51 verbose exit [ 1, true ]
1 { 1 {
2 "name": "klas-file-downloader", 2 "name": "klas-file-downloader",
3 - "version": "0.0.1", 3 + "version": "0.0.3",
4 "description": "Project that download lecture reference files from Klas", 4 "description": "Project that download lecture reference files from Klas",
5 "main": "index.js", 5 "main": "index.js",
6 "scripts": { 6 "scripts": {
......