1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.downloadEPUBFromLCPL = void 0;
|
4 | const debug_ = require("debug");
|
5 | const fs = require("fs");
|
6 | const path = require("path");
|
7 | const request = require("request");
|
8 | const requestPromise = require("request-promise-native");
|
9 | const BufferUtils_1 = require("r2-utils-js/dist/es8-es2017/src/_utils/stream/BufferUtils");
|
10 | const zipInjector_1 = require("r2-utils-js/dist/es8-es2017/src/_utils/zip/zipInjector");
|
11 | const lcp_1 = require("./parser/epub/lcp");
|
12 | const serializable_1 = require("./serializable");
|
13 | const debug = debug_("r2:lcp#publication-download");
|
14 | const IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");
|
15 | async function downloadEPUBFromLCPL(filePath, dir, destFileName) {
|
16 | return new Promise(async (resolve, reject) => {
|
17 | const lcplStr = fs.readFileSync(filePath, { encoding: "utf8" });
|
18 | const lcplJson = global.JSON.parse(lcplStr);
|
19 | const lcpl = (0, serializable_1.TaJsonDeserialize)(lcplJson, lcp_1.LCP);
|
20 | if (lcpl.Links) {
|
21 | const pubLink = lcpl.Links.find((link) => {
|
22 | return link.Rel === "publication";
|
23 | });
|
24 | if (pubLink) {
|
25 | const isAudio = pubLink.Type === "application/audiobook+zip";
|
26 | const isAudioLcp = pubLink.Type === "application/audiobook+lcp";
|
27 | const ext = isAudio ? ".audiobook" : (isAudioLcp ? ".lcpa" : ".epub");
|
28 | const destPathTMP = path.join(dir, destFileName + ".tmp");
|
29 | const destPathFINAL = path.join(dir, destFileName + ext);
|
30 | const failure = (err) => {
|
31 | debug(err);
|
32 | reject(pubLink.Href + " (" + err + ")");
|
33 | };
|
34 | const success = async (response) => {
|
35 | if (IS_DEV) {
|
36 | Object.keys(response.headers).forEach((header) => {
|
37 | debug(header + " => " + response.headers[header]);
|
38 | });
|
39 | }
|
40 | if (response.statusCode && (response.statusCode < 200 || response.statusCode >= 300)) {
|
41 | let failBuff;
|
42 | try {
|
43 | failBuff = await (0, BufferUtils_1.streamToBufferPromise)(response);
|
44 | }
|
45 | catch (buffErr) {
|
46 | if (IS_DEV) {
|
47 | debug(buffErr);
|
48 | }
|
49 | failure(response.statusCode);
|
50 | return;
|
51 | }
|
52 | try {
|
53 | const failStr = failBuff.toString("utf8");
|
54 | if (IS_DEV) {
|
55 | debug(failStr);
|
56 | }
|
57 | try {
|
58 | const failJson = global.JSON.parse(failStr);
|
59 | if (IS_DEV) {
|
60 | debug(failJson);
|
61 | }
|
62 | failJson.httpStatusCode = response.statusCode;
|
63 | failure(failJson);
|
64 | }
|
65 | catch (jsonErr) {
|
66 | if (IS_DEV) {
|
67 | debug(jsonErr);
|
68 | }
|
69 | failure({ httpStatusCode: response.statusCode, httpResponseBody: failStr });
|
70 | }
|
71 | }
|
72 | catch (strErr) {
|
73 | if (IS_DEV) {
|
74 | debug(strErr);
|
75 | }
|
76 | failure(response.statusCode);
|
77 | }
|
78 | return;
|
79 | }
|
80 | const destStreamTMP = fs.createWriteStream(destPathTMP);
|
81 | response.pipe(destStreamTMP);
|
82 | destStreamTMP.on("finish", () => {
|
83 | const zipError = (err) => {
|
84 | debug(err);
|
85 | reject(destPathTMP + " (" + err + ")");
|
86 | };
|
87 | const doneCallback = () => {
|
88 | setTimeout(() => {
|
89 | fs.unlinkSync(destPathTMP);
|
90 | }, 1000);
|
91 | resolve([destPathFINAL, pubLink.Href]);
|
92 | };
|
93 | const zipEntryPath = (isAudio || isAudioLcp) ? "license.lcpl" : "META-INF/license.lcpl";
|
94 | (0, zipInjector_1.injectFileInZip)(destPathTMP, destPathFINAL, filePath, zipEntryPath, zipError, doneCallback);
|
95 | });
|
96 | };
|
97 | const needsStreamingResponse = true;
|
98 | if (needsStreamingResponse) {
|
99 | request.get({
|
100 | headers: {},
|
101 | method: "GET",
|
102 | timeout: 5000,
|
103 | uri: pubLink.Href,
|
104 | })
|
105 | .on("response", async (res) => {
|
106 | try {
|
107 | await success(res);
|
108 | }
|
109 | catch (successError) {
|
110 | failure(successError);
|
111 | return;
|
112 | }
|
113 | })
|
114 | .on("error", failure);
|
115 | }
|
116 | else {
|
117 | let response;
|
118 | try {
|
119 | response = await requestPromise({
|
120 | headers: {},
|
121 | method: "GET",
|
122 | resolveWithFullResponse: true,
|
123 | uri: pubLink.Href,
|
124 | });
|
125 | }
|
126 | catch (err) {
|
127 | failure(err);
|
128 | return;
|
129 | }
|
130 | await success(response);
|
131 | }
|
132 | }
|
133 | }
|
134 | });
|
135 | }
|
136 | exports.downloadEPUBFromLCPL = downloadEPUBFromLCPL;
|
137 |
|
\ | No newline at end of file |