summaryrefslogtreecommitdiff
path: root/export_xml.c
blob: 212b4635625416c51b80f5d2c4aad6ae60203f24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <libxml/xmlwriter.h>
#include <string.h>

#include "export_xml.h"
#include "word.h"

#if !defined(LIBXML_WRITER_ENABLED)
#error "libxml must be compiled with text writer support"
#endif


int export_xml(struct channel_t *channel, struct user_t *users) {
	/* Create document and set root node. */
	xmlTextWriterPtr writer = xmlNewTextWriterFilename(channel->xmlpath, 0);
	if(writer == NULL) {
		fprintf(stderr, "Failed to create text writer for filename \"%s\"\n", channel->xmlpath);
		return 0;
	}

	xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
	xmlTextWriterStartElement(writer, (const xmlChar*)"channel");

	/* Set the channel name. */
	xmlTextWriterStartElement(writer, (const xmlChar*)"name");
	xmlTextWriterWriteString(writer, (const xmlChar*)channel->name);
	xmlTextWriterEndElement(writer);

	/* Add lines. */
	xmlTextWriterStartElement(writer, (const xmlChar*)"lines");
	for(int h = 0; h < 24; h++) {
		xmlTextWriterStartElement(writer, (const xmlChar*)"hour");
		for(int q = 0; q < 4; q++) {
			xmlTextWriterStartElement(writer, (const xmlChar*)"quarter");
			xmlTextWriterWriteFormatString(writer, "%lu", channel->hours[h*4 + q]);
			xmlTextWriterEndElement(writer);
		}
		xmlTextWriterEndElement(writer); // hour
	}
	xmlTextWriterEndElement(writer); // lines

	/* Add users. */
	xmlTextWriterStartElement(writer, (const xmlChar*)"users");
	for(int u = 0; u < USERS_MAX; u++) {
		struct user_t *user = &users[u];
		/* Iterate while we have a user (nick is non-NULL). */
		while(user && user->nick) {
			/* Skip mapped nicks and <NULL> (filtered nicks eg. bots). */
			if(user->real_user != NULL || strcmp(user->nick, "<NULL>") == 0) {
				user = user->next;
				continue;
			}
			xmlTextWriterStartElement(writer, (const xmlChar*)"user");

			xmlTextWriterStartElement(writer, (const xmlChar*)"nick");
			xmlTextWriterWriteString(writer, (const xmlChar*)user->nick);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"words");
			xmlTextWriterWriteFormatString(writer, "%llu", user->words);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"characters");
			xmlTextWriterWriteFormatString(writer, "%llu", user->characters);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"kicks");
			xmlTextWriterWriteFormatString(writer, "%llu", user->kicks);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"kicked");
			xmlTextWriterWriteFormatString(writer, "%llu", user->kicked);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"monolog_lines");
			xmlTextWriterWriteFormatString(writer, "%llu", user->monolog_lines);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"monologs");
			xmlTextWriterWriteFormatString(writer, "%llu", user->monologs);
			xmlTextWriterEndElement(writer);

			/* Add lines for this user. */
			xmlTextWriterStartElement(writer, (const xmlChar*)"lines");
			for(int h = 0; h < 24; h++) {
				xmlTextWriterStartElement(writer, (const xmlChar*)"hour");
				for(int q = 0; q < 4; q++) {
					xmlTextWriterStartElement(writer, (const xmlChar*)"quarter");
					xmlTextWriterWriteFormatString(writer, "%lu", user->lines[h*4 + q]);
					xmlTextWriterEndElement(writer);
				}
				xmlTextWriterEndElement(writer); // hour
			}
			xmlTextWriterEndElement(writer); // lines
			user = user->next;

			xmlTextWriterEndElement(writer); // user
		}
	}
	xmlTextWriterEndElement(writer); // users

	/* Add words. */
	xmlTextWriterStartElement(writer, (const xmlChar*)"words");
	for(int w = 0; w < WORDS_MAX; w++) {
		struct word_t *word = &words[w];
		while(word && word->name) {
			xmlTextWriterStartElement(writer, (const xmlChar*)"word");

			xmlTextWriterStartElement(writer, (const xmlChar*)"name");
			xmlTextWriterWriteString(writer, (const xmlChar*)word->name);
			xmlTextWriterEndElement(writer);

			xmlTextWriterStartElement(writer, (const xmlChar*)"count");
			xmlTextWriterWriteFormatString(writer, "%llu", word->count);
			xmlTextWriterEndElement(writer);

			word = word->next;

			xmlTextWriterEndElement(writer); // word
		}
	}
	xmlTextWriterEndElement(writer); // words

	xmlTextWriterEndElement(writer); // channel

	xmlTextWriterEndDocument(writer);
	xmlFreeTextWriter(writer);

	return 1;
}