commit:a3b400b3d5eff0027efe12936b08d80c93e0273a
author:Chip Black
committer:Chip Black
date:Mon Jul 18 03:45:12 2011 -0500
parents:69a7870e1420f767d56aae94d97b1c871b21217a
Add subscription marking to keep track of things you've read
diff --git a/cgi/cgi_blerg.c b/cgi/cgi_blerg.c
line changes: +12/-12
index b479535..85af748
--- a/cgi/cgi_blerg.c
+++ b/cgi/cgi_blerg.c
@@ -381,21 +381,21 @@ int main(int argc, char *argv[]) {
 		if (!check_auth(username))
 			exit(0);
 
-		if (path[9] != '/') {
-			respond_404();
-			exit(0);
-		}
-
+		yajl_gen g = yajl_gen_alloc(&yajl_c, NULL);
+		yajl_gen_map_open(g);
 		ret = parse_url_info(path + 10, &info);
 		if ((ret & URL_INFO_NAME) == 0) {
-			respond_404();
-			exit(0);
-		}
+			struct blerg *b = blerg_open(username);
+			uint64_t subscription_mark = blerg_get_subscription_mark(b);
+			blerg_close(b);
 
-		yajl_gen g = yajl_gen_alloc(&yajl_c, NULL);
-		yajl_gen_map_open(g);
-		yajl_gen_string(g, "subscribed", 10);
-		yajl_gen_bool(g, is_subscribed(username, info.name));
+			yajl_gen_string(g, "new", 3);
+			yajl_gen_integer(g, subscription_count_items(username) - subscription_mark);
+		} else {
+			yajl_gen_string(g, "subscribed", 10);
+			yajl_gen_bool(g, is_subscribed(username, info.name));
+
+		}
 		yajl_gen_map_close(g);
 
 		const unsigned char *ybuf;

diff --git a/database/database.c b/database/database.c
line changes: +19/-4
index a45c92b..e6e8707
--- a/database/database.c
+++ b/database/database.c
@@ -164,10 +164,17 @@ struct blerg *blerg_open(const char *name) {
 		goto open_failed_meta_open;
 	}
 	fstat(blerg->meta_fd, &st);
-	if (st.st_size == 0) {
-		char *buf = (char *) malloc(sizeof(struct meta));
-		memset(buf, 0, sizeof(struct meta));
-		write(blerg->meta_fd, buf, sizeof(struct meta));
+	if (st.st_size < sizeof(struct meta)) {
+		// Fill the difference in size between sizeof(struct meta) and
+		// the file size with nulls.  This allows seamless upgrades as
+		// long as struct meta only adds members.
+		int len = sizeof(struct meta) - st.st_size;
+		char *buf = (char *) malloc(len);
+		memset(buf, 0, len);
+		int tmpfd = dup(blerg->meta_fd);
+		FILE* tmp = fdopen(tmpfd, "a");
+		fwrite(buf, len, 1, tmp);
+		fclose(tmp);
 		free(buf);
 	}
 	blerg->meta = (struct meta *) mmap(NULL, sizeof(struct meta), PROT_READ | PROT_WRITE, MAP_SHARED, blerg->meta_fd, 0);
@@ -324,3 +331,11 @@ time_t blerg_get_timestamp(struct blerg *blerg, int record) {
 
 	return blerg->index[seg_rec].timestamp;
 }
+
+int blerg_set_subscription_mark(struct blerg *blerg) {
+	blerg->meta->subscription_mark = subscription_count_items(blerg->name);
+}
+
+uint64_t blerg_get_subscription_mark(struct blerg *blerg) {
+	return blerg->meta->subscription_mark;
+}

diff --git a/database/database.h b/database/database.h
line changes: +3/-0
index 2f71bee..412d6c7
--- a/database/database.h
+++ b/database/database.h
@@ -19,6 +19,7 @@ struct record {
 
 struct meta {
 	uint64_t sequence;
+	uint64_t subscription_mark;
 };
 
 struct blerg {
@@ -41,5 +42,7 @@ int blerg_store(struct blerg *, const char *, int);
 int blerg_fetch(struct blerg *, int, char **, int *);
 uint64_t blerg_get_record_count(struct blerg *);
 time_t blerg_get_timestamp(struct blerg *blerg, int record);
+int blerg_set_subscription_mark(struct blerg *blerg);
+uint64_t blerg_get_subscription_mark(struct blerg *blerg);
 
 #endif //_DATABASE_H

diff --git a/database/subscription.c b/database/subscription.c
line changes: +13/-0
index d3686ad..5a948d7
--- a/database/subscription.c
+++ b/database/subscription.c
@@ -142,3 +142,16 @@ int is_subscribed(const char *from, const char *to) {
 
 	return ret;
 }
+
+int subscription_count_items(const char *user) {
+	char filename[512];
+	struct stat st;
+
+	if (!valid_name(user))
+		return -1;
+
+	snprintf(filename, 512, "%s/%s/subscription_feed", DATA_PATH, user);
+
+	stat(filename, &st);
+	return st.st_size / sizeof(struct blergref);
+}

diff --git a/database/subscription.h b/database/subscription.h
line changes: +1/-0
index c07fc6d..a35c568
--- a/database/subscription.h
+++ b/database/subscription.h
@@ -12,5 +12,6 @@ int subscription_remove(const char *from, const char *to);
 int subscription_notify(const char *author, uint64_t record);
 struct blergref * subscription_list(const char *author, uint64_t offset, int *count, int direction);
 int is_subscribed(const char *from, const char *to);
+int subscription_count_items(const char *user);
 
 #endif /* _SUBSCRIPTION_H */