changeset 15:d2628fb14ec6

story: display comments
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Wed, 04 Feb 2009 02:16:03 -0500
parents 06b2d0a67c4d
children 03eead276f15
files html.c post.c post.h sar.c sar.h
diffstat 5 files changed, 225 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/html.c	Wed Feb 04 01:32:32 2009 -0500
+++ b/html.c	Wed Feb 04 02:16:03 2009 -0500
@@ -8,36 +8,39 @@
 /************************************************************************/
 void html_story(struct post *post)
 {
-	cat(post, "templates/story-top.html", repltab_html);
+	cat(post, NULL, "templates/story-top.html", repltab_html);
 
 #if 0
 	for_each_category(post)
 		cat(stdout, "templates/story-cat-item.html", repltab_html);
 #endif
 
-	cat(post, "templates/story-middle.html", repltab_html);
+	cat(post, NULL, "templates/story-middle.html", repltab_html);
 
 	cat_post(post);
 
-	cat(post, "templates/story-bottom.html", NULL);
+	cat(post, NULL, "templates/story-bottom.html", NULL);
 }
 
 /************************************************************************/
 /*                           POST COMMENTS                              */
 /************************************************************************/
+static void __html_comment(struct post *post, struct comment *comm)
+{
+	cat(post, comm, "templates/story-comment-item-head.html",
+	    repltab_comm_html);
+	cat_post_comment(post, comm);
+	cat(post, comm, "templates/story-comment-item-tail.html",
+	    repltab_comm_html);
+}
+
 void html_comments(struct post *post)
 {
-	cat(post, "templates/story-comment-head.html", repltab_html);
+	cat(post, NULL, "templates/story-comment-head.html", repltab_html);
 
-#if 0
-	for_each_comment(post) {
-		cat(post, "templates/story-comment-item-head.html", repltab_html);
-		cat_post_comment(post, commentid);
-		cat(post, "templates/story-comment-item-tail.html", repltab_html);
-	}
-#endif
+	invoke_for_each_comment(post, __html_comment);
 
-	cat(post, "templates/story-comment-tail.html", repltab_html);
+	cat(post, NULL, "templates/story-comment-tail.html", repltab_html);
 }
 
 /************************************************************************/
@@ -45,17 +48,17 @@
 /************************************************************************/
 void html_sidebar(struct post *post)
 {
-	cat(post, "templates/sidebar-top.html", repltab_html);
+	cat(post, NULL, "templates/sidebar-top.html", repltab_html);
 #if 0
 	for_each_category()
-		cat(post, "templates/sidebar-cat-item.html", repltab_html);
+		cat(post, NULL, "templates/sidebar-cat-item.html", repltab_html);
 #endif
-	cat(post, "templates/sidebar-middle.html", repltab_html);
+	cat(post, NULL, "templates/sidebar-middle.html", repltab_html);
 #if 0
 	for_each_month()
-		cat(post, "templates/sidebar-archive-item.html", repltab_html);
+		cat(post, NULL, "templates/sidebar-archive-item.html", repltab_html);
 #endif
-	cat(post, "templates/sidebar-bottom.html", repltab_html);
+	cat(post, NULL, "templates/sidebar-bottom.html", repltab_html);
 }
 
 /************************************************************************/
@@ -63,7 +66,7 @@
 /************************************************************************/
 void html_header(struct post *post)
 {
-	cat(post, "templates/header.html", repltab_html);
+	cat(post, NULL, "templates/header.html", repltab_html);
 }
 
 /************************************************************************/
@@ -71,5 +74,5 @@
 /************************************************************************/
 void html_footer(struct post *post)
 {
-	cat(post, "templates/footer.html", repltab_html);
+	cat(post, NULL, "templates/footer.html", repltab_html);
 }
--- a/post.c	Wed Feb 04 01:32:32 2009 -0500
+++ b/post.c	Wed Feb 04 02:16:03 2009 -0500
@@ -10,12 +10,14 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <time.h>
+#include <dirent.h>
 
 #include "post.h"
 #include "xattr.h"
 #include "sar.h"
 
-void cat(struct post *post, char *tmpl, struct repltab_entry *repltab)
+void cat(struct post *post, struct comment *comm, char *tmpl,
+	 struct repltab_entry *repltab)
 {
 	struct stat statbuf;
 	char *ibuf;
@@ -40,7 +42,7 @@
 		goto out_close;
 	}
 
-	sar(post, ibuf, statbuf.st_size, repltab);
+	sar(post, comm, ibuf, statbuf.st_size, repltab);
 
 	munmap(ibuf, statbuf.st_size);
 
@@ -87,6 +89,109 @@
 	close(fd);
 }
 
