This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/src/blog.c
Dan Cross 0a91165b07 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>
2018-10-12 10:13:04 +10:00

237 lines
5.5 KiB
C

#include <sqlite3.h>
#include <time.h>
#include <string.h>
#include "bbs.h"
extern struct bbs_config conf;
extern struct user_record *gUser;
struct ptr_vector blog_load(void) {
static 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;
snprintf(buffer, PATH_MAX, "%s/blog.sq3", conf.bbs_path);
rc = sqlite3_open(buffer, &db);
if (rc != SQLITE_OK) {
dolog("Cannot open database: %s", sqlite3_errmsg(db));
return EMPTY_PTR_VECTOR;
}
sqlite3_busy_timeout(db, 5000);
rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
if (rc != SQLITE_OK) {
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
sqlite3_close(db);
return EMPTY_PTR_VECTOR;
}
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(&entries, entry);
}
sqlite3_finalize(res);
sqlite3_close(db);
return entries;
}
void blog_display() {
struct ptr_vector entries = blog_load();
struct tm thetime;
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;
int lines = 2;
s_printf("\e[2J\e[1;1H");
s_printf(get_string(280));
s_printf(get_string(281));
if (ptr_vector_len(&entries) == 0) {
s_printf(get_string(282));
s_printf(get_string(6));
s_getchar();
return;
}
c = 'y';
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), entry->subject, entry->author);
lines++;
if (lines == 22 && tolower(c) != 'c') {
s_printf("\r\n");
s_printf(get_string(223));
c = s_getchar();
if (tolower(c) == 'n') {
break;
}
s_printf("\r\n\r\n");
lines = 0;
}
if (thetime.tm_hour >= 12) {
hour = thetime.tm_hour - 12;
} else {
hour = thetime.tm_hour;
}
s_printf(get_string(284), (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);
lines++;
if (lines == 22 && tolower(c) != 'c') {
s_printf("\r\n");
s_printf(get_string(223));
c = s_getchar();
if (tolower(c) == 'n') {
break;
}
s_printf("\r\n\r\n");
lines = 0;
}
s_printf("\r\n\e[0m");
lines++;
if (lines == 22 && tolower(c) != 'c') {
s_printf("\r\n");
s_printf(get_string(223));
c = s_getchar();
if (tolower(c) == 'n') {
break;
}
s_printf("\r\n\r\n");
lines = 0;
}
for (j = 0; j < strlen(entry->body); j++) {
if (entry->body[j] == '\r') {
s_printf("\r\n");
lines++;
if (lines == 22 && tolower(c) != 'c') {
s_printf("\r\n");
s_printf(get_string(223));
c = s_getchar();
if (tolower(c) == 'n') {
break;
}
s_printf("\r\n\r\n");
lines = 0;
}
} else {
s_printf("%c", entry->body[j]);
}
}
if (tolower(c) == 'n') {
break;
}
s_printf("\r\n");
lines++;
if (lines == 22 && tolower(c) != 'c') {
s_printf("\r\n");
s_printf(get_string(223));
c = s_getchar();
if (tolower(c) == 'n') {
break;
}
s_printf("\r\n\r\n");
lines = 0;
}
}
ptr_vector_apply(&entries, free);
destroy_ptr_vector(&entries);
s_printf(get_string(6));
s_getchar();
}
void blog_write() {
char *csql = "CREATE TABLE IF NOT EXISTS blog ("
"id INTEGER PRIMARY KEY,"
"author TEXT COLLATE NOCASE,"
"title TEXT,"
"body TEXT,"
"date INTEGER);";
char *isql = "INSERT INTO blog (author, title, body, date) VALUES(?, ?, ?, ?)";
int rc;
sqlite3 *db;
sqlite3_stmt *res;
char *blog_entry;
char buffer[PATH_MAX];
char *blog_subject;
char *err_msg = 0;
s_printf(get_string(285));
s_readstring(buffer, 64);
s_printf("\r\n");
if (strlen(buffer) == 0) {
s_printf(get_string(39));
return;
}
blog_subject = strdup(buffer);
blog_entry = external_editor(gUser, "No-One", "No-One", NULL, 0, "No-One", "Blog Editor", 0, 1);
if (blog_entry != NULL) {
snprintf(buffer, PATH_MAX, "%s/blog.sq3", conf.bbs_path);
rc = sqlite3_open(buffer, &db);
if (rc != SQLITE_OK) {
dolog("Cannot open database: %s", sqlite3_errmsg(db));
free(blog_entry);
free(blog_subject);
return;
}
sqlite3_busy_timeout(db, 5000);
rc = sqlite3_exec(db, csql, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
dolog("SQL error: %s", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
free(blog_entry);
free(blog_subject);
return;
}
rc = sqlite3_prepare_v2(db, isql, -1, &res, 0);
if (rc == SQLITE_OK) {
sqlite3_bind_text(res, 1, gUser->loginname, -1, 0);
sqlite3_bind_text(res, 2, blog_subject, -1, 0);
sqlite3_bind_text(res, 3, blog_entry, -1, 0);
sqlite3_bind_int(res, 4, time(NULL));
} else {
dolog("Failed to execute statement: %s", sqlite3_errmsg(db));
sqlite3_finalize(res);
sqlite3_close(db);
free(blog_entry);
free(blog_subject);
return;
}
sqlite3_step(res);
sqlite3_finalize(res);
sqlite3_close(db);
free(blog_entry);
free(blog_subject);
return;
}
free(blog_subject);
}