From 5956e421952721dfea0eff838f74a5d4f13b5e94 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Fri, 11 Jun 2021 16:09:27 -0400 Subject: Generalize index.{atom,html} to search pages --- archive.c | 4 ++-- archive.h | 19 +++++++++++-------- atom.c | 32 +++++++++++++++++++++++++------- concat.c | 35 ++++++++++++++++++++++++----------- html.c | 43 +++++++++++++++++++++++++++++++------------ 5 files changed, 93 insertions(+), 40 deletions(-) diff --git a/archive.c b/archive.c index 575bc56..0bee374 100644 --- a/archive.c +++ b/archive.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) { 0 < (opt = getopt(argc, argv, "A:C:H:S:T:a:h:im:p:qs:u:vw:y:")); ) { switch (opt) { - break; case 'A': concatIndexEntries = strtoul(optarg, NULL, 10); + break; case 'A': concatSearchEntries = strtoul(optarg, NULL, 10); break; case 'C': { int error = chdir(optarg); if (error) err(EX_NOINPUT, "%s", optarg); @@ -260,7 +260,7 @@ concat:; respFree(resp); concatThreads(threads, envelopes); - concatIndex(threads, envelopes); + concatSearch("index", threads, envelopes); fflush(stdout); uidWrite("UIDNEXT", uidNext); diff --git a/archive.h b/archive.h index 1a94744..3f13109 100644 --- a/archive.h +++ b/archive.h @@ -44,6 +44,7 @@ #define PATH_THREAD "thread/[messageID].[type]" #define PATH_ATTACHMENT \ "attachment/[messageID]/[section]/[name][disposition][.][subtype]" +#define PATH_SEARCH "[name].[type]" #define MBOX_HEADERS \ "Date Subject From Sender Reply-To To Cc Bcc " \ @@ -214,13 +215,15 @@ bool exportFetch(FILE *imap, enum Atom tag, struct List threads); bool exportData(FILE *imap, enum Atom tag, struct List items); extern const char *concatHead; -extern size_t concatIndexEntries; +extern size_t concatSearchEntries; void concatFetch(FILE *imap, enum Atom tag, struct List threads); void concatData( struct List threads, struct Envelope *envelopes, struct List items ); void concatThreads(struct List threads, const struct Envelope *envelopes); -void concatIndex(struct List threads, const struct Envelope *envelopes); +void concatSearch( + const char *name, struct List threads, const struct Envelope *envelopes +); int mboxFrom(FILE *file); int mboxHeader(FILE *file, const char *header); @@ -231,8 +234,8 @@ int atomContent(FILE *file, const char *content); int atomEntryClose(FILE *file); int atomThreadOpen(FILE *file, const struct Envelope *envelope); int atomThreadClose(FILE *file); -int atomIndexOpen(FILE *file); -int atomIndexClose(FILE *file); +int atomSearchOpen(FILE *file, const char *name); +int atomSearchClose(FILE *file); int htmlMessageOpen(FILE *file, const struct Envelope *envelope, bool nested); int htmlInline(FILE *file, const struct BodyPart *part, const char *content); @@ -247,9 +250,9 @@ int htmlThreadOpen(FILE *file, const struct Envelope *envelope); int htmlSubthreadOpen(FILE *file, struct List thread); int htmlSubthreadClose(FILE *file); int htmlThreadClose(FILE *file); -int htmlIndexHead(FILE *file); -int htmlIndexOpen(FILE *file); -int htmlIndexThread( +int htmlSearchHead(FILE *file, const char *name); +int htmlSearchOpen(FILE *file, const char *name); +int htmlSearchThread( FILE *file, const struct Envelope *envelope, struct List thread ); -int htmlIndexClose(FILE *file); +int htmlSearchClose(FILE *file); diff --git a/atom.c b/atom.c index 14f9d54..a58f71c 100644 --- a/atom.c +++ b/atom.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -162,26 +163,43 @@ int atomThreadClose(FILE *file) { return templateRender(file, Q(), NULL, NULL); } -int atomIndexOpen(FILE *file) { +static char *atomSearchURL(const char *name, const char *type) { + struct Variable vars[] = { + { "name", name }, + { "type", type }, + {0}, + }; + return templateString("/" PATH_SEARCH, vars, escapeURL); +} + +int atomSearchOpen(FILE *file, const char *name) { + char *atom = atomSearchURL(name, "atom"); + char *html = atomSearchURL(name, "html"); const char *template = XML_DECL Q( bubger - [base]/ - [title] + [base][atom] + [+name][name] - [-][title] [updated] - - + + ); struct Variable vars[] = { { "generator", GENERATOR_URL }, + { "name", (strcmp(name, "index") ? name : NULL) }, { "title", baseTitle }, { "updated", iso8601(time(NULL)).s }, { "base", baseURL }, + { "atom", atom }, + { "html", html }, {0}, }; - return templateRender(file, template, vars, escapeXML); + int error = templateRender(file, template, vars, escapeXML); + free(atom); + free(html); + return error; } -int atomIndexClose(FILE *file) { +int atomSearchClose(FILE *file) { return templateRender(file, Q(), NULL, NULL); } diff --git a/concat.c b/concat.c index 3e03f3b..82f2c84 100644 --- a/concat.c +++ b/concat.c @@ -230,6 +230,15 @@ void concatThreads(struct List threads, const struct Envelope *envelopes) { } } +static char *searchPath(const char *name, const char *type) { + struct Variable vars[] = { + { "name", name }, + { "type", type }, + {0}, + }; + return templateString(PATH_SEARCH, vars, escapePath); +} + static int numberCompare(const void *_a, const void *_b) { const struct Data *a = _a; const struct Data *b = _b; @@ -252,20 +261,22 @@ static int sortCompare(const void *_a, const void *_b) { } } -size_t concatIndexEntries = 20; +size_t concatSearchEntries = 20; -void concatIndex(struct List threads, const struct Envelope *envelopes) { - const char *path = "index.atom"; +void concatSearch( + const char *name, struct List threads, const struct Envelope *envelopes +) { + char *path = searchPath(name, "atom"); FILE *file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); - int error = atomIndexOpen(file); + int error = atomSearchOpen(file, name); if (error) err(EX_IOERR, "%s", path); struct List flat = {0}; listFlatten(&flat, threads); qsort(flat.ptr, flat.len, sizeof(*flat.ptr), numberCompare); - for (size_t i = 0; i < flat.len && i < concatIndexEntries; ++i) { + for (size_t i = 0; i < flat.len && i < concatSearchEntries; ++i) { uint32_t uid = dataCheck(flat.ptr[i], Number).number; char *src = uidPath(uid, "atom"); error = concatFile(file, src); @@ -274,9 +285,10 @@ void concatIndex(struct List threads, const struct Envelope *envelopes) { } listFree(flat); - error = atomIndexClose(file) || fclose(file); + error = atomSearchClose(file) || fclose(file); if (error) err(EX_IOERR, "%s", path); if (!quiet) printf("%s\n", path); + free(path); struct Sort *order = calloc(threads.len, sizeof(*order)); if (!order) err(EX_OSERR, "calloc"); @@ -294,11 +306,11 @@ void concatIndex(struct List threads, const struct Envelope *envelopes) { } qsort(order, threads.len, sizeof(*order), sortCompare); - path = "index.html"; + path = searchPath(name, "html"); file = fopen(path, "w"); if (!file) err(EX_CANTCREAT, "%s", path); - error = htmlIndexHead(file); + error = htmlSearchHead(file, name); if (error) err(EX_IOERR, "%s", path); if (concatHead) { @@ -306,18 +318,19 @@ void concatIndex(struct List threads, const struct Envelope *envelopes) { if (error) err(EX_IOERR, "%s", path); } - error = htmlIndexOpen(file); + error = htmlSearchOpen(file, name); if (error) err(EX_IOERR, "%s", path); for (size_t i = threads.len - 1; i < threads.len; --i) { const struct Envelope *envelope = &envelopes[order[i].index]; struct List thread = dataCheck(threads.ptr[order[i].index], List).list; - error = htmlIndexThread(file, envelope, thread); + error = htmlSearchThread(file, envelope, thread); if (error) err(EX_IOERR, "%s", path); } free(order); - error = htmlIndexClose(file) || fclose(file); + error = htmlSearchClose(file) || fclose(file); if (error) err(EX_IOERR, "%s", path); if (!quiet) printf("%s\n", path); + free(path); } diff --git a/html.c b/html.c index f8f8539..5eb2f29 100644 --- a/html.c +++ b/html.c @@ -512,31 +512,46 @@ int htmlThreadClose(FILE *file) { || htmlFooter(file); } -int htmlIndexHead(FILE *file) { +static char *htmlSearchURL(const char *name, const char *type) { + struct Variable vars[] = { + { "name", name }, + { "type", type }, + {0}, + }; + return templateString(PATH_SEARCH, vars, escapeURL); +} + +int htmlSearchHead(FILE *file, const char *name) { + char *atom = htmlSearchURL(name, "atom"); const char *template = Q( - [title] - + [+name][name] - [-][title] + ); struct Variable vars[] = { { "generator", GENERATOR_URL }, + { "name", (strcmp(name, "index") ? name : NULL) }, { "title", baseTitle }, + { "atom", atom }, {0}, }; - return 0 + int error = 0 || templateRender(file, template, vars, escapeXML) || htmlStylesheet(file); + free(atom); + return error; } -int htmlIndexOpen(FILE *file) { +int htmlSearchOpen(FILE *file, const char *name) { + char *atom = htmlSearchURL(name, "atom"); const char *template = Q(
-

[title]

+

[+name][name] - [-][title]