+void cat_post_comment(struct post *post, struct comment *comm)
+{
+	char path[FILENAME_MAX];
+	struct stat statbuf;
+	char *ibuf;
+	int ret;
+	int fd;
+
+	snprintf(path, FILENAME_MAX, "data/posts/%d/comments/%d/text.txt",
+		 post->id, comm->id);
+
+	fd = open(path, O_RDONLY);
+	if (fd == -1) {
+		fprintf(post->out, "post.txt open error\n");
+		return;
+	}
+
+	ret = fstat(fd, &statbuf);
+	if (ret == -1) {
+		fprintf(post->out, "fstat failed\n");
+		goto out_close;
+	}
+
+	ibuf = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+	if (ibuf == MAP_FAILED) {
+		fprintf(post->out, "mmap failed\n");
+		goto out_close;
+	}
+
+	/* FIXME: do <p> insertion, etc. */
+	fwrite("<p>", 1, 3, post->out);
+	fwrite(ibuf, 1, statbuf.st_size, post->out);
+	fwrite("</p>", 1, 4, post->out);
+
+	munmap(ibuf, statbuf.st_size);
+
+out_close:
+	close(fd);
+}
+
+int load_comment(struct post *post, int commid, struct comment *comm)
+{
+	char path[FILENAME_MAX];
+	char *buf;
+
+	snprintf(path, FILENAME_MAX, "data/posts/%d/comments/%d", post->id,
+		 commid);
+
+	comm->id = commid;
+	comm->author = safe_getxattr(path, XATTR_COMM_AUTHOR);
+	buf          = safe_getxattr(path, XATTR_TIME);
+
+	if (comm->author && buf && (strlen(buf) == 16)) {
+		/* "2005-01-02 03:03" */
+		strptime(buf, "%Y-%m-%d %H:%M", &comm->time);
+
+		free(buf);
+
+		return 0;
+	}
+
+	free(buf);
+	return ENOMEM;
+}
+
+void destroy_comment(struct comment *comm)
+{
+	free(comm->author);
+}
+
+void invoke_for_each_comment(struct post *post, void(*f)(struct post*,
+							 struct comment*))
+{
+	char path[FILENAME_MAX];
+	struct dirent *de;
+	DIR *dir;
+	struct comment comm;
+	int commid;
+
+	snprintf(path, FILENAME_MAX, "data/posts/%d/comments", post->id);
+
+	dir = opendir(path);
+	if (!dir)
+		return;
+
+	while((de = readdir(dir))) {
+		if (!strcmp(de->d_name, ".") ||
+		    !strcmp(de->d_name, ".."))
+			continue;
+
+		commid = atoi(de->d_name);
+
+		if (load_comment(post, commid, &comm))
+			break;
+
+		f(post, &comm);
+
+		destroy_comment(&comm);
+	}
+
+	closedir(dir);
+}
+
 int load_post(int postid, struct post *post)
 {
 	char path[FILENAME_MAX];
--- a/post.h	Wed Feb 04 01:32:32 2009 -0500
+++ b/post.h	Wed Feb 04 02:16:03 2009 -0500
@@ -3,6 +3,12 @@
 
 #include <time.h>
 
+struct comment {
+	int id;
+	char *author;
+	struct tm time;
+};
+
 struct post {
 	FILE *out;
 	int id;
@@ -11,17 +17,26 @@
 	struct tm time;
 };
 
-#define XATTR_TITLE	"user.post_title"
-#define XATTR_CATS	"user.post_cats"
-#define XATTR_TIME	"user.post_time"
+#define XATTR_TITLE		"user.post_title"
+#define XATTR_CATS		"user.post_cats"
+#define XATTR_TIME		"user.post_time"
+#define XATTR_COMM_AUTHOR	"user.author"
 
 extern int load_post(int postid, struct post *post);
 extern void dump_post(struct post *post);
 extern void destroy_post(struct post *post);
 
+extern int load_comment(struct post *post, int commid, struct comment *comm);
+extern void destroy_comment(struct comment *comm);
+
 struct repltab_entry;
 
 extern void cat_post(struct post *post);
-extern void cat(struct post *post, char *tmpl, struct repltab_entry *repltab);
+extern void cat_post_comment(struct post *post, struct comment *comm);
+extern void cat(struct post *post, struct comment *comm, char *tmpl,
+		struct repltab_entry *repltab);
+
+extern void invoke_for_each_comment(struct post *post,
+				    void(*f)(struct post*, struct comment*));
 
 #endif
--- a/sar.c	Wed Feb 04 01:32:32 2009 -0500
+++ b/sar.c	Wed Feb 04 02:16:03 2009 -0500
@@ -1,10 +1,12 @@
 #include <stdio.h>
 #include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 #include "post.h"
 #include "sar.h"
 
-static void echo_postid(struct post *post)
+static void echo_postid(struct post *post, struct comment *comm)
 {
 	fprintf(post->out, "%d", post->id);
 }
@@ -14,27 +16,49 @@
 	"July", "August", "September", "October", "November", "December",
 };
 
