X-Git-Url: http://royale.zerezo.com/git/?p=irssistats;a=blobdiff_plain;f=irssistats.c;h=b7a855ca2ec362c4e8b13465d5796e67c3bd2a89;hp=e9a26c3bae3f08b7bbdad65c29a35b987f65553b;hb=3908ded2c18f259d9eea9f31600020cf940ada3e;hpb=b174acf3baf7bc2acd24edb7e6198c8d572e0c97 diff --git a/irssistats.c b/irssistats.c index e9a26c3..b7a855c 100644 --- a/irssistats.c +++ b/irssistats.c @@ -1,77 +1,317 @@ -/* Usage: cat /path/to/file.log | ./irssistats > /path/to/file.html */ +/* Usage: cat /path/to/file.log | ./irssistats channel maintainer language theme [nickfile] > /path/to/file.html */ + +#include +#include +#include +#include +#include /* Config */ -#define CHANNEL "#channel" -#define MAINTAINER "maintainer" +#define MAXUSERS 5000 +#define MAXNICKLENGTH 50 +#define MAXLINELENGTH 2000 +#define MAXQUOTELENGTH 100 +#define NBUSERS 50 +#define NBUSERSTIME 10 +#define NBURLS 5 +#define NBTOPICS 5 +#define NBWORDS 20 +#define MINWORDLENGTH 5 -/* Language */ -#define HEADER "Statistiques de %s par %s" -#define LEGEND "Légende" -#define LASTDAYS "Statistiques des derniers jours" -#define TOPHOURS "Statistiques horaires" -#define TOPUSERS "Personnes les plus actives" -#define OTHERS "Il reste %d personnes non classées..." -#define NBLINES "lignes" -#define NICK "nick" -#define AVGLETTERS "lettres/lignes" -#define HOURS "heures" -#define QUOTE "message aléatoire" -#define RANDTOPICS "Quelques topics" -#define CHANGEDBY "changé par" -#define NEWTOPIC "nouveau topic" -#define RANDURLS "Quelques URLs" -#define POSTEDBY "postée par" -#define POSTEDURL "URL" -#define BIGNUMBERS "Quelques grands nombres..." -#define TIME "%d lignes traitées en %d secondes" -#define FOOTER "Statistiques générées par" +/* irssistats */ +#define VERSION "0.4" +#define URL "http://royale.zerezo.com/programmation/irssistats/" -/* Colors */ -#define BGCOLOR "#FFFFFF" -#define TEXT "#000000" -#define LINK "#0000EE" -#define VLINK "#551A8B" -#define ALINK "#FF0000" -#define TITLE1 "#000000" -#define TITLE2 "#000000" -#define BGTABLE "#EEEEEE" -#define BGTITLE "#FFEEEE" +/* Counters */ +#define D_SMILE 0 +#define D_FROWN 1 +#define D_EXCLAM 2 +#define D_QUESTION 3 +#define D_ME 4 +#define D_TOPIC 5 +#define D_MODE 6 +#define D_KICK 7 +#define D_KICKED 8 +#define D_URL 9 +#define D_JOIN 10 +#define D_NICK 11 +#define D_MONOLOGUE 12 +#define NBCOUNTERS 13 +char *counters[NBCOUNTERS]={"C_SMILE","C_FROWN","C_EXCLAM","C_QUESTION","C_ME","C_TOPIC","C_MODE","C_KICK","C_KICKED","C_URL","C_JOIN","C_NICK","C_MONOLOGUE"}; -/* Dark Theme... */ -/* -#define BGCOLOR "#000000" -#define TEXT "#FFFFFF" -#define LINK "#AAAAFF" -#define VLINK "#CCCCDD" -#define ALINK "#FFAAAA" -#define TITLE1 "#AAAAFF" -#define TITLE2 "#FFAAAA" -#define BGTABLE "#225522" -#define BGTITLE "#552222" -*/ +/* Languages */ +#define NBLANGUAGES 4 +#define NBKEYS 38 +char *keys[NBLANGUAGES][NBKEYS+1][2]= /* first key used for language name and abbreviation */ +{ + { /* English language */ + { "English", "en" }, + { "HEADER", "Statistics for #%s by %s" }, + { "LEGEND", "Legend" }, + { "LASTDAYS", "Lastdays statistics" }, + { "TOPHOURS", "Hourly statistics" }, + { "TOPUSERS", "Most active people" }, + { "OTHERS", "There are %d left not ranked..." }, + { "NBLINES", "lines" }, + { "NICK", "nick" }, + { "AVGLETTERS", "letters/lines" }, + { "HOURS", "hours" }, + { "QUOTE", "random message" }, + { "TOPUSERSTIME", "Most active people by time of day" }, + { "RANDTOPICS", "Some topics" }, + { "CHANGEDBY", "changed by" }, + { "NEWTOPIC", "new topic" }, + { "RANDURLS", "Some URLs" }, + { "POSTEDBY", "posted by" }, + { "POSTEDURL", "URL" }, + { "TOPWORDS", "Most used words" }, + { "WORD", "word" }, + { "OCCURRENCES", "occurrences" }, + { "BIGNUMBERS", "Some big numbers..." }, + { "NUMBERS", "numbers" }, + { "TIME", "%d lines parsed in %d seconds" }, + { "FOOTER", "Statistics generated by" }, + { "C_SMILE", "is often happy :)" }, + { "C_FROWN", "is often sad :(" }, + { "C_EXCLAM", "yells a lot !" }, + { "C_QUESTION", "asks a lot of questions ?" }, + { "C_ME", "likes /me command" }, + { "C_TOPIC", "often changes the topic" }, + { "C_MODE", "often changes the modes" }, + { "C_KICK", "likes to /kick" }, + { "C_KICKED", "is often kicked" }, + { "C_URL", "posts many URLs" }, + { "C_JOIN", "doesn't know wether to stay or quit" }, + { "C_NICK", "often changes his nick" }, + { "C_MONOLOGUE", "speaks a lot of monologues" } + }, + { /* French language */ + { "Français", "fr" }, + { "HEADER", "Statistiques de #%s par %s" }, + { "LEGEND", "Légende" }, + { "LASTDAYS", "Statistiques des derniers jours" }, + { "TOPHOURS", "Statistiques horaires" }, + { "TOPUSERS", "Personnes les plus actives" }, + { "OTHERS", "Il reste %d personnes non classées..." }, + { "NBLINES", "lignes" }, + { "NICK", "nick" }, + { "AVGLETTERS", "lettres/lignes" }, + { "HOURS", "heures" }, + { "QUOTE", "message aléatoire" }, + { "TOPUSERSTIME", "Personnes les plus actives par période de la journée" }, + { "RANDTOPICS", "Quelques topics" }, + { "CHANGEDBY", "changé par" }, + { "NEWTOPIC", "nouveau topic" }, + { "RANDURLS", "Quelques URLs" }, + { "POSTEDBY", "postée par" }, + { "POSTEDURL", "URL" }, + { "TOPWORDS", "Mots les plus utilisés" }, + { "WORD", "mot" }, + { "OCCURRENCES", "occurrences" }, + { "BIGNUMBERS", "Quelques grands nombres..." }, + { "NUMBERS", "nombres" }, + { "TIME", "%d lignes traitées en %d secondes" }, + { "FOOTER", "Statistiques générées par" }, + { "C_SMILE", "est souvent heureux :)" }, + { "C_FROWN", "est souvent triste :(" }, + { "C_EXCLAM", "hurle beaucoup !" }, + { "C_QUESTION", "pose beaucoup de questions ?" }, + { "C_ME", "aime la commande /me" }, + { "C_TOPIC", "change souvent le topic" }, + { "C_MODE", "change souvent les modes" }, + { "C_KICK", "aime la commande /kick" }, + { "C_KICKED", "est souvent kické" }, + { "C_URL", "poste beaucoup d'URLs" }, + { "C_JOIN", "ne sait pas s'il doit rester ou partir" }, + { "C_NICK", "change souvent de nick" }, + { "C_MONOLOGUE", "parle beaucoup de monologues" } + }, + { /* German language */ + /* contributed by Valentin Gelhorn */ + { "German", "de" }, + { "HEADER", "Statistiken für #%s von %s" }, + { "LEGEND", "Legende" }, + { "LASTDAYS", "Statistik der letzten Tage" }, + { "TOPHOURS", "Stündliche Statistik" }, + { "TOPUSERS", "Die aktivsten Personen" }, + { "OTHERS", "Es bleiben noch %d uneingetragene" }, + { "NBLINES", "Zeilen" }, + { "NICK", "Nick" }, + { "AVGLETTERS", "Buchstaben/Zeile" }, + { "HOURS", "Stunden" }, + { "QUOTE", "Zufällig ausgewaehlte Zitate" }, + { "TOPUSERSTIME", "Die aktivsten Personen zur bestimmten Tageszeit" }, + { "RANDTOPICS", "Ein paar Topics" }, + { "CHANGEDBY", "Gesetzt von" }, + { "NEWTOPIC", "Neues topic" }, + { "RANDURLS", "Ein paar URLs" }, + { "POSTEDBY", "Geschrieben von" }, + { "POSTEDURL", "URL" }, + { "TOPWORDS", "Am häufigsten benutze Wörter" }, + { "WORD", "Wort" }, + { "OCCURRENCES", "Vorkommen" }, + { "BIGNUMBERS", "Ein paar grosse Zahlen" }, + { "NUMBERS", "Zahlen" }, + { "TIME", "%d Zeilen analysiert in %d Sekunden" }, + { "FOOTER", "Statistiken wurden erstellt von" }, + { "C_SMILE", "ist oft glüklich :)" }, + { "C_FROWN", "ist oft traurig :(" }, + { "C_EXCLAM", "schreit oft !" }, + { "C_QUESTION", "stellt viele Fragen ?" }, + { "C_ME", "mag /me'en" }, + { "C_TOPIC", "aendert oft das Topico" }, + { "C_MODE", "aendert oft die Modes" }, + { "C_KICK", "mag /kick'en" }, + { "C_KICKED", "wird oft gekickt"}, + { "C_URL", "schreibt viele URLs"}, + { "C_JOIN", "kann sich nicht entscheiden ob er bleiben oder gehen soll" }, + { "C_NICK", "ändert oft seinen Nick" }, + { "C_MONOLOGUE", "spricht oft Monologe" } + }, + { /* Spanish language */ + /* contributed by Alex */ + { "Spanish", "es" }, + { "HEADER", "Estadísticas de #%s por %s" }, + { "LEGEND", "Leyenda" }, + { "LASTDAYS", "Estadísticas de los últimos días" }, + { "TOPHOURS", "Estadísticas por horas" }, + { "TOPUSERS", "Los que más escriben" }, + { "OTHERS", "Hay %d más que no llegaron..." }, + { "NBLINES", "líneas" }, + { "NICK", "nick" }, + { "AVGLETTERS", "letras por línea" }, + { "HOURS", "horas" }, + { "QUOTE", "Frase aleatoria" }, + { "TOPUSERSTIME", "Los que más escriben según la hora" }, + { "RANDTOPICS", "Algunos topics" }, + { "CHANGEDBY", "Puestos por" }, + { "NEWTOPIC", "topic" }, + { "RANDURLS", "Algunas URLs" }, + { "POSTEDBY", "puestas por" }, + { "POSTEDURL", "URL" }, + { "TOPWORDS", "Palabras más usadas" }, + { "WORD", "Palabra" }, + { "OCCURRENCES", "Frecuencia" }, + { "BIGNUMBERS", "Algunos datos..." }, + { "NUMBERS", "Número de veces" }, + { "TIME", "%d lineas procesadas en %d segundos" }, + { "FOOTER", "Estadísticas generadas por" }, + { "C_SMILE", "Suele estar felíz :)" }, + { "C_FROWN", "Suele estar triste :(" }, + { "C_EXCLAM", "Grita mucho !" }, + { "C_QUESTION", "Hace muchas preguntas ?" }, + { "C_ME", "Abusa del comando /me" }, + { "C_TOPIC", "Suele cambiar el topic" }, + { "C_MODE", "Cambia a veces los modos del canal" }, + { "C_KICK", "Le gusta patear" }, + { "C_KICKED", "Es pateado con frecuencia" }, + { "C_URL", "Pone muchas URLs" }, + { "C_JOIN", "No sabe si irse o quedarse" }, + { "C_NICK", "Cambia mucho de nick" }, + { "C_MONOLOGUE", "Habla solo" } + } +}; +int language; -/* irssistats */ -#define VERSION "0.1" -#define URL "http://royale.zerezo.com/programmation/irssistats/" +char *L(char *key) +{ + int i; + for (i=1;i<=NBKEYS;i++) if (strcmp(key,keys[language][i][0])==0) return(keys[language][i][1]); + fprintf(stderr,"unknown language key: %s\n",key); + return(""); +} +/* Themes */ +#define NBTHEMES 5 +#define NBCOLORS 9 +char *colors[NBTHEMES][NBCOLORS+1][2]= /* first key used for theme name/description and abbreviation */ +{ + { /* Default theme */ + { "White background", "default" }, + { "BGCOLOR", "#FFFFFF" }, + { "TEXT", "#000000" }, + { "LINK", "#0000EE" }, + { "VLINK", "#551A8B" }, + { "ALINK", "#FF0000" }, + { "TITLE1", "#000000" }, + { "TITLE2", "#000000" }, + { "BGTABLE", "#EEEEEE" }, + { "BGTITLE", "#FFEEEE" } + }, + { /* Dark theme */ + { "Black background", "dark" }, + { "BGCOLOR", "#000000" }, + { "TEXT", "#FFFFFF" }, + { "LINK", "#AAAAFF" }, + { "VLINK", "#CCCCDD" }, + { "ALINK", "#FFAAAA" }, + { "TITLE1", "#AAAAFF" }, + { "TITLE2", "#FFAAAA" }, + { "BGTABLE", "#225522" }, + { "BGTITLE", "#552222" } + }, + { /* zeRezo theme */ + { "Green theme...", "zerezo" }, + { "BGCOLOR", "#000000" }, + { "TEXT", "#FFFFFF" }, + { "LINK", "#14F024" }, + { "VLINK", "#0CBA18" }, + { "ALINK", "#FFFFFF" }, + { "TITLE1", "#0CBA18" }, + { "TITLE2", "#84DB8C" }, + { "BGTABLE", "#085D10" }, + { "BGTITLE", "#0B810B" } + }, + { /* tit-namour theme */ + { "Purple and Pink", "namour" }, + { "BGCOLOR", "#9933CC" }, + { "TEXT", "#DDAAFF" }, + { "LINK", "#CC99FF" }, + { "VLINK", "#999999" }, + { "ALINK", "#FFC8C8" }, + { "TITLE1", "#FFC8C8" }, + { "TITLE2", "#FFC8C8" }, + { "BGTABLE", "#7711AA" }, + { "BGTITLE", "#550088" } + }, + { /* zeDuel theme */ + { "Orange theme...", "zeduel" }, + { "BGCOLOR", "#FFFFFF" }, + { "TEXT", "#000000" }, + { "LINK", "#FF7700" }, + { "VLINK", "#C05A00" }, + { "ALINK", "#FF9A41" }, + { "TITLE1", "#C05A00" }, + { "TITLE2", "#FF7700" }, + { "BGTABLE", "#FFEEEE" }, + { "BGTITLE", "#FF7700" } + } +}; -#include -#include -#include -#include +int theme; -#define MAXUSERS 2000 -#define MAXNICKLENGTH 50 -#define MAXLINELENGTH 2000 +char *T(char *color) +{ + int i; + for (i=1;i<=NBCOLORS;i++) if (strcmp(color,colors[theme][i][0])==0) return(colors[theme][i][1]); + fprintf(stderr,"unknown theme color: %s\n",color); + return(""); +} -struct +/* Variables */ + +char *channel; +char *maintainer; + +struct { char nick[MAXNICKLENGTH]; int lines; int letters; int hours[4]; - char quote[MAXLINELENGTH]; + char quote[MAXQUOTELENGTH+1]; + int counters[NBCOUNTERS]; } users[MAXUSERS]; int nbusers=0; @@ -79,13 +319,14 @@ struct { char nick[MAXNICKLENGTH]; char url[MAXLINELENGTH]; + char shorturl[MAXQUOTELENGTH+1]; } urls[5]; int nburls=0; struct { char nick[MAXNICKLENGTH]; - char topic[MAXLINELENGTH]; + char topic[MAXQUOTELENGTH+1]; } topics[5]; int nbtopics=0; @@ -99,32 +340,161 @@ int days=0; int hours[24]; int lines=0; -void unhtml(char *string) /* replace < and > by { and } */ +struct letter +{ + int nb; + struct letter *next[26]; +} words; + +struct +{ + int nb; + char word[MAXLINELENGTH]; +} topwords[NBWORDS]; + +#define isletter(c) (((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))) +#define lowercase(c) (((c>='A')&&(c<='Z'))?c-'A'+'a':c) +void findwords(char *message) +{ + int i,c; + struct letter *pos,*tmp; + for (;;) + { + while (!isletter(*message)) if (*message=='\0') return; else message++; + pos=&words; + while (isletter(*message)) + { + c=lowercase(*message)-'a'; + if (pos->next[(int)c]==NULL) + { + tmp=malloc(sizeof(struct letter)); + tmp->nb=0; + for (i=0;i<26;i++) tmp->next[i]=NULL; + pos->next[(int)c]=tmp; + } + pos=pos->next[(int)c]; + message++; + } + pos->nb++; + } + return; +} + +char tempword[MAXLINELENGTH]; +void bestwords(struct letter pos,int cur) +{ + int i,j; + if ((cur>=MINWORDLENGTH)&&(pos.nb>topwords[NBWORDS-1].nb)) + { + for (i=0;pos.nbi;j--) + { + topwords[j].nb=topwords[j-1].nb; + strcpy(topwords[j].word,topwords[j-1].word); + } + topwords[i].nb=pos.nb; + strcpy(topwords[i].word,tempword); + } + for (i=0;i<26;i++) if (pos.next[i]!=NULL) + { + tempword[cur]='a'+i; + bestwords(*(pos.next[i]),cur+1); + } + tempword[cur]='\0'; +} + +void printhtml(char *string) /* replace < and > by < and > */ { while (*string!='\0') { - if (*string=='<') *string='{'; - if (*string=='>') *string='}'; + switch (*string) + { + case '<':printf("<"); break; + case '>':printf(">"); break; + case '&':printf("&"); break; + default:printf("%c",*string); break; + } string++; } return; } +int dichotomic(char *nick) +{ + int i,j,start=0,end=nbusers-1,middle; + while (start<=end) + { + middle=(start+end)/2; + if (strcmp(nick,users[middle].nick)>0) start=middle+1; else end=middle-1; + } + if (strcmp(nick,users[start].nick)!=0) + { + nbusers++; + if (nbusers>=MAXUSERS) { fprintf(stderr,"too many users\n"); exit(1); } + for (i=nbusers-1;i>start;i--) + { + strcpy(users[i].nick,users[i-1].nick); + users[i].lines=users[i-1].lines; + users[i].letters=users[i-1].letters; + for (j=0;j<4;j++) users[i].hours[j]=users[i-1].hours[j]; + strcpy(users[i].quote,users[i-1].quote); + for (j=0;j6)) + { + fprintf(stderr,"Usage: cat /path/to/file.log | ./irssistats channel maintainer language theme [nickfile] > /path/to/file.html\n\n"); + fprintf(stderr,"Version :\nirssistats %s\n\n",VERSION); + fprintf(stderr,"Supported languages :\n"); + for (i=0;i=MAXLINELENGTH) { fprintf(stderr,"line too long\n"); exit(1); } if (c=='\n') { + line[pos-1]='\0'; totallines++; if (totallines%10000==0) { fprintf(stderr,"."); fflush(stdout); } if (strncmp("--- Day changed",line,15)==0) /* --- Day changed Wed May 01 2002 */ @@ -145,165 +516,305 @@ int main(int argc,char *argv[]) for (j=0;j<4;j++) lastdays[0].hours[j]=0; days++; } - else if (strncmp("-!-",&line[6],3)==0) /* 00:00 -!- Nick changed the topic of #channel to: new topic */ + else if (strncmp("-!- mode/",&line[6],9)==0) /* 00:00 -!- mode/#channel [...] by (Nick, Nick2, )Nick3 */ + { + for (i=strlen(line);line[i]!=' ';i--); + nick=&line[i+1]; + users[dichotomic(nick)].counters[D_MODE]++; + } + else if (strncmp("-!-",&line[6],3)==0) /* 00:00 -!- Nick something... */ { for (i=10;line[i]!=' ';i++); line[i]='\0'; nick=&line[10]; - unhtml(nick); message=&line[i+1]; - unhtml(message); - if (strncmp("changed the topic of",message,20)==0) + if (strncmp("changed the topic of",message,20)==0) /* 00:00 -!- Nick changed the topic of #channel to: new topic */ { + users[dichotomic(nick)].counters[D_TOPIC]++; for (i=21;message[i]!=':';i++); message=&message[i+2]; - line[pos-1]='\0'; nbtopics++; - if ((nbtopics<=5) || (rand()%nbtopics==0)) + if ((nbtopics<=NBTOPICS) || (rand()%(nbtopics/NBTOPICS)==0)) { - for (i=4;i>0;i--) - { - strcpy(topics[i].nick,topics[i-1].nick); - strcpy(topics[i].topic,topics[i-1].topic); - } - strcpy(topics[0].nick,nick); - strcpy(topics[0].topic,message); + temp=nbtopics<=NBTOPICS?nbtopics-1:rand()%NBTOPICS; + strcpy(topics[temp].nick,nick); + strncpy(topics[temp].topic,message,MAXQUOTELENGTH); } } + else if (strncmp("was kicked from",message,15)==0) /* 00:00 -!- Nick was kicked from #channel by Nick [Reason] */ + { + users[dichotomic(nick)].counters[D_KICKED]++; + for (i=16;message[i]!=' ';i++); + message=&message[i+4]; + for (i=0;message[i]!=' ';i++); + message[i]='\0'; + users[dichotomic(message)].counters[D_KICK]++; + } + else if (strncmp("is now known as",message,15)==0) /* 00:00 -!- Nick is now known as Nick */ + users[dichotomic(nick)].counters[D_NICK]++; + else if (message[0]=='[') /* 00:00 -!- Nick [user@host] something... */ + { + for (i=0;message[i]!=']';i++); + message=&message[i+2]; + if (strncmp("has joined",message,10)==0) /* 00:00 -!- Nick [user@host] has joined #channel */ + users[dichotomic(nick)].counters[D_JOIN]++; + else if (strncmp("has quit",message,8)==0); /* 00:00 -!- Nick [user@host] has quit [Reason] */ + else if (strncmp("has left",message,8)==0); /* 00:00 -!- Nick [user@host] has left #channel [Reason] */ + else; + } } - else /* 00:00 the message */ + else if ((line[6]=='<') || (line[7]=='*')) { line[2]='\0'; hour=atoi(line); - if ((line[6]=='<') && (line[7]!='>')) + if (line[7]=='*') /* 00:00 * Nick the message */ + { + for (i=9;line[i]!=' ';i++); + nick=&line[9]; + message=&line[i+1]; + } + else if (line[7]=='>') /* 00:00 <>>>?Nick<<<> the personal message */ + /* 00:00 <>>?Nick<<> the personal message */ { - for (i=7;line[i]!='>';i++); - line[i]='\0'; + for (i=10;line[i]!='<';i++); + nick=&line[10]; + if (line[9]=='>') nick++; + message=&line[i+5]; + } + else /* 00:00 the message */ + { + for (i=8;line[i]!='>';i++); nick=&line[8]; - unhtml(nick); - line[pos-1]='\0'; message=&line[i+2]; - unhtml(message); - for (i=0;i=MAXUSERS) { fprintf(stderr,"too many users\n"); exit(1); } - } - users[i].lines++; - users[i].letters+=strlen(message); - users[i].hours[hour/6]++; - lastdays[0].lines++; - lastdays[0].hours[hour/6]++; - lines++; - hours[hour]++; - if (rand()%users[i].lines==0) strncpy(users[i].quote,message,100); - if (strncmp("http://",message,7)==0) + } + line[i]='\0'; + i=dichotomic(nick); + if (line[7]=='*') users[i].counters[D_ME]++; + if (i==mononick) + { + monolines++; + if (monolines==5) users[i].counters[D_MONOLOGUE]++; + } + else + { + mononick=i; + monolines=1; + } + j=strlen(message); + users[i].lines++; + users[i].letters+=j; + users[i].hours[hour/6]++; + lastdays[0].lines++; + lastdays[0].hours[hour/6]++; + lines++; + hours[hour]++; + if (message[j-1]=='?') users[i].counters[D_QUESTION]++; + else if (message[j-1]=='!') users[i].counters[D_EXCLAM]++; + else if ((message[j-3]==' ')&&(message[j-2]==':')) + { + if (message[j-1]==')') users[i].counters[D_SMILE]++; + else if (message[j-1]=='(') users[i].counters[D_FROWN]++; + } + if (rand()%users[i].lines==0) strncpy(users[i].quote,message,MAXQUOTELENGTH); + if (strncmp("http://",message,7)==0) + { + users[i].counters[D_URL]++; + for (i=0;(message[i]!=' ') && (i0;i--) - { - strcpy(urls[i].nick,urls[i-1].nick); - strcpy(urls[i].url,urls[i-1].url); - } - strcpy(urls[0].nick,nick); - strcpy(urls[0].url,message); - } + temp=nburls<=NBURLS?nburls-1:rand()%NBURLS; + strcpy(urls[temp].nick,nick); + strcpy(urls[temp].url,message); + strncpy(urls[temp].shorturl,message,MAXQUOTELENGTH); } } + findwords(message); } pos=0; } } fprintf(stderr,"done\n"); + bestwords(words,0); + + /*** ALIAS ***/ + + if (argc==6) + { + if ((fic=fopen(argv[5],"rt"))==NULL) { fprintf(stderr,"can't open nick file\n"); exit(1); } + while (fscanf(fic,"%s",line)==1) + { + user=dichotomic(line); + fscanf(fic,"%s",line); + if (regcomp(&preg,line,0)!=0) { fprintf(stderr,"error in nick file"); exit(1); } + temp=users[user].lines; + for (i=0;i=0)) + { + if (users[i].lines>temp) /* for nick alias, keep the random quote of the most used nick */ + { + strcpy(users[user].quote,users[i].quote); + temp=users[i].lines; + } + users[user].lines+=users[i].lines; + users[user].letters+=users[i].letters; + for (j=0;j<4;j++) users[user].hours[j]+=users[i].hours[j]; + for (j=0;j\n\n",VERSION,URL); printf("\n\n\n\n"); - printf(HEADER,CHANNEL,MAINTAINER); + printf(L("HEADER"),channel,maintainer); printf("\n\n\n"); - printf("\n\n
\n\n

