commit:d07aee6282c303bba6ca9dbd0fa0ad3dfca58c5a
author:Chip Black
committer:Chip Black
date:Wed Feb 2 15:14:07 2011 -0600
parents:d214c4d7d835a3f06925db9a7e2e6c42bc4d4346
Add blerglatest tool for figuring latest traffic
diff --git a/.gitignore b/.gitignore
line changes: +1/-0
index f7649a3..811c30e
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
 *.a
 *.so
 blergtool
+blerglatest
 blerg.httpd
 blerg.cgi
 blerg.fcgi

diff --git a/Makefile b/Makefile
line changes: +5/-1
index c3ed5da..d18e276
--- a/Makefile
+++ b/Makefile
@@ -8,9 +8,10 @@ LDFLAGS ?=
 HTTP_LIBDIRS = $(MHD_LIBDIR) $(YAJL_LIBDIR)
 CGI_LIBDIRS = $(CGI_UTIL_LIBDIR) $(YAJL_LIBDIR)
 
-targets = blerg.a blergtool blerg.httpd blerg.cgi rss.cgi
+targets = blerg.a blergtool blerglatest blerg.httpd blerg.cgi rss.cgi
 blerg_a_objects = database/database.o database/tags.o database/util.o
 blergtool_objects = tools/blergtool.o blerg.a
+blerglatest_objects = tools/blerglatest.o blerg.a common/json.o
 rss_objects = cgi/rss.o cgi/canned_responses.o common/app.o common/escapery.o blerg.a
 http_blerg_objects = http/http_blerg.o http/canned_responses.o common/app.o common/json.o common/auth.o blerg.a
 cgi_blerg_objects = cgi/cgi_blerg.o cgi/canned_responses.o common/app.o common/json.o common/auth.o blerg.a
@@ -26,6 +27,9 @@ blerg.a: $(blerg_a_objects)
 blergtool: $(blergtool_objects)
 	gcc $(LDFLAGS) $^ -o $@
 
+blerglatest: $(blerglatest_objects)
+	gcc $(YAJL_LIBDIR) $(LDFLAGS) $^ -lyajl_s -o $@
+
 blerg.httpd: $(http_blerg_objects)
 	gcc $(HTTP_LIBDIRS) $(LDFLAGS) $(http_blerg_objects) -lpthread -lmicrohttpd -lyajl_s -o $@
 

diff --git a/tools/blerglatest.c b/tools/blerglatest.c
line changes: +158/-0
index 0000000..a2d1c67
--- /dev/null
+++ b/tools/blerglatest.c
@@ -0,0 +1,158 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <yajl/yajl_gen.h>
+#include "database.h"
+#include "json.h"
+#include "config.h"
+
+yajl_gen_config yajl_config = {0, 0};
+
+struct thing {
+	time_t t;
+	char *name;
+	int len;
+};
+
+struct things {
+	struct thing *arr;
+	unsigned int len;
+	unsigned int size;
+};
+
+struct things * things_alloc() {
+	struct things *things = malloc(sizeof(struct things));
+	things->len = 0;
+	things->size = 65536;
+	things->arr = malloc(sizeof(struct thing) * things->size);
+}
+
+void things_free(struct things *things) {
+	int i;
+
+	for (i = 0; i < things->len; i++) {
+		free(things->arr[i].name);
+	}
+
+	free(things->arr);
+	free(things);
+}
+
+void things_add(struct things *things, time_t t, char *name) {
+	things->arr[things->len].t = t;
+	things->arr[things->len].len = strlen(name);
+	things->arr[things->len].name = malloc(things->arr[things->len].len + 1);
+	strcpy(things->arr[things->len].name, name);
+	things->len++;
+	if (things->len == things->size) {
+		things->size *= 2;
+		things->arr = realloc(things->arr, sizeof(struct thing) * things->size);
+	}
+}
+
+int thing_compare(const void *a, const void *b) {
+	struct thing * aa = (struct thing *) a;
+	struct thing * bb = (struct thing *) b;
+
+	if (aa->t == bb->t)
+		return 0;
+	else if (aa->t > bb->t)
+		return -1;
+	else
+		return 1;
+}
+
+void things_sort(struct things *things) {
+	qsort(things->arr, things->len, sizeof(struct thing), thing_compare);
+}
+
+struct things * latest_things(const char *path, const char *file) {
+	DIR* d;
+	struct dirent *f;
+	struct things * things = things_alloc();
+	char filename[512];
+	struct stat st;
+	int i;
+
+	d = opendir(path);
+	while (f = readdir(d)) {
+		if (f->d_name[0] == '.') continue;
+		if (file) {
+			snprintf(filename, 512, "%s/%s/%s", path, f->d_name, file);
+		} else {
+			snprintf(filename, 512, "%s/%s", path, f->d_name);
+		}
+		stat(filename, &st);
+		things_add(things, st.st_mtime, f->d_name);
+	}
+	closedir(d);
+
+	things_sort(things);
+
+	return things;
+}
+
+void latest_tags(yajl_gen g) {
+	int i;
+	struct things * things = latest_things(HASH_TAGS_PATH, NULL);
+
+	unsigned int count = (things->len >= 50 ? 50 : things->len);
+	yajl_gen_array_open(g);
+	for (i = 0; i < count; i++) {
+		yajl_gen_string(g, things->arr[i].name, things->arr[i].len);
+	}
+	yajl_gen_array_close(g);
+
+	things_free(things);
+}
+
+void latest_records(yajl_gen g) {
+	int i;
+	struct things * things = latest_things(DATA_PATH, "meta");
+
+	unsigned int count = (things->len >= 50 ? 50 : things->len);
+	yajl_gen_array_open(g);
+	for (i = 0; i < count; i++) {
+		struct blerg * b = blerg_open(things->arr[i].name);
+		if (b == NULL) {
+			fprintf(stderr, "Could not open blerg for %s\n", things->arr[i].name);
+			continue;
+		}
+		uint64_t record_count = blerg_get_record_count(b);
+		if (record_count > 0)
+			json_generate_one_record(g, things->arr[i].name, b, record_count - 1);
+		blerg_close(b);
+	}
+	yajl_gen_array_close(g);
+	things_free(things);
+}
+
+int main(int argc, char *argv[]) {
+	const unsigned char *buf;
+	unsigned int len;
+
+	yajl_gen g = yajl_gen_alloc(&yajl_config, NULL);
+
+	yajl_gen_map_open(g);
+	yajl_gen_string(g, "tags", 4);
+
+	latest_tags(g);
+
+	yajl_gen_get_buf(g, &buf, &len);
+	fwrite(buf, len, 1, stdout);
+	yajl_gen_clear(g);
+
+	yajl_gen_string(g, "records", 7);
+
+	latest_records(g);
+
+	yajl_gen_map_close(g);
+	yajl_gen_get_buf(g, &buf, &len);
+	fwrite(buf, len, 1, stdout);
+
+	yajl_gen_free(g);
+}