-static void echo_title(struct post *post)
+static void echo_title(struct post *post, struct comment *comm)
 {
 	fprintf(post->out, "%s", post->title);
 }
 
-static void echo_posttime(struct post *post)
+static void echo_posttime(struct post *post, struct comment *comm)
 {
 	fprintf(post->out, "%02d:%02d", post->time.tm_hour,
 		post->time.tm_min);
 }
 
-static void echo_postdate(struct post *post)
+static void echo_postdate(struct post *post, struct comment *comm)
 {
 	fprintf(post->out, "%s %d, %04d",
 		up_month_strs[post->time.tm_mon], post->time.tm_mday,
 		1900+post->time.tm_year);
 }
 
-static void echo_comment_count(struct post *post)
+static void echo_comment_count(struct post *post, struct comment *comm)
 {
-	fprintf(post->out, "???"); // FIXME
+	char path[FILENAME_MAX];
+	struct dirent *de;
+	DIR *dir;
+	int count;
+
+	snprintf(path, FILENAME_MAX, "data/posts/%d/comments", post->id);
+
+	dir = opendir(path);
+	if (!dir)
+		return;
+
+	count = 0;
+	while((de = readdir(dir))) {
+		if (!strcmp(de->d_name, ".") ||
+		    !strcmp(de->d_name, ".."))
+			continue;
+
+		count++;
+	}
+
+	closedir(dir);
+
+	fprintf(post->out, "%d", count);
 }
 
 static struct repltab_entry __repltab_html[] = {
@@ -46,9 +70,46 @@
 	{"",		NULL},
 };
 
-struct repltab_entry *repltab_html = __repltab_html;
+static void echo_comment_id(struct post *post, struct comment *comm)
+{
+	fprintf(post->out, "%d", comm->id);
+}
+
+static void echo_comment_author(struct post *post, struct comment *comm)
+{
+	fprintf(post->out, "%s", comm->author);
+}
+
+static void echo_comment_time(struct post *post, struct comment *comm)
+{
+	fprintf(post->out, "%02d:%02d", comm->time.tm_hour,
+		comm->time.tm_min);
+}
 
-static int invoke_repl(struct post *post, char *cmd,
+static void echo_comment_date(struct post *post, struct comment *comm)
+{
+	fprintf(post->out, "%s %d, %04d",
+		up_month_strs[comm->time.tm_mon], comm->time.tm_mday,
+		1900+comm->time.tm_year);
+}
+
+static struct repltab_entry __repltab_comm_html[] = {
+	{"POSTID",	echo_postid},
+	{"POSTDATE",	echo_postdate},
+	{"POSTTIME",	echo_posttime},
+	{"TITLE",	echo_title},
+	{"COMCOUNT",	echo_comment_count},
+	{"COMID",	echo_comment_id},
+	{"COMAUTHOR",	echo_comment_author},
+	{"COMDATE",	echo_comment_date},
+	{"COMTIME",	echo_comment_time},
+	{"",		NULL},
+};
+
+struct repltab_entry *repltab_html = __repltab_html;
+struct repltab_entry *repltab_comm_html = __repltab_comm_html;
+
+static int invoke_repl(struct post *post, struct comment *comm, char *cmd,
 		       struct repltab_entry *repltab)
 {
 	int i;
@@ -60,7 +121,7 @@
 		if (strcmp(cmd, repltab[i].what))
 			continue;
 
-		repltab[i].f(post);
+		repltab[i].f(post, comm);
 		return 0;
 	}
 
@@ -78,7 +139,7 @@
 					oi++; \
 				} while(0)
 
-void sar(struct post *post, char *ibuf, int size,
+void sar(struct post *post, struct comment *comm, char *ibuf, int size,
 	 struct repltab_entry *repltab)
 {
 	char obuf[size];
@@ -128,7 +189,7 @@
 					state = SAR_ERROR;
 				else {
 					COPYCHAR(cmd, cidx, '\0');
-					if (invoke_repl(post, cmd, repltab))
+					if (invoke_repl(post, comm, cmd, repltab))
 						fprintf(post->out, "@@%s@@", cmd);
 					cidx = 0;
 					state = SAR_NORMAL;
--- a/sar.h	Wed Feb 04 01:32:32 2009 -0500
+++ b/sar.h	Wed Feb 04 02:16:03 2009 -0500
@@ -5,12 +5,13 @@
 
 struct repltab_entry {
 	char what[16];
-	void (*f)(struct post*);
+	void (*f)(struct post*, struct comment*);
 };
 
-extern void sar(struct post *post, char *ibuf, int size,
-		struct repltab_entry *repltab);
+extern void sar(struct post *post, struct comment *comm, char *ibuf,
+		int size, struct repltab_entry *repltab);
 
-struct repltab_entry *repltab_html;
+extern struct repltab_entry *repltab_html;
+extern struct repltab_entry *repltab_comm_html;
 
 #endif