diff options
Diffstat (limited to 'parsing.c')
-rw-r--r-- | parsing.c | 315 |
1 files changed, 309 insertions, 6 deletions
@@ -3,6 +3,7 @@ #include <wctype.h> #include <wchar.h> #include <pthread.h> +#include <errno.h> #include "parsing.h" #include "channel.h" @@ -15,12 +16,15 @@ #define TEXT_BUFFER_SIZE 0x400 #define LINE_BUFFER_SIZE 0x400 #define TIME_BUFFER_SIZE 0xf +#define DATE_BUFFER_SIZE 0x20 -static pthread_mutex_t user_mutex, word_mutex, channel_mutex; +static pthread_mutex_t user_mutex, user_time_mutex, word_mutex, channel_mutex, time_mutex; static struct user_t *last_user = NULL; static int in_monolog = 0, monolog_len = 0; +static struct tm now_global; + static inline void add_word(struct user_t *user, wchar_t *word, int len) { pthread_mutex_lock(&user_mutex); user->words++; @@ -36,6 +40,24 @@ static inline void add_word(struct user_t *user, wchar_t *word, int len) { static void process_file(FILE *f, struct channel_t *channel, struct regexset_t *rs) { char line[LINE_BUFFER_SIZE]; + const char *log_date_format, *day_date_format; + struct tm now; + + if(rs->log_date_format) { + log_date_format = rs->log_date_format; + } else if(ircstats_config.log_date_format) { + log_date_format = ircstats_config.log_date_format; + } else { + log_date_format = NULL; + } + + if(rs->day_date_format) { + day_date_format = rs->day_date_format; + } else if(ircstats_config.day_date_format) { + day_date_format = ircstats_config.day_date_format; + } else { + day_date_format = NULL; + } while(fgets(line, LINE_BUFFER_SIZE, f)) { int rc; @@ -82,6 +104,30 @@ static void process_file(FILE *f, struct channel_t *channel, struct regexset_t * user->lines[time_i]++; pthread_mutex_unlock(&user_mutex); + pthread_mutex_lock(&time_mutex); + now = now_global; + pthread_mutex_unlock(&time_mutex); + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + pthread_mutex_lock(&user_time_mutex); + struct user_time_t *user_time = user_time_get(nick, 0); + if(user_time->seen_first == 0) { + user_time->seen_first = now_ut; + } + /* Set if user is not yet seen. */ + if(user_time->last_join == 0) { + user_time->last_join = now_ut; + } + /* Add to online total. */ + if(user_time->seen_last > 0) { + user_time->time_total += now_ut - user_time->seen_last; + } + user_time->seen_last = now_ut; + pthread_mutex_unlock(&user_time_mutex); + pthread_mutex_lock(&channel_mutex); channel->hours[time_i]++; pthread_mutex_unlock(&channel_mutex); @@ -112,25 +158,240 @@ static void process_file(FILE *f, struct channel_t *channel, struct regexset_t * rc = pcre_exec(rs->join, rs->join_e, line, strlen(line), 0, 0, ovector, 30); if(rc > 0) { - char nick[NICK_BUFFER_SIZE]; + char nick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; pcre_copy_named_substring(rs->join, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); - pthread_mutex_lock(&user_mutex); - struct user_t *user = user_get(nick); - pthread_mutex_unlock(&user_mutex); + pcre_copy_named_substring(rs->join, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->join, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + pthread_mutex_lock(&time_mutex); + now = now_global; + pthread_mutex_unlock(&time_mutex); + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + pthread_mutex_lock(&user_time_mutex); + struct user_time_t *user_time = user_time_get(nick, 0); + + if(user_time->seen_first == 0) { + user_time->seen_first = now_ut; + } + user_time->last_join = user_time->seen_last = now_ut; + pthread_mutex_unlock(&user_time_mutex); + + continue; + } + + rc = pcre_exec(rs->part, rs->part_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char nick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->part, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->part, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->part, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + pthread_mutex_lock(&time_mutex); + now = now_global; + pthread_mutex_unlock(&time_mutex); + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + pthread_mutex_lock(&user_time_mutex); + struct user_time_t *user_time = user_time_get(nick, 1); + + if(user_time->real_user) { + struct user_time_t *temp = user_time->real_user; + user_time->real_user = NULL; + user_time = temp; + } + + if(user_time->seen_first == 0) { + user_time->seen_first = now_ut; + } + /* Add to online total. */ + if(user_time->seen_last > 0) { + user_time->time_total += now_ut - user_time->seen_last; + } + user_time->seen_last = now_ut; + pthread_mutex_unlock(&user_time_mutex); + + continue; + } + + rc = pcre_exec(rs->quit, rs->quit_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char nick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->quit, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->quit, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->quit, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + pthread_mutex_lock(&time_mutex); + now = now_global; + pthread_mutex_unlock(&time_mutex); + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + pthread_mutex_lock(&user_time_mutex); + struct user_time_t *user_time = user_time_get(nick, 1); + + if(user_time->real_user) { + struct user_time_t *temp = user_time->real_user; + user_time->real_user = NULL; + user_time = temp; + } + + if(user_time->seen_first == 0) { + user_time->seen_first = now_ut; + } + /* Add to online total. */ + if(user_time->seen_last > 0) { + user_time->time_total += now_ut - user_time->seen_last; + } + user_time->seen_last = now_ut; + pthread_mutex_unlock(&user_time_mutex); + + continue; + } + + rc = pcre_exec(rs->nick_changed, rs->nick_changed_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char oldnick[NICK_BUFFER_SIZE], newnick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "old_nick", oldnick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "new_nick", newnick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + pthread_mutex_lock(&time_mutex); + now = now_global; + pthread_mutex_unlock(&time_mutex); + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + pthread_mutex_lock(&user_time_mutex); + struct user_time_t *from_user = user_time_get(oldnick, 1); + struct user_time_t *to_user = user_time_get(newnick, 1); + + if(from_user->real_user) { + to_user->real_user = from_user->real_user; + from_user->real_user = NULL; + } else { + to_user->real_user = from_user; + } + if(to_user->real_user) { + to_user->time_total += now_ut - to_user->seen_last; + to_user->real_user->seen_last = now_ut; + } else { + from_user->time_total += now_ut - from_user->seen_last; + from_user->seen_last = now_ut; + } + pthread_mutex_unlock(&user_time_mutex); + + continue; + } + + rc = pcre_exec(rs->log_opened, rs->log_opened_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char date[DATE_BUFFER_SIZE]; + + if(!log_date_format) { + continue; + } + + pcre_copy_named_substring(rs->log_opened, line, ovector, rc, "date", date, DATE_BUFFER_SIZE); + if(!strptime(date, log_date_format, &now)) { + printf("log fail: %s\n", date); + continue; + } + + pthread_mutex_lock(&time_mutex); + now_global = now; + pthread_mutex_unlock(&time_mutex); + + continue; + } + + rc = pcre_exec(rs->day_changed, rs->day_changed_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char date[DATE_BUFFER_SIZE]; + + if(!day_date_format) { + continue; + } + + pcre_copy_named_substring(rs->day_changed, line, ovector, rc, "date", date, DATE_BUFFER_SIZE); + if(!strptime(date, day_date_format, &now)) { + printf("day fail: %s\n", date); + continue; + } + + pthread_mutex_lock(&time_mutex); + now_global = now; + pthread_mutex_unlock(&time_mutex); + continue; } rc = pcre_exec(rs->kick, rs->kick_e, line, strlen(line), 0, 0, ovector, 30); if(rc > 0) { - char nick[NICK_BUFFER_SIZE], victim[NICK_BUFFER_SIZE]; + char nick[NICK_BUFFER_SIZE], victim[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->kick, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->kick, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); pcre_copy_named_substring(rs->kick, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); pcre_copy_named_substring(rs->kick, line, ovector, rc, "victim", victim, NICK_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + pthread_mutex_lock(&time_mutex); + now = now_global; + pthread_mutex_unlock(&time_mutex); + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + pthread_mutex_lock(&user_mutex); struct user_t *user = user_get(nick), *victim_user = user_get(victim); user->kicks++; victim_user->kicked++; pthread_mutex_unlock(&user_mutex); + + pthread_mutex_lock(&user_time_mutex); + struct user_time_t *user_time = user_time_get(nick, 0); + if(user_time->seen_first == 0) { + user_time->seen_first = now_ut; + } + /* Add to online total. */ + if(user_time->seen_last > 0) { + user_time->time_total += now_ut - user_time->seen_last; + } + user_time->seen_last = now_ut; + pthread_mutex_unlock(&user_time_mutex); + continue; } } @@ -149,13 +410,49 @@ static void *thread_func(void *arg) { return NULL; } +static void merge_user_time_data(struct user_time_t *user_time) { + struct user_t *user; + + user = user_get(user_time->nick); + + if(user->seen_first == 0 || user_time->seen_first < user->seen_first) { + user->seen_first = user_time->seen_first; + } + + if(user_time->seen_last > user->seen_last) { + user->seen_last = user_time->seen_last; + } + + printf("adding %lu to %s\n", user_time->time_total, user->nick); + user->time_total += user_time->time_total; +} + +static void merge_time_data() { + for(int i = 0; i < USERS_MAX; i++) { + struct user_time_t *user_time; + + user_time = &users_time[i]; + if(user_time->nick) + merge_user_time_data(user_time); + user_time = user_time->next; + + while(user_time) { + merge_user_time_data(user_time); + user_time = user_time->next; + } + } +} + void process(int thread_n) { pthread_mutex_init(&user_mutex, NULL); + pthread_mutex_init(&user_time_mutex, NULL); pthread_mutex_init(&word_mutex, NULL); pthread_mutex_init(&channel_mutex, NULL); + pthread_mutex_init(&time_mutex, NULL); /* Parsing stuff goes here. */ for(int chan_i = 0; chan_i < channel_get_count(); chan_i++) { user_init(); + user_time_init(); word_init(); struct channel_t *channel = channel_get(chan_i); printf("Channel %s\n", channel->name); @@ -190,11 +487,17 @@ void process(int thread_n) { fclose(f); file = file->next; } + + merge_time_data(); + export_xml(channel, users); user_free(); + user_time_free(); word_free(); } + pthread_mutex_destroy(&time_mutex); pthread_mutex_destroy(&user_mutex); + pthread_mutex_destroy(&user_time_mutex); pthread_mutex_destroy(&word_mutex); pthread_mutex_destroy(&channel_mutex); } |