Clean up blog code (particularly the www side).

Make `blog_load` return a ptr_vector which is
consumed by the code that uses blog entries.
Greatly clean up WWW page generation by using
stralloc and strftime and the ptr_vector
infrastructure.

Needs to be tested. :-)

Signed-off-by: Dan Cross <patchdev@fat-dragon.org>
This commit is contained in:
Dan Cross 2018-10-11 19:01:57 +00:00 committed by Andrew Pamment
parent 9b4238209e
commit 0a91165b07
3 changed files with 68 additions and 137 deletions

View File

@ -448,6 +448,6 @@ extern void nl_browser();
extern void blog_display();
extern void blog_write();
extern int blog_load(struct blog_entry_t ***entries);
extern struct ptr_vector blog_load(void);
#endif

View File

@ -6,12 +6,11 @@
extern struct bbs_config conf;
extern struct user_record *gUser;
int blog_load(struct blog_entry_t ***entries) {
int blog_entry_count = 0;
struct ptr_vector blog_entries;
char *sql = "SELECT author, title, body, date FROM blog ORDER BY date DESC";
struct ptr_vector blog_load(void) {
static char buffer[PATH_MAX];
char buffer[PATH_MAX];
struct ptr_vector entries = EMPTY_PTR_VECTOR;
const char *sql = "SELECT author, title, body, date FROM blog ORDER BY date DESC";
int rc;
sqlite3 *db;
sqlite3_stmt *res;
@ -22,8 +21,7 @@ int blog_load(struct blog_entry_t ***entries) {
if (rc != SQLITE_OK) {
dolog("Cannot open database: %s", sqlite3_errmsg(db));
*entries = NULL;
return 0;
return EMPTY_PTR_VECTOR;
}
sqlite3_busy_timeout(db, 5000);
rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
@ -31,37 +29,29 @@ int blog_load(struct blog_entry_t ***entries) {
if (rc != SQLITE_OK) {
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
sqlite3_close(db);
*entries = NULL;
return 0;
return EMPTY_PTR_VECTOR;
}
init_ptr_vector(&blog_entries);
init_ptr_vector(&entries);
while (sqlite3_step(res) == SQLITE_ROW) {
struct blog_entry_t *entry = (struct blog_entry_t *)malloz(sizeof(struct blog_entry_t));
entry->author = strdup(sqlite3_column_text(res, 0));
entry->subject = strdup(sqlite3_column_text(res, 1));
entry->body = strdup(sqlite3_column_text(res, 2));
entry->date = sqlite3_column_int(res, 3);
ptr_vector_append(&blog_entries, entry);
ptr_vector_append(&entries, entry);
}
sqlite3_finalize(res);
sqlite3_close(db);
blog_entry_count = ptr_vector_len(&blog_entries);
*entries = (struct blog_entry_t **)consume_ptr_vector(&blog_entries);
return blog_entry_count;
return entries;
}
void blog_display() {
struct blog_entry_t **blog_entries;
int blog_entry_count = 0;
int i;
struct ptr_vector entries = blog_load();
struct tm thetime;
char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???"};
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???"};
static const char *const days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???"};
static const char *const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???"};
char c;
int hour;
int j;
@ -70,8 +60,7 @@ void blog_display() {
s_printf(get_string(280));
s_printf(get_string(281));
blog_entry_count = blog_load(&blog_entries);
if (blog_entry_count == 0) {
if (ptr_vector_len(&entries) == 0) {
s_printf(get_string(282));
s_printf(get_string(6));
s_getchar();
@ -80,10 +69,11 @@ void blog_display() {
c = 'y';
for (i = 0; i < blog_entry_count; i++) {
localtime_r(&blog_entries[i]->date, &thetime);
for (size_t i = 0; i < ptr_vector_len(&entries); i++) {
struct blog_entry_t *entry = ptr_vector_get(&entries, i);
localtime_r(&entry->date, &thetime);
s_printf(get_string(283), blog_entries[i]->subject, blog_entries[i]->author);
s_printf(get_string(283), entry->subject, entry->author);
lines++;
if (lines == 22 && tolower(c) != 'c') {
s_printf("\r\n");
@ -126,8 +116,8 @@ void blog_display() {
s_printf("\r\n\r\n");
lines = 0;
}
for (j = 0; j < strlen(blog_entries[i]->body); j++) {
if (blog_entries[i]->body[j] == '\r') {
for (j = 0; j < strlen(entry->body); j++) {
if (entry->body[j] == '\r') {
s_printf("\r\n");
lines++;
if (lines == 22 && tolower(c) != 'c') {
@ -141,7 +131,7 @@ void blog_display() {
lines = 0;
}
} else {
s_printf("%c", blog_entries[i]->body[j]);
s_printf("%c", entry->body[j]);
}
}
@ -161,14 +151,8 @@ void blog_display() {
lines = 0;
}
}
for (i = 0; i < blog_entry_count; i++) {
free(blog_entries[i]->subject);
free(blog_entries[i]->author);
free(blog_entries[i]->body);
free(blog_entries[i]);
}
free(blog_entries);
ptr_vector_apply(&entries, free);
destroy_ptr_vector(&entries);
s_printf(get_string(6));
s_getchar();

View File

@ -8,112 +8,59 @@
extern struct bbs_config conf;
char *www_blog() {
char *page;
int max_len;
int len;
char buffer[4096];
stralloc page = EMPTY_STRALLOC;
struct ptr_vector entries = blog_load();
struct blog_entry_t **blog_entries;
int blog_entry_count = 0;
int i, j;
struct tm thetime;
int hour;
stralloc_copys(&page, "<div class=\"content-header\"><h2>System Blog</h2></div>\n");
char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???"};
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???"};
page = (char *)malloz(4096);
max_len = 4096;
len = 0;
sprintf(buffer, "<div class=\"content-header\"><h2>System Blog</h2></div>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
if (ptr_vector_len(&entries) == 0) {
stralloc_cats(&page, "<p>No Entries</p>\n");
stralloc_0(&page);
return page.s;
}
strcat(page, buffer);
len += strlen(buffer);
for (size_t i = 0; i < ptr_vector_len(&entries); i++) {
struct blog_entry_t *entry = ptr_vector_get(&entries, i);
struct tm entry_time;
int hour;
char timebuf[16];
char datebuf[24];
blog_entry_count = blog_load(&blog_entries);
localtime_r(&entry->date, &entry_time);
hour = entry_time.tm_hour;
strftime(timebuf, sizeof timebuf, "%l:%M", &entry_time);
strftime(datebuf, sizeof datebuf, " %a, %e %b %Y", &entry_time);
if (blog_entry_count == 0) {
sprintf(buffer, "<p>No Entries</p>\n");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
stralloc_cats(&page, "<div class=\"blog-header\"><div class=\"blog-title\"><h3>");
stralloc_cats(&page, entry->subject);
stralloc_cats(&page, "</h3></div><div class=\"blog-date\">");
stralloc_cats(&page, timebuf);
stralloc_cats(&page, hour >= 12 ? "pm" : "am");
stralloc_cats(&page, datebuf);
stralloc_cats(&page, "</div><div class=\"blog-author\">by ");
stralloc_cats(&page, entry->author);
stralloc_cats(&page, "</div></div>");
stralloc_cats(&page, "<div class=\"blog-entry\"><p>");
for (char *p = entry->body; *p != '\0'; ++p) {
if (*p != '\r') {
stralloc_append1(&page, *p);
continue;
}
if (p[1] != '\0' && p[1] != '\r') {
stralloc_append1(&page, ' ');
continue;
}
++p;
stralloc_cats(&page, "</p><p>");
}
strcat(page, buffer);
len += strlen(buffer);
} else {
for (i = 0; i < blog_entry_count; i++) {
localtime_r(&blog_entries[i]->date, &thetime);
if (thetime.tm_hour >= 12) {
hour = thetime.tm_hour - 12;
} else {
hour = thetime.tm_hour;
}
sprintf(buffer, "<div class=\"blog-header\"><div class=\"blog-title\"><h3>%s</h3></div><div class=\"blog-date\">%d:%02d%s %s, %s %d %d</div><div class=\"blog-author\">by %s</div></div>", blog_entries[i]->subject, (hour == 0 ? 12 : hour), thetime.tm_min, (thetime.tm_hour >= 12 ? "pm" : "am"), days[thetime.tm_wday], months[thetime.tm_mon], thetime.tm_mday, thetime.tm_year + 1900, blog_entries[i]->author);
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
sprintf(buffer, "<div class=\"blog-entry\"><p>");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
for (j = 0; j < strlen(blog_entries[i]->body); j++) {
if (blog_entries[i]->body[j] == '\r') {
if (blog_entries[i]->body[j + 1] == '\r') {
sprintf(buffer, "</p><p>");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
} else {
if (len + 1 > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
page[len++] = ' ';
page[len] = '\0';
}
} else {
if (len + 1 > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
page[len++] = blog_entries[i]->body[j];
page[len] = '\0';
}
}
sprintf(buffer, "</p></div>");
if (len + strlen(buffer) > max_len - 1) {
max_len += 4096;
page = (char *)realloc(page, max_len);
}
strcat(page, buffer);
len += strlen(buffer);
}
for (i = 0; i < blog_entry_count; i++) {
free(blog_entries[i]->subject);
free(blog_entries[i]->author);
free(blog_entries[i]->body);
free(blog_entries[i]);
}
free(blog_entries);
stralloc_cats(&page, "</p></div>");
}
ptr_vector_apply(&entries, free);
destroy_ptr_vector(&entries);
stralloc_0(&page);
return page;
return page.s;
}
#endif