commit 35e6666986e5793bd0a5b4b7abbed2bfa1224080
parent 7e2cec0aa0face7fe3b55c9f784da0332e2d289e
Author: Paco Esteban <paco@e1e0.net>
Date: Sun, 24 May 2020 20:50:19 +0200
basic html index (optional).
date order is still pending.
Diffstat:
M | ssnail.c | | | 93 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------- |
1 file changed, 76 insertions(+), 17 deletions(-)
diff --git a/ssnail.c b/ssnail.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#include <lowdown.h>
@@ -40,6 +41,7 @@ struct article {
char *title;
char *author;
char *date;
+ char *type;
long long src_mtime;
long long dst_mtime;
SLIST_ENTRY(article) entries;
@@ -49,27 +51,28 @@ struct article *a = NULL;
SLIST_HEAD(listhead, article) head;
char *str_rep(const char *, const char *, const char *);
-int gen_html(char **, size_t *, char **, char **, char **, char *, size_t);
+int gen_html(struct article *);
int build_full_path(char *, char *, char *);
int load_from_file(char **, char *);
void usage();
int populate_article_entry(struct article *);
int write_html(struct article *, char *, char *);
void articleq_free(struct listhead *);
+int generate_index(struct listhead *, char *, char *, char *);
int
main(int argc, char *argv[])
{
DIR *dirp;
struct dirent *dp;
- int ch, force = 0;
+ int ch, force = 0, index = 0, needs_index = 0;
char srcdir[PATH_MAX] = "", dstdir[PATH_MAX] = "",
header_tpl[PATH_MAX] = "./_header.html",
footer_tpl[PATH_MAX] = "./_footer.html",
*fbuf = NULL;
struct article *ap = NULL;
- while ((ch = getopt(argc, argv, "F:H:d:fs:")) != -1) {
+ while ((ch = getopt(argc, argv, "F:H:d:fis:")) != -1) {
switch (ch) {
case 'F':
(void)strlcpy(footer_tpl, optarg, PATH_MAX);
@@ -83,6 +86,9 @@ main(int argc, char *argv[])
case 'f':
force = 1;
break;
+ case 'i':
+ index = 1;
+ break;
case 's':
(void)strlcpy(srcdir, optarg, PATH_MAX);
break;
@@ -117,20 +123,72 @@ main(int argc, char *argv[])
closedir(dirp);
free(fbuf);
- printf("Generating html files ... \n");
+ printf("Generate html files ... \n");
SLIST_FOREACH(ap, &head, entries) {
if ((ap->src_mtime > ap->dst_mtime) || force) {
printf("... %s\n", ap->dst_path);
if (write_html(ap, header_tpl, footer_tpl) == -1)
err(3, "cannot write html file");
+ needs_index = 1;
}
}
+ if (index && (needs_index || force)) {
+ printf("Generate html index ... \n");
+ generate_index(&head, header_tpl, footer_tpl, dstdir);
+ }
+
articleq_free(&head);
return 0;
}
+int
+generate_index(struct listhead *h, char head_tpl[PATH_MAX],
+ char foot_tpl[PATH_MAX], char *dst_dir)
+{
+ struct article *a;
+ char *header = NULL, *footer = NULL;
+ FILE *fout;
+ int r = -1;
+ time_t now;
+ struct tm *timeInfo;
+ char mytime[12], index_path[PATH_MAX];
+
+ time(&now);
+ timeInfo = localtime(&now);
+ strftime(mytime, sizeof(mytime), "%Y-%m-%d", timeInfo);
+
+ load_from_file(&header, head_tpl);
+ header = str_rep(header, "$title$", "index");
+ header = str_rep(header, "$author$", getlogin());
+ header = str_rep(header, "$date$", mytime);
+ load_from_file(&footer, foot_tpl);
+ footer = str_rep(footer, "$title$", "index");
+
+ build_full_path(index_path, dst_dir, "index.html");
+ if ((fout = fopen(index_path, "w")) == NULL)
+ goto out;
+ fwrite(header, 1, strlen(header), fout);
+ // TODO: make this list reverse date ordered
+ fprintf(fout, "<ul>\n");
+ SLIST_FOREACH(a, h, entries) {
+ if (strcmp(a->type, "article") == 0)
+ fprintf(fout, "<li><a href='%s'>%s</a></li>\n",
+ a->dst_path, a->title);
+ }
+ fprintf(fout, "</ul>\n");
+ fwrite(footer, 1, strlen(footer), fout);
+ fclose(fout);
+
+ r = 0;
+out:
+ free(header);
+ free(footer);
+ return r;
+
+}
+
void
articleq_free(struct listhead *h)
{
@@ -199,9 +257,7 @@ str_rep(const char *s, const char *oldW, const char *newW)
}
int
-gen_html(char **dest, size_t *destz,
- char **title, char **author, char **date,
- char *orig, size_t origz)
+gen_html(struct article *a)
{
struct lowdown_opts opts;
struct lowdown_metaq mq;
@@ -230,22 +286,27 @@ gen_html(char **dest, size_t *destz,
// use strlen(orig) here because the of the \0 char that
// was showing up on the dest buffer.
// playing with origz did not work here.
- lowdown_buf(&opts, orig, strlen(orig), dest, destz, &mq);
+ lowdown_buf(&opts, a->orig_content, strlen(a->orig_content),
+ &a->html_content, &a->htmlz, &mq);
TAILQ_FOREACH(md, &mq, entries) {
size_t valz = (strlen(md->value) > MAX_META)
? MAX_META : strlen(md->value) + 1;
if (strcmp(md->key, "title") == 0 ) {
- *title = malloc(valz);
- (void)strlcpy(*title, md->value, valz);
+ a->title = malloc(valz);
+ (void)strlcpy(a->title, md->value, valz);
}
if (strcmp(md->key, "author") == 0 ) {
- *author = malloc(valz);
- (void)strlcpy(*author, md->value, valz);
+ a->author = malloc(valz);
+ (void)strlcpy(a->author, md->value, valz);
}
if (strcmp(md->key, "date") == 0 ) {
- *date = malloc(valz);
- (void)strlcpy(*date, md->value, valz);
+ a->date = malloc(valz);
+ (void)strlcpy(a->date, md->value, valz);
+ }
+ if (strcmp(md->key, "type") == 0 ) {
+ a->type = malloc(valz);
+ (void)strlcpy(a->type, md->value, valz);
}
}
@@ -312,9 +373,7 @@ populate_article_entry(struct article *ap)
if ((ap->origz = load_from_file(&ap->orig_content, ap->src_path)) == 0)
goto out;
- gen_html(&ap->html_content, &ap->htmlz,
- &ap->title, &ap->author, &ap->date,
- ap->orig_content, ap->origz);
+ gen_html(ap);
retval = 0;
out:
return retval;