UNPKG

16.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.serverOPDS_browse_v1 = exports.serverOPDS_browse_v1_PATH = void 0;
4var tslib_1 = require("tslib");
5var debug_ = require("debug");
6var express = require("express");
7var morgan = require("morgan");
8var request = require("request");
9var requestPromise = require("request-promise-native");
10var xmldom = require("xmldom");
11var opds_1 = require("r2-opds-js/dist/es5/src/opds/opds1/opds");
12var opds_entry_1 = require("r2-opds-js/dist/es5/src/opds/opds1/opds-entry");
13var UrlUtils_1 = require("r2-utils-js/dist/es5/src/_utils/http/UrlUtils");
14var BufferUtils_1 = require("r2-utils-js/dist/es5/src/_utils/stream/BufferUtils");
15var xml_js_mapper_1 = require("r2-utils-js/dist/es5/src/_utils/xml-js-mapper");
16var request_ext_1 = require("./request-ext");
17var server_lcp_lsd_show_1 = require("./server-lcp-lsd-show");
18var server_trailing_slash_redirect_1 = require("./server-trailing-slash-redirect");
19var server_url_1 = require("./server-url");
20var debug = debug_("r2:streamer#http/server-opds-browse-v1");
21exports.serverOPDS_browse_v1_PATH = "/opds-v1-browse";
22function serverOPDS_browse_v1(_server, topRouter) {
23 var _this = this;
24 var routerOPDS_browse_v1 = express.Router({ strict: false });
25 routerOPDS_browse_v1.use(morgan("combined", { stream: { write: function (msg) { return debug(msg); } } }));
26 routerOPDS_browse_v1.use(server_trailing_slash_redirect_1.trailingSlashRedirect);
27 routerOPDS_browse_v1.get("/", function (_req, res) {
28 var html = "<html><head>";
29 html += "<script type=\"text/javascript\">function encodeURIComponent_RFC3986(str) { " +
30 "return encodeURIComponent(str).replace(/[!'()*]/g, (c) => { " +
31 "return \"%\" + c.charCodeAt(0).toString(16); }); }" +
32 "function go(evt) {" +
33 "if (evt) { evt.preventDefault(); } var url = " +
34 "location.origin +" +
35 (" '" + exports.serverOPDS_browse_v1_PATH + "/' +") +
36 " encodeURIComponent_RFC3986(document.getElementById(\"url\").value);" +
37 "location.href = url;}</script>";
38 html += "</head>";
39 html += "<body><h1>OPDS feed browser</h1>";
40 html += "<form onsubmit=\"go();return false;\">" +
41 "<input type=\"text\" name=\"url\" id=\"url\" size=\"80\">" +
42 "<input type=\"submit\" value=\"Go!\"></form>";
43 html += "</body></html>";
44 res.status(200).send(html);
45 });
46 routerOPDS_browse_v1.param("urlEncoded", function (req, _res, next, value, _name) {
47 req.urlEncoded = value;
48 next();
49 });
50 routerOPDS_browse_v1.get("/:" + request_ext_1._urlEncoded + "(*)", function (req, res) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
51 var reqparams, urlDecoded, failure, success, headers, needsStreamingResponse, response, err_1;
52 var _this = this;
53 return tslib_1.__generator(this, function (_a) {
54 switch (_a.label) {
55 case 0:
56 reqparams = req.params;
57 if (!reqparams.urlEncoded) {
58 reqparams.urlEncoded = req.urlEncoded;
59 }
60 urlDecoded = reqparams.urlEncoded;
61 debug(urlDecoded);
62 failure = function (err) {
63 debug(err);
64 res.status(500).send("<html><body><p>Internal Server Error</p><p>"
65 + err + "</p></body></html>");
66 };
67 success = function (response) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
68 function processEntry(entry) {
69 html += "<hr/>";
70 html += "<div>";
71 if (opds) {
72 html += "<h3>" + entry.Title + "</h3>";
73 }
74 if (entry.Summary) {
75 if (!entry.SummaryType || entry.SummaryType === "text") {
76 html += "<strong>" + entry.Summary + "</strong>";
77 }
78 else if (entry.SummaryType === "html") {
79 html += "<div>" + entry.Summary + "</div>";
80 }
81 html += "<br/>";
82 }
83 if (entry.Content) {
84 if (!entry.ContentType || entry.ContentType === "text") {
85 html += "<strong>" + entry.Content + "</strong>";
86 }
87 else if (entry.ContentType === "html") {
88 html += "<div>" + entry.Content + "</div>";
89 }
90 html += "<br/>";
91 }
92 if (entry.Links && entry.Links.length) {
93 var image_1;
94 var imageThumbnail_1;
95 var epub_1;
96 entry.Links.forEach(function (link) {
97 if (link.Type === "application/epub+zip") {
98 epub_1 = link.Href;
99 }
100 if (link.HasRel("http://opds-spec.org/image")
101 || link.HasRel("x-stanza-cover-image")) {
102 image_1 = link.Href;
103 }
104 if (link.HasRel("http://opds-spec.org/image/thumbnail")
105 || link.HasRel("http://opds-spec.org/thumbnail")
106 || link.HasRel("x-stanza-cover-image-thumbnail")) {
107 imageThumbnail_1 = link.Href;
108 }
109 if (opds && link.Type &&
110 (link.Type.indexOf("opds-catalog") >= 0 || link.Type === "application/atom+xml")) {
111 var linkUrl = UrlUtils_1.ensureAbsolute(urlDecoded, link.Href);
112 var opdsUrl = req.originalUrl.substr(0, req.originalUrl.indexOf(exports.serverOPDS_browse_v1_PATH + "/"))
113 + exports.serverOPDS_browse_v1_PATH + "/" + UrlUtils_1.encodeURIComponent_RFC3986(linkUrl);
114 html += "<a href='" + opdsUrl
115 + "'>" + link.Href + "</a> (TITLE: " + link.Title
116 + ") [REL: " + link.Rel + "]<br/>";
117 }
118 else if (opds && link.Type &&
119 (link.Type === "application/vnd.readium.lcp.license.v1.0+json")) {
120 var linkUrl = UrlUtils_1.ensureAbsolute(urlDecoded, link.Href);
121 var opdsUrl = req.originalUrl.substr(0, req.originalUrl.indexOf(exports.serverOPDS_browse_v1_PATH + "/"))
122 + server_lcp_lsd_show_1.serverLCPLSD_show_PATH + "/" + UrlUtils_1.encodeURIComponent_RFC3986(linkUrl);
123 html += "<a href='" + opdsUrl
124 + "'>" + link.Href + "</a> (TITLE: " + link.Title
125 + ") [REL: " + link.Rel + "]<br/>";
126 }
127 });
128 if (imageThumbnail_1) {
129 var imageThumbnailUrl = UrlUtils_1.ensureAbsolute(urlDecoded, imageThumbnail_1);
130 if (image_1) {
131 var imageUrl = UrlUtils_1.ensureAbsolute(urlDecoded, image_1);
132 html += "<a href='" + imageUrl + "'><img src='"
133 + imageThumbnailUrl + "' alt='' /></a><br/>";
134 }
135 else {
136 html += "<img src='" + imageThumbnailUrl + "' alt='' /><br/>";
137 }
138 }
139 else if (image_1) {
140 var imageUrl = UrlUtils_1.ensureAbsolute(urlDecoded, image_1);
141 html += "<img src='" + imageUrl + "' alt='' /><br/>";
142 }
143 if (epub_1) {
144 var epub_ = UrlUtils_1.ensureAbsolute(urlDecoded, epub_1);
145 var epubUrl = req.originalUrl.substr(0, req.originalUrl.indexOf(exports.serverOPDS_browse_v1_PATH + "/"))
146 + server_url_1.serverRemotePub_PATH + "/" + UrlUtils_1.encodeURIComponent_RFC3986(epub_);
147 html += "<strong><a href='" + epubUrl + "'>" + epub_1 + "</a></strong>";
148 }
149 }
150 html += "</div>";
151 }
152 var responseData, err_2, responseStr, responseXml, isEntry, opds, opdsEntry, html, iconUrl, links;
153 return tslib_1.__generator(this, function (_a) {
154 switch (_a.label) {
155 case 0:
156 if (response.statusCode && (response.statusCode < 200 || response.statusCode >= 300)) {
157 failure("HTTP CODE " + response.statusCode);
158 return [2];
159 }
160 _a.label = 1;
161 case 1:
162 _a.trys.push([1, 3, , 4]);
163 return [4, BufferUtils_1.streamToBufferPromise(response)];
164 case 2:
165 responseData = _a.sent();
166 return [3, 4];
167 case 3:
168 err_2 = _a.sent();
169 debug(err_2);
170 res.status(500).send("<html><body><p>Internal Server Error</p><p>"
171 + err_2 + "</p></body></html>");
172 return [2];
173 case 4:
174 responseStr = responseData.toString("utf8");
175 responseXml = new xmldom.DOMParser().parseFromString(responseStr);
176 if (!responseXml || !responseXml.documentElement) {
177 res.status(500).send("<html><body><p>Internal Server Error</p><p>"
178 + "XML parse fail" + "</p></body></html>");
179 return [2];
180 }
181 isEntry = responseXml.documentElement.localName === "entry";
182 if (isEntry) {
183 opdsEntry = xml_js_mapper_1.XML.deserialize(responseXml, opds_entry_1.Entry);
184 }
185 else {
186 opds = xml_js_mapper_1.XML.deserialize(responseXml, opds_1.OPDS);
187 }
188 html = "<html><head>";
189 html += "</head>";
190 html += "<body><h1>" + urlDecoded + "</h1>";
191 if (opds && opds.Title) {
192 html += "<h2>" + opds.Title + "</h2>";
193 }
194 if (opdsEntry && opdsEntry.Title) {
195 html += "<h2>" + opdsEntry.Title + "</h2>";
196 }
197 if (opds && opds.Icon) {
198 iconUrl = UrlUtils_1.ensureAbsolute(urlDecoded, opds.Icon);
199 html += "<img src='" + iconUrl + "' alt='' />";
200 }
201 links = opds ? opds.Links : (opdsEntry ? opdsEntry.Links : undefined);
202 if (links && links.length) {
203 html += "<p>";
204 links.forEach(function (link) {
205 if (link.Type &&
206 (link.Type.indexOf("opds-catalog") >= 0 || link.Type === "application/atom+xml")) {
207 var linkUrl = UrlUtils_1.ensureAbsolute(urlDecoded, link.Href);
208 var opdsUrl = req.originalUrl.substr(0, req.originalUrl.indexOf(exports.serverOPDS_browse_v1_PATH + "/"))
209 + exports.serverOPDS_browse_v1_PATH + "/" + UrlUtils_1.encodeURIComponent_RFC3986(linkUrl);
210 html += "<a href='" + opdsUrl
211 + "'>" + link.Href + "</a> (TITLE: " + link.Title
212 + ") [REL: " + link.Rel + "]<br/>";
213 }
214 });
215 html += "</p>";
216 }
217 if (opds && opds.Entries && opds.Entries.length) {
218 opds.Entries.forEach(function (entry) {
219 processEntry(entry);
220 });
221 }
222 if (opdsEntry) {
223 processEntry(opdsEntry);
224 }
225 html += "</body></html>";
226 res.status(200).send(html);
227 return [2];
228 }
229 });
230 }); };
231 headers = {
232 "Accept": "application/json,application/xml",
233 "Accept-Language": "en-UK,en-US;q=0.7,en;q=0.5",
234 "User-Agent": "READIUM2",
235 };
236 needsStreamingResponse = true;
237 if (!needsStreamingResponse) return [3, 1];
238 request.get({
239 headers: headers,
240 method: "GET",
241 uri: urlDecoded,
242 })
243 .on("response", success)
244 .on("error", failure);
245 return [3, 7];
246 case 1:
247 response = void 0;
248 _a.label = 2;
249 case 2:
250 _a.trys.push([2, 4, , 5]);
251 return [4, requestPromise({
252 headers: headers,
253 method: "GET",
254 resolveWithFullResponse: true,
255 uri: urlDecoded,
256 })];
257 case 3:
258 response = _a.sent();
259 return [3, 5];
260 case 4:
261 err_1 = _a.sent();
262 failure(err_1);
263 return [2];
264 case 5: return [4, success(response)];
265 case 6:
266 _a.sent();
267 _a.label = 7;
268 case 7: return [2];
269 }
270 });
271 }); });
272 topRouter.use(exports.serverOPDS_browse_v1_PATH, routerOPDS_browse_v1);
273}
274exports.serverOPDS_browse_v1 = serverOPDS_browse_v1;
275//# sourceMappingURL=server-opds-browse-v1.js.map
\No newline at end of file