html generation

git-svn-id: file:///raid/svn-personal/irc-archiver/trunk@11 f310dea9-ad02-7e44-859a-30a050007fc7
This commit is contained in:
Nishi 2024-08-30 05:20:32 +00:00
parent da4db78a14
commit ff891c655b
8 changed files with 177 additions and 7 deletions

View File

@ -5,12 +5,15 @@
#include "ia_util.h"
#include "ia_db.h"
#include "web_html.h"
#include "ircfw.h"
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
@ -177,18 +180,93 @@ void ia_bot_loop(void) {
} else {
/* Command, I guess */
int i;
char* name = NULL;
char* chn = NULL;
char* frm = NULL;
char* to = NULL;
char* prm = ia_strdup(msg);
int incr = 0;
int t = 0;
for(i = 0;; i++) {
if(prm[i] == ' ' || prm[i] == 0) {
char oldc = prm[i];
prm[i] = 0;
if(strcasecmp(prm, "help") == 0) {
sprintf(construct, "PRIVMSG %s :HELP Show this help", nick);
sprintf(construct, "PRIVMSG %s :HELP Show this help", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
sprintf(construct, "PRIVMSG %s :SHUTDOWN Shutdown the bot", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
sprintf(construct, "PRIVMSG %s :ARCHIVE [name] [channel] <yyyy-mm-dd-hh:mm:ss> <yyyy-mm-dd-hh:mm:ss> Archive the log", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
} else if(strcasecmp(prm, "archive") == 0) {
if(strcmp(admin, nick) == 0) {
if(t <= 4 && t != 0) {
char* p = prm + incr;
if(t == 1) {
name = p;
} else if(t == 2) {
chn = p;
} else if(t == 3) {
frm = p;
} else if(t == 4) {
to = p;
}
}
if(oldc == 0) {
if(chn == NULL) {
sprintf(construct, "PRIVMSG %s :Insufficient arguments", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
} else {
web_range_t range;
struct tm from_tm;
memset(&from_tm, 0, sizeof(from_tm));
struct tm to_tm;
memset(&to_tm, 0, sizeof(to_tm));
time_t tfrom = 0;
time_t tto = 0;
if(frm != NULL) {
if(strptime(frm, "%Y-%m-%d-%H:%M:%S", &from_tm) == NULL) {
sprintf(construct, "PRIVMSG %s :Date parsing failure", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
break;
}
tfrom = mktime(&from_tm);
}
if(to != NULL) {
if(strptime(to, "%Y-%m-%d-%H:%M:%S", &to_tm) == NULL) {
sprintf(construct, "PRIVMSG %s :Date parsing failure", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
break;
}
tto = mktime(&to_tm);
}
int j;
bool found = false;
for(j = 0; channels[j] != NULL; j++) {
if(strcmp(channels[j], chn) == 0) {
found = true;
break;
}
}
if(!found) {
sprintf(construct, "PRIVMSG %s :I do not know the channel", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
break;
}
range.from = tfrom;
range.to = tto;
range.channel = chn;
web_html_generate(name, range);
}
}
} else {
sprintf(construct, "PRIVMSG %s :You must be an admin to use this", nick);
ircfw_socket_send_cmd(ia_sock, NULL, construct);
break;
}
} else if(strcasecmp(prm, "shutdown") == 0) {
if(strcmp(admin, nick) == 0) {
loop = false;
@ -204,6 +282,7 @@ void ia_bot_loop(void) {
}
incr = i + 1;
t++;
if(oldc == 0) break;
}
}

View File

@ -4,6 +4,8 @@
#define __IA_UTIL_H__
char* ia_strcat(const char* a, const char* b);
char* ia_strcat3(const char* a, const char* b, const char* c);
char* ia_strcat4(const char* a, const char* b, const char* c, const char* d);
char* ia_strdup(const char* str);
#endif

View File

@ -13,4 +13,18 @@ char* ia_strcat(const char* a, const char* b) {
return str;
}
char* ia_strcat3(const char* a, const char* b, const char* c) {
char* tmp = ia_strcat(a, b);
char* str = ia_strcat(tmp, c);
free(tmp);
return str;
}
char* ia_strcat4(const char* a, const char* b, const char* c, const char* d) {
char* tmp = ia_strcat3(a, b, c);
char* str = ia_strcat(tmp, d);
free(tmp);
return str;
}
char* ia_strdup(const char* str) { return ia_strcat(str, ""); }

View File

@ -5,7 +5,7 @@ include $(PWD)/Platform/$(PLATFORM).mk
.PHONY: all clean
.SUFFIXES: .c .o
OBJS = db.o
OBJS = db.o html.o
all: web.a

View File

@ -1,7 +1,3 @@
/* $Id$ */
#include "web_db.h"
#include "ia_db.h"
void web_db_generate(const char* name, const char* match) {}

64
Web/html.c Normal file
View File

@ -0,0 +1,64 @@
/* $Id$ */
#include "web_html.h"
#include "ia_util.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char* webroot;
char* web_html_escape(const char* html) {
char* str = malloc(strlen(html) * 5 + 1);
int i;
int incr = 0;
for(i = 0; html[i] != 0; i++) {
if(html[i] == '&') {
str[incr++] = '&';
str[incr++] = 'a';
str[incr++] = 'm';
str[incr++] = 'p';
str[incr++] = ';';
} else if(html[i] == '<') {
str[incr++] = '&';
str[incr++] = 'l';
str[incr++] = 't';
str[incr++] = ';';
} else if(html[i] == '>') {
str[incr++] = '&';
str[incr++] = 'g';
str[incr++] = 't';
str[incr++] = ';';
} else {
str[incr++] = html[i];
;
}
}
str[incr] = 0;
return str;
}
int web_html_generate(const char* name, web_range_t range) {
char* path = ia_strcat4(webroot, "/", name, ".html");
FILE* f = fopen(path, "w");
if(f != NULL) {
char* htmlesc = web_html_escape(name);
char* title = ia_strcat("Archive: ", htmlesc);
fprintf(f, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n");
fprintf(f, "<html>\n");
fprintf(f, " <head>\n");
fprintf(f, " <meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n");
fprintf(f, " <title>%s</title>\n", title);
fprintf(f, " </head>\n");
fprintf(f, " <body>\n");
fprintf(f, " </body>\n");
fprintf(f, "</html>\n");
fclose(f);
free(title);
free(htmlesc);
}
free(path);
}

View File

@ -3,6 +3,10 @@
#ifndef __WEB_DB_H__
#define __WEB_DB_H__
void web_db_generate(const char* name, const char* match);
typedef struct {
unsigned long long from;
unsigned long long to;
const char* channel;
} web_range_t;
#endif

11
Web/web_html.h Normal file
View File

@ -0,0 +1,11 @@
/* $Id$ */
#ifndef __WEB_HTML_H__
#define __WEB_HTML_H__
#include "web_db.h"
char* web_html_escape(const char* html);
int web_html_generate(const char* name, web_range_t range);
#endif