dongnelibrary 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -8
- package/package.json +1 -1
- package/src/cli.js +99 -74
- package/src/dongnelibrary.js +75 -78
- package/src/example.js +16 -16
- package/src/library/gg.js +81 -71
- package/src/library/gunpo.js +74 -64
- package/src/library/hscity.js +95 -84
- package/src/library/osan.js +7 -0
- package/src/library/snlib.js +90 -80
- package/src/library/suwon.js +8 -3
- package/src/util.js +3 -4
- package/test/dongne.spec.js +30 -26
- package/test/gg.spec.js +3 -75
- package/test/gunpo.spec.js +3 -81
- package/test/helpers/libraryTestSuite.js +141 -0
- package/test/hscity.spec.js +3 -81
- package/test/osan.spec.js +3 -81
- package/test/snlib.spec.js +3 -81
- package/test/suwon.spec.js +3 -81
- package/test/util.spec.js +42 -15
package/README.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
[![NPM Version][npm-image]][npm-url]
|
|
2
|
-
[![Travis Build][travis-build-image]][travis-build-url]
|
|
3
2
|
[](https://opensource.org/licenses/mit-license.php)
|
|
4
3
|
|
|
5
4
|
# DongneLibrary
|
|
@@ -103,14 +102,12 @@ dl.search(
|
|
|
103
102
|
[dongnelibraryspa]: https://github.com/afrontend/dongnelibraryspa "AngularJS, Foundation을 사용한 Web UI"
|
|
104
103
|
[npm-image]: https://img.shields.io/npm/v/dongnelibrary.svg
|
|
105
104
|
[npm-url]: https://npmjs.org/package/dongnelibrary
|
|
106
|
-
[travis-build-image]: https://travis-ci.org/afrontend/dongnelibrary.svg?branch=master
|
|
107
|
-
[travis-build-url]: https://travis-ci.org/afrontend/dongnelibrary
|
|
108
105
|
[web-ui-url]: https://dongne.onrender.com
|
|
109
106
|
[web-api]: https://github.com/afrontend/dlserver "같은 기능을 지원하는 Web API"
|
|
110
|
-
[gg-url]:
|
|
111
|
-
[gunpo-url]:
|
|
107
|
+
[gg-url]: https://lib.goe.go.kr
|
|
108
|
+
[gunpo-url]: https://www.gunpolib.go.kr
|
|
112
109
|
[hscity-url]: https://hscitylib.or.kr
|
|
113
|
-
[osan-url]:
|
|
114
|
-
[snlib-url]:
|
|
115
|
-
[suwon-url]:
|
|
110
|
+
[osan-url]: https://www.osanlibrary.go.kr
|
|
111
|
+
[snlib-url]: https://www.snlib.go.kr
|
|
112
|
+
[suwon-url]: https://www.suwonlib.go.kr
|
|
116
113
|
[sample-url]: https://npm.runkit.com/dongnelibrary
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const Configstore = require(
|
|
3
|
-
const _ = require(
|
|
4
|
-
const colors = require(
|
|
5
|
-
const figlet = require(
|
|
6
|
-
const fp = require(
|
|
7
|
-
const inquirer = require(
|
|
8
|
-
const program = require(
|
|
9
|
-
const dl = require(
|
|
10
|
-
const util = require(
|
|
11
|
-
const pkg = require(
|
|
2
|
+
const Configstore = require("configstore");
|
|
3
|
+
const _ = require("lodash");
|
|
4
|
+
const colors = require("colors");
|
|
5
|
+
const figlet = require("figlet");
|
|
6
|
+
const fp = require("lodash/fp");
|
|
7
|
+
const inquirer = require("inquirer");
|
|
8
|
+
const program = require("commander");
|
|
9
|
+
const dl = require("./dongnelibrary");
|
|
10
|
+
const util = require("./util");
|
|
11
|
+
const pkg = require("../package.json");
|
|
12
12
|
|
|
13
13
|
const conf = new Configstore(pkg.name, {});
|
|
14
|
-
const getDefaultLibrary = () =>
|
|
15
|
-
const setDefaultLibrary = (name) =>
|
|
16
|
-
const getDefaultTitle = () =>
|
|
17
|
-
|
|
14
|
+
const getDefaultLibrary = () => conf.get("library");
|
|
15
|
+
const setDefaultLibrary = (name) => conf.set("library", name);
|
|
16
|
+
const getDefaultTitle = () =>
|
|
17
|
+
conf.get("title") === undefined ? "javascript" : conf.get("title");
|
|
18
|
+
const setDefaultTitle = (title) => conf.set("title", title);
|
|
18
19
|
|
|
19
20
|
const introMessage = (msg) => {
|
|
20
|
-
console.log(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
console.log(
|
|
22
|
+
figlet.textSync(msg, {
|
|
23
|
+
font: "Standard",
|
|
24
|
+
horizontalLayout: "default",
|
|
25
|
+
verticalLayout: "default",
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
25
28
|
};
|
|
26
29
|
|
|
27
30
|
program
|
|
28
31
|
.version(pkg.version)
|
|
29
|
-
.option(
|
|
30
|
-
.option(
|
|
31
|
-
.option(
|
|
32
|
-
.option(
|
|
32
|
+
.option("-a, --library-list", "Show libraries")
|
|
33
|
+
.option("-i, --interactive", "Use menu")
|
|
34
|
+
.option("-l, --library-name [name,name]", "library name")
|
|
35
|
+
.option("-t, --title [title]", "a part of book title")
|
|
33
36
|
.parse(process.argv);
|
|
34
37
|
|
|
35
38
|
function cutTail(str, tail) {
|
|
36
|
-
let result =
|
|
39
|
+
let result = "";
|
|
37
40
|
const index = str.indexOf(tail);
|
|
38
41
|
if (index === -1) {
|
|
39
42
|
result = str;
|
|
@@ -43,65 +46,83 @@ function cutTail(str, tail) {
|
|
|
43
46
|
return result;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
const okMark =
|
|
47
|
-
const notokMark =
|
|
49
|
+
const okMark = "✓ ";
|
|
50
|
+
const notokMark = "✖ ";
|
|
48
51
|
|
|
49
52
|
function printBooks(book) {
|
|
50
|
-
_.each(book.booklist, book => {
|
|
51
|
-
console.log(
|
|
53
|
+
_.each(book.booklist, (book) => {
|
|
54
|
+
console.log(
|
|
55
|
+
cutTail(book.libraryName, "도서관") +
|
|
56
|
+
(book.exist ? " " + okMark + " " : " " + colors.red(notokMark) + " ") +
|
|
57
|
+
book.title +
|
|
58
|
+
" ",
|
|
59
|
+
);
|
|
52
60
|
});
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
function printAllLibraryName() {
|
|
56
64
|
const libs = dl.getLibraryNames();
|
|
57
|
-
libs.forEach(name => {
|
|
65
|
+
libs.forEach((name) => {
|
|
58
66
|
console.log(name);
|
|
59
67
|
});
|
|
60
68
|
const msg = `모두 ${libs.length} 개의 도서관`;
|
|
61
69
|
console.log(colors.green(msg));
|
|
62
70
|
}
|
|
63
71
|
|
|
64
|
-
const getFullLibraryName = str
|
|
72
|
+
const getFullLibraryName = (str) =>
|
|
73
|
+
_.find(dl.getLibraryNames(), (name) => name.indexOf(str) >= 0);
|
|
65
74
|
|
|
66
75
|
function search(option, bookCallback, allBookCallback) {
|
|
67
|
-
dl.search(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (err) {
|
|
83
|
-
err.msg = err.msg || "Unknown Error";
|
|
84
|
-
if (allBookCallback) {
|
|
85
|
-
allBookCallback(err);
|
|
76
|
+
dl.search(
|
|
77
|
+
{
|
|
78
|
+
title: option.title,
|
|
79
|
+
libraryName: getLibraries(option.libraryName),
|
|
80
|
+
},
|
|
81
|
+
(err, book) => {
|
|
82
|
+
if (err) {
|
|
83
|
+
err.msg = err.msg || "Unknown Error";
|
|
84
|
+
if (bookCallback) {
|
|
85
|
+
bookCallback(err);
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
if (bookCallback) {
|
|
89
|
+
bookCallback(null, book);
|
|
90
|
+
}
|
|
86
91
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
},
|
|
93
|
+
(err, books) => {
|
|
94
|
+
if (err) {
|
|
95
|
+
err.msg = err.msg || "Unknown Error";
|
|
96
|
+
if (allBookCallback) {
|
|
97
|
+
allBookCallback(err);
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
if (allBookCallback) {
|
|
101
|
+
allBookCallback(null, books);
|
|
102
|
+
}
|
|
90
103
|
}
|
|
91
|
-
}
|
|
92
|
-
|
|
104
|
+
},
|
|
105
|
+
);
|
|
93
106
|
}
|
|
94
107
|
|
|
95
|
-
const getBookCount = (results) =>
|
|
96
|
-
_.reduce(
|
|
97
|
-
|
|
108
|
+
const getBookCount = (results) =>
|
|
109
|
+
_.reduce(
|
|
110
|
+
results,
|
|
111
|
+
(memo, book) =>
|
|
112
|
+
memo +
|
|
113
|
+
(book && book.booklist && book.booklist.length
|
|
114
|
+
? book.booklist.length
|
|
115
|
+
: 0),
|
|
116
|
+
0,
|
|
117
|
+
);
|
|
98
118
|
|
|
99
119
|
const getLibraryFullNameList = _.flow([
|
|
100
120
|
util.getArrayFromCommaSeparatedString,
|
|
101
|
-
fp.filter(shortLibraryName =>
|
|
121
|
+
fp.filter((shortLibraryName) => getFullLibraryName(shortLibraryName)),
|
|
102
122
|
]);
|
|
103
123
|
|
|
104
|
-
const getLibraries = (libraryName) =>
|
|
124
|
+
const getLibraries = (libraryName) =>
|
|
125
|
+
libraryName ? getLibraryFullNameList(libraryName) : dl.getLibraryNames();
|
|
105
126
|
|
|
106
127
|
const processOneLibrary = (err, book) => {
|
|
107
128
|
if (err) {
|
|
@@ -113,9 +134,13 @@ const processOneLibrary = (err, book) => {
|
|
|
113
134
|
|
|
114
135
|
const processLibraries = (err, results) => {
|
|
115
136
|
if (err) {
|
|
116
|
-
console.log(
|
|
137
|
+
console.log("Error, Can't access detail information");
|
|
117
138
|
} else {
|
|
118
|
-
console.log(
|
|
139
|
+
console.log(
|
|
140
|
+
colors.green(
|
|
141
|
+
`${results.length} 개의 도서관에서 ${getBookCount(results)} 권 검색됨`,
|
|
142
|
+
),
|
|
143
|
+
);
|
|
119
144
|
}
|
|
120
145
|
};
|
|
121
146
|
|
|
@@ -126,26 +151,26 @@ function activate(option) {
|
|
|
126
151
|
}
|
|
127
152
|
|
|
128
153
|
if (option.interactive) {
|
|
129
|
-
introMessage(
|
|
154
|
+
introMessage("Dongne Library");
|
|
130
155
|
inquirer
|
|
131
156
|
.prompt([
|
|
132
157
|
{
|
|
133
|
-
type:
|
|
134
|
-
name:
|
|
135
|
-
message:
|
|
158
|
+
type: "list",
|
|
159
|
+
name: "library",
|
|
160
|
+
message: "도서관 이름은?",
|
|
136
161
|
choices: dl.getLibraryNames(),
|
|
137
|
-
default: getDefaultLibrary()
|
|
162
|
+
default: getDefaultLibrary(),
|
|
138
163
|
},
|
|
139
164
|
{
|
|
140
|
-
type:
|
|
141
|
-
name:
|
|
142
|
-
message:
|
|
143
|
-
default: getDefaultTitle()
|
|
144
|
-
}
|
|
165
|
+
type: "input",
|
|
166
|
+
name: "title",
|
|
167
|
+
message: "책 이름은?",
|
|
168
|
+
default: getDefaultTitle(),
|
|
169
|
+
},
|
|
145
170
|
])
|
|
146
|
-
.then(answers => {
|
|
147
|
-
option.libraryName = answers[
|
|
148
|
-
option.title = answers[
|
|
171
|
+
.then((answers) => {
|
|
172
|
+
option.libraryName = answers["library"];
|
|
173
|
+
option.title = answers["title"];
|
|
149
174
|
setDefaultLibrary(option.libraryName);
|
|
150
175
|
setDefaultTitle(option.title);
|
|
151
176
|
if (option.libraryName && option.title) {
|
package/src/dongnelibrary.js
CHANGED
|
@@ -1,135 +1,132 @@
|
|
|
1
|
-
const _ = require(
|
|
2
|
-
const fp = require(
|
|
3
|
-
const gg = require(
|
|
4
|
-
const gunpo = require(
|
|
5
|
-
const hscity = require(
|
|
6
|
-
const osan = require(
|
|
7
|
-
const snlib = require(
|
|
8
|
-
const suwon = require(
|
|
9
|
-
const async = require(
|
|
10
|
-
const util = require(
|
|
1
|
+
const _ = require("lodash");
|
|
2
|
+
const fp = require("lodash/fp");
|
|
3
|
+
const gg = require("./library/gg");
|
|
4
|
+
const gunpo = require("./library/gunpo");
|
|
5
|
+
const hscity = require("./library/hscity");
|
|
6
|
+
const osan = require("./library/osan");
|
|
7
|
+
const snlib = require("./library/snlib");
|
|
8
|
+
const suwon = require("./library/suwon");
|
|
9
|
+
const async = require("async");
|
|
10
|
+
const util = require("./util.js");
|
|
11
11
|
|
|
12
12
|
const libraryList = [];
|
|
13
13
|
|
|
14
|
-
const getLibraryNames = () =>
|
|
14
|
+
const getLibraryNames = () => util.getLibraryNames(libraryList);
|
|
15
15
|
|
|
16
16
|
function makeLibraryList() {
|
|
17
|
-
const library = [
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
osan,
|
|
22
|
-
snlib,
|
|
23
|
-
suwon
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
_.each(library, library => {
|
|
27
|
-
_.each(library.getLibraryNames(), name => {
|
|
17
|
+
const library = [gg, gunpo, hscity, osan, snlib, suwon];
|
|
18
|
+
|
|
19
|
+
_.each(library, (library) => {
|
|
20
|
+
_.each(library.getLibraryNames(), (name) => {
|
|
28
21
|
libraryList.push({
|
|
29
22
|
name,
|
|
30
|
-
search: library.search
|
|
23
|
+
search: library.search,
|
|
31
24
|
});
|
|
32
25
|
});
|
|
33
26
|
});
|
|
34
27
|
}
|
|
35
28
|
|
|
36
|
-
const getLibraryFunction = libraryName => {
|
|
37
|
-
const found = _.find(libraryList, lib =>
|
|
38
|
-
return found
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
const getLibraryFunction = (libraryName) => {
|
|
30
|
+
const found = _.find(libraryList, (lib) => lib.name === libraryName);
|
|
31
|
+
return found
|
|
32
|
+
? found
|
|
33
|
+
: {
|
|
34
|
+
search: (opt, getBook) => {
|
|
35
|
+
if (getBook) {
|
|
36
|
+
getBook({ msg: "Unknown library name" });
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
name: "Unknown",
|
|
40
|
+
};
|
|
46
41
|
};
|
|
47
42
|
|
|
48
43
|
function completeLibraryName(str) {
|
|
49
|
-
const found = _.find(getLibraryNames(), name =>
|
|
50
|
-
return found ? found :
|
|
44
|
+
const found = _.find(getLibraryNames(), (name) => name.indexOf(str) >= 0);
|
|
45
|
+
return found ? found : "";
|
|
51
46
|
}
|
|
52
47
|
|
|
53
48
|
function isValidLibraryName(libraryName) {
|
|
54
|
-
const found = _.find(libraryList, lib =>
|
|
49
|
+
const found = _.find(libraryList, (lib) => lib.name === libraryName);
|
|
55
50
|
return found ? true : false;
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
function getLibArray(libraryName) {
|
|
59
54
|
return _.flow([
|
|
60
|
-
fp.map(name => {
|
|
55
|
+
fp.map((name) => {
|
|
61
56
|
const fullName = completeLibraryName(name);
|
|
62
57
|
return isValidLibraryName(fullName) ? getLibraryFunction(fullName) : null;
|
|
63
58
|
}),
|
|
64
|
-
_.compact
|
|
59
|
+
_.compact,
|
|
65
60
|
])(Array.isArray(libraryName) ? libraryName : [libraryName]);
|
|
66
61
|
}
|
|
67
62
|
|
|
68
63
|
const getSortedBooks = _.flow([
|
|
69
|
-
fp.map(book => ({
|
|
64
|
+
fp.map((book) => ({
|
|
70
65
|
libraryName: book.libraryName,
|
|
71
66
|
title: book.title,
|
|
72
|
-
exist: book.exist
|
|
67
|
+
exist: book.exist,
|
|
73
68
|
})),
|
|
74
|
-
fp.sortBy(book =>
|
|
69
|
+
fp.sortBy((book) => !book.exist),
|
|
75
70
|
]);
|
|
76
71
|
|
|
77
72
|
function search(opt, getBook, getAllBooks) {
|
|
78
73
|
if (!opt || (!getBook && !getAllBooks)) {
|
|
79
|
-
console.log(
|
|
74
|
+
console.log("invalid search options");
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
const title = opt.title;
|
|
84
79
|
const tasks = [];
|
|
85
80
|
|
|
86
|
-
_.each(getLibArray(opt.libraryName), lib => {
|
|
87
|
-
tasks.push(callback => {
|
|
88
|
-
lib.search(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
_.each(getLibArray(opt.libraryName), (lib) => {
|
|
82
|
+
tasks.push((callback) => {
|
|
83
|
+
lib.search(
|
|
84
|
+
{
|
|
85
|
+
title: title,
|
|
86
|
+
libraryName: lib.name,
|
|
87
|
+
},
|
|
88
|
+
(err, data) => {
|
|
89
|
+
if (err) {
|
|
90
|
+
if (getBook) {
|
|
91
|
+
getBook(err);
|
|
92
|
+
}
|
|
93
|
+
callback(err);
|
|
94
|
+
return;
|
|
95
95
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
if (!data || !data.booklist) {
|
|
97
|
+
if (getBook) {
|
|
98
|
+
getBook({ msg: "invalid Data response" });
|
|
99
|
+
}
|
|
100
|
+
callback({ msg: "invalid Data response" });
|
|
101
|
+
return;
|
|
102
102
|
}
|
|
103
|
-
callback({msg: 'invalid Data response'});
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
const bookObj = {
|
|
105
|
+
title: title,
|
|
106
|
+
libraryName: lib.name,
|
|
107
|
+
totalBookCount: data.totalBookCount,
|
|
108
|
+
startPage: data.startPage,
|
|
109
|
+
booklist: getSortedBooks(data.booklist),
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
if (getBook) {
|
|
113
|
+
getBook(null, bookObj);
|
|
114
|
+
}
|
|
115
|
+
callback(null, bookObj);
|
|
116
|
+
},
|
|
117
|
+
);
|
|
120
118
|
});
|
|
121
119
|
});
|
|
122
120
|
|
|
123
121
|
async.parallel(tasks, (err, results) => {
|
|
124
|
-
if(getAllBooks) {
|
|
125
|
-
if(err) {
|
|
122
|
+
if (getAllBooks) {
|
|
123
|
+
if (err) {
|
|
126
124
|
getAllBooks(err);
|
|
127
125
|
} else {
|
|
128
126
|
getAllBooks(null, results);
|
|
129
127
|
}
|
|
130
128
|
}
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
});
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
function activate() {
|
|
@@ -140,5 +137,5 @@ activate();
|
|
|
140
137
|
|
|
141
138
|
module.exports = {
|
|
142
139
|
search,
|
|
143
|
-
getLibraryNames
|
|
140
|
+
getLibraryNames,
|
|
144
141
|
};
|
package/src/example.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
const dl = require(
|
|
2
|
-
dl.search(
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
console.log(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
const dl = require("dongnelibrary");
|
|
2
|
+
dl.search(
|
|
3
|
+
{
|
|
4
|
+
title: "javascript",
|
|
5
|
+
libraryName: ["여주", "판교"],
|
|
6
|
+
},
|
|
7
|
+
function (err, book) {
|
|
8
|
+
console.log(book.libraryName + ' "' + book.title + '"');
|
|
9
|
+
book.booklist.forEach(function (book) {
|
|
10
|
+
console.log((book.exist ? " ✓ " : " ✖ ") + " " + book.title);
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
function (err, books) {
|
|
14
|
+
console.log(books.length + " 개의 도서관을 검색했습니다.");
|
|
15
|
+
},
|
|
16
|
+
);
|