#include #include "bot.h" struct tree_t *nick_tree; struct tree_t *chan_tree; struct stats_t *mk_stats(hash_t hash, time_t current_time) { struct stats_t *stats; stats = malloc(sizeof(struct stats_t)); stats->hash = hash; stats->last_msg = current_time; stats->msgs = 0; stats->actions = 0; return stats; } void update_stats(char *nick, char *channel, char *line) { hash_t h_n = hash(nick); hash_t h_c = hash(channel); time_t current_time = time(NULL); struct tree_t *c_node; struct stats_t *stats; char *word1; if(DEBUG) {fprintf(stderr,"Start update_stats\n");} /* Update Nick Stats */ c_node = tree_find(nick_tree, h_n); /* find nick in nick tree */ if(DEBUG) {fprintf(stderr,"1");} if (c_node == NULL) { if (nick_tree == NULL) { nick_tree = tree_init(nick); c_node = nick_tree; if(DEBUG) {fprintf(stderr,"2");} } else { c_node = tree_insert(nick_tree, nick); if(DEBUG) {fprintf(stderr,"3");} } c_node->other = mk_stats(h_n,current_time); if(c_node->other == NULL) { if(DEBUG) {fprintf(stderr,"c_node->other == NULL :\\\n");} } } if(DEBUG) {fprintf(stderr,"4");} stats = (struct stats_t *) c_node->other; /*if (data == '\001') { word1 = word(data,1); if(strcasecmp(word1,"ACTION") == 0) { stats->actions += 1; } free(word1); } else {*/ stats->msgs += 1; stats->total_time += current_time - stats->last_msg; stats->last_msg = current_time; if(DEBUG) {fprintf(stderr,"5");} /* Update Channel Stats */ if ((*channel) == '#') { if(DEBUG) {fprintf(stderr,"6");} /* Only is a real channel */ c_node = tree_find(chan_tree, h_c); if(DEBUG) {fprintf(stderr,"7");} if (c_node == NULL) { if (chan_tree == NULL) { chan_tree = tree_init(channel); c_node = chan_tree; if(DEBUG) {fprintf(stderr,"8");} } else { c_node = tree_insert(chan_tree,channel); if(DEBUG) {fprintf(stderr,"9");} } c_node->other = mk_stats(h_c,current_time); } if(DEBUG) {fprintf(stderr,"A");} stats = (struct stats_t *) c_node->other; stats->msgs += 1; stats->total_time += current_time - stats->last_msg; stats->last_msg = current_time; } if(DEBUG) {fprintf(stderr,"\nEnd update_stats\n");} } void output_stats(int s, char *channel, char *data) { char *fword = word(data,1); char *temp_ptr = NULL; char buffer[BUFSIZE]; struct tree_t *c_node; struct stats_t *stats; double avg_time; time_t current_time = time(NULL); if((*data) == '#') { /* Channel Stats */ c_node = chan_tree; } else { /* Nick Stats */ c_node = nick_tree; } c_node = tree_find(c_node,hash(fword)); if (c_node != NULL) { stats = (struct stats_t *) c_node->other; avg_time = (double)stats->total_time / (double)stats->msgs; sprintf(buffer,"---Stats for %s---",fword); queue_msg(SPEAK,channel,buffer,current_time); sprintf(buffer,"Messages: %d.",stats->msgs); queue_msg(SPEAK,channel,buffer,current_time); sprintf(buffer,"Average time between messages %.2fs.",avg_time); queue_msg(SPEAK,channel,buffer,current_time); temp_ptr = ctime(&stats->last_msg); chomp(temp_ptr,strlen(temp_ptr)); sprintf(buffer,"Last Message: %s.",temp_ptr); queue_msg(SPEAK,channel,buffer,current_time); } else { sprintf(buffer,"Sorry I have no stats for %s",fword); queue_msg(SPEAK,channel,buffer,current_time); } free(fword); } void move_nick_stats(char *nick_old, char *nick_new) { hash_t nick_old_h = hash(nick_old); hash_t nick_new_h = hash(nick_new); struct stats_t *n_stats = NULL; struct stats_t *o_stats = NULL; struct tree_t *o_node = NULL; struct tree_t *n_node = NULL; time_t current_time = time(NULL); if(DEBUG) {fprintf(stderr,"move_nick_stats\n");} o_node = tree_find(nick_tree,nick_old_h); if (o_node != NULL) { n_node = tree_insert(nick_tree,nick_new); if (n_node == NULL) { n_node = tree_find(nick_tree,nick_new_h); if (n_node != o_node) { n_stats = (struct stats_t *) n_node->other; o_stats = (struct stats_t *) o_node->other; o_stats->msgs += n_stats->msgs; o_stats->total_time += n_stats->total_time; o_stats->actions += n_stats->actions; free(n_stats); } } n_node->other = o_node->other; } } void store_node(FILE *of, struct tree_t *node) { struct stats_t *stats = (struct stats_t *) node->other; fprintf(of,"ITEM %s IHASH %d SHASH %d MSGS %d ACTIONS %d LAST_MSG %d TOTAL_TIME %d\n", node->data, node->hash, stats->hash, stats->msgs, stats->actions, stats->last_msg, stats->total_time); } void pre_order_store(FILE *of, struct tree_t *node) { store_node(of,node); if (node->left != NULL) { pre_order_store(of,node->left); } if (node->right != NULL) { pre_order_store(of,node->right); } } void store_stats(char *fileprefix) { FILE *stat_file; char buffer[BUFSIZE]; /* Nick Stats */ snprintf(buffer,BUFSIZE,"%s.nickstats",fileprefix); stat_file = fopen(buffer,"w"); pre_order_store(stat_file,nick_tree); fclose(stat_file); /* Channel Stats */ snprintf(buffer,BUFSIZE,"%s.chanstats",fileprefix); stat_file = fopen(buffer,"w"); pre_order_store(stat_file,chan_tree); fclose(stat_file); } char *split_stat_line(char *buffer, hash_t *ihash, hash_t *shash, int *msgs, int *actions, time_t *last_msg, unsigned long *total_time) { char *item; char *temp; item = word(buffer,2); temp = word(buffer,4); *ihash = atol(temp); free(temp); temp = word(buffer,6); *shash = atol(temp); free(temp); temp = word(buffer,8); *msgs = atoi(temp); free(temp); temp = word(buffer,10); *actions = atoi(temp); free(temp); temp = word(buffer,12); *last_msg = atol(temp); free(temp); temp = word(buffer,14); *total_time = atol(temp); free(temp); return item; } struct tree_t *parse_stat_line(struct tree_t *tree, char *buffer) { struct tree_t *c_node = tree; struct tree_t *n_node; struct stats_t *stats = NULL; char *w; char *item; int actions; int msgs; time_t last_msg; unsigned long total_time; hash_t ihash; hash_t shash; item = split_stat_line(buffer, &ihash,&shash,&msgs,&actions,&last_msg,&total_time); if(DEBUG) {fprintf(stderr,"ITEM %s IHASH %ld SHASH %ld MSGS %d ACTIONS %d LAST_MSG %ld TOTAL_TIME %ld\n", item,ihash,shash,msgs,actions,last_msg,total_time);} if(c_node == NULL) { tree = tree_init(item); n_node = tree; } else { n_node = tree_insert(c_node,item); } if(n_node != NULL) { if(ihash != shash) { c_node = tree_find(tree,shash); if (c_node != NULL) { n_node->other = c_node->other; return tree; } } stats = malloc(sizeof(struct stats_t)); stats->hash = shash; stats->msgs = msgs; stats->actions = actions; stats->last_msg = last_msg; stats->total_time = total_time; n_node->other = stats; } return tree; } void load_stats(char *fileprefix) { FILE *stat_file; char buffer[BUFSIZE]; int length; if(DEBUG) {fprintf(stderr,"load_stats: start\n");} snprintf(buffer,BUFSIZE,"%s.nickstats",fileprefix); stat_file = fopen(buffer,"r"); while(get_line(stat_file,buffer,BUFSIZE) != EOF) { chomp(buffer,strlen(buffer)); nick_tree = parse_stat_line(nick_tree,buffer); } fclose(stat_file); snprintf(buffer,BUFSIZE,"%s.chanstats",fileprefix); stat_file = fopen(buffer,"r"); while(get_line(stat_file,buffer,BUFSIZE) != EOF) { chomp(buffer,strlen(buffer)); chan_tree = parse_stat_line(chan_tree,buffer); } fclose(stat_file); if(DEBUG) {fprintf(stderr,"load_stats: end\n");} }