",BGCOLOR,TEXT,LINK,VLINK,ALINK,TITLE1); - printf(HEADER,CHANNEL,MAINTAINER); + printf("\n\n
\n\n

",T("BGCOLOR"),T("TEXT"),T("LINK"),T("VLINK"),T("ALINK"),T("TITLE1")); + printf(L("HEADER"),channel,maintainer); printf("

\n%s
\n

\n\n",ctime(&debut)); /* legend */ - printf("

%s

\n\n\n",TITLE2,LEGEND,BGTABLE); - for (i=0;i<4;i++) printf("\n",i+1,HOURS,i*6,i*6+5); + printf("

%s

\n
: %s %d-%d 
\n\n",T("TITLE2"),L("LEGEND"),T("BGTABLE")); + for (i=0;i<4;i++) printf("\n",i+1,L("HOURS"),i*6,i*6+5); printf("\n
: %s %d-%d
\n

\n\n"); /* last days */ - printf("

%s

\n\n\n",TITLE2,LASTDAYS); + printf("

%s

\n
\n\n",T("TITLE2"),L("LASTDAYS")); max=-1; for (i=30;i>=0;i--) if (lastdays[i].lines>max) max=lastdays[i].lines; for (i=30;i>=0;i--) { - printf("\n"); } printf("\n\n"); for (i=30;i>=0;i--) - printf("\n",BGTABLE,i); + printf("\n",T("BGTABLE"),i); printf("\n
%d
",lastdays[i].lines); - if (max!=0) for (j=0;j<4;j++) printf("
",j+1,150*lastdays[i].hours[j]/max); + printf("
%d
",lastdays[i].lines); + for (j=0;j<4;j++) if (lastdays[i].hours[j]!=0) printf("
",j+1,150*lastdays[i].hours[j]/max); printf("
%d%d
\n

