diff options
Diffstat (limited to 'src/mimehooks.c')
-rw-r--r-- | src/mimehooks.c | 112 |
1 files changed, 10 insertions, 102 deletions
diff --git a/src/mimehooks.c b/src/mimehooks.c index 931c8138..364449ec 100644 --- a/src/mimehooks.c +++ b/src/mimehooks.c | |||
@@ -23,9 +23,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
23 | #include "mimehooks.h" | 23 | #include "mimehooks.h" |
24 | #include "defs.h" | 24 | #include "defs.h" |
25 | #include "gmutil.h" | 25 | #include "gmutil.h" |
26 | #include "gempub.h" | ||
26 | #include "app.h" | 27 | #include "app.h" |
27 | 28 | ||
28 | #include <the_Foundation/archive.h> | ||
29 | #include <the_Foundation/file.h> | 29 | #include <the_Foundation/file.h> |
30 | #include <the_Foundation/fileinfo.h> | 30 | #include <the_Foundation/fileinfo.h> |
31 | #include <the_Foundation/path.h> | 31 | #include <the_Foundation/path.h> |
@@ -203,112 +203,20 @@ finished: | |||
203 | return output; | 203 | return output; |
204 | } | 204 | } |
205 | 205 | ||
206 | static void appendGemPubProperty_(iString *out, const char *key, const iString *value) { | 206 | iBlock *translateGemPubCoverPage_(const iBlock *source, const iString *requestUrl) { |
207 | if (!isEmpty_String(value)) { | ||
208 | appendFormat_String(out, "%s %s\n", key, cstr_String(value)); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | iBlock *translateGemPubCoverPage_(const iString *mime, const iBlock *source, | ||
213 | const iString *requestUrl) { | ||
214 | iBlock *output = NULL; | 207 | iBlock *output = NULL; |
215 | iArchive *arch = new_Archive(); | 208 | iGempub *gempub = new_Gempub(); |
216 | if (openData_Archive(arch, source)) { | 209 | if (open_Gempub(gempub, source)) { |
217 | /* Parse the metadata and check if the required contents are present. */ | 210 | setBaseUrl_Gempub(gempub, requestUrl); |
218 | const iBlock *metadata = dataCStr_Archive(arch, "metadata.txt"); | 211 | output = newCStr_Block("20 text/gemini; charset=utf-8\r\n"); |
219 | if (!metadata) { | 212 | append_Block(output, collect_Block(coverPageSource_Gempub(gempub))); |
220 | goto cleanup; | ||
221 | } | ||
222 | enum iGemPubProperty { | ||
223 | title_GemPubProperty, | ||
224 | index_GemPubProperty, | ||
225 | author_GemPubProperty, | ||
226 | language_GemPubProperty, | ||
227 | description_GemPubProperty, | ||
228 | published_GemPubProperty, | ||
229 | publishDate_GemPubProperty, | ||
230 | revisionDate_GemPubProperty, | ||
231 | copyright_GemPubProperty, | ||
232 | license_GemPubProperty, | ||
233 | version_GemPubProperty, | ||
234 | cover_GemPubProperty, | ||
235 | max_GemPubProperty | ||
236 | }; | ||
237 | static const char *labels[max_GemPubProperty] = { | ||
238 | "title:", | ||
239 | "index:", | ||
240 | "author:", | ||
241 | "language:", | ||
242 | "description:", | ||
243 | "published:", | ||
244 | "publishDate:", | ||
245 | "revisionDate:", | ||
246 | "copyright:", | ||
247 | "license:", | ||
248 | "version:", | ||
249 | "cover:", | ||
250 | }; | ||
251 | iString *props[max_GemPubProperty]; | ||
252 | iForIndices(i, props) { | ||
253 | props[i] = collectNew_String(); | ||
254 | } | ||
255 | /* Default values. */ | ||
256 | setCStr_String(props[title_GemPubProperty], "Untitled Book"); | ||
257 | setCStr_String(props[cover_GemPubProperty], | ||
258 | entryCStr_Archive(arch, "cover.jpg") ? "cover.jpg" : | ||
259 | entryCStr_Archive(arch, "cover.png") ? "cover.png" : ""); | ||
260 | setCStr_String(props[index_GemPubProperty], "index.gmi"); | ||
261 | iRangecc line = iNullRange; | ||
262 | while (nextSplit_Rangecc(range_Block(metadata), "\n", &line)) { | ||
263 | iRangecc clean = line; | ||
264 | trim_Rangecc(&clean); | ||
265 | iForIndices(i, props) { | ||
266 | if (startsWithCase_Rangecc(clean, labels[i])) { | ||
267 | setRange_String(props[i], (iRangecc){ clean.start + strlen(labels[i]), clean.end }); | ||
268 | trim_String(props[i]); | ||
269 | } | ||
270 | } | ||
271 | } | ||
272 | const iString *baseUrl = withSpacesEncoded_String(requestUrl); | ||
273 | iString *out = new_String(); | ||
274 | format_String(out, "20 text/gemini; charset=utf-8\r\n" | ||
275 | "# %s\n", | ||
276 | cstr_String(props[title_GemPubProperty])); | ||
277 | if (!isEmpty_String(props[description_GemPubProperty])) { | ||
278 | appendFormat_String(out, "%s\n", cstr_String(props[description_GemPubProperty])); | ||
279 | } | ||
280 | appendCStr_String(out, "\n"); | ||
281 | appendGemPubProperty_(out, "Author:", props[author_GemPubProperty]); | ||
282 | appendFormat_String(out, "\n=> %s " book_Icon " Book index page\n", | ||
283 | cstrCollect_String(concat_Path(baseUrl, props[index_GemPubProperty]))); | ||
284 | if (!isEmpty_String(props[cover_GemPubProperty])) { | ||
285 | appendFormat_String(out, "\n=> %s/%s Cover image\n", | ||
286 | cstr_String(baseUrl), | ||
287 | cstr_String(props[cover_GemPubProperty])); | ||
288 | } | ||
289 | appendCStr_String(out, "\n## About this book\n"); | ||
290 | appendGemPubProperty_(out, "Version:", props[version_GemPubProperty]); | ||
291 | appendGemPubProperty_(out, "Revision date:", props[revisionDate_GemPubProperty]); | ||
292 | if (!isEmpty_String(props[publishDate_GemPubProperty])) { | ||
293 | appendGemPubProperty_(out, "Publish date:", props[publishDate_GemPubProperty]); | ||
294 | } | ||
295 | else { | ||
296 | appendGemPubProperty_(out, "Published:", props[published_GemPubProperty]); | ||
297 | } | ||
298 | appendGemPubProperty_(out, "Language:", props[language_GemPubProperty]); | ||
299 | appendGemPubProperty_(out, "License:", props[license_GemPubProperty]); | ||
300 | appendGemPubProperty_(out, "\u00a9", props[copyright_GemPubProperty]); | ||
301 | output = copy_Block(utf8_String(out)); | ||
302 | delete_String(out); | ||
303 | } | 213 | } |
304 | cleanup: | 214 | delete_Gempub(gempub); |
305 | iRelease(arch); | ||
306 | return output; | 215 | return output; |
307 | } | 216 | } |
308 | 217 | ||
309 | /*----------------------------------------------------------------------------------------------*/ | 218 | /*----------------------------------------------------------------------------------------------*/ |
310 | 219 | ||
311 | static const char *gpubMimeType_MimeHooks_ = "application/gpub+zip"; | ||
312 | static const char *mimeHooksFilename_MimeHooks_ = "mimehooks.txt"; | 220 | static const char *mimeHooksFilename_MimeHooks_ = "mimehooks.txt"; |
313 | 221 | ||
314 | struct Impl_MimeHooks { | 222 | struct Impl_MimeHooks { |
@@ -331,7 +239,7 @@ void deinit_MimeHooks(iMimeHooks *d) { | |||
331 | static iBool checkGemPub_(const iString *mime, const iString *requestUrl) { | 239 | static iBool checkGemPub_(const iString *mime, const iString *requestUrl) { |
332 | /* Only process GemPub in local files. */ | 240 | /* Only process GemPub in local files. */ |
333 | return (equalCase_Rangecc(urlScheme_String(requestUrl), "file") && | 241 | return (equalCase_Rangecc(urlScheme_String(requestUrl), "file") && |
334 | startsWithCase_String(mime, gpubMimeType_MimeHooks_)); | 242 | startsWithCase_String(mime, mimeType_Gempub)); |
335 | } | 243 | } |
336 | 244 | ||
337 | iBool willTryFilter_MimeHooks(const iMimeHooks *d, const iString *mime) { | 245 | iBool willTryFilter_MimeHooks(const iMimeHooks *d, const iString *mime) { |
@@ -367,7 +275,7 @@ iBlock *tryFilter_MimeHooks(const iMimeHooks *d, const iString *mime, const iBlo | |||
367 | } | 275 | } |
368 | /* Built-in filters. */ | 276 | /* Built-in filters. */ |
369 | if (checkGemPub_(mime, requestUrl)) { | 277 | if (checkGemPub_(mime, requestUrl)) { |
370 | iBlock *result = translateGemPubCoverPage_(mime, body, requestUrl); | 278 | iBlock *result = translateGemPubCoverPage_(body, requestUrl); |
371 | if (result) { | 279 | if (result) { |
372 | return result; | 280 | return result; |
373 | } | 281 | } |