summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAli Fardan <raiz@stellarbound.space>2020-11-04 14:23:47 +0300
committerAli Fardan <raiz@stellarbound.space>2020-11-04 14:23:47 +0300
commiteb1a7e0e8d802423cc3aa1ff6db81923df2f3045 (patch)
tree10248a4a079d6d00ed1b418c3d3b6f87a906ad29
parentb9b2ae68e26ef1b1b033d4231f8d7e53244cebff (diff)
downloadgemlog-eb1a7e0e8d802423cc3aa1ff6db81923df2f3045.tar.gz
add HTML index generator HEAD master
-rw-r--r--Makefile2
-rw-r--r--atom.c13
-rw-r--r--gemlog.h6
-rw-r--r--index_html.c174
-rw-r--r--main.c25
5 files changed, 211 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 9036784..9c0158a 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ OUT = gemlog
 
 PREFIX = /usr
 
-OBJS = gemlog.o html.o index_gmi.o free.o main.o strlcpy.o strlcat.o
+OBJS = atom.o gemlog.o html.o index_gmi.o index_html.o free.o main.o strlcpy.o strlcat.o
 MANPAGES = 
 
 all: $(OUT)
diff --git a/atom.c b/atom.c
new file mode 100644
index 0000000..818ed46
--- /dev/null
+++ b/atom.c
@@ -0,0 +1,13 @@
+#include <time.h>
+
+#include <gemtext.h>
+
+#include "gemlog.h"
+
+int
+gemlog_write_atom(struct gemlog_entry **feed, const char *path)
+{
+	(void)feed;
+	(void)path;
+	return -1;
+}
diff --git a/gemlog.h b/gemlog.h
index e9cefa0..841e914 100644
--- a/gemlog.h
+++ b/gemlog.h
@@ -23,6 +23,12 @@ int gemlog_write_html(struct gemlog_entry **, const char *);
 /* index_gmi.c */
 int gemlog_write_index(struct gemlog_entry **, const char *);
 
+/* index_html.c */
+int gemlog_write_html_index(struct gemlog_entry **, const char *);
+
+/* atom.c */
+int gemlog_write_atom(struct gemlog_entry **, const char *);
+
 /* free.c */
 void gemlog_entry_free(struct gemlog_entry *);
 void gemlog_entry_list_free(struct gemlog_entry **);
