Subversion Repositories IRC-Archiver

Rev

Rev 12 | Rev 14 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 12 Rev 13
Line 1... Line 1...
1
/* $Id: html.c 12 2024-08-30 05:23:43Z nishi $ */
1
/* $Id: html.c 13 2024-08-30 07:33:43Z nishi $ */
2
 
2
 
3
#include "web_html.h"
3
#include "web_html.h"
4
 
4
 
-
 
5
#include "web_db.h"
-
 
6
 
5
#include "ia_util.h"
7
#include "ia_util.h"
6
 
8
 
7
#include <time.h>
9
#include <time.h>
8
#include <stdio.h>
10
#include <stdio.h>
9
#include <stdlib.h>
11
#include <stdlib.h>
10
#include <string.h>
12
#include <string.h>
-
 
13
#include <stdbool.h>
11
 
14
 
12
extern char* webroot;
15
extern char* webroot;
-
 
16
extern const char* ircarc_version;
13
 
17
 
14
char* web_html_escape(const char* html) {
18
char* web_html_escape(const char* html) {
15
	char* str = malloc(strlen(html) * 5 + 1);
19
	char* str = malloc(strlen(html) * 5 + 1);
16
	int i;
20
	int i;
17
	int incr = 0;
21
	int incr = 0;
Line 39... Line 43...
39
	}
43
	}
40
	str[incr] = 0;
44
	str[incr] = 0;
41
	return str;
45
	return str;
42
}
46
}
43
 
47
 
-
 
48
#define TAG(tagname, el, chr) \
-
 
49
	bool attr = true; \
-
 
50
	if(bufincr > 0) { \
-
 
51
		int k; \
-
 
52
		for(k = bufincr - 1; k >= 0; k--) { \
-
 
53
			if(buffer[k] == chr) { \
-
 
54
				attr = false; \
-
 
55
				int l; \
-
 
56
				buffer[k] = 0; \
-
 
57
				for(l = k; l < bufincr; l++) { \
-
 
58
					buffer[l] = buffer[l + 1]; \
-
 
59
				} \
-
 
60
				break; \
-
 
61
			} \
-
 
62
		} \
-
 
63
		if(!attr) bufincr--; \
-
 
64
	} \
-
 
65
	if(attr) { \
-
 
66
		buffer[bufincr++] = chr; \
-
 
67
		char* tmp = fmtmsg; \
-
 
68
		fmtmsg = ia_strcat4(tmp, "<" tagname, el, ">"); \
-
 
69
		free(tmp); \
-
 
70
	} else { \
-
 
71
		char* tmp = fmtmsg; \
-
 
72
		fmtmsg = ia_strcat(tmp, "</" tagname ">"); \
-
 
73
		free(tmp); \
-
 
74
	}
-
 
75
 
