229 lines
5.8 KiB
Perl
Executable file
229 lines
5.8 KiB
Perl
Executable file
#!/usr/bin/env perl
|
|
# -*- perl -*-
|
|
=head1 NAME
|
|
|
|
freemobile - A plugin to monitor a freemobile subscription
|
|
|
|
=head1 INSTALLATION
|
|
|
|
Create a link to this script in /etc/munin/plugins/ :
|
|
$ ln -s /path/to/freemobile-munin /etc/munin/plugins/freemobile
|
|
|
|
|
|
=head1 CONFIGURATION
|
|
|
|
You need to configure the plugin like that:
|
|
|
|
[freemobile]
|
|
user florent
|
|
env.HOME /home/florent
|
|
env.phonenumber 06ABCDEFGH
|
|
env.freemonitored voice sms mms data specialvoice
|
|
env.cache_expire 3600
|
|
timeout 30
|
|
|
|
C<user> I<required>: user with freemobile backend configured
|
|
|
|
C<env.HOME> I<required>: path to user home
|
|
|
|
C<env.phonenumber> (optional): add your phone number if you have more than one
|
|
subscription for this account.
|
|
|
|
C<env.freemonitored> (optional): default only 'voice sms'
|
|
The full list of monitored options is :
|
|
* voice sms mms data specialvoice voicetoint voiceint smsint mmsint dataint
|
|
|
|
C<env.cache_expire 3600> (optional): cache interval in second, or time
|
|
between two connection to the website. The cache interval is 3 hours by default.
|
|
|
|
C<timeout 30> (optional): Munin internal option. The plugin can be slow,
|
|
30s is recommended.
|
|
|
|
=head1 LICENSE
|
|
|
|
AGPLv3
|
|
|
|
=cut
|
|
use strict;
|
|
use warnings;
|
|
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 $cachedir = $ENV{'HOME'} . '/.config/weboob/munin/';
|
|
my $cachefile = "$cachedir/freemobile-munin";
|
|
|
|
my $refreshtime = $ENV{'cache_expire'} || 10_800;
|
|
|
|
my $phone = $ENV{'phonenumber'};
|
|
my $account = '';
|
|
|
|
if (length($phone) > 0) {
|
|
$account = $phone . '@freemobile';
|
|
}
|
|
|
|
my $weboob = 'boobill -f table -b freemobile details ' . $account;
|
|
my $cache_fh;
|
|
|
|
my %label = (
|
|
'voice' => 'Voix en France (min)',
|
|
'voicetoint' => 'Voix vers l\'international (min)',
|
|
'specialvoice' => 'Numéros 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,
|
|
'specialvoice' => 4,
|
|
'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',
|
|
'specialvoice' => '\| (\d+)h(\d+) min (\d+)s',
|
|
'sms' => 'Conso SMS \s+ \| (\d+) \/ (.*)',
|
|
'mms' => 'Vous avez consommé (\d+) MMS',
|
|
'data' => 'Vous avez consommé ([\d\-\.]+) (Mo|Go)',
|
|
'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|Go)',
|
|
);
|
|
|
|
my %post = (
|
|
'voice' => 'postvoice',
|
|
'voicetoint' => 'postvoice',
|
|
'specialvoice' => 'postvoice',
|
|
'sms' => 'simplepost',
|
|
'mms' => 'simplepost',
|
|
'data' => 'datapost',
|
|
'voiceint' => 'postvoice',
|
|
'smsint' => 'simplepost',
|
|
'mmsint' => 'simplepost',
|
|
'dataint' => 'datapost',
|
|
);
|
|
|
|
sub doubleprint {
|
|
my $var = shift;
|
|
print {$cache_fh} $var;
|
|
print $var;
|
|
return 0;
|
|
}
|
|
|
|
sub postvoice {
|
|
my @args = @_;
|
|
my $minutes = $args[0] * 60 + $args[1] + $args[2] / 60;
|
|
doubleprint "$minutes \n";
|
|
return 0;
|
|
}
|
|
|
|
sub simplepost {
|
|
my @args = @_;
|
|
doubleprint "$args[0] \n";
|
|
return 0;
|
|
}
|
|
|
|
sub datapost {
|
|
my @args = @_;
|
|
my $multi = 1;
|
|
my $unit = $args[1];
|
|
if ($unit eq "Go") {
|
|
$multi = 1024;
|
|
}
|
|
$multi = $args[0] * $multi;
|
|
doubleprint "$multi \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 {
|
|
my @cache_data;
|
|
# Check if cache exist and not older than the refresh threshold.
|
|
if ( open $cache_fh, '<', $cachefile ) {
|
|
@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;
|
|
}
|
|
}
|
|
}
|
|
# execute weboob
|
|
open my $data, q(-|), $weboob or croak "Couldn't execute program: $ERRNO";
|
|
my @lines = <$data>;
|
|
close $data or carp "unable to close: $ERRNO";
|
|
# If error output, print the cache (if exist) and exit
|
|
if ( @lines == 0 ) {
|
|
if ( @cache_data > 0 ) {
|
|
print join q{}, @cache_data[ 1 .. $#cache_data ];
|
|
exit 0;
|
|
}
|
|
exit 1;
|
|
}
|
|
|
|
# Open cache for writing
|
|
open $cache_fh, '>', $cachefile
|
|
or croak "Failed to open file $cachefile";
|
|
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;
|
|
}
|
|
|
|
# Create the munin cache dir if missing
|
|
if ( !-d $cachedir ) {
|
|
mkdir $cachedir;
|
|
}
|
|
|
|
if ( $ARGV[0] and $ARGV[0] eq 'config' ) {
|
|
config;
|
|
}
|
|
else {
|
|
fetch;
|
|
}
|
|
|
|
__END__
|