-
Notifications
You must be signed in to change notification settings - Fork 1
/
enrich
executable file
·238 lines (234 loc) · 6.93 KB
/
enrich
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#!/usr/bin/node
const fs = require("fs");
const BNF = require("./src/bnf.js");
const Babelio = require("./src/babelio.js");
const GB = require("./src/googlebooks.js");
const decitre = require("./src/decitre.js");
const Utils = require("./src/utils.js");
const enrichAuthors = require("./src/process_authors.js");
require("./src/logger.js")(true);
// CLI HELPERS:
const INPUT_STRUCTURE = `Le fichier d'entrée doit être formaté comme suit :
- Un livre par ligne
- Deux colonnes obligatoires : Titre, auteurs
- Deux colonnes facultatives : Résumé, ISBN
- Colonnes séparées par des pipes : |
- Auteurs séparés par des esperluettes : &
Exemple :
Titre 1 | Auteur1 & Auteur 2 & Auteur 3 | Résumé
Titre 2 | | | ISBN
`;
const ARGS_STRUCTURE = {
process: process.argv[1].split("/").slice(-1),
mandatory: {
"input":[],
"output":[]
},
optional: [
"errors"
],
};
const checkArgs = (arguments) => {
Object.keys(ARGS_STRUCTURE.mandatory).map(e => {
if (typeof arguments[e] === "undefined") {
throw new Error("Argument obligatoire: "+e)
}
});
}
const help = () => {
let h = `Usage: `+ARGS_STRUCTURE.process+` `
+Object.keys(ARGS_STRUCTURE.mandatory).join(" ")+` [OPTIONS]
\nOptions:\t\tSyntaxe: --KEY=VALUE
\t`+ARGS_STRUCTURE.optional.join("\n\t")+`\n`;
console.log(h);
process.exit();
}
const ARGS = (() => {
let args = {};
process.argv.slice(2).map((e,i) => {
if (i == 0) {
if (e == "--help") {
console.log(INPUT_STRUCTURE);
help();
}
return ["input",e];
} else if (i == 1) {
return ["output",e];
} else {
if (e.slice(0,2) == "--") {
return e.slice(2).split("=");
} else {
return [e,true];
}
}
}).map(e => { args[e[0]] = e[1] });
return args;
})();
const DIE = (e) => {
console.warn(e+"\n");
help();
}
let writeErrorLog = (livre) => {
if (typeof ARGS.errors !== "undefined") {
let content;
try {
content = fs.readFileSync(ARGS.errors,"utf8")+"\n";
} catch {
content = "";
}
fs.writeFileSync(ARGS.errors, content+livre.titre+" | "+livre.auteurs.join(" & "));
}
}
let getKey = () => {
return new Promise((resolve,reject) => {
let stdin = process.stdin;
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding("utf8");
stdin.on("data", key => {
resolve(key);
});
});
}
//enrichments functions:
let enrichments = {
BNF,
Babelio,
decitre,
GoogleBooks: GB
}
let enrich = async (livre) => {
livre.enrichments = {};
livre.enriched = false;
await Promise.all(Object.keys(enrichments).map(async e => {
if (e != "decitre") {
let results = await enrichments[e].module.enrich(livre);
livre.enrichments[e] = results;
if (results.featuresFound > 0) {
enrichments[e].success++;
livre.enriched = true;
}
}
}));
if (livre.enriched) {
let ean = (Object.keys(livre.enrichments)
.find(e => typeof livre.enrichments[e].isbn !== "undefined"));
if (typeof ean !== "undefined") {
ean = (livre.enrichments[ean].isbn);
livre.enrichments.decitre = await enrichments.decitre.module.enrich(ean);
if (livre.enrichments.decitre.featuresFound > 0) {
enrichments.decitre.success++;
}
}
} else if (typeof livre.ean !== "undefined") {
livre.enrichments.decitre = await enrichments.decitre.module.enrich(livre.ean);
if (livre.enrichments.decitre.featuresFound > 0) {
enrichments.decitre.success++;
livre.enriched = true;
}
}
return livre;
}
let main = async () => {
console.info("Bienvenue dans le programme d'enrichissement bibliographique");
await Utils.wait(2000);
let input,output;
Object.keys(enrichments).map(e => {
enrichments[e] = { module:enrichments[e], success:0 };
});
try {
input = fs.readFileSync(ARGS.input,"utf8");
} catch {
DIE("Le fichier input "+ARGS.input+" n'a pas pu être lu");
}
try {
output = fs.readFileSync(ARGS.output,"utf8");
} catch {
DIE("Le fichier de sortie "+ARGS.output+" n'a pas pu être lu");
}
input = input.split("\n").filter(e => e != "").map(e => {
let livre = {};
e = e.split("|");
livre.titre = Utils.normalize(e[0]);
livre.auteurs = e[1].split("&").map(auteur => Utils.normalize(auteur));
if (e.length > 2 && Utils.normalize(e[2]) !== "") {
livre.resume = Utils.normalize(e[2]);
}
if (e.length > 3) {
livre.ean = Utils.normalize(e[3]);
}
livre.tags = {};
return livre;
});
output = JSON.parse(output);
let id = 0;
output.books.map(e => {
if (parseInt(e.id.slice(1)) > id) {
id = parseInt(e.id.slice(1));
}
});
let processing = 1;
let success = 0;
console.clear();
for (let i of input) {
i.titre = i.titre.replace(/’/g,"'");
i.auteurs = i.auteurs.map(e => e.replace(/’/g,"'"));
i.id = "b"+id+processing;
let double = output.books.find(e => e.titre == i.titre);
let continu = true;
if (typeof double !== "undefined") {
console.warn(`/!\\ Il existe déjà un ouvrage dans la base avec ce titre: /!\\
`+i.titre+`
Auteurs : `+double.auteurs.join(" & "));
console.info("Souhaitez-vous continuer ? o/N");
let key = await getKey();
continu = (key.toLowerCase() == "o");
}
if (continu) {
if (i.auteurs == ["Collectif"]) { i.auteurs = [] };
i = await enrich(i);
if (i.enriched) {
success++;
} else {
writeErrorLog(i);
}
await Utils.wait();
console.info("# Livres traités: "+processing+"/"+input.length+"... ("+Math.round(processing/input.length*100)+"%)");
let info = Object.keys(enrichments).map(e => e+": "+enrichments[e].success).join(" | ");
console.info("# Enrichmissements: "+info+" | "+success+" globalement");
info = Object.keys(enrichments).map(e => e+": "+Math.round(enrichments[e].success/processing*100)+"%").join(" | ");
console.info("# Taux de succès: "+info+" | "+" globally: "+Math.round(success/processing*100)+"%");
} else {
i.discarded = true;
}
if (processing <= input.length) {
console.clear();
}
processing++;
}
console.clear();
input = input.filter(e => e.discarded !== true);
if (input.length == 0) {
console.info("Aucun livre n'a été ajouté");
} else {
console.info("enrichissement des auteurs...");
output.books = [...output.books,...input];
output = enrichAuthors(output,input);
fs.writeFileSync(ARGS.output, JSON.stringify(output));
fs.writeFileSync("./lastupd", (new Date()).valueOf().toString());
console.info(`Taux de succès global à `+Math.round(success/input.length*100)+`%,
le fichier de sortie `+ARGS.output+` a été complété.
---
Vous devriez désormais conserver et pousser ces modifications :
git commit `+ARGS.output+` lastupd -m "ajout de `+input.length+` ouvrage`
+((input.length > 1) ? "s":"")+`"
git push origin master`);
}
process.exit();
};
try {
checkArgs(ARGS);
main();
} catch (e) {
DIE(e);
}