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