diff --git a/guile/examples/msg-graphs b/guile/examples/msg-graphs new file mode 100755 index 00000000..daeb80d3 --- /dev/null +++ b/guile/examples/msg-graphs @@ -0,0 +1,107 @@ +#!/bin/sh +exec guile -e main -s $0 $@ +!# + +;; +;; Copyright (C) 2011 Dirk-Jan C. Binnema +;; +;; This program is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by the +;; Free Software Foundation; either version 3, or (at your option) any +;; later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; + +;; You should have received a copy of the GNU General Public License +;; along with this program; if not, write to the Free Software Foundation, +;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +(setlocale LC_ALL "") + +(use-modules (ice-9 getopt-long) (ice-9 optargs) (ice-9 popen) (ice-9 format)) +(use-modules (mu) (mu message) (mu stats) (mu plot)) + +(define (per-hour expr plain-text) + "Count the total number of messages for each weekday (0-6 for +Sun..Sat) that match EXPR. If PLAIN-TEXT is true, use a plain-text +display, otherwise, use a graphical window." + (mu:plot + (sort + (mu:tabulate-messages + (lambda (msg) + (tm:hour (localtime (mu:date msg)))) expr) + (lambda (x y) (< (car x) (car y)))) + "Messages per hour" "Hour" "Messages" plain-text)) + +(define (per-day expr plain-text) + "Count the total number of messages for each weekday (0-6 for +Sun..Sat) that match EXPR. If PLAIN-TEXT is true, use a plain-text +display, otherwise, use a graphical window." + (mu:plot + (mu:weekday-numbers->names + (sort (mu:tabulate-messages + (lambda (msg) + (tm:wday (localtime (mu:date msg)))) expr) + (lambda (x y) (< (car x) (car y))))) + "Messages per weekday" "Day" "Messages" plain-text)) + +(define (per-month expr plain-text) + "Count the total number of messages for each weekday (0-6 for +Sun..Sat) that match EXPR. If PLAIN-TEXT is true, use a plain-text +display, otherwise, use a graphical window." + (mu:plot + (mu:month-numbers->names + (sort + (mu:tabulate-messages + (lambda (msg) + (tm:mon (localtime (mu:date msg)))) expr) + (lambda (x y) (< (car x) (car y))))) + "Messages per month" "Month" "Messages" plain-text)) + +(define (per-year expr plain-text) + "Count the total number of messages for each weekday (0-6 for +Sun..Sat) that match EXPR. If PLAIN-TEXT is true, use a plain-text +display, otherwise, use a graphical window." + (mu:plot + (sort (mu:tabulate-messages + (lambda (msg) + (tm:year (localtime (mu:date msg)))) expr) + (lambda (x y) (< (car x) (car y)))) + "Messages per year" "Year" "Messages" plain-text)) + +(define (main args) + (let* ((optionspec '( (muhome (value #t)) + (what (value #t)) + (text (value #f)) + (help (single-char #\h) (value #f)))) + (options (getopt-long args optionspec)) + (msg (string-append + "usage: mu-msg-stats [--help] [--text] " + "[--muhome=] " + "--what= [searchexpr]\n")) + (help (option-ref options 'help #f)) + (what (option-ref options 'what #f)) + (text (option-ref options 'text #t)) + (muhome (option-ref options 'muhome #f)) + (restargs (option-ref options '() #f)) + (expr (if restargs (string-join restargs) ""))) + (if (or help (not what)) + (begin + (display msg) + (exit (if help 0 1)))) + (mu:initialize muhome) + (cond + ((string= what "per-hour") (per-hour expr text)) + ((string= what "per-day") (per-day expr text)) + ((string= what "per-month") (per-month expr text)) + ((string= what "per-year") (per-year expr text)) + (else (begin + (display msg) + (exit 1)))))) + +;; Local Variables: +;; mode: scheme +;; End: diff --git a/guile/examples/msg-stats b/guile/examples/msg-stats deleted file mode 100755 index b29aad80..00000000 --- a/guile/examples/msg-stats +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/sh -exec guile -e main -s $0 $@ -!# - -;; -;; Copyright (C) 2011 Dirk-Jan C. Binnema -;; -;; This program is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published by the -;; Free Software Foundation; either version 3, or (at your option) any -;; later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; - -;; You should have received a copy of the GNU General Public License -;; along with this program; if not, write to the Free Software Foundation, -;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -(use-modules (ice-9 getopt-long) (ice-9 optargs) (ice-9 popen) (ice-9 format)) -(use-modules (mu) (mu message) (mu stats)) - -(define* (per-weekday #:optional (EXPR "")) - "Count the total number of messages for each weekday (0-6 for -Sun..Sat). If the optional EXPR is provided, only count the messages -that match it. The result is a list of pairs (weekday . frequency).\n" - (let* ((stats (mu:tabulate-messages - (lambda (msg) (tm:wday (localtime (date msg)))) EXPR))) - (sort stats (lambda(a b) (< (car a) (car b)))))) ;; in order of weekday - -(define* (mu:plot:per-weekday #:optional (EXPR "")) - (let* ((datafile (export-pairs (per-weekday EXPR))) - (gnuplot (open-pipe "gnuplot -p" OPEN_WRITE))) - ;; note, we cannot use the weekday "%a" support in gnuplot because - ;; demands the field to be a date field ('set xdata time' etc.) - ;; for that to work, but we cannot use that since gnuplot does not - ;; support weekdays ('%w') as a date field in its input - (display (string-append - "reset\n" - "set xtics (\"Sun\" 0, \"Mon\" 1, \"Tue\" 2, \"Wed\" 3," - "\"Thu\" 4, \"Fri\" 5, \"Sat\" 6);\n" - "set xlabel \"Weekday\"\n" - "set ylabel \"# of messages\"\n" - "set boxwidth 0.9\n") gnuplot) - (display (string-append "plot \"" datafile "\" using 1:2 with boxes fs solid\n") - gnuplot) - (close-pipe gnuplot))) - - -(define* (per-month #:optional (EXPR "")) - "Count the total number of messages for each month (1-12 for -Jan..Dec). If the optional EXPR is provided, only count the messages -that match it. The result is a list of pairs (month . frequency).\n" - (let* ((stats (mu:tabulate-messages - (lambda (msg) ;; note the 1+ - (1+ (tm:mon (localtime (date msg))))) EXPR))) - (sort stats - (lambda(a b) - (< (car a) (car b)))))) ;; in order ofmonth - - -(define* (mu:plot:per-month #:optional (EXPR "")) - (let* ((datafile (export-pairs (per-month EXPR))) - (gnuplot (open-pipe "gnuplot -p" OPEN_WRITE))) - (display (string-append - "reset\n" - "set xtics (\"Jan\" 1, \"Feb\" 2, \"Mar\" 3, \"Apr\" 4," - "\"May\" 5, \"Jun\" 6, \"Jul\" 7, \"Aug\" 8," - "\"Sep\" 9, \"Oct\" 10, \"Nov\" 11, \"Dec\" 12);\n" - "set xlabel \"Month\"\n" - "set ylabel \"# of messages\"\n" - "set boxwidth 0.9\n") gnuplot) - (display (string-append "plot \"" datafile "\" using 1:2 with boxes fs solid\n") - gnuplot) - (close-pipe gnuplot))) - - -(define* (per-hour #:optional (EXPR "")) - "Count the total number of messages for each weekday (0-6 for -Sun..Sat). If the optional EXPR is provided, only count the messages -that match it. The result is a list of pairs (weekday . frequency).\n" - (let* ((stats (mu:tabulate-messages - (lambda (msg) (tm:hour (localtime (date msg)))) EXPR))) - (sort stats (lambda(a b) (< (car a) (car b)))))) ;; in order of hour - -(define* (mu:plot:per-hour #:optional (EXPR "")) - (let* ((datafile (export-pairs (per-hour EXPR))) - (gnuplot (open-pipe "gnuplot -p" OPEN_WRITE))) - (display (string-append - "reset\n" - "set xlabel \"Hour\"\n" - "set ylabel \"# of messages\"\n" - "set boxwidth 0.9\n") gnuplot) - (display (string-append "plot \"" datafile "\" using 1:2 with boxes fs solid\n") - gnuplot) - (close-pipe gnuplot))) - - -(define* (per-year #:optional (EXPR "")) - "Count the total number of messages for each year since 1970. If the -optional EXPR is provided, only count the messages that match it. The -result is a list of pairs (year . frequency).\n" - (let* ((stats (mu:tabulate-messages - (lambda (msg) (+ 1900 (tm:year (localtime (date msg))))) - EXPR))) - (sort stats (lambda(a b) (< (car a) (car b)))))) ;; in order of year - -(define* (mu:plot:per-year #:optional (EXPR "")) - (let* ((datafile (export-pairs (per-year EXPR))) - (gnuplot (open-pipe "gnuplot -p" OPEN_WRITE))) - (display (string-append - "reset\n" - "set xlabel \"Year\"\n" - "set ylabel \"# of messages\"\n" - "set boxwidth 0.9\n") gnuplot) - (display (string-append "plot \"" datafile "\" using 1:2 with boxes fs solid\n") - gnuplot) - (close-pipe gnuplot))) - - -(define* (table pairs #:optional (port (current-output-port))) - "Display a list of PAIRS in a table-like fashion." - (let ((maxlen 0)) - (for-each ;; find the widest in the first col - (lambda (pair) - (set! maxlen - (max maxlen (string-length (format #f "~s " (car pair)))))) pairs) - (for-each - (lambda (pair) - (let ((first (format #f "~s" (car pair))) - (second (format #f "~s" (cdr pair)))) - (display (format #f "~A~v_~A\n" - first (- maxlen (string-length first)) second) port))) - pairs))) - -;; (define* (histogram pairs #:optional (port (current-output-port))) -;; "Display a histogram of the list of cons pairs; the car of each pair -;; is used for the x-asxis, while the cdr represents the y value." -;; (let ((pairs ;; pairs may be unsorted, so let's sort first -;; (sort (pairs) (lambda(x1 x2) (< x1 x2))))) - -(define (export-pairs pairs) - "Export PAIRS to a temporary file, return its name. The data can -then be used in, e.g., R and gnuplot." - (let* ((datafile (tmpnam)) - (output (open datafile (logior O_CREAT O_WRONLY) #O0644))) - (table pairs output) - (close output) - datafile)) - -(define (main args) - (let* ((optionspec '( (muhome (value #t)) - (period (value #t)) - (help (single-char #\h) (value #f)))) - (options (getopt-long args optionspec)) - (msg (string-append - "usage: mu-msg-stats [--help] [--muhome=] " - "--period= [searchexpr]\n")) - (help (option-ref options 'help #f)) - (period (option-ref options 'period #f)) - (muhome (option-ref options 'muhome #f)) - (restargs (option-ref options '() #f)) - (expr (if restargs (string-join restargs) ""))) - (if (or help (not period)) - (begin - (display msg) - (exit (if help 0 1)))) - (mu:initialize muhome) - (cond - ((string= period "hour") (mu:plot:per-hour expr)) - ((string= period "day") (mu:plot:per-weekday expr)) - ((string= period "month") (mu:plot:per-month expr)) - ((string= period "year") (mu:plot:per-year expr)) - (else (begin - (display msg) - (exit 1)))))) - -;; Local Variables: -;; mode: scheme -;; End: