diff --git a/contrib/freemobile-munin b/contrib/freemobile-munin index 8d7a2f09..7bb9cba5 100755 --- a/contrib/freemobile-munin +++ b/contrib/freemobile-munin @@ -1,176 +1,183 @@ #!/usr/bin/env perl # -*- perl -*- - =head1 NAME - freemobile - A plugin to monitor a freemobile subscription -create a link to this script in /etc/munin/plugins/ -=note1 +=head1 Installation -You have to manually create the folder: - $HOME/.config/weboob/munin/ +Create a link to this script in /etc/munin/plugins/ + +I + F<$HOME/.config/weboob/munin/> =head1 CONFIGURATION You need to configure the user and the home PATH like that: -[freemobile] -env.HOME /home/florent -user florent -group florent + [freemobile] + env.HOME /home/florent + user florent + group florent You can configure the list of monitored data with the line: -env.freemonitored voice sms mms data +C Others monitored options: voicetoint voiceint smsint mmsint dataint specialvoice The cache timeout is 3 hours by default. You can change this value -with env.cache_expire. +with C (seconds). + +=head1 LICENSE + +AGPLv3 =cut +use strict; use warnings; -# Munin doesn't like utf-8 :-( -use encoding "iso-8859-1"; +use Carp; +use English qw(-no_match_vars); +use encoding 'iso-8859-1'; # Munin doesn't like utf-8 :-( use Encode; -my @monitored = split(/ /, $ENV{'freemonitored'} || 'voice sms'); +my @monitored = split / /, $ENV{'freemonitored'} || 'voice sms'; my $cachefile = $ENV{'HOME'} . '/.config/weboob/munin/freemobile-munin'; -my $refreshtime = $ENV{'cache_expire'} || 10800; -my $weboob = "/usr/bin/env weboob-cli ICapBill get_details coin -f table |"; + +my $refreshtime = $ENV{'cache_expire'} || 10_800; +my $weboob = '/usr/bin/env weboob-cli ICapBill get_details coin -f table'; +my $cache_fh; my %label = ( - 'voice' => "Voix en France (min)\n", - 'voicetoint' => "Voix vers l'international (min)\n", - 'specialvoice' => "Numéro spéciaux (min) \n", - 'sms' => "SMS en France\n", - 'mms' => "MMS en France\n", - 'data' => "Data en France\n", - 'voiceint' => "Voix à l\'international (min)\n", - 'smsint' => "SMS à l\'international\n", - 'mmsint' => "MMS à l\'international\n", - 'dataint' => "Data à l\'international\n" - ); + 'voice' => 'Voix en France (min)', + 'voicetoint' => 'Voix vers l\'international (min)', + 'specialvoice' => 'Numéro spéciaux (min) ', + 'sms' => 'SMS en France', + 'mms' => 'MMS en France', + 'data' => 'Data en France', + 'voiceint' => 'Voix à l\'international (min)', + 'smsint' => 'SMS à l\'international', + 'mmsint' => 'MMS à l\'international', + 'dataint' => 'Data à l\'international', +); my %linenum = ( - 'voice' => 3, - 'voicetoint' => 3, + 'voice' => 3, + 'voicetoint' => 3, 'specialvoice' => 4, - 'sms' => 5, - 'mms' => 6, - 'data' => 7, - 'voiceint' => 8, - 'smsint' => 9, - 'mmsint' => 10, - 'dataint' => 11 - ); + 'sms' => 5, + 'mms' => 6, + 'data' => 7, + 'voiceint' => 8, + 'smsint' => 9, + 'mmsint' => 10, + 'dataint' => 11, +); my %regexp = ( - 'voice' => 'National : (\d+)h(\d+)min(\d+)s', - 'voicetoint' => 'International : (\d+)h(\d+)min(\d+)s', + 'voice' => 'National : (\d+)h(\d+)min(\d+)s', + 'voicetoint' => 'International : (\d+)h(\d+)min(\d+)s', 'specialvoice' => '\| (\d+)h(\d+) min (\d+)s', - 'sms' => 'Conso SMS \| (\d+) \/ (.*)', - 'mms' => 'Vous avez consommé (\d+) MMS', - 'data' => 'Vous avez consommé ([\d\-\.]+) Mo', - 'voiceint' => 'Appels émis (\d+)h(\d+)min(\d+)s', - 'smsint' => 'Conso SMS (international) \| (\d+)', - 'mmsint' => 'Vous avez consommé (\d+) MMS', - 'dataint' => 'Vous avez consommé ([\d\-]+) Mo' - ); + 'sms' => 'Conso SMS \| (\d+) \/ (.*)', + 'mms' => 'Vous avez consommé (\d+) MMS', + 'data' => 'Vous avez consommé ([\d\-\.]+) Mo', + 'voiceint' => 'Appels émis (\d+)h(\d+)min(\d+)s', + 'smsint' => 'Conso SMS (international) \| (\d+)', + 'mmsint' => 'Vous avez consommé (\d+) MMS', + 'dataint' => 'Vous avez consommé ([\d\-]+) Mo', +); my %post = ( - 'voice' => 'postvoice', - 'voicetoint' => 'postvoice', + 'voice' => 'postvoice', + 'voicetoint' => 'postvoice', 'specialvoice' => 'postvoice', - 'sms' => 'simplepost', - 'mms' => 'simplepost', - 'data' => 'simplepost', - 'voiceint' => 'postvoice', - 'smsint' => 'simplepost', - 'mmsint' => 'simplepost', - 'dataint' => 'simplepost' - ); - -my @lines; -my $cache; -my $expr; - -if ($ARGV[0] and $ARGV[0] eq "config") { - binmode STDOUT, ":encoding(iso-8859-1)"; - print "graph_title Conso Free\n"; - print "graph_vlabel Suivi conso du forfait Free Mobile\n"; - print "graph_category weboob\n"; - print "graph_args -l 0\n"; - foreach (@monitored) { - print "$_" . ".label "; - print $label{$_}; - } -} -else { - my $refresh; - my $first = 1; - my $time = time(); - # Check if cache exist and not older than 3 hours - if (open(CACHE, "< " . $cachefile)) { - $cache = 1; - LOOP: while() { - if ($first) { - if ($time - $_ > $refreshtime) { - $refresh = 0; - last; - } - else { - $refresh = 1; - } - $first = 0; - } - else { - print $_; - } - } - } - close(CACHE); - exit if $cache and $refresh; - - # Open cache for writing and execute weboob - open(CACHE, "> " . $cachefile) or die "Failed to open file $cachefile"; - open(DATA, $weboob) or die "Couldn't execute program: $!"; - LOOP: while () { - push(@lines,$_); - } - close(DATA); - print CACHE time(). "\n"; - - foreach $monit (@monitored) { - doubleprint("$monit" . ".value "); - if ($lines[$linenum{$monit}] =~ /$regexp{$monit}/ ) { - my $string; - foreach $expr (1..$#-) { - $string = $string . "${$expr} "; - } - my $postfunction = $post{$monit}; - &$postfunction($string); - } - else { - doubleprint("0 \n"); - } - } - close(CACHE); -} + 'sms' => 'simplepost', + 'mms' => 'simplepost', + 'data' => 'simplepost', + 'voiceint' => 'postvoice', + 'smsint' => 'simplepost', + 'mmsint' => 'simplepost', + 'dataint' => 'simplepost', +); sub doubleprint { - print CACHE $_[0]; - print $_[0]; + my $var = shift; + print {$cache_fh} $var; + print $var; + return 0; } sub postvoice { - my @args = split(/ /, $_[0]); + my @args = @_; my $minutes = $args[0] * 60 + $args[1] + $args[2] / 60; - doubleprint("$minutes \n"); + doubleprint "$minutes \n"; + return 0; } sub simplepost { - my @args = split(/ /,$_[0]); - doubleprint("$args[0] \n"); + my @args = @_; + doubleprint "$args[0] \n"; + return 0; } + +sub config { + binmode STDOUT, ':encoding(iso-8859-1)'; + print <<'EOF'; +graph_title Conso Free +graph_vlabel Suivi conso du forfait Free Mobile +graph_category weboob +graph_args -l 0 +EOF + foreach (@monitored) { + print "$_.label $label{$_}\n"; + } + return 0; +} + +sub fetch { + + # Check if cache exist and not older than the refresh threshold. + if ( open $cache_fh, '<', $cachefile ) { + my @cache_data = <$cache_fh>; + close $cache_fh or croak "unable to close: $ERRNO"; + + # File not empty? + if ( @cache_data > 0 ) { + + # Data is still fresh. Display cached values and exit. + if ( time - $cache_data[0] < $refreshtime ) { + print join q{}, @cache_data[ 1 .. $#cache_data ]; + exit 0; + } + } + } + + # Open cache for writing and execute weboob + open $cache_fh, '>', $cachefile + or croak "Failed to open file $cachefile"; + open my $data, q(-|), $weboob or croak "Couldn't execute program: $ERRNO"; + my @lines = <$data>; + close $data or carp "unable to close: $ERRNO"; + print {$cache_fh} time . "\n"; + + foreach my $monit (@monitored) { + doubleprint "$monit.value "; + if ( my @results = $lines[ $linenum{$monit} ] =~ /$regexp{$monit}/ ) { + my $postfunction = $post{$monit}; + &{ \&$postfunction }(@results); + } + else { + doubleprint "0 \n"; + } + } + close $cache_fh or croak "unable to close: $ERRNO"; + return 0; +} + +if ( $ARGV[0] and $ARGV[0] eq 'config' ) { + config; +} +else { + fetch; +} + +__END__