1 | "use strict";
|
2 | var _this = this;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | var tslib_1 = require("tslib");
|
5 | var fs = require("fs");
|
6 | var http = require("http");
|
7 | var https = require("https");
|
8 | var path = require("path");
|
9 | var url_1 = require("url");
|
10 | var status_document_processing_1 = require("r2-lcp-js/dist/es5/src/lsd/status-document-processing");
|
11 | var lcp_1 = require("r2-lcp-js/dist/es5/src/parser/epub/lcp");
|
12 | var lcp_2 = require("r2-lcp-js/dist/es5/src/parser/epub/lcp");
|
13 | var publication_download_1 = require("r2-lcp-js/dist/es5/src/publication-download");
|
14 | var readium_css_settings_1 = require("r2-navigator-js/dist/es5/src/electron/common/readium-css-settings");
|
15 | var sessions_1 = require("r2-navigator-js/dist/es5/src/electron/common/sessions");
|
16 | var browser_window_tracker_1 = require("r2-navigator-js/dist/es5/src/electron/main/browser-window-tracker");
|
17 | var lsd_injectlcpl_1 = require("r2-navigator-js/dist/es5/src/electron/main/lsd-injectlcpl");
|
18 | var readium_css_1 = require("r2-navigator-js/dist/es5/src/electron/main/readium-css");
|
19 | var sessions_2 = require("r2-navigator-js/dist/es5/src/electron/main/sessions");
|
20 | var init_globals_1 = require("r2-opds-js/dist/es5/src/opds/init-globals");
|
21 | var init_globals_2 = require("r2-shared-js/dist/es5/src/init-globals");
|
22 | var publication_1 = require("r2-shared-js/dist/es5/src/models/publication");
|
23 | var epub_1 = require("r2-shared-js/dist/es5/src/parser/epub");
|
24 | var server_1 = require("r2-streamer-js/dist/es5/src/http/server");
|
25 | var UrlUtils_1 = require("r2-utils-js/dist/es5/src/_utils/http/UrlUtils");
|
26 | var UrlUtils_2 = require("r2-utils-js/dist/es5/src/_utils/http/UrlUtils");
|
27 | var BufferUtils_1 = require("r2-utils-js/dist/es5/src/_utils/stream/BufferUtils");
|
28 | var zip_ex_1 = require("r2-utils-js/dist/es5/src/_utils/zip/zip-ex");
|
29 | var zip_ex_http_1 = require("r2-utils-js/dist/es5/src/_utils/zip/zip-ex-http");
|
30 | var debug_ = require("debug");
|
31 | var electron_1 = require("electron");
|
32 | var express = require("express");
|
33 | var portfinder = require("portfinder");
|
34 | var request = require("request");
|
35 | var requestPromise = require("request-promise-native");
|
36 | var ta_json_x_1 = require("ta-json-x");
|
37 | var uuid = require("uuid");
|
38 | var events_1 = require("../common/events");
|
39 | var store_electron_1 = require("../common/store-electron");
|
40 | var lcp_3 = require("./lcp");
|
41 | var lsd_1 = require("./lsd");
|
42 | var lsd_deviceid_manager_1 = require("./lsd-deviceid-manager");
|
43 | var SECURE = true;
|
44 | var electronStoreLSD = new store_electron_1.StoreElectron("readium2-testapp-lsd", {});
|
45 | var deviceIDManager = lsd_deviceid_manager_1.getDeviceIDManager(electronStoreLSD, "Readium2 Electron desktop app");
|
46 | electron_1.ipcMain.on("R2_EVENT_LCP_LSD_OPEN_SETTINGS", function (_event, _arg) {
|
47 | if (electronStoreLSD.reveal) {
|
48 | electronStoreLSD.reveal();
|
49 | }
|
50 | });
|
51 | init_globals_1.initGlobalConverters_OPDS();
|
52 | init_globals_2.initGlobalConverters_SHARED();
|
53 | init_globals_2.initGlobalConverters_GENERIC();
|
54 | var IS_DEV = (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "dev");
|
55 | var lcpPluginPath = IS_DEV ?
|
56 | path.join(process.cwd(), "LCP", "lcp.node") :
|
57 | path.join(__dirname, "lcp.node");
|
58 | lcp_2.setLcpNativePluginPath(lcpPluginPath);
|
59 | var debug = debug_("r2:testapp#electron/main/index");
|
60 | var _publicationsServer;
|
61 | var _publicationsServerPort;
|
62 | var _publicationsRootUrl;
|
63 | var _publicationsFilePaths;
|
64 | var _publicationsUrls;
|
65 | var _lastBookPath;
|
66 | function openAllDevTools() {
|
67 | var e_1, _a;
|
68 | try {
|
69 | for (var _b = tslib_1.__values(electron_1.webContents.getAllWebContents()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
70 | var wc = _c.value;
|
71 | wc.openDevTools({ mode: "detach" });
|
72 | }
|
73 | }
|
74 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
75 | finally {
|
76 | try {
|
77 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
78 | }
|
79 | finally { if (e_1) throw e_1.error; }
|
80 | }
|
81 | }
|
82 | function openTopLevelDevTools() {
|
83 | var bw = electron_1.BrowserWindow.getFocusedWindow();
|
84 | if (bw) {
|
85 | bw.webContents.openDevTools({ mode: "detach" });
|
86 | }
|
87 | else {
|
88 | var arr = electron_1.BrowserWindow.getAllWindows();
|
89 | arr.forEach(function (bww) {
|
90 | bww.webContents.openDevTools({ mode: "detach" });
|
91 | });
|
92 | }
|
93 | }
|
94 | electron_1.ipcMain.on(events_1.R2_EVENT_DEVTOOLS, function (_event, _arg) {
|
95 | openAllDevTools();
|
96 | });
|
97 | function isManifestJSON(urlOrPath) {
|
98 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
99 | var p, url_2, promise, ok, err_1, isMan;
|
100 | return tslib_1.__generator(this, function (_a) {
|
101 | switch (_a.label) {
|
102 | case 0:
|
103 | p = urlOrPath;
|
104 | if (!UrlUtils_1.isHTTP(urlOrPath)) return [3, 4];
|
105 | url_2 = new url_1.URL(urlOrPath);
|
106 | p = url_2.pathname;
|
107 | promise = new Promise(function (resolve, reject) {
|
108 | var isHTTPS = urlOrPath.startsWith("https://");
|
109 | var options = {
|
110 | host: url_2.host,
|
111 | method: "HEAD",
|
112 | path: urlOrPath.substr(urlOrPath.indexOf(url_2.pathname)),
|
113 | };
|
114 | debug(options);
|
115 | (isHTTPS ? https : http).request(options, function (response) {
|
116 | debug(response.statusCode);
|
117 | if (response.statusCode && (response.statusCode < 200 || response.statusCode >= 300)) {
|
118 | reject("STATUS: " + response.statusCode);
|
119 | return;
|
120 | }
|
121 | debug(response.headers);
|
122 | debug(response.headers["content-type"]);
|
123 | var okay = response.headers["content-type"] &&
|
124 | (response.headers["content-type"].indexOf("application/webpub+json") >= 0 ||
|
125 | response.headers["content-type"].indexOf("application/audiobook+json") >= 0 ||
|
126 | response.headers["content-type"].indexOf("application/json") >= 0);
|
127 | resolve(okay);
|
128 | }).on("error", function (err) {
|
129 | reject(err);
|
130 | }).end();
|
131 | });
|
132 | ok = void 0;
|
133 | _a.label = 1;
|
134 | case 1:
|
135 | _a.trys.push([1, 3, , 4]);
|
136 | return [4, promise];
|
137 | case 2:
|
138 | ok = _a.sent();
|
139 | debug("########### IS MANIFEST (HTTP): " + ok);
|
140 | return [2, ok];
|
141 | case 3:
|
142 | err_1 = _a.sent();
|
143 | debug(err_1);
|
144 | return [3, 4];
|
145 | case 4:
|
146 | isMan = /.*manifest\.json[\?]?.*/.test(p);
|
147 | debug("########### IS MANIFEST: " + isMan);
|
148 | return [2, isMan];
|
149 | }
|
150 | });
|
151 | });
|
152 | }
|
153 | function tryLSD(publication, publicationFilePath) {
|
154 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
155 | var _this = this;
|
156 | return tslib_1.__generator(this, function (_a) {
|
157 | return [2, new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
158 | var err_2;
|
159 | var _this = this;
|
160 | return tslib_1.__generator(this, function (_a) {
|
161 | switch (_a.label) {
|
162 | case 0:
|
163 | if (!publication.LCP) {
|
164 | reject("No LCP data!");
|
165 | return [2];
|
166 | }
|
167 | _a.label = 1;
|
168 | case 1:
|
169 | _a.trys.push([1, 3, , 4]);
|
170 | return [4, status_document_processing_1.launchStatusDocumentProcessing(publication.LCP, deviceIDManager, function (licenseUpdateJson) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
171 | var res, err_3, err_4;
|
172 | return tslib_1.__generator(this, function (_a) {
|
173 | switch (_a.label) {
|
174 | case 0:
|
175 | debug("launchStatusDocumentProcessing DONE.");
|
176 | if (!licenseUpdateJson) return [3, 9];
|
177 | res = void 0;
|
178 | _a.label = 1;
|
179 | case 1:
|
180 | _a.trys.push([1, 7, , 8]);
|
181 | return [4, lsd_injectlcpl_1.lsdLcpUpdateInject(licenseUpdateJson, publication, publicationFilePath)];
|
182 | case 2:
|
183 | res = _a.sent();
|
184 | debug("EPUB LCP INJECTED: " + res);
|
185 | _a.label = 3;
|
186 | case 3:
|
187 | _a.trys.push([3, 5, , 6]);
|
188 | return [4, tryLSD(publication, publicationFilePath)];
|
189 | case 4:
|
190 | _a.sent();
|
191 | resolve(true);
|
192 | return [3, 6];
|
193 | case 5:
|
194 | err_3 = _a.sent();
|
195 | debug(err_3);
|
196 | reject(err_3);
|
197 | return [3, 6];
|
198 | case 6: return [3, 8];
|
199 | case 7:
|
200 | err_4 = _a.sent();
|
201 | debug(err_4);
|
202 | reject(err_4);
|
203 | return [3, 8];
|
204 | case 8: return [3, 10];
|
205 | case 9:
|
206 | resolve(true);
|
207 | _a.label = 10;
|
208 | case 10: return [2];
|
209 | }
|
210 | });
|
211 | }); })];
|
212 | case 2:
|
213 | _a.sent();
|
214 | return [3, 4];
|
215 | case 3:
|
216 | err_2 = _a.sent();
|
217 | debug(err_2);
|
218 | reject(err_2);
|
219 | return [3, 4];
|
220 | case 4: return [2];
|
221 | }
|
222 | });
|
223 | }); })];
|
224 | });
|
225 | });
|
226 | }
|
227 | function createElectronBrowserWindow(publicationFilePath, publicationUrl) {
|
228 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
229 | var lcpHint, publication, isWebPub, isHttpWebPub, isHttpWebPubWithoutLCP, failure_1, handleLCP_1, successLCP_1, needsStreamingResponse_1, handleManifestJson_1, success_1, promise, err_5, response, err_6, responseStr, err_7, err_8, blockBecauseLSD, electronBrowserWindow, urlEncoded, htmlPath, fullUrl, urlRoot;
|
230 | var _this = this;
|
231 | return tslib_1.__generator(this, function (_a) {
|
232 | switch (_a.label) {
|
233 | case 0:
|
234 | debug("createElectronBrowserWindow() " + publicationFilePath + " : " + publicationUrl);
|
235 | return [4, isManifestJSON(publicationFilePath)];
|
236 | case 1:
|
237 | isWebPub = _a.sent();
|
238 | isHttpWebPub = isWebPub && UrlUtils_1.isHTTP(publicationFilePath);
|
239 | isHttpWebPubWithoutLCP = isHttpWebPub;
|
240 | if (!isWebPub) return [3, 19];
|
241 | failure_1 = function (err) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
242 | return tslib_1.__generator(this, function (_a) {
|
243 | debug(err);
|
244 | return [2];
|
245 | });
|
246 | }); };
|
247 | handleLCP_1 = function (responseStr, pub) {
|
248 | var responseJson = global.JSON.parse(responseStr);
|
249 | debug(responseJson);
|
250 | var lcpl;
|
251 | lcpl = ta_json_x_1.JSON.deserialize(responseJson, lcp_1.LCP);
|
252 | lcpl.ZipPath = "META-INF/license.lcpl";
|
253 | lcpl.JsonSource = responseStr;
|
254 | lcpl.init();
|
255 | pub.LCP = lcpl;
|
256 | };
|
257 | successLCP_1 = function (response, pub) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
258 | var responseStr, responseData, err_9;
|
259 | return tslib_1.__generator(this, function (_a) {
|
260 | switch (_a.label) {
|
261 | case 0:
|
262 | if (!(response.statusCode && (response.statusCode < 200 || response.statusCode >= 300))) return [3, 2];
|
263 | return [4, failure_1("HTTP CODE " + response.statusCode)];
|
264 | case 1:
|
265 | _a.sent();
|
266 | return [2];
|
267 | case 2:
|
268 | if (!response.body) return [3, 3];
|
269 | debug("RES BODY");
|
270 | responseStr = response.body;
|
271 | return [3, 8];
|
272 | case 3:
|
273 | debug("RES STREAM");
|
274 | responseData = void 0;
|
275 | _a.label = 4;
|
276 | case 4:
|
277 | _a.trys.push([4, 6, , 7]);
|
278 | return [4, BufferUtils_1.streamToBufferPromise(response)];
|
279 | case 5:
|
280 | responseData = _a.sent();
|
281 | return [3, 7];
|
282 | case 6:
|
283 | err_9 = _a.sent();
|
284 | debug(err_9);
|
285 | return [2];
|
286 | case 7:
|
287 | responseStr = responseData.toString("utf8");
|
288 | _a.label = 8;
|
289 | case 8:
|
290 | handleLCP_1(responseStr, pub);
|
291 | return [2];
|
292 | }
|
293 | });
|
294 | }); };
|
295 | needsStreamingResponse_1 = true;
|
296 | handleManifestJson_1 = function (responseStr) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
297 | var manifestJson, arrLinks, licenseLink, p, url, dirPath, zip, url, dirPath, zip, pathDecoded, publicationUrls, pubCheck, lcplHref_1, promise, err_10, responsez, err_11, responsezStr;
|
298 | var _this = this;
|
299 | return tslib_1.__generator(this, function (_a) {
|
300 | switch (_a.label) {
|
301 | case 0:
|
302 | manifestJson = global.JSON.parse(responseStr);
|
303 | debug(manifestJson);
|
304 | if (UrlUtils_1.isHTTP(publicationFilePath)) {
|
305 | arrLinks = [];
|
306 | if (manifestJson.readingOrder) {
|
307 | arrLinks.push.apply(arrLinks, tslib_1.__spread(manifestJson.readingOrder));
|
308 | }
|
309 | if (manifestJson.resources) {
|
310 | arrLinks.push.apply(arrLinks, tslib_1.__spread(manifestJson.resources));
|
311 | }
|
312 | arrLinks.forEach(function (link) {
|
313 | if (link.properties && link.properties.encrypted &&
|
314 | (link.properties.encrypted.algorithm === "http://www.idpf.org/2008/embedding" ||
|
315 | link.properties.encrypted.algorithm === "http://ns.adobe.com/pdf/enc#RC")) {
|
316 | delete link.properties.encrypted;
|
317 | var atLeastOne_1 = false;
|
318 | var jsonProps = Object.keys(link.properties);
|
319 | if (jsonProps) {
|
320 | jsonProps.forEach(function (jsonProp) {
|
321 | if (link.properties.hasOwnProperty(jsonProp)) {
|
322 | atLeastOne_1 = true;
|
323 | return false;
|
324 | }
|
325 | return true;
|
326 | });
|
327 | }
|
328 | if (!atLeastOne_1) {
|
329 | delete link.properties;
|
330 | }
|
331 | }
|
332 | });
|
333 | }
|
334 | try {
|
335 | publication = ta_json_x_1.JSON.deserialize(manifestJson, publication_1.Publication);
|
336 | }
|
337 | catch (erorz) {
|
338 | debug(erorz);
|
339 | return [2];
|
340 | }
|
341 | debug(publication);
|
342 | licenseLink = publication.Links ? publication.Links.find(function (link) {
|
343 | return link.Rel.indexOf("license") >= 0 &&
|
344 | link.TypeLink === "application/vnd.readium.lcp.license.v1.0+json";
|
345 | }) : undefined;
|
346 | isHttpWebPubWithoutLCP = isHttpWebPub && !licenseLink;
|
347 | p = publicationFilePath;
|
348 | if (UrlUtils_1.isHTTP(publicationFilePath)) {
|
349 | url = new url_1.URL(publicationFilePath);
|
350 | p = url.pathname;
|
351 | }
|
352 | publication.AddToInternal("filename", path.basename(p));
|
353 | publication.AddToInternal("type", "epub");
|
354 | if (!!isHttpWebPubWithoutLCP) return [3, 4];
|
355 | if (!!UrlUtils_1.isHTTP(publicationFilePath)) return [3, 2];
|
356 | dirPath = path.dirname(publicationFilePath);
|
357 | return [4, zip_ex_1.ZipExploded.loadPromise(dirPath)];
|
358 | case 1:
|
359 | zip = _a.sent();
|
360 | publication.AddToInternal("zip", zip);
|
361 | return [3, 4];
|
362 | case 2:
|
363 | url = new url_1.URL(publicationFilePath);
|
364 | dirPath = path.dirname(p);
|
365 | url.pathname = dirPath + "/";
|
366 | return [4, zip_ex_http_1.ZipExplodedHTTP.loadPromise(url.toString())];
|
367 | case 3:
|
368 | zip = _a.sent();
|
369 | publication.AddToInternal("zip", zip);
|
370 | _a.label = 4;
|
371 | case 4:
|
372 | pathDecoded = publicationFilePath;
|
373 | debug("ADDED HTTP pub to server cache: " + pathDecoded + " --- " + publicationFilePath);
|
374 | publicationUrls = _publicationsServer.addPublications([pathDecoded]);
|
375 | _publicationsServer.cachePublication(pathDecoded, publication);
|
376 | pubCheck = _publicationsServer.cachedPublication(pathDecoded);
|
377 | if (!pubCheck) {
|
378 | debug("PUB CHECK FAIL?");
|
379 | }
|
380 | if (!isHttpWebPubWithoutLCP) {
|
381 | publicationUrl = "" + _publicationsServer.serverUrl() + publicationUrls[0];
|
382 | }
|
383 | debug(publicationUrl);
|
384 | if (!(licenseLink && licenseLink.Href)) return [3, 20];
|
385 | lcplHref_1 = licenseLink.Href;
|
386 | if (!UrlUtils_1.isHTTP(lcplHref_1)) {
|
387 | if (UrlUtils_1.isHTTP(publicationFilePath)) {
|
388 | lcplHref_1 = new url_1.URL(lcplHref_1, publicationFilePath).toString();
|
389 | }
|
390 | else {
|
391 | lcplHref_1 = publicationFilePath.replace("manifest.json", licenseLink.Href);
|
392 | }
|
393 | }
|
394 | debug(lcplHref_1);
|
395 | if (!UrlUtils_1.isHTTP(lcplHref_1)) return [3, 17];
|
396 | if (!needsStreamingResponse_1) return [3, 9];
|
397 | promise = new Promise(function (resolve, reject) {
|
398 | request.get({
|
399 | headers: {},
|
400 | method: "GET",
|
401 | uri: lcplHref_1,
|
402 | })
|
403 | .on("response", function (responsez) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
404 | return tslib_1.__generator(this, function (_a) {
|
405 | switch (_a.label) {
|
406 | case 0: return [4, successLCP_1(responsez, publication)];
|
407 | case 1:
|
408 | _a.sent();
|
409 | resolve();
|
410 | return [2];
|
411 | }
|
412 | });
|
413 | }); })
|
414 | .on("error", function (err) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
415 | return tslib_1.__generator(this, function (_a) {
|
416 | switch (_a.label) {
|
417 | case 0: return [4, failure_1(err)];
|
418 | case 1:
|
419 | _a.sent();
|
420 | reject();
|
421 | return [2];
|
422 | }
|
423 | });
|
424 | }); });
|
425 | });
|
426 | _a.label = 5;
|
427 | case 5:
|
428 | _a.trys.push([5, 7, , 8]);
|
429 | return [4, promise];
|
430 | case 6:
|
431 | _a.sent();
|
432 | return [3, 8];
|
433 | case 7:
|
434 | err_10 = _a.sent();
|
435 | return [2];
|
436 | case 8: return [3, 16];
|
437 | case 9:
|
438 | responsez = void 0;
|
439 | _a.label = 10;
|
440 | case 10:
|
441 | _a.trys.push([10, 12, , 14]);
|
442 | return [4, requestPromise({
|
443 | headers: {},
|
444 | method: "GET",
|
445 | resolveWithFullResponse: true,
|
446 | uri: lcplHref_1,
|
447 | })];
|
448 | case 11:
|
449 | responsez = _a.sent();
|
450 | return [3, 14];
|
451 | case 12:
|
452 | err_11 = _a.sent();
|
453 | return [4, failure_1(err_11)];
|
454 | case 13:
|
455 | _a.sent();
|
456 | return [2];
|
457 | case 14: return [4, successLCP_1(responsez, publication)];
|
458 | case 15:
|
459 | _a.sent();
|
460 | _a.label = 16;
|
461 | case 16: return [3, 20];
|
462 | case 17:
|
463 | responsezStr = fs.readFileSync(lcplHref_1, { encoding: "utf8" });
|
464 | if (!!responsezStr) return [3, 19];
|
465 | return [4, failure_1("Cannot read local file: " + lcplHref_1)];
|
466 | case 18:
|
467 | _a.sent();
|
468 | return [2];
|
469 | case 19:
|
470 | handleLCP_1(responsezStr, publication);
|
471 | _a.label = 20;
|
472 | case 20: return [2];
|
473 | }
|
474 | });
|
475 | }); };
|
476 | if (!UrlUtils_1.isHTTP(publicationFilePath)) return [3, 14];
|
477 | success_1 = function (response) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
478 | var responseStr, responseData, err_12;
|
479 | return tslib_1.__generator(this, function (_a) {
|
480 | switch (_a.label) {
|
481 | case 0:
|
482 | if (!(response.statusCode && (response.statusCode < 200 || response.statusCode >= 300))) return [3, 2];
|
483 | return [4, failure_1("HTTP CODE " + response.statusCode)];
|
484 | case 1:
|
485 | _a.sent();
|
486 | return [2];
|
487 | case 2:
|
488 | if (!response.body) return [3, 3];
|
489 | debug("RES BODY");
|
490 | responseStr = response.body;
|
491 | return [3, 8];
|
492 | case 3:
|
493 | debug("RES STREAM");
|
494 | responseData = void 0;
|
495 | _a.label = 4;
|
496 | case 4:
|
497 | _a.trys.push([4, 6, , 7]);
|
498 | return [4, BufferUtils_1.streamToBufferPromise(response)];
|
499 | case 5:
|
500 | responseData = _a.sent();
|
501 | return [3, 7];
|
502 | case 6:
|
503 | err_12 = _a.sent();
|
504 | debug(err_12);
|
505 | return [2];
|
506 | case 7:
|
507 | responseStr = responseData.toString("utf8");
|
508 | _a.label = 8;
|
509 | case 8: return [4, handleManifestJson_1(responseStr)];
|
510 | case 9:
|
511 | _a.sent();
|
512 | return [2];
|
513 | }
|
514 | });
|
515 | }); };
|
516 | if (!needsStreamingResponse_1) return [3, 6];
|
517 | promise = new Promise(function (resolve, reject) {
|
518 | request.get({
|
519 | headers: {},
|
520 | method: "GET",
|
521 | uri: publicationFilePath,
|
522 | })
|
523 | .on("response", function (response) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
524 | return tslib_1.__generator(this, function (_a) {
|
525 | switch (_a.label) {
|
526 | case 0: return [4, success_1(response)];
|
527 | case 1:
|
528 | _a.sent();
|
529 | resolve();
|
530 | return [2];
|
531 | }
|
532 | });
|
533 | }); })
|
534 | .on("error", function (err) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
535 | return tslib_1.__generator(this, function (_a) {
|
536 | switch (_a.label) {
|
537 | case 0: return [4, failure_1(err)];
|
538 | case 1:
|
539 | _a.sent();
|
540 | reject();
|
541 | return [2];
|
542 | }
|
543 | });
|
544 | }); });
|
545 | });
|
546 | _a.label = 2;
|
547 | case 2:
|
548 | _a.trys.push([2, 4, , 5]);
|
549 | return [4, promise];
|
550 | case 3:
|
551 | _a.sent();
|
552 | return [3, 5];
|
553 | case 4:
|
554 | err_5 = _a.sent();
|
555 | return [2];
|
556 | case 5: return [3, 13];
|
557 | case 6:
|
558 | response = void 0;
|
559 | _a.label = 7;
|
560 | case 7:
|
561 | _a.trys.push([7, 9, , 11]);
|
562 | return [4, requestPromise({
|
563 | headers: {},
|
564 | method: "GET",
|
565 | resolveWithFullResponse: true,
|
566 | uri: publicationFilePath,
|
567 | })];
|
568 | case 8:
|
569 | response = _a.sent();
|
570 | return [3, 11];
|
571 | case 9:
|
572 | err_6 = _a.sent();
|
573 | return [4, failure_1(err_6)];
|
574 | case 10:
|
575 | _a.sent();
|
576 | return [2];
|
577 | case 11: return [4, success_1(response)];
|
578 | case 12:
|
579 | _a.sent();
|
580 | _a.label = 13;
|
581 | case 13: return [3, 18];
|
582 | case 14:
|
583 | responseStr = fs.readFileSync(publicationFilePath, { encoding: "utf8" });
|
584 | if (!!responseStr) return [3, 16];
|
585 | return [4, failure_1("Cannot read local file: " + publicationFilePath)];
|
586 | case 15:
|
587 | _a.sent();
|
588 | return [2];
|
589 | case 16: return [4, handleManifestJson_1(responseStr)];
|
590 | case 17:
|
591 | _a.sent();
|
592 | _a.label = 18;
|
593 | case 18: return [3, 23];
|
594 | case 19:
|
595 | if (!epub_1.isEPUBlication(publicationFilePath)) return [3, 23];
|
596 | _a.label = 20;
|
597 | case 20:
|
598 | _a.trys.push([20, 22, , 23]);
|
599 | return [4, _publicationsServer.loadOrGetCachedPublication(publicationFilePath)];
|
600 | case 21:
|
601 | publication = _a.sent();
|
602 | return [3, 23];
|
603 | case 22:
|
604 | err_7 = _a.sent();
|
605 | debug(err_7);
|
606 | return [2];
|
607 | case 23:
|
608 | if (!(publication && publication.LCP)) return [3, 28];
|
609 | debug(publication.LCP);
|
610 | _a.label = 24;
|
611 | case 24:
|
612 | _a.trys.push([24, 26, , 27]);
|
613 | return [4, tryLSD(publication, publicationFilePath)];
|
614 | case 25:
|
615 | _a.sent();
|
616 | return [3, 27];
|
617 | case 26:
|
618 | err_8 = _a.sent();
|
619 | debug(err_8);
|
620 | return [3, 27];
|
621 | case 27:
|
622 | blockBecauseLSD = false;
|
623 | if (publication.LCP.LSD) {
|
624 | if (publication.LCP.LSD.Status === "revoked"
|
625 | || publication.LCP.LSD.Status === "returned"
|
626 | || publication.LCP.LSD.Status === "cancelled"
|
627 | || publication.LCP.LSD.Status === "expired") {
|
628 | blockBecauseLSD = true;
|
629 | debug(">>>> LICENSE LSD STATUS BLOCK ACCESS!");
|
630 | }
|
631 | }
|
632 | if (!blockBecauseLSD) {
|
633 | if (publication.LCP.Encryption &&
|
634 | publication.LCP.Encryption.UserKey &&
|
635 | publication.LCP.Encryption.UserKey.TextHint) {
|
636 | lcpHint = publication.LCP.Encryption.UserKey.TextHint;
|
637 | }
|
638 | if (!lcpHint) {
|
639 | lcpHint = "LCP passphrase";
|
640 | }
|
641 | }
|
642 | _a.label = 28;
|
643 | case 28:
|
644 | electronBrowserWindow = new electron_1.BrowserWindow({
|
645 | height: 600,
|
646 | webPreferences: {
|
647 | allowRunningInsecureContent: false,
|
648 | contextIsolation: false,
|
649 | devTools: true,
|
650 | nodeIntegration: true,
|
651 | nodeIntegrationInWorker: false,
|
652 | sandbox: false,
|
653 | webSecurity: true,
|
654 | webviewTag: true,
|
655 | },
|
656 | width: 800,
|
657 | });
|
658 | browser_window_tracker_1.trackBrowserWindow(electronBrowserWindow);
|
659 | electronBrowserWindow.webContents.on("dom-ready", function () {
|
660 | debug("electronBrowserWindow dom-ready " + publicationFilePath + " : " + publicationUrl);
|
661 | });
|
662 | if (!isHttpWebPubWithoutLCP && SECURE && UrlUtils_1.isHTTP(publicationUrl)) {
|
663 | publicationUrl = sessions_1.convertHttpUrlToCustomScheme(publicationUrl);
|
664 | }
|
665 | urlEncoded = UrlUtils_2.encodeURIComponent_RFC3986(publicationUrl);
|
666 | htmlPath = IS_DEV ? __dirname + "/../renderer/index.html" : __dirname + "/index.html";
|
667 | htmlPath = htmlPath.replace(/\\/g, "/");
|
668 | fullUrl = "file://" + htmlPath + "?pub=" + urlEncoded;
|
669 | if (lcpHint) {
|
670 | fullUrl = fullUrl + "&lcpHint=" + UrlUtils_2.encodeURIComponent_RFC3986(lcpHint);
|
671 | }
|
672 | urlRoot = _publicationsServer.serverUrl();
|
673 | fullUrl = fullUrl + "&pubServerRoot=" + UrlUtils_2.encodeURIComponent_RFC3986(urlRoot);
|
674 | if (isHttpWebPubWithoutLCP) {
|
675 | fullUrl = fullUrl + "&isHttpWebPubWithoutLCP=1";
|
676 | }
|
677 | debug(fullUrl);
|
678 | electronBrowserWindow.webContents.loadURL(fullUrl, { extraHeaders: "pragma: no-cache\n" });
|
679 | return [2];
|
680 | }
|
681 | });
|
682 | });
|
683 | }
|
684 | sessions_2.initSessions();
|
685 | var readiumCssDefaultsJson = Object.assign({}, readium_css_settings_1.readiumCSSDefaults);
|
686 | var readiumCssKeys = Object.keys(readium_css_settings_1.readiumCSSDefaults);
|
687 | readiumCssKeys.forEach(function (key) {
|
688 | var value = readium_css_settings_1.readiumCSSDefaults[key];
|
689 | if (typeof value === "undefined") {
|
690 | readiumCssDefaultsJson[key] = null;
|
691 | }
|
692 | else {
|
693 | readiumCssDefaultsJson[key] = value;
|
694 | }
|
695 | });
|
696 | var electronStore = new store_electron_1.StoreElectron("readium2-testapp", {
|
697 | basicLinkTitles: true,
|
698 | readiumCSS: readiumCssDefaultsJson,
|
699 | readiumCSSEnable: false,
|
700 | });
|
701 | function __computeReadiumCssJsonMessage(_publication, _link) {
|
702 | var on = electronStore.get("readiumCSSEnable");
|
703 | if (on) {
|
704 | var cssJson = electronStore.get("readiumCSS");
|
705 | if (!cssJson) {
|
706 | cssJson = readium_css_settings_1.readiumCSSDefaults;
|
707 | }
|
708 | var jsonMsg = {
|
709 | setCSS: cssJson,
|
710 | };
|
711 | return jsonMsg;
|
712 | }
|
713 | else {
|
714 | return { setCSS: undefined };
|
715 | }
|
716 | }
|
717 | var _electronBrowserWindowFileOrUrlDialog;
|
718 | function loadFileOrUrlDialog(initval) {
|
719 | if (_electronBrowserWindowFileOrUrlDialog) {
|
720 | _electronBrowserWindowFileOrUrlDialog.show();
|
721 | debug("_electronBrowserWindowFileOrUrlDialog.show()");
|
722 | return;
|
723 | }
|
724 | var dialogid = uuid.v4().replace(/-/g, "_");
|
725 | var html = "\n<html>\n<head>\n<script type=\"text/javascript\">\n\nconst { ipcRenderer } = require('electron');\n\nipcRenderer.on(\"filePath\", (ev, filePath) => {\n\n const dataEl = document.getElementById('data');\n dataEl.value = filePath;\n});\n\nconst cancel = () => {\nconst payload = {\nurlOrPath: undefined,\n};\nipcRenderer.send(\"" + (events_1.R2_EVENT_OPEN_URL_OR_PATH + dialogid) + "\", payload);\n};\nconst submit = () => {\nconst dataEl = document.getElementById('data');\nconst payload = {\nurlOrPath: dataEl.value,\n};\nipcRenderer.send(\"" + (events_1.R2_EVENT_OPEN_URL_OR_PATH + dialogid) + "\", payload);\n};\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n\ndocument.getElementById('filechoose').addEventListener('click', () => {\n const payload = {\n urlOrPath: undefined,\n fileChooser: true,\n };\n ipcRenderer.send(\"" + (events_1.R2_EVENT_OPEN_URL_OR_PATH + dialogid) + "\", payload);\n});\n\ndocument.getElementById('ok').addEventListener('click', () => submit());\ndocument.getElementById('cancel').addEventListener('click', () => cancel());\n\nconst dataEl = document.getElementById('data');\n\ndataEl.addEventListener('keyup', e => {\ne.which = e.which || e.keyCode;\nif (e.which === 13) {\n submit();\n}\nif (e.which === 27) {\n cancel();\n}\n});\n\ndataEl.focus();\ndataEl.select();\n\nconst drag = (ev) => {\nev.preventDefault();\nreturn false;\n};\nconst drop = (ev) => {\nev.preventDefault();\n\nif (!ev.dataTransfer) {\n return;\n}\n\nlet urlOrPath = undefined;\nif (ev.dataTransfer.items) {\n for (const item of ev.dataTransfer.items) {\n if (item.kind === \"file\") {\n const file = item.getAsFile();\n if (file) {\n console.log(file.name);\n console.log(file.path);\n urlOrPath = file.path;\n break;\n }\n } else if (item.kind === \"string\") {\n if (item.type === \"text/plain\") { /* text/uri-list text/html */\n const data = ev.dataTransfer.getData(item.type);\n console.log(data);\n urlOrPath = data;\n } else {\n console.log(item.type);\n console.log(ev.dataTransfer.getData(item.type));\n }\n } else {\n console.log(item.kind);\n }\n }\n} else if (ev.dataTransfer.files) {\n for (const file of ev.dataTransfer.files) {\n console.log(file.name);\n console.log(file.path);\n urlOrPath = file.path;\n break;\n }\n}\n\nif (urlOrPath) {\n const payload = {\n urlOrPath\n };\n ipcRenderer.send(\"" + (events_1.R2_EVENT_OPEN_URL_OR_PATH + dialogid) + "\", payload);\n}\n\n};\n\nwindow.document.addEventListener(\"dragover\", drag, false);\nwindow.document.addEventListener(\"drop\", drag, false);\n\nconst dropEl = document.getElementById('drop');\n\ndropEl.addEventListener(\"dragover\", drag, false);\ndropEl.addEventListener(\"drop\", drop, false);\n});\n\n</script>\n<style>\nbody {\nfont-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\nline-height: 1.5em;\ncolor: #333;\nbackground-color: #fff;\n}\n\n#container {\n/* align-items: center;\njustify-content: center; */\ndisplay: block;\noverflow: hidden;\n}\n\n#form {\nwidth: 100%;\n}\n\n#label {\nmax-width: 100%;\nmax-height: 100%;\nmargin-bottom: .8em;\npadding: 0 .5em;\n/* white-space: nowrap; */\n/* overflow: hidden; */\n/* text-overflow: ellipsis; */\n}\n\n#data {\nborder-radius: 2px;\nbackground: #fff;\nwidth: 400px;\npadding: .4em .5em;\nborder: 1px solid black;\nmin-height: 2em;\nmargin: 0 0 1.2em;\n}\n\n#data-container {\ntext-align: center;\n}\n\n#buttons {\ntext-align: right;\npadding: 0 .5em 0 0;\n}\n\n#filechoose,\n#buttons > button {\nborder-radius: 2px;\nborder: 0;\nmargin: 0 0 0 .5em;\nfont-size: .8em;\nline-height: 1em;\npadding: .6em 1em;\ncursor: pointer;\n}\n\n#filechoose {\n margin-right: 8px;\n}\n#filechoose, input {\n display: inline-block;\n}\n\n/*\n#ok {\nbackground-color: #3879D9;\ncolor: white;\n}\n\n#cancel {\nbackground-color: #DDD;\ncolor: black;\n}\n*/\n\n*:focus {\noutline-style: solid !important;\noutline-width: 2px !important;\noutline-color: blue !important;\noutline-offset: 2px !important;\n}\n\n#drop {\ndisplay: block;\nmargin-top: 1em;\nwidth: 99%;\nheight: 100px;\ncolor: black;\nbackground-color: #eeffee;\nborder: 1px dashed #333333;\nborder-radius: 8px;\nvertical-align: middle;\ntext-align: center;\n\ndisplay: flex;\njustify-content: center;\nflex-direction: column;\n}\n</style>\n</head>\n<body>\n<div id=\"container\">\n<div id=\"form\">\n<div id=\"label\">Enter URL or filepath:</div>\n<div id=\"data-container\">\n<button id=\"filechoose\">Choose...</button>\n<input id=\"data\" value=\"" + initval + "\"/>\n</div>\n<div id=\"buttons\">\n<button id=\"cancel\">Cancel</button>\n<button id=\"ok\">OK</button>\n</div>\n</div>\n<div id=\"drop\">\nfile drag-and-drop\n</div>\n</div>\n</body>\n</html>\n ";
|
726 | _electronBrowserWindowFileOrUrlDialog = new electron_1.BrowserWindow({
|
727 | alwaysOnTop: true,
|
728 | height: 300,
|
729 | modal: false,
|
730 | resizable: false,
|
731 | skipTaskbar: false,
|
732 | title: "Readium2 Electron/NodeJS test app",
|
733 | useContentSize: false,
|
734 | webPreferences: {
|
735 | allowRunningInsecureContent: false,
|
736 | contextIsolation: false,
|
737 | devTools: true,
|
738 | nodeIntegration: true,
|
739 | nodeIntegrationInWorker: false,
|
740 | sandbox: false,
|
741 | webSecurity: true,
|
742 | webviewTag: false,
|
743 | },
|
744 | width: 600,
|
745 | });
|
746 | resetMenu(undefined);
|
747 | function dialogResult(_event, payload) {
|
748 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
749 | var _this = this;
|
750 | return tslib_1.__generator(this, function (_a) {
|
751 | if (payload.urlOrPath) {
|
752 | process.nextTick(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
753 | return tslib_1.__generator(this, function (_a) {
|
754 | switch (_a.label) {
|
755 | case 0: return [4, loadFileOrUrl(payload.urlOrPath)];
|
756 | case 1:
|
757 | _a.sent();
|
758 | return [2];
|
759 | }
|
760 | });
|
761 | }); });
|
762 | setTimeout(function () {
|
763 | if (_electronBrowserWindowFileOrUrlDialog) {
|
764 | _electronBrowserWindowFileOrUrlDialog.close();
|
765 | }
|
766 | }, 200);
|
767 | }
|
768 | else if (payload.fileChooser) {
|
769 | process.nextTick(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
770 | var choice, filePath;
|
771 | return tslib_1.__generator(this, function (_a) {
|
772 | choice = electron_1.dialog.showOpenDialog({
|
773 | defaultPath: _lastBookPath,
|
774 | filters: [
|
775 | { name: "EPUB publication", extensions: ["epub", "epub3"] },
|
776 | { name: "LCP license", extensions: ["lcpl"] },
|
777 | { name: "Comic book", extensions: ["cbz"] },
|
778 | ],
|
779 | message: "Choose a file",
|
780 | properties: ["openFile"],
|
781 | title: "Open from filesystem",
|
782 | });
|
783 | if (!choice || !choice.length) {
|
784 | return [2];
|
785 | }
|
786 | filePath = choice[0];
|
787 | debug(filePath);
|
788 | if (_electronBrowserWindowFileOrUrlDialog) {
|
789 | _electronBrowserWindowFileOrUrlDialog.webContents.send("filePath", filePath);
|
790 | }
|
791 | return [2];
|
792 | });
|
793 | }); });
|
794 | }
|
795 | else {
|
796 | if (_electronBrowserWindowFileOrUrlDialog) {
|
797 | _electronBrowserWindowFileOrUrlDialog.close();
|
798 | }
|
799 | }
|
800 | return [2];
|
801 | });
|
802 | });
|
803 | }
|
804 | electron_1.ipcMain.on(events_1.R2_EVENT_OPEN_URL_OR_PATH + dialogid, dialogResult);
|
805 | _electronBrowserWindowFileOrUrlDialog.on("closed", function (_ev) {
|
806 | electron_1.ipcMain.removeListener(events_1.R2_EVENT_OPEN_URL_OR_PATH + dialogid, dialogResult);
|
807 | _electronBrowserWindowFileOrUrlDialog = undefined;
|
808 | });
|
809 | _electronBrowserWindowFileOrUrlDialog.webContents.loadURL("data:text/html," + html);
|
810 | }
|
811 | electron_1.ipcMain.on(events_1.R2_EVENT_OPEN_URL_OR_PATH, function (_event, payload) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
812 | return tslib_1.__generator(this, function (_a) {
|
813 | switch (_a.label) {
|
814 | case 0: return [4, loadFileOrUrl(payload.urlOrPath)];
|
815 | case 1:
|
816 | _a.sent();
|
817 | return [2];
|
818 | }
|
819 | });
|
820 | }); });
|
821 | function loadFileOrUrl(argPath) {
|
822 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
823 | var filePathToLoadOnLaunch, filePath, _a;
|
824 | return tslib_1.__generator(this, function (_b) {
|
825 | switch (_b.label) {
|
826 | case 0:
|
827 | filePath = argPath;
|
828 | debug(filePath);
|
829 | if (!UrlUtils_1.isHTTP(filePath)) return [3, 2];
|
830 | return [4, openFile(filePath)];
|
831 | case 1:
|
832 | _b.sent();
|
833 | return [2, true];
|
834 | case 2:
|
835 | if (!fs.existsSync(filePath)) {
|
836 | filePath = path.join(__dirname, argPath);
|
837 | debug(filePath);
|
838 | if (!fs.existsSync(filePath)) {
|
839 | filePath = path.join(process.cwd(), argPath);
|
840 | debug(filePath);
|
841 | if (!fs.existsSync(filePath)) {
|
842 | debug("FILEPATH DOES NOT EXIST: " + filePath);
|
843 | }
|
844 | else {
|
845 | filePathToLoadOnLaunch = filePath;
|
846 | }
|
847 | }
|
848 | else {
|
849 | filePathToLoadOnLaunch = filePath;
|
850 | }
|
851 | }
|
852 | else {
|
853 | filePath = fs.realpathSync(filePath);
|
854 | debug(filePath);
|
855 | filePathToLoadOnLaunch = filePath;
|
856 | }
|
857 | _b.label = 3;
|
858 | case 3:
|
859 | if (!filePathToLoadOnLaunch) return [3, 9];
|
860 | _a = epub_1.isEPUBlication(filePathToLoadOnLaunch);
|
861 | if (_a) return [3, 5];
|
862 | return [4, isManifestJSON(filePathToLoadOnLaunch)];
|
863 | case 4:
|
864 | _a = (_b.sent());
|
865 | _b.label = 5;
|
866 | case 5:
|
867 | if (!_a) return [3, 7];
|
868 | return [4, openFile(filePathToLoadOnLaunch)];
|
869 | case 6:
|
870 | _b.sent();
|
871 | return [2, true];
|
872 | case 7:
|
873 | if (!!fs.lstatSync(filePathToLoadOnLaunch).isDirectory()) return [3, 9];
|
874 | return [4, openFileDownload(filePathToLoadOnLaunch)];
|
875 | case 8:
|
876 | _b.sent();
|
877 | return [2, true];
|
878 | case 9: return [2, false];
|
879 | }
|
880 | });
|
881 | });
|
882 | }
|
883 | electron_1.app.on("ready", function () {
|
884 | debug("app ready");
|
885 | (function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
886 | var readiumCSSPath, preloadPath, distTarget, dirnameSlashed, staticOptions, err_13, pubPaths;
|
887 | var _this = this;
|
888 | return tslib_1.__generator(this, function (_a) {
|
889 | switch (_a.label) {
|
890 | case 0:
|
891 | _publicationsFilePaths = [];
|
892 | _publicationsUrls = [];
|
893 | _publicationsServer = new server_1.Server({
|
894 | disableDecryption: false,
|
895 | disableOPDS: true,
|
896 | disableReaders: true,
|
897 | disableRemotePubUrl: true,
|
898 | });
|
899 | if (SECURE) {
|
900 | sessions_2.secureSessions(_publicationsServer);
|
901 | }
|
902 | lcp_3.installLcpHandler(_publicationsServer);
|
903 | lsd_1.installLsdHandler(_publicationsServer, deviceIDManager);
|
904 | readiumCSSPath = IS_DEV ?
|
905 | path.join(process.cwd(), "dist", "ReadiumCSS").replace(/\\/g, "/") :
|
906 | path.join(__dirname, "ReadiumCSS").replace(/\\/g, "/");
|
907 | readium_css_1.setupReadiumCSS(_publicationsServer, readiumCSSPath, __computeReadiumCssJsonMessage);
|
908 | if (IS_DEV) {
|
909 | preloadPath = "FOLDER_PATH_TO/preload.js";
|
910 | distTarget = void 0;
|
911 | dirnameSlashed = __dirname.replace(/\\/g, "/");
|
912 | if (dirnameSlashed.indexOf("/dist/es5") > 0) {
|
913 | distTarget = "es5";
|
914 | }
|
915 | else if (dirnameSlashed.indexOf("/dist/es6-es2015") > 0) {
|
916 | distTarget = "es6-es2015";
|
917 | }
|
918 | else if (dirnameSlashed.indexOf("/dist/es7-es2016") > 0) {
|
919 | distTarget = "es7-es2016";
|
920 | }
|
921 | else if (dirnameSlashed.indexOf("/dist/es8-es2017") > 0) {
|
922 | distTarget = "es8-es2017";
|
923 | }
|
924 | if (distTarget) {
|
925 | preloadPath = path.join(process.cwd(), "node_modules/r2-navigator-js/dist/" +
|
926 | distTarget);
|
927 | }
|
928 | preloadPath = preloadPath.replace(/\\/g, "/");
|
929 | console.log(preloadPath);
|
930 | staticOptions = {
|
931 | dotfiles: "ignore",
|
932 | etag: true,
|
933 | fallthrough: false,
|
934 | immutable: true,
|
935 | index: false,
|
936 | maxAge: "1d",
|
937 | redirect: false,
|
938 | };
|
939 | _publicationsServer.expressUse(preloadPath, express.static(preloadPath, staticOptions));
|
940 | }
|
941 | _a.label = 1;
|
942 | case 1:
|
943 | _a.trys.push([1, 3, , 4]);
|
944 | return [4, portfinder.getPortPromise()];
|
945 | case 2:
|
946 | _publicationsServerPort = _a.sent();
|
947 | return [3, 4];
|
948 | case 3:
|
949 | err_13 = _a.sent();
|
950 | debug(err_13);
|
951 | return [3, 4];
|
952 | case 4: return [4, _publicationsServer.start(_publicationsServerPort, SECURE)];
|
953 | case 5:
|
954 | _a.sent();
|
955 | _publicationsRootUrl = _publicationsServer.serverUrl();
|
956 | debug(_publicationsRootUrl);
|
957 | if (_publicationsFilePaths && _publicationsFilePaths.length) {
|
958 | pubPaths = _publicationsServer.addPublications(_publicationsFilePaths);
|
959 | _publicationsUrls = pubPaths.map(function (pubPath) {
|
960 | return "" + _publicationsRootUrl + pubPath;
|
961 | });
|
962 | debug(_publicationsUrls);
|
963 | }
|
964 | resetMenu(undefined);
|
965 | process.nextTick(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
966 | var args, argPath;
|
967 | return tslib_1.__generator(this, function (_a) {
|
968 | switch (_a.label) {
|
969 | case 0:
|
970 | args = process.argv.slice(2);
|
971 | debug("args:");
|
972 | debug(args);
|
973 | if (!(args && args.length && args[0])) return [3, 2];
|
974 | argPath = args[0].trim();
|
975 | return [4, loadFileOrUrl(argPath)];
|
976 | case 1:
|
977 | if (_a.sent()) {
|
978 | return [2];
|
979 | }
|
980 | _a.label = 2;
|
981 | case 2:
|
982 | loadFileOrUrlDialog("");
|
983 | return [2];
|
984 | }
|
985 | });
|
986 | }); });
|
987 | return [2];
|
988 | }
|
989 | });
|
990 | }); })();
|
991 | });
|
992 | function resetMenu(browserWindow) {
|
993 | var _this = this;
|
994 | var menuTemplate = [
|
995 | {
|
996 | label: "Readium2 Electron",
|
997 | submenu: [
|
998 | { label: "About...", selector: "orderFrontStandardAboutPanel:" },
|
999 | { type: "separator" },
|
1000 | {
|
1001 | accelerator: "Command+Q",
|
1002 | click: function () { electron_1.app.quit(); },
|
1003 | label: "Quit",
|
1004 | },
|
1005 | ],
|
1006 | },
|
1007 | {
|
1008 | label: "File",
|
1009 | submenu: [],
|
1010 | },
|
1011 | {
|
1012 | label: "Edit",
|
1013 | submenu: [
|
1014 | { label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
|
1015 | { label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
|
1016 | { type: "separator" },
|
1017 | { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
|
1018 | { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
|
1019 | { label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
|
1020 | { label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" },
|
1021 | ],
|
1022 | },
|
1023 | {
|
1024 | role: "window",
|
1025 | submenu: [
|
1026 | {
|
1027 | role: "togglefullscreen",
|
1028 | },
|
1029 | {
|
1030 | role: "minimize",
|
1031 | },
|
1032 | {
|
1033 | role: "close",
|
1034 | },
|
1035 | ],
|
1036 | },
|
1037 | {
|
1038 | label: "Tools",
|
1039 | submenu: [
|
1040 | {
|
1041 | accelerator: "CmdOrCtrl+R",
|
1042 | click: function (_item, focusedWindow) {
|
1043 | if (focusedWindow) {
|
1044 | focusedWindow.reload();
|
1045 | }
|
1046 | },
|
1047 | label: "Reload",
|
1048 | },
|
1049 | {
|
1050 | accelerator: process.platform === "darwin" ? "Alt+Command+I" : "Ctrl+Shift+I",
|
1051 | click: function (_item, _focusedWindow) {
|
1052 | openAllDevTools();
|
1053 | },
|
1054 | label: "Dev Tools (all)",
|
1055 | },
|
1056 | {
|
1057 | accelerator: process.platform === "darwin" ? "Shift+Alt+Command+I" : "Alt+Ctrl+Shift+I",
|
1058 | click: function (_item, _focusedWindow) {
|
1059 | openTopLevelDevTools();
|
1060 | },
|
1061 | label: "Dev Tools (top only)",
|
1062 | },
|
1063 | ],
|
1064 | },
|
1065 | {
|
1066 | role: "help",
|
1067 | submenu: [
|
1068 | {
|
1069 | click: function (_item, _focusedWindow) {
|
1070 | electron_1.shell.openExternal("https://github.com/readium/r2-testapp-js/");
|
1071 | },
|
1072 | label: "Website...",
|
1073 | },
|
1074 | ],
|
1075 | },
|
1076 | ];
|
1077 | menuTemplate[1].submenu.push({
|
1078 | accelerator: "CmdOrCtrl+O",
|
1079 | click: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
1080 | return tslib_1.__generator(this, function (_a) {
|
1081 | loadFileOrUrlDialog("");
|
1082 | return [2];
|
1083 | });
|
1084 | }); },
|
1085 | label: "Open...",
|
1086 | });
|
1087 | menuTemplate[1].submenu.push({
|
1088 | type: "separator",
|
1089 | });
|
1090 | _publicationsUrls.forEach(function (pubManifestUrl, n) {
|
1091 | var filePath = _publicationsFilePaths[n];
|
1092 | debug("MENU ITEM: " + filePath + " : " + pubManifestUrl);
|
1093 | menuTemplate[1].submenu.push({
|
1094 | click: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
1095 | return tslib_1.__generator(this, function (_a) {
|
1096 | switch (_a.label) {
|
1097 | case 0:
|
1098 | debug(filePath);
|
1099 | return [4, openFileDownload(filePath)];
|
1100 | case 1:
|
1101 | _a.sent();
|
1102 | return [2];
|
1103 | }
|
1104 | });
|
1105 | }); },
|
1106 | label: filePath,
|
1107 | });
|
1108 | });
|
1109 | var menu = electron_1.Menu.buildFromTemplate(menuTemplate);
|
1110 | if (browserWindow) {
|
1111 | browserWindow.setMenu(menu);
|
1112 | }
|
1113 | else {
|
1114 | electron_1.Menu.setApplicationMenu(menu);
|
1115 | }
|
1116 | }
|
1117 | function openFileDownload(filePath) {
|
1118 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
1119 | var dir, ext, filename, destFileName, epubFilePath, err_14, result_1;
|
1120 | var _this = this;
|
1121 | return tslib_1.__generator(this, function (_a) {
|
1122 | switch (_a.label) {
|
1123 | case 0:
|
1124 | dir = path.dirname(filePath);
|
1125 | _lastBookPath = dir;
|
1126 | debug(_lastBookPath);
|
1127 | ext = path.extname(filePath);
|
1128 | filename = path.basename(filePath);
|
1129 | destFileName = filename + ".epub";
|
1130 | if (!(ext === ".lcpl")) return [3, 5];
|
1131 | epubFilePath = void 0;
|
1132 | _a.label = 1;
|
1133 | case 1:
|
1134 | _a.trys.push([1, 3, , 4]);
|
1135 | return [4, publication_download_1.downloadEPUBFromLCPL(filePath, dir, destFileName)];
|
1136 | case 2:
|
1137 | epubFilePath = _a.sent();
|
1138 | return [3, 4];
|
1139 | case 3:
|
1140 | err_14 = _a.sent();
|
1141 | process.nextTick(function () {
|
1142 | var detail = (typeof err_14 === "string") ?
|
1143 | err_14 :
|
1144 | (err_14.toString ? err_14.toString() : "ERROR!?");
|
1145 | var message = "LCP EPUB download fail!]";
|
1146 | var res = electron_1.dialog.showMessageBox({
|
1147 | buttons: ["&OK"],
|
1148 | cancelId: 0,
|
1149 | defaultId: 0,
|
1150 | detail: detail,
|
1151 | message: message,
|
1152 | noLink: true,
|
1153 | normalizeAccessKeys: true,
|
1154 | title: "Readium2 Electron streamer / navigator",
|
1155 | type: "info",
|
1156 | });
|
1157 | if (res === 0) {
|
1158 | debug("ok");
|
1159 | }
|
1160 | });
|
1161 | return [2];
|
1162 | case 4:
|
1163 | result_1 = epubFilePath;
|
1164 | process.nextTick(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
1165 | var detail, message, res;
|
1166 | return tslib_1.__generator(this, function (_a) {
|
1167 | switch (_a.label) {
|
1168 | case 0:
|
1169 | detail = result_1[0] + " ---- [" + result_1[1] + "]";
|
1170 | message = "LCP EPUB file download success [" + destFileName + "]";
|
1171 | res = electron_1.dialog.showMessageBox({
|
1172 | buttons: ["&OK"],
|
1173 | cancelId: 0,
|
1174 | defaultId: 0,
|
1175 | detail: detail,
|
1176 | message: message,
|
1177 | noLink: true,
|
1178 | normalizeAccessKeys: true,
|
1179 | title: "Readium2 Electron streamer / navigator",
|
1180 | type: "info",
|
1181 | });
|
1182 | if (res === 0) {
|
1183 | debug("ok");
|
1184 | }
|
1185 | return [4, openFile(result_1[0])];
|
1186 | case 1:
|
1187 | _a.sent();
|
1188 | return [2];
|
1189 | }
|
1190 | });
|
1191 | }); });
|
1192 | return [3, 7];
|
1193 | case 5: return [4, openFile(filePath)];
|
1194 | case 6:
|
1195 | _a.sent();
|
1196 | _a.label = 7;
|
1197 | case 7: return [2];
|
1198 | }
|
1199 | });
|
1200 | });
|
1201 | }
|
1202 | function openFile(filePath) {
|
1203 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
1204 | var n, publicationPaths, file, pubManifestUrl;
|
1205 | return tslib_1.__generator(this, function (_a) {
|
1206 | switch (_a.label) {
|
1207 | case 0:
|
1208 | n = _publicationsFilePaths.indexOf(filePath);
|
1209 | if (!(n < 0)) return [3, 2];
|
1210 | return [4, isManifestJSON(filePath)];
|
1211 | case 1:
|
1212 | if (_a.sent()) {
|
1213 | _publicationsFilePaths.push(filePath);
|
1214 | debug(_publicationsFilePaths);
|
1215 | _publicationsUrls.push(filePath);
|
1216 | debug(_publicationsUrls);
|
1217 | n = _publicationsFilePaths.length - 1;
|
1218 | }
|
1219 | else {
|
1220 | publicationPaths = _publicationsServer.addPublications([filePath]);
|
1221 | debug(publicationPaths);
|
1222 | _publicationsFilePaths.push(filePath);
|
1223 | debug(_publicationsFilePaths);
|
1224 | _publicationsUrls.push("" + _publicationsRootUrl + publicationPaths[0]);
|
1225 | debug(_publicationsUrls);
|
1226 | n = _publicationsFilePaths.length - 1;
|
1227 | }
|
1228 | process.nextTick(function () {
|
1229 | resetMenu(undefined);
|
1230 | });
|
1231 | _a.label = 2;
|
1232 | case 2:
|
1233 | file = _publicationsFilePaths[n];
|
1234 | pubManifestUrl = _publicationsUrls[n];
|
1235 | return [4, createElectronBrowserWindow(file, pubManifestUrl)];
|
1236 | case 3:
|
1237 | _a.sent();
|
1238 | return [2];
|
1239 | }
|
1240 | });
|
1241 | });
|
1242 | }
|
1243 | electron_1.app.on("activate", function () {
|
1244 | debug("app activate");
|
1245 | });
|
1246 | electron_1.app.on("before-quit", function () {
|
1247 | debug("app before quit");
|
1248 | });
|
1249 | electron_1.app.on("window-all-closed", function () {
|
1250 | debug("app window-all-closed");
|
1251 | setTimeout(function () {
|
1252 | electron_1.dialog.showMessageBox({
|
1253 | buttons: ["yes", "no"],
|
1254 | cancelId: 1,
|
1255 | checkboxChecked: undefined,
|
1256 | checkboxLabel: undefined,
|
1257 | defaultId: 0,
|
1258 | detail: undefined,
|
1259 | icon: undefined,
|
1260 | message: "Do you want to exit this application?",
|
1261 | noLink: true,
|
1262 | normalizeAccessKeys: false,
|
1263 | title: "Readium2 test app, exit?",
|
1264 | type: "question",
|
1265 | }, function (response, _checkboxChecked) {
|
1266 | if (response === 0) {
|
1267 | electron_1.app.quit();
|
1268 | }
|
1269 | else {
|
1270 | loadFileOrUrlDialog("");
|
1271 | }
|
1272 | });
|
1273 | }, 300);
|
1274 | });
|
1275 | electron_1.app.on("quit", function () {
|
1276 | debug("app quit");
|
1277 | _publicationsServer.stop();
|
1278 | });
|
1279 |
|
\ | No newline at end of file |