diff --git a/index_html.c b/index_html.c
new file mode 100644
index 0000000..7778d9f
--- /dev/null
+++ b/index_html.c
@@ -0,0 +1,174 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <gemtext.h>
+
+#include "gemlog.h"
+
+static int
+find_latest_year(struct gemlog_entry **feed)
+{
+	int i;
+	int ret;
+
+	ret = 0;
+	for (i = 0; feed[i] != NULL; i++) {
+		if (feed[i]->date.tm_year > ret)
+			ret = feed[i]->date.tm_year;
+	}
+	return ret;
+}
+
+static int
+find_latest_month(struct gemlog_entry **feed, int year)
+{
+	int i;
+	int ret;
+
+	ret = 0;
+	for (i = 0; feed[i] != NULL; i++) {
+		if (feed[i]->date.tm_year == year) {
+			if (feed[i]->date.tm_mon > ret)
+				ret = feed[i]->date.tm_mon;
+		}
+	}
+	return ret;
+}
+
+static int
+find_latest_day(struct gemlog_entry **feed, int year, int month)
+{
+	int i;
+	int ret;
+
+	ret = 0;
+	for (i = 0; feed[i] != NULL; i++) {
+		if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month) {
+			if (feed[i]->date.tm_mday > ret)
+				ret = feed[i]->date.tm_mday;
+		}
+	}
+	return ret;
+}
+
+static int
+find_latest_hour(struct gemlog_entry **feed, int year, int month, int day)
+{
+	int i;
+	int ret;
+
+	ret = 0;
+	for (i = 0; feed[i] != NULL; i++) {
+		if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month && feed[i]->date.tm_mday == day) {
+			if (feed[i]->date.tm_hour > ret)
+				ret = feed[i]->date.tm_hour;
+		}
+	}
+	return ret;
+}
+
+static int
+gemlog_write_index_hour(struct gemlog_entry **feed, int fd, int year, int month, int day, int hour)
+{
+	int i;
+	char entrybuf[PATH_MAX+1];
+	char pathbuf[PATH_MAX+1];
+	char timestamp[11]; /* 1990-01-01\0 */
+
+	for (i = 0; feed[i] != NULL; i++) {
+		if (feed[i]->date.tm_year == year
+		 && feed[i]->date.tm_mon  == month
+		 && feed[i]->date.tm_mday == day
+		 && feed[i]->date.tm_hour == hour) {
+			strftime(timestamp, sizeof(timestamp), "%F", &(feed[i]->date));
+			snprintf(pathbuf, sizeof(pathbuf), "%d/%d/%d/%d/%s", year+1900, month+1, day, hour, GEMLOG_CONTENT_HTML_FILENAME);
+			snprintf(entrybuf, sizeof(entrybuf), "<li><a href=\"%s\">%s: %s</a></li>\n", pathbuf, timestamp, feed[i]->title);
+			if (write(fd, entrybuf, strlen(entrybuf)) == -1)
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int
+gemlog_write_index_day(struct gemlog_entry **feed, int fd, int year, int month, int day)
+{
+	int hour;
+
+	for (hour = find_latest_hour(feed, year, month, day); hour != 0; hour--) {
+		if (gemlog_write_index_hour(feed, fd, year, month, day, hour) == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int
+gemlog_write_index_month(struct gemlog_entry **feed, int fd, int year, int month)
+{
+	int day;
+
+	for (day = find_latest_day(feed, year, month); day != 0; day--) {
+		if (gemlog_write_index_day(feed, fd, year, month, day) == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int
+gemlog_write_index_year(struct gemlog_entry **feed, int fd, int year)
+{
+	int month;
+
+	for (month = find_latest_month(feed, year); month != 0; month--) {
+		if (gemlog_write_index_month(feed, fd, year, month) == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+int
+gemlog_write_html_index(struct gemlog_entry **feed, const char *path)
+{
+	int year;
+	int fd;
+
+	fd = open(path, O_WRONLY|O_CREAT|O_TRUNC);
+	if (fd == -1)
+		return -1;
+	if (chmod(path, 0644) == -1) {
+		close(fd);
+		return -1;
+	}
+
+	if (write(fd, "<ul>\n", strlen("<ul>\n")) == -1) {
+		close(fd);
+		return -1;
+	}
+
+	for (year = find_latest_year(feed); year != 0; year--) {
+		if (gemlog_write_index_year(feed, fd, year) == -1) {
+			close(fd);
+			return -1;
+		}
+	}
+
+	if (write(fd, "</ul>\n", strlen("</ul>\n")) == -1) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+	return 0;
+}
diff --git a/main.c b/main.c
index fd0c64a..fb39b91 100644
--- a/main.c
+++ b/main.c
@@ -26,13 +26,15 @@ main(int argc, char *argv[])
 	char *aflag;
 	char *hflag;
 	char *iflag;
+	char *lflag;
 	int ch;
 
 	aflag = NULL;
 	hflag = NULL;
 	iflag = NULL;
+	lflag = NULL;
 
-	while ((ch = getopt(argc, argv, "a:h:i:")) != -1) {
+	while ((ch = getopt(argc, argv, "a:h:i:l:")) != -1) {
 		switch (ch) {
 		case 'a':
 			aflag = optarg;
@@ -43,14 +45,17 @@ main(int argc, char *argv[])
 		case 'i':
 			iflag = optarg;
 			break;
+		case 'l':
+			lflag = optarg;
+			break;
 		default:
-			fprintf(stderr, "Usage: %s [-a file] [-h path] path\n", argv[0]);
+			fprintf(stderr, "Usage: %s [-a file] [-h path] [-i file] [-l file] path\n", argv[0]);
 			return 1;
 		}
 	}
 
 	if (optind >= argc) {
-		fprintf(stderr, "Usage: %s [-a file] [-h path] path\n", argv[0]);
+		fprintf(stderr, "Usage: %s [-a file] [-h path] [-i file] [-l file] path\n", argv[0]);
 		return 1;
 	}
 
@@ -58,13 +63,13 @@ main(int argc, char *argv[])
 	if (log == NULL)
 		err(1, "gemlog_readdir");
 
-	if (!aflag && !hflag && !iflag)
+	if (!aflag && !hflag && !iflag && !lflag)
 		_print_gemlog(log);
 
-//	if (aflag) {
-//		if (gemlog_write_atom(log, aflag) == -1)
-//			err(1, "gemlog_write_atom");
-//	}
+	if (aflag) {
+		if (gemlog_write_atom(log, aflag) == -1)
+			err(1, "gemlog_write_atom");
+	}
 	if (hflag) {
 		if (gemlog_write_html(log, hflag) == -1)
 			err(1, "gemlog_write_html");
@@ -73,6 +78,10 @@ main(int argc, char *argv[])
 		if (gemlog_write_index(log, iflag) == -1)
 			err(1, "gemlog_write_index");
 	}
+	if (lflag) {
+		if (gemlog_write_html_index(log, lflag) == -1)
+			err(1, "gemlog_write_html_index");
+	}
 
 	gemlog_entry_list_free(log);
 	return 0;