]> jfr.im git - irc/quakenet/newserv.git/blob - helpmod2/hstat.c
fix bug in G stats
[irc/quakenet/newserv.git] / helpmod2 / hstat.c
1 #include <time.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <assert.h>
5
6 #include "hchannel.h"
7 #include "hstat.h"
8 #include "helpmod.h"
9 #include "hgen.h"
10
11 int hstat_is_prime_time(void)
12 {
13 time_t timer = time(NULL);
14 struct tm *tstruct = localtime(&timer);
15
16 if (tstruct->tm_hour > 12 && tstruct->tm_hour < 23)
17 return !0;
18 return 0;
19 }
20
21 void hstat_scheduler(void)
22 {
23 time_t timer = time(NULL);
24 struct tm *tstruct = localtime(&timer);
25 int is_sunday = (tstruct->tm_wday == 0); /* is it sunday ? */
26 int i;
27
28 { /* accounts */
29 haccount *ptr = haccounts;
30 for (;ptr;ptr = ptr->next)
31 if (ptr->level > H_PEON)
32 {
33 hstat_account *ptr2 = ptr->stats;
34 for (;ptr2;ptr2 = ptr2->next)
35 {
36 if (is_sunday)
37 {
38 HSTAT_ACCOUNT_ZERO(ptr2->longterm[(hstat_week() + 1) % 10]);
39 for (i=0;i<7;i++)
40 {
41 HSTAT_ACCOUNT_SUM(ptr2->longterm[(hstat_week() + 1) % 10], ptr2->longterm[(hstat_week() + 1) % 10], ptr2->week[i]);
42 }
43 }
44 HSTAT_ACCOUNT_ZERO(ptr2->week[(hstat_day() + 1) % 7]);
45 }
46 }
47 }
48 { /* hchannels */
49 hchannel *ptr = hchannels;
50 for (;ptr;ptr = ptr->next)
51 {
52 hstat_channel *ptr2;
53 if (ptr->flags & H_REPORT && hchannel_is_valid(ptr->report_to))
54 {
55 hstat_channel_entry *entry = &ptr->stats->week[hstat_day()];
56 helpmod_message_channel(ptr->report_to, "Daily summary for channel %s: Time spent %s, joins %d and queue usage %d", hchannel_get_name(ptr),helpmod_strtime(entry->time_spent), entry->joins, entry->queue_use);
57 }
58
59 ptr2 = ptr->stats;
60 if (is_sunday)
61 {
62 HSTAT_CHANNEL_ZERO(ptr2->longterm[(hstat_week() + 1) % 10]);
63 for (i=0;i<7;i++)
64 {
65 HSTAT_CHANNEL_SUM(ptr2->longterm[(hstat_week() + 1) % 10], ptr2->longterm[(hstat_week() + 1) % 10], ptr2->week[i]);
66 }
67 }
68 HSTAT_CHANNEL_ZERO(ptr2->week[(hstat_day() + 1) % 7]);
69 }
70 }
71
72 if (is_sunday)
73 hstat_cycle++;
74 }
75
76 int hstat_get_schedule_time(void)
77 {
78 time_t timer = time(NULL);
79 struct tm *tstruct = localtime(&timer);
80
81 return timer + (HDEF_d - (HDEF_h * tstruct->tm_hour + HDEF_m * tstruct->tm_min + tstruct->tm_sec));
82 }
83
84 hstat_channel *get_hstat_channel(void)
85 {
86 hstat_channel *tmp;
87
88 tmp = malloc(sizeof(hstat_channel));
89
90 memset(tmp, 0x00, sizeof(hstat_channel));
91
92 return tmp;
93 }
94
95 void hstat_del_channel(hchannel *hchan)
96 {
97 haccount *hacc = haccounts;
98 hstat_account **hs_acc;
99 for (;hacc;hacc = hacc->next)
100 for (hs_acc = &hacc->stats;*hs_acc;hs_acc = &(*hs_acc)->next)
101 if ((*hs_acc)->hchan == hchan)
102 {
103 hstat_account *tmp = (*hs_acc)->next;
104 free(*hs_acc);
105 *hs_acc = tmp;
106 break;
107 }
108 }
109
110 hstat_account *get_hstat_account(void)
111 {
112 hstat_account *tmp;
113
114 tmp = malloc(sizeof(hstat_account));
115
116 memset(tmp, 0x00, sizeof(hstat_account));
117
118 tmp->next = NULL; /* just for style */
119
120 return tmp;
121 }
122
123 void hstat_calculate_account(hchannel *hchan, huser* husr, const char *message)
124 {
125 hstat_account **acc_stat;
126 hstat_account_entry *acc_entry;
127 huser_channel *huserchan = huser_on_channel(husr, hchan);
128
129 int wordc = 0, time_spent;
130
131 if (huserchan == NULL || husr->account == NULL)
132 return;
133
134 for (acc_stat = &husr->account->stats;*acc_stat;acc_stat = &(*acc_stat)->next)
135 if ((*acc_stat)->hchan == hchan)
136 break;
137
138 if (*acc_stat == NULL)
139 { /* this user has no stats for the channel -> create them */
140 *acc_stat = get_hstat_account();
141 (*acc_stat)->hchan = hchan;
142 }
143
144 acc_entry = &(*acc_stat)->week[hstat_day()];
145
146 time_spent = time(NULL) - huserchan->last_activity;
147
148 if (time_spent > 0 && time_spent < HSTAT_ACTIVITY_TRESHOLD)
149 {
150 acc_entry->time_spent+=time_spent;
151
152 if (hstat_is_prime_time())
153 acc_entry->prime_time_spent+=time_spent;
154 }
155
156 acc_entry->lines++;
157
158 wordc = hword_count(message);
159 acc_entry->words+=wordc;
160 }
161
162 void hstat_calculate_channel(hchannel *hchan, huser* husr, const char *message)
163 {
164 hstat_channel_entry *chan_entry;
165 huser_channel *huserchan = huser_on_channel(husr, hchan);
166
167 int wordc = 0, time_spent, activity_channel, activity_staff_channel;
168
169 if (huserchan == NULL)
170 return;
171
172 chan_entry = &hchan->stats->week[hstat_day()];
173
174 activity_channel = time(NULL) - hchan->last_activity;
175 activity_staff_channel = time(NULL) - hchan->last_staff_activity;
176
177 time_spent = time(NULL) - huserchan->last_activity;
178
179 if (time_spent > 0 && time_spent < HSTAT_ACTIVITY_TRESHOLD)
180 {
181 chan_entry->time_spent+=time_spent;
182
183 if (hstat_is_prime_time())
184 chan_entry->prime_time_spent+=time_spent;
185 }
186
187
188 { /* everyone */
189 if (activity_channel > 0 && activity_channel < HSTAT_ACTIVITY_TRESHOLD)
190 chan_entry->active_time+=activity_channel;
191 hchan->last_activity = time(NULL);
192 }
193
194 if (huser_get_level(husr) > H_PEON)
195 { /* staff */
196 if (activity_staff_channel > 0 && activity_staff_channel < HSTAT_ACTIVITY_TRESHOLD)
197 chan_entry->staff_active_time+=activity_staff_channel;
198 hchan->last_staff_activity = time(NULL);
199 }
200
201 chan_entry->lines++;
202
203 wordc = hword_count(message);
204 chan_entry->words+=wordc;
205 }
206
207 void hstat_add_join(hchannel *hchan)
208 {
209 hchan->stats->week[hstat_day()].joins++;
210 }
211
212 void hstat_add_queue(hchannel *hchan, int amount)
213 {
214 hchan->stats->week[hstat_day()].queue_use+=amount;
215 }
216
217 const char *hstat_channel_print(hstat_channel_entry *entry, int type)
218 {
219 static char buffer[256];
220 buffer[0] = '\0';
221 switch (type)
222 {
223 case HSTAT_CHANNEL_LONG:
224 /* sprintf(buffer, "%-18s %-18s %-10d %-10d %-10d %-10d", helpmod_strtime(entry->time_spent), helpmod_strtime(entry->prime_time_spent), entry->joins, entry->queue_use, entry->lines, entry->words); */
225 sprintf(buffer, "%-16s %-5.1f%% %-16s %-5.1f%% %-8d %-8d %-8d %-10d", helpmod_strtime(entry->time_spent), helpmod_percentage(entry->time_spent, entry->prime_time_spent), helpmod_strtime(entry->active_time), helpmod_percentage(entry->active_time, entry->staff_active_time), entry->joins, entry->queue_use, entry->lines, entry->words);
226 break;
227 case HSTAT_CHANNEL_SHORT:
228 sprintf(buffer, "%-18s %-18s", helpmod_strtime(entry->time_spent), helpmod_strtime(entry->prime_time_spent));
229 break;
230 }
231 return buffer;
232 }
233
234 const char *hstat_account_print(hstat_account_entry *entry, int type)
235 {
236 static char buffer[256];
237 buffer[0] = '\0';
238 switch (type)
239 {
240 case HSTAT_ACCOUNT_LONG:
241 sprintf(buffer, "%-18s %-18s %-10d %-10d", helpmod_strtime(entry->time_spent), helpmod_strtime(entry->prime_time_spent), entry->lines, entry->words);
242 break;
243 case HSTAT_ACCOUNT_SHORT:
244 sprintf(buffer, "%-18s %-18s", helpmod_strtime(entry->time_spent), helpmod_strtime(entry->prime_time_spent));
245 break;
246 }
247 return buffer;
248 }
249
250
251 const char *hstat_header(hstat_type type)
252 {
253 switch (type)
254 {
255 case HSTAT_ACCOUNT_SHORT:
256 return "TimeSpent PrimeTimeSpent";
257 case HSTAT_ACCOUNT_LONG:
258 return "TimeSpent PrimeTimeSpent Lines Words";
259 case HSTAT_CHANNEL_SHORT:
260 return "TimeSpent PrimeTimeSpent";
261 case HSTAT_CHANNEL_LONG:
262 /*return "TimeSpent PrimeTimeSpent Joins QueueUse Lines Words";*/
263 return "TimeSpent Prime-% Activity Staff-% Joins QueueUse Lines Words";
264 default:
265 return "Error: please contact strutsi";
266 }
267 }
268
269 int hstat_week(void)
270 {
271 return hstat_cycle % 10;
272 }
273
274 int hstat_day(void)
275 {
276 time_t timer = time(NULL);
277 struct tm *tstruct = localtime(&timer);
278
279 return tstruct->tm_wday;
280 }
281
282 int hstat_account_count(hstat_account *hs_acc)
283 {
284 int count = 0;
285 for (;hs_acc;hs_acc = hs_acc->next)
286 count++;
287 return count;
288 }
289
290 hstat_account_entry_sum hstat_account_last_week(hstat_account *hs_acc)
291 {
292 hstat_account_entry_sum tmp = {0,0,0,0};
293 int i;
294 for (i=0;i<7;i++)
295 {
296 HSTAT_ACCOUNT_SUM(tmp, tmp, hs_acc->week[i]);
297 }
298 return tmp;
299 }
300
301 hstat_account_entry_sum hstat_account_last_month(hstat_account *hs_acc)
302 {
303 hstat_account_entry_sum tmp = {0,0,0,0};
304 int i;
305
306 for (i=0;i<4;i++)
307 {
308 HSTAT_ACCOUNT_SUM(tmp, tmp, hs_acc->longterm[(hstat_week() - i + 10) % 10]);
309 }
310 return tmp;
311 }
312
313 hstat_channel_entry hstat_channel_last_week(hstat_channel *hs_chan)
314 {
315 hstat_channel_entry tmp = {0,0,0,0,0,0,0,0};
316 int i;
317 for (i=0;i<7;i++)
318 {
319 HSTAT_CHANNEL_SUM(tmp, tmp, hs_chan->week[i]);
320 }
321 return tmp;
322 }
323
324 hstat_channel_entry hstat_channel_last_month(hstat_channel *hs_chan)
325 {
326 hstat_channel_entry tmp = {0,0,0,0,0,0,0,0};
327 int i;
328
329 for (i=0;i<4;i++)
330 {
331 HSTAT_CHANNEL_SUM(tmp, tmp, hs_chan->longterm[(hstat_week() - i + 10) % 10]);
332 }
333 return tmp;
334 }
335
336 static int hstat_account_compare(hstat_account_entry_sum *e1, hstat_account_entry_sum *e2)
337 {
338 return e2->time_spent - e1->time_spent;
339 }
340
341 hstat_accounts_array create_hstat_account_array(hchannel *hchan, hlevel lvl, hstat_account_array_type type)
342 {
343 hstat_accounts_array arr = {NULL, 0};
344 hstat_account *ptr;
345 hstat_account_entry_sum tmp1, tmp2;
346 haccount *hacc = haccounts;
347 int initial_arrlen = 0;
348
349 if (lvl == H_OPER)
350 initial_arrlen = haccount_count(H_OPER) + haccount_count(H_ADMIN);
351 else if (lvl == H_STAFF)
352 initial_arrlen = haccount_count(H_STAFF) + haccount_count(H_TRIAL);
353 else /* works fine for H_ANY */
354 initial_arrlen = haccount_count(lvl);
355
356 if (!initial_arrlen)
357 return arr;
358
359 arr.array = (hstat_account_entry_sum*)malloc(sizeof(hstat_account_entry_sum) * initial_arrlen);
360 for (;hacc;hacc = hacc->next)
361 if ((lvl == H_ANY) ||
362 (lvl == H_OPER && (hacc->level == H_OPER || hacc->level == H_ADMIN)) ||
363 (lvl == H_STAFF && (hacc->level == H_TRIAL || hacc->level == H_STAFF)))
364 for (ptr = hacc->stats;ptr;ptr = ptr->next)
365 if (ptr->hchan == hchan)
366 {
367 assert(arr.arrlen < initial_arrlen);
368
369 if (type == HSTAT_ACCOUNT_ARRAY_TOP10)
370 tmp1 = hstat_account_last_month(ptr);
371 else
372 {
373 HSTAT_ACCOUNT_ZERO(tmp1);
374 }
375
376 tmp2 = hstat_account_last_week(ptr);
377 HSTAT_ACCOUNT_SUM(arr.array[arr.arrlen], tmp1, tmp2);
378 arr.array[arr.arrlen].owner = hacc;
379 arr.arrlen++;
380 }
381
382 qsort(arr.array, arr.arrlen, sizeof(hstat_account_entry_sum), (int(*)(const void*, const void*))hstat_account_compare);
383 return arr;
384 }