44
int web_html_generate(const char* name, web_range_t range) {
76
int web_html_generate(const char* name, web_range_t range) {
-
 
77
	time_t t = time(NULL);
45
	char* path = ia_strcat4(webroot, "/", name, ".html");
78
	char* path = ia_strcat4(webroot, "/", name, ".html");
46
	FILE* f = fopen(path, "w");
79
	FILE* f = fopen(path, "w");
47
	if(f != NULL) {
80
	if(f != NULL) {
-
 
81
		entry_t** e = web_db_query(range);
-
 
82
 
-
 
83
		char date[512];
-
 
84
		struct tm* tm = gmtime(&t);
-
 
85
		strftime(date, sizeof(date), "%Y/%m/%d %H:%M:%S UTC", tm);
48
		char* htmlesc = web_html_escape(name);
86
		char* htmlesc = web_html_escape(name);
49
		char* title = ia_strcat("Archive: ", htmlesc);
87
		char* title = ia_strcat("Archive: ", htmlesc);
-
 
88
		free(htmlesc);
50
		fprintf(f, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
89
		fprintf(f, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
51
		fprintf(f, "<html>\n");
90
		fprintf(f, "<html>\n");
52
		fprintf(f, "	<head>\n");
91
		fprintf(f, "	<head>\n");
53
		fprintf(f, "		<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n");
92
		fprintf(f, "		<meta http-equiv=\"Content-Type\" content=\"text/html;charset=UTF-8\">\n");
54
		fprintf(f, "		<title>%s</title>\n", title);
93
		fprintf(f, "		<title>%s</title>\n", title);
-
 
94
		fprintf(f, "		<style type=\"text/css\">\n");
-
 
95
		fprintf(f, "		</style>\n");
55
		fprintf(f, "	</head>\n");
96
		fprintf(f, "	</head>\n");
56
		fprintf(f, "	<body>\n");
97
		fprintf(f, "	<body style=\"padding: 15px; margin: 0 auto; width: 900px;\">\n");
57
		fprintf(f, "		<div style=\"text-align: center; background-color: #0000e0;\">\n");
98
		fprintf(f, "		<div style=\"padding: 1px 0; margin: 0; text-align: center; background-color: #8080ff;\">\n");
58
		fprintf(f, "			<h1>%s</h1>\n", title);
99
		fprintf(f, "			<h1>%s</h1>\n", title);
59
		fprintf(f, "		</div>\n");
100
		fprintf(f, "		</div>\n");
-
 
101
		fprintf(f, "		Archived at %s.<br>\n", date);
-
 
102
		htmlesc = web_html_escape(range.channel);
-
 
103
		fprintf(f, "		Channel: <code>%s</code><br>\n", htmlesc);
-
 
104
		free(htmlesc);
-
 
105
		fprintf(f, "		<hr>\n");
-
 
106
		fprintf(f, "		<a href=\"./\">Go back to index</a>\n");
-
 
107
		fprintf(f, "		<hr>\n");
-
 
108
		fprintf(f, "<div>\n");
-
 
109
		fprintf(f, "		<pre style=\"margin: 0; border: solid 1px black; padding: 10px; overflow: scroll; width: 678px; min-height: 900px; background-color: #d0d0ff; float: left;\"><code>");
-
 
110
		int i;
-
 
111
		int bgcolor = 0xd0d0ff;
-
 
112
		int fgcolor = 0x000000;
-
 
113
		for(i = 0; e[i] != NULL; i++) {
-
 
114
			time_t t = e[i]->time;
-
 
115
			struct tm* tm = gmtime(&t);
-
 
116
			char* escusr = web_html_escape(e[i]->username);
-
 
117
			char* escmsg = web_html_escape(e[i]->message);
-
 
118
			char date[512];
-
 
119
			strftime(date, 512, "%Y/%m/%d %H:%M:%S UTC", tm);
-
 
120
			char cbuf[2];
-
 
121
			cbuf[1] = 0;
-
 
122
			char* fmtmsg = ia_strdup("");
-
 
123
			int j;
-
 
124
			char buffer[512];
-
 
125
			memset(buffer, 0, 512);
-
 
126
			int bufincr = 0;
-
 
127
			for(j = 0; escmsg[j] != 0; j++) {
-
 
128
				if(escmsg[j] == 2) {
-
 
129
					TAG("b", "", 'B');
-
 
130
				} else if(escmsg[j] == 0x1d) {
-
 
131
					TAG("i", "", 'I');
-
 
132
				} else if(escmsg[j] == 0x1f) {
-
 
133
					TAG("u", "", 'U');
-
 
134
				} else if(escmsg[j] == 0x1e) {
-
 
135
					TAG("s", "", 'S');
-
 
136
				} else if(escmsg[j] == 0x16) {
-
 
137
					char fgt[32];
-
 
138
					char bgt[32];
-
 
139
					int _c = fgcolor;
-
 
140
					fgcolor = bgcolor;
-
 
141
					bgcolor = _c;
-
 
142
					sprintf(fgt, "#%06X", fgcolor);
-
 
143
					sprintf(bgt, "#%06X", bgcolor);
-
 
144
					char* _ = ia_strcat4(" style=\"background-color: ", bgt, "; color: ", fgt);
-
 
145
					char* style = ia_strcat(_, ";\"");
-
 
146
					free(_);
-
 
147
					TAG("span", style, 'R');
-
 
148
				} else if(escmsg[j] == 0x03) {
-
 
149
					j++;
-
 
150
					int k = j;
-
 
151
					for(; escmsg[j] != 0 && j < k + 2; j++) {
-
 
152
						if(!('0' <= escmsg[j] && escmsg[j] <= '9')) break;
-
 
153
					}
-
 
154
					if(escmsg[j] == ',') {
-
 
155
						j++;
-
 
156
						k = j;
-
 
157
						for(; escmsg[j] != 0 && j < k + 2; j++) {
-
 
158
							if(!('0' <= escmsg[j] && escmsg[j] <= '9')) break;
-
 
159
						}
-
 
160
					}
-
 
161
					j--;
-
 
162
				} else if(escmsg[j] == 0x0f) {
-
 
163
					int k;
-
 
164
					for(k = bufincr - 1; k >= 0; k--) {
-
 
165
						char c = buffer[k];
-
 
166
						if(c == 'B') {
-
 
167
							char* tmp = fmtmsg;
-
 
168
							fmtmsg = ia_strcat(tmp, "</b>");
-
 
169
							free(tmp);
-
 
170
						} else if(c == 'I') {
-
 
171
							char* tmp = fmtmsg;
-
 
172
							fmtmsg = ia_strcat(tmp, "</i>");
-
 
173
							free(tmp);
-
 
174
						} else if(c == 'U') {
-
 
175
							char* tmp = fmtmsg;
-
 
176
							fmtmsg = ia_strcat(tmp, "</u>");
-
 
177
							free(tmp);
-
 
178
						} else if(c == 'S') {
-
 
179
							char* tmp = fmtmsg;
-
 
180
							fmtmsg = ia_strcat(tmp, "</s>");
-
 
181
							free(tmp);
-
 
182
						} else if(c == 'R') {
-
 
183
							char* tmp = fmtmsg;
-
 
184
							fmtmsg = ia_strcat(tmp, "</span>");
-
 
185
							free(tmp);
-
 
186
						}
-
 
187
					}
-
 
188
					bufincr = 0;
-
 
189
					bgcolor = 0xd0d0ff;
-
 
190
					fgcolor = 0x000000;
-
 
191
				} else {
-
 
192
					cbuf[0] = escmsg[j];
-
 
193
					char* tmp;
-
 
194
					tmp = fmtmsg;
-
 
195
					fmtmsg = ia_strcat(tmp, cbuf);
-
 
196
					free(tmp);
-
 
197
				}
-
 
198
			}
-
 
199
			for(j = bufincr - 1; j >= 0; j--) {
-
 
200
				char c = buffer[j];
-
 
201
				if(c == 'B') {
-
 
202
					char* tmp = fmtmsg;
-
 
203
					fmtmsg = ia_strcat(tmp, "</b>");
-
 
204
					free(tmp);
-
 
205
				} else if(c == 'I') {
-
 
206
					char* tmp = fmtmsg;
-
 
207
					fmtmsg = ia_strcat(tmp, "</i>");
-
 
208
					free(tmp);
-
 
209
				} else if(c == 'U') {
-
 
210
					char* tmp = fmtmsg;
-
 
211
					fmtmsg = ia_strcat(tmp, "</u>");
-
 
212
					free(tmp);
-
 
213
				} else if(c == 'S') {
-
 
214
					char* tmp = fmtmsg;
-
 
215
					fmtmsg = ia_strcat(tmp, "</s>");
-
 
216
					free(tmp);
-
 
217
				} else if(c == 'R') {
-
 
218
					char* tmp = fmtmsg;
-
 
219
					fmtmsg = ia_strcat(tmp, "</span>");
-
 
220
					free(tmp);
-
 
221
				}
-
 
222
			}
-
 
223
			fprintf(f, "<span class=\"line\">[%s] &lt;%s&gt; %s</span>\n", date, escusr, fmtmsg);
-
 
224
			free(fmtmsg);
-
 
225
			free(escusr);
-
 
226
			free(escmsg);
-
 
227
			free(e[i]->username);
-
 
228
			free(e[i]->message);
-
 
229
			free(e[i]);
-
 
230
		}
-
 
231
		free(e);
-
 
232
		fprintf(f, "</code></pre>\n");
-
 
233
		fprintf(f, "		<div style=\"margin: 0; border: solid 1px black; width: 178px; min-height: 900px; padding: 10px; background-color: #d0d0ff; float: right; overflow: scroll\">Statistics<hr>%d messages</div>\n", i);
-
 
234
		fprintf(f, "		</div>\n");
-
 
235
		fprintf(f, "		<div style=\"clear: both\"></div>\n");
-
 
236
		fprintf(f, "		<hr>\n");
-
 
237
		fprintf(f, "		<a href=\"./\">Go back to index</a>\n");
-
 
238
		fprintf(f, "		<hr>\n");
-
 
239
		fprintf(f, "		<i>Generated by <a href=\"http://nishi.boats/ircarc\">IRC-Archiver</a> %s</i>\n", ircarc_version);
60
		fprintf(f, "	</body>\n");
240
		fprintf(f, "	</body>\n");
61
		fprintf(f, "</html>\n");
241
		fprintf(f, "</html>\n");
62
		fclose(f);
242
		fclose(f);
63
		free(title);
243
		free(title);
64
		free(htmlesc);
-
 
65
	}
244
	}
66
	free(path);
245
	free(path);
67
}
246
}