\n\n"); /* top hours */ - printf("

%s

\n\n\n",TITLE2,TOPHOURS); - if (lines!=0) for (i=0;i<24;i++) - printf("\n",(float)100*hours[i]/lines,i/6+1,1500*hours[i]/lines); + printf("

%s

\n
%.1f%%
\n\n",T("TITLE2"),L("TOPHOURS")); + max=-1; + for (i=0;i<24;i++) if (hours[i]>max) max=hours[i]; + for (i=0;i<24;i++) + { + printf("\n"); + } printf("\n\n"); for (i=0;i<24;i++) - printf("\n",BGTABLE,i); + printf("\n",T("BGTABLE"),i); printf("\n
%.1f%%
",lines!=0?(float)100*hours[i]/lines:0); + if (hours[i]!=0) printf("
",i/6+1,150*hours[i]/max); + printf("
%d%d
\n

\n\n"); /* top users */ - printf("

%s

\n",TITLE2,TOPUSERS); - printf("\n\n",BGTITLE,NICK,BGTITLE,NBLINES,BGTITLE,HOURS,BGTITLE,AVGLETTERS,BGTITLE,QUOTE); - for (i=1;i<=50;i++) + printf("

%s

\n",T("TITLE2"),L("TOPUSERS")); + printf("
%s%s%s%s%s
\n\n",T("BGTITLE"),L("NICK"),T("BGTITLE"),L("NBLINES"),T("BGTITLE"),L("HOURS"),T("BGTITLE"),L("AVGLETTERS"),T("BGTITLE"),L("QUOTE")); + for (i=1;i<=NBUSERS;i++) { user=-1; - max=-1; + max=0; for (j=0;jmax) max=users[user=j].lines; if (user!=-1) { - printf("\n",BGTABLE,users[user].letters/users[user].lines,BGTABLE,users[user].letters/users[user].lines,BGTABLE,users[user].quote); + printf("\n"); users[user].lines=-1; } } - printf("
%s%s%s%s%s
%d%s%d",BGTABLE,i,BGTABLE,users[user].nick,BGTABLE,users[user].lines,BGTABLE); - for (j=0;j<4;j++) - printf("",j+1,100*users[user].hours[j]/users[user].lines); - printf("%d\"%s\"
%d%s%d",T("BGTABLE"),i,T("BGTABLE"),users[user].nick,T("BGTABLE"),users[user].lines,T("BGTABLE")); + for (j=0;j<4;j++) if (users[user].hours[j]!=0) printf("",j+1,100*users[user].hours[j]/users[user].lines); + printf("%d\"",T("BGTABLE"),users[user].lines!=0?users[user].letters/users[user].lines:0,T("BGTABLE"),users[user].lines!=0?users[user].letters/users[user].lines:0,T("BGTABLE")); + printhtml(users[user].quote); + printf("\"

\n"); - if (nbusers>50) printf(OTHERS,nbusers-50); - printf("
\n

\n\n"); + printf("\n"); + temp=0; + for (i=0;i<=nbusers;i++) if (users[i].lines>=0) temp++; + if (temp>0) + { + printf("
"); + printf(L("OTHERS"),temp); + printf("
\n"); + } + printf("

\n\n"); + + /* top users by time */ + printf("

%s

\n",T("TITLE2"),L("TOPUSERSTIME")); + printf("\n"); + for (i=0;i<4;i++) printf("",T("BGTITLE"),L("HOURS"),i*6,i*6+5); + printf("\n"); + for (i=1;i<=NBUSERSTIME;i++) + { + printf("",T("BGTABLE"),i); + for (j=0;j<4;j++) + { + user=-1; + max=0; + for (k=0;kmax) max=users[user=k].hours[j]; + if (user!=-1) + { + printf("",T("BGTABLE"),users[user].nick,T("BGTABLE"),users[user].hours[j]); + users[user].hours[j]=-1; + } + else printf(""); + } + printf("\n"); + } + printf("
%s %d-%d
%d%s%d
\n

\n\n"); /* random topics */ - printf("

%s

\n",TITLE2,RANDTOPICS); - printf("\n\n",BGTITLE,CHANGEDBY,BGTITLE,NEWTOPIC); - for (i=4;i>=0;i--) - printf("\n",BGTABLE,topics[i].nick,BGTABLE,topics[i].topic); + printf("

%s

\n",T("TITLE2"),L("RANDTOPICS")); + printf("
%s%s
%s\"%s\"
\n\n",T("BGTITLE"),L("CHANGEDBY"),T("BGTITLE"),L("NEWTOPIC")); + for (i=nbtopics=0;i--) + { + printf("\n"); + } printf("
%s%s
%s\"",T("BGTABLE"),topics[i].nick,T("BGTABLE")); + printhtml(topics[i].topic); + printf("\"
\n

\n\n"); /* random urls */ - printf("

%s

\n",TITLE2,RANDURLS); - printf("\n\n",BGTITLE,POSTEDBY,BGTITLE,POSTEDURL); - for (i=4;i>=0;i--) - printf("\n",BGTABLE,urls[i].nick,BGTABLE,urls[i].url,urls[i].url); + printf("

%s

\n",T("TITLE2"),L("RANDURLS")); + printf("
%s%s
%s\"%s\"
\n\n",T("BGTITLE"),L("POSTEDBY"),T("BGTITLE"),L("POSTEDURL")); + for (i=nburls=0;i--) + { + printf("\n"); + } printf("
%s%s
%s\"",T("BGTABLE"),urls[i].nick,T("BGTABLE"),urls[i].url); + printhtml(urls[i].shorturl); + printf("\"
\n

\n\n"); - /* big numbers (todo...) - printf("

%s

\n",TITLE2,BIGNUMBERS); - */ + /* top words */ + printf("

%s

\n",T("TITLE2"),L("TOPWORDS")); + printf("\n\n",T("BGTITLE"),L("WORD"),T("BGTITLE"),L("OCCURRENCES")); + for (i=0;i\n",T("BGTABLE"),i+1,T("BGTABLE"),topwords[i].word,T("BGTABLE"),topwords[i].nb); + printf("
%s%s
%d\"%s\"%d
\n

\n\n"); + + /* big numbers */ + printf("

%s

\n",T("TITLE2"),L("BIGNUMBERS")); + printf("\n\n",T("BGTITLE"),L("NICK"),T("BGTITLE"),L("NUMBERS"),T("BGTITLE"),L("NBLINES")); + for (i=0;imax) max=users[user=j].counters[i]; + if (user!=-1) printf("",T("BGTABLE"),users[user].nick,T("BGTABLE"),L(counters[i]),T("BGTABLE"),users[user].counters[i]); + } + printf("
%s%s%s
%s%s%d
\n

\n\n"); /* footer */ - printf(TIME,totallines,(int)(time(NULL)-debut)); - printf("
\n%s irssistats %s",FOOTER,URL,VERSION); + printf(L("TIME"),totallines,(int)(time(NULL)-debut)); + printf("
\n%s irssistats %s",L("FOOTER"),URL,VERSION); printf("\n\n
\n\n\n\n\n"); return(0);