summaryrefslogtreecommitdiff
path: root/src/gmutil.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-24 15:37:48 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-24 15:37:48 +0300
commit15a10da4e82c688b0cb1e266f4aebd477c979dce (patch)
treee6fef2fc87be5e03a26f554063b52695d4db2aba /src/gmutil.c
parent90717c77b29c4a8ca0c3f49e9b4670b6fcbbe9d9 (diff)
Gempub cover page; cleanup
Use MIME hooks to generate a Gempub cover page with a preloaded cover image. This required applying MIME filtering to "file://" requests as well. Todo: More cleanup, add a gempub.c.
Diffstat (limited to 'src/gmutil.c')
-rw-r--r--src/gmutil.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/gmutil.c b/src/gmutil.c
index 18130951..806c989c 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -422,6 +422,71 @@ const char *makeFileUrl_CStr(const char *localFilePath) {
422 return cstrCollect_String(makeFileUrl_String(collectNewCStr_String(localFilePath))); 422 return cstrCollect_String(makeFileUrl_String(collectNewCStr_String(localFilePath)));
423} 423}
424 424
425iString *localFilePathFromUrl_String(const iString *d) {
426 iUrl url;
427 init_Url(&url, d);
428 if (!equalCase_Rangecc(url.scheme, "file")) {
429 return NULL;
430 }
431 iString *path = urlDecode_String(collect_String(newRange_String(url.path)));
432#if defined (iPlatformMsys)
433 /* Remove the extra slash from the beginning. */
434 if (startsWith_String(path, "/")) {
435 remove_Block(&path->chars, 0, 1);
436 }
437#endif
438 return path;
439}
440
441const char *mediaTypeFromPath_String(const iString *path) {
442 if (endsWithCase_String(path, ".gmi") || endsWithCase_String(path, ".gemini")) {
443 return "text/gemini; charset=utf-8";
444 }
445 /* TODO: It would be better to default to text/plain, but switch to
446 application/octet-stream if the contents fail to parse as UTF-8. */
447 else if (endsWithCase_String(path, ".txt") ||
448 endsWithCase_String(path, ".md") ||
449 endsWithCase_String(path, ".c") ||
450 endsWithCase_String(path, ".h") ||
451 endsWithCase_String(path, ".cc") ||
452 endsWithCase_String(path, ".hh") ||
453 endsWithCase_String(path, ".cpp") ||
454 endsWithCase_String(path, ".hpp")) {
455 return "text/plain";
456 }
457 else if (endsWithCase_String(path, ".zip")) {
458 return "application/zip";
459 }
460 else if (endsWithCase_String(path, ".gpub")) {
461 return "application/gpub+zip";
462 }
463 else if (endsWithCase_String(path, ".xml")) {
464 return "text/xml";
465 }
466 else if (endsWithCase_String(path, ".png")) {
467 return "image/png";
468 }
469 else if (endsWithCase_String(path, ".jpg") || endsWithCase_String(path, ".jpeg")) {
470 return "image/jpeg";
471 }
472 else if (endsWithCase_String(path, ".gif")) {
473 return "image/gif";
474 }
475 else if (endsWithCase_String(path, ".wav")) {
476 return "audio/wave";
477 }
478 else if (endsWithCase_String(path, ".ogg")) {
479 return "audio/ogg";
480 }
481 else if (endsWithCase_String(path, ".mp3")) {
482 return "audio/mpeg";
483 }
484 else if (endsWithCase_String(path, ".mid")) {
485 return "audio/midi";
486 }
487 return "application/octet-stream";
488}
489
425void urlEncodeSpaces_String(iString *d) { 490void urlEncodeSpaces_String(iString *d) {
426 for (;;) { 491 for (;;) {
427 const size_t pos = indexOfCStr_String(d, " "); 492 const size_t pos = indexOfCStr_String(d, " ");
@@ -440,6 +505,12 @@ const iString *withSpacesEncoded_String(const iString *d) {
440 return collect_String(enc); 505 return collect_String(enc);
441} 506}
442 507
508iRangecc mediaTypeWithoutParameters_Rangecc(iRangecc mime) {
509 iRangecc part = iNullRange;
510 nextSplit_Rangecc(mime, ";", &part);
511 return part;
512}
513
443const iString *feedEntryOpenCommand_String(const iString *url, int newTab) { 514const iString *feedEntryOpenCommand_String(const iString *url, int newTab) {
444 if (!isEmpty_String(url)) { 515 if (!isEmpty_String(url)) {
445 iString *cmd = collectNew_String(); 516 iString *cmd = collectNew_String();