jaromail

a commandline tool to easily and privately handle your e-mail
git clone git://parazyd.org/jaromail.git
Log | Files | Refs | Submodules | README

stats (6868B)


      1 #!/usr/bin/env zsh
      2 #
      3 # Jaro Mail, your humble and faithful electronic postman
      4 #
      5 # a tool to easily and privately handle your e-mail communication
      6 #
      7 # Copyleft (C) 2010-2014 Denis Roio <jaromil@dyne.org>
      8 #
      9 # This source  code is free  software; you can redistribute  it and/or
     10 # modify it under the terms of  the GNU Public License as published by
     11 # the Free  Software Foundation; either  version 3 of the  License, or
     12 # (at your option) any later version.
     13 #
     14 # This source code is distributed in  the hope that it will be useful,
     15 # but  WITHOUT ANY  WARRANTY;  without even  the  implied warranty  of
     16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     17 # Please refer to the GNU Public License for more details.
     18 #
     19 # You should have received a copy of the GNU Public License along with
     20 # this source code; if not, write to:
     21 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     22 
     23 
     24 
     25 stats() {
     26     fn stats $*
     27 
     28     # make index of all maildirs
     29     notice "Computing statistics on stdin"
     30     typeset -A count
     31     num=0
     32 
     33     case $1 in
     34 
     35 	# timecloud) timecloud ;;
     36 
     37 	# weeks) weeks ;;
     38 
     39         domain*)
     40             _domain=""
     41 	    for i in "${(f)$(cat)}"; do
     42                 _domain=${i[(ws:@:)-1]/>/}
     43                 num=${count[$_domain]:-0}
     44                 count[$_domain]=$(( $num + 1 ))
     45 	    done
     46 
     47             ;;
     48 
     49         email*)
     50             _email=""
     51 	    for i in "${(f)$(cat)}"; do
     52                 _email=${i[(ws:<:)2]/>/}
     53                 num=${count[$_email]:-0}
     54                 count[$_email]=$(( $num + 1 ))
     55 	    done
     56             ;;
     57 
     58         name*)
     59             _name=""
     60 	    for i in "${(f)$(cat)}"; do
     61                 _name=${i[(ws:<:)1]//}
     62                 num=${count[$_name]:-0}
     63                 count[$_name]=$(( $num + 1 ))
     64 	    done
     65             ;;
     66 
     67 	folder*)
     68 
     69             _folder=""
     70 
     71 	    for i in `cat`; do
     72                 _folder=${i[(ws:/:)-3]}
     73 
     74 		# find maildir prefixes
     75 		# pfx="${_folder[(ws:.:)1]}"
     76 		# is it a new prefix?
     77                 num=${count[$_folder]:-0}
     78                 count[$_folder]=$(( $num + 1 ))
     79 	    done
     80 
     81 	    ;;
     82 
     83         *)
     84             error "Stats type not specified, available:"
     85             error "domain, email, name, folder"
     86             return 1
     87             ;;
     88     esac
     89 
     90     # calculate screen size and bigger tot
     91     maxtot=0
     92     for x in ${(v)count}; do # find max
     93 	if [ $x -gt $maxtot ]; then
     94 	    maxtot=$x; fi
     95     done
     96 
     97     for k in ${(k)count}; do
     98         v=${count[$k]}
     99 	sbar=""
    100 	# Euclides: cols : x = maxtot : tot
    101 	cols=$(( $COLUMNS - 20 ))
    102 	bar=$(( $cols * $v ))
    103 	bar=$(( $bar / $maxtot ))
    104 	for b in {0..$bar}; do sbar="${sbar}#"; done
    105 	print " $v\t$sbar $k"
    106     done
    107     notice "Total: ${#count}"
    108 
    109 
    110     return 0
    111 }
    112 
    113 weeks() {
    114     id=$RANDOM
    115     db=$TMPDIR/weekstats.db.$id
    116     sql=$TMPDIR/weekstats.select.$id
    117     list_maildirs
    118     notice "Computing weekly statistics on ${#maildirs} maildirs"
    119     func "Creating temporary database"
    120     cat <<EOF | ${SQL} -batch $db
    121 CREATE TABLE stats
    122 (
    123   date    text nocase,
    124   ml      text collate nocase,
    125   hits    int
    126 );
    127 EOF
    128     { test $? != 0 } && {
    129 	error "Error creating temporary week stats database."
    130 	return 1 }
    131 
    132     act "gathering timestamps..."
    133     for m in ${maildirs}; do
    134 	func "  ${m}"
    135 	rm -rf $TMPDIR/weekstats.db.mdir
    136 	cp -r $MAILDIRS/${m} $TMPDIR/weekstats.db.mdir
    137 	for f in `${=find} $TMPDIR/weekstats.db.mdir -type f`; do
    138 	    timestamp=`fetchdate ${f} "%Y-%U"`
    139 	    mdir="${m[(ws:.:)1]}"
    140 	    cat <<EOF | ${SQL} -batch $db > $sql
    141 SELECT * FROM stats
    142 WHERE ml IS "${mdir}" AND date IS "${timestamp}";
    143 EOF
    144 	    res=`cat $sql`
    145 	    if [ "$res" = "" ]; then
    146 		# new tag
    147 		cat <<EOF | ${SQL} -batch $db
    148 INSERT INTO stats (date, ml, hits)
    149 VALUES ("${timestamp}", "${mdir}", 1);
    150 EOF
    151 	    else
    152 		cat <<EOF | ${SQL} -batch $db
    153 UPDATE stats SET hits = hits + 1
    154 WHERE ml IS "${mdir}" AND date IS "${timestamp}";
    155 EOF
    156 	    fi
    157 	done
    158     done
    159     # render results from the database
    160     act "rendering results..."
    161 
    162     table=$WORKDIR/.stats/jaromail.html
    163     ${=mkdir} $WORKDIR/.stats
    164 
    165     cat <<EOF > $table
    166 <table >
    167 	<caption>Jaro Mail weekly statistics</caption>
    168 	<thead>
    169 		<tr>
    170 		<td></td>
    171 EOF
    172     typeset -al week
    173     cat <<EOF | ${SQL} -batch $db > $sql
    174 SELECT date FROM stats ORDER BY date;
    175 EOF
    176     for w in `cat $sql | uniq`; do
    177 	week+=($w)
    178 	print "<th scope=\"col\">${w}</th>" >> $table
    179     done
    180     cat <<EOF >> $table
    181 		</tr>
    182 	</thead>
    183 	<tbody>
    184 
    185 EOF
    186     prevmdir=""
    187     for m in ${maildirs}; do
    188 	mdir="${m[(ws:.:)1]}"
    189 	# skip duplicates
    190 	if [ "$prevmdir" = "$mdir" ]; then continue
    191 	else prevmdir=$mdir; fi
    192 
    193 	print -n "<tr><th scopre=\"row\">$mdir</th>" >> $table
    194 	for w in ${week}; do
    195 	    cat <<EOF | ${SQL} -batch $db > $sql
    196 SELECT hits FROM stats
    197 WHERE ml IS "${mdir}" AND date IS "${w}";
    198 EOF
    199 	    sum=0
    200 	    for h in `cat $sql`; do
    201 		sum=$(( $sum + $h ))
    202 	    done
    203 	    print -n "<td>$sum</td>" >> $table
    204 	done
    205 	print "</tr>" >> $table
    206     done
    207 
    208     cat <<EOF >> $table
    209 	</tbody>
    210 </table>
    211 EOF
    212     cp $WORKDIR/.stats/visualize/header.html \
    213 	$WORKDIR/.stats/index.html
    214     cat $table >> $WORKDIR/.stats/index.html
    215     print "</body>\n</html>\n" >> $WORKDIR/.stats/index.html
    216 }
    217 
    218 timecloud() {
    219     id=$RANDOM
    220     list_maildirs
    221     notice "Computing timecloud statistics on ${#maildirs} maildirs"
    222     func "Creating temporary database"
    223     cat <<EOF | ${SQL} -batch $TMPDIR/timecloud.db.$id
    224 CREATE TABLE stats
    225 (
    226   date    text collate nocase,
    227   tag     text collate nocase,
    228   hits    int
    229 );
    230 EOF
    231     { test $? != 0 } && {
    232 	error "Error creating temporary timecloud database."
    233 	return 1 }
    234 
    235     for m in ${maildirs}; do
    236 	for f in `${=find} $MAILDIRS/${m} -type f`; do
    237 	    timestamp=`fetchdate ${f} "%Y-%m-%d"`
    238 	    cat <<EOF | ${SQL} -batch $TMPDIR/timecloud.db.$id > $TMPDIR/timecloud.select.$id
    239 SELECT * FROM stats
    240 WHERE tag IS "${m}" AND date IS "${timestamp}";
    241 EOF
    242 	    res=`cat $TMPDIR/timecloud.select.$id`
    243 	    if [ "$res" = "" ]; then
    244 		# new tag
    245 		cat <<EOF | ${SQL} -batch $TMPDIR/timecloud.db.$id
    246 INSERT INTO stats (date, tag, hits)
    247 VALUES ("${timestamp}", "${m}", 1);
    248 EOF
    249 	    else
    250 		cat <<EOF | ${SQL} -batch $TMPDIR/timecloud.db.$id
    251 UPDATE stats SET hits = hits + 1
    252 WHERE tag IS "${m}" AND date IS "${timestamp}";
    253 EOF
    254 	    fi
    255 	done
    256     done
    257     # gather results from the database
    258     cat <<EOF | ${SQL} -batch $TMPDIR/timecloud.db.$id > $TMPDIR/timecloud.results.$id
    259 .separator \t
    260 SELECT * FROM stats ORDER BY date;
    261 EOF
    262     # format the results into a JSON string
    263     awk 'BEGIN { date=0; printf "[" }
    264 { if(date != $1) {
    265     if( date != 0 ) printf "]],"
    266     date=$1
    267     printf "[\"" date "\",["
    268     printf "[\"" $2 "\",\"" $3 "\"]"
    269   } else {
    270     printf ",[\"" $2 "\",\"" $3 "\"]"
    271   }
    272 }
    273 END { print "]]];" }
    274 '  $TMPDIR/timecloud.results.$id > $TMPDIR/timecloud.json.$id
    275     ${=mkdir} $WORKDIR/timecloud
    276     cat <<EOF > $WORKDIR/timecloud/jaromail.js
    277 var jaromail=`cat $TMPDIR/timecloud.json.$id`
    278 EOF
    279     rm $TMPDIR/timecloud.*.$id
    280 }