my $help = undef;
my $xml_file = undef;
my $verbose = 0;
+my $disk_space_warn = 95; # Percent to warn at.
my $VERSION = '0.5.1';
'scheduled-recordings!' => \$display{'Scheduled Recordings'},
'schedule-conflicts!' => \$display{'Schedule Conflicts'},
'next-recording!' => \$display{'Time till next recording'},
+ 'disk-space!' => \$display{'Disk Space'},
'file=s' => \$xml_file,
'sub' => \&process_conflicts
},
+ # Diskspace, before storage groups
+ {
+ 'name' => 'Disk Space',
+ 'type' => 'xpath',
+ 'xpath' => '//Status/MachineInfo/Storage',
+ 'xml_version' => [ "<= 31" ],
+ 'attrs' => [ qw/_total_total _total_used/ ],
+ 'commify' => [ qw/_total_total _total_used/ ],
+ 'template' => "Total space is ___total_total__ GB, with ___total_used__ GB used (__percent__)",
+ 'format' => 'one line',
+ 'subs' => {
+ 'percent' => sub {
+ my $vars = shift;
+ my $percent = sprintf("%.1f",
+ $vars->{'_total_used'} / $vars->{'_total_total'} * 100);
+ if ($percent >= $disk_space_warn) {
+ return "$warning$percent\%$normal";
+ } else {
+ return "$safe$percent\%$normal";
+ }
+ }
+ }
+ },
+
+ # Diskspace, with storage groups
+ {
+ 'name' => 'Disk Space',
+ 'type' => 'xpath',
+ 'xpath' => '//Status/MachineInfo/Storage',
+ 'xml_version' => [ ">= 32" ],
+ 'attrs' => [ qw/drive_total_total drive_total_used/ ],
+ 'commify' => [ qw/drive_total_total drive_total_used/ ],
+ 'template' => "Total space is __drive_total_total__ GB, with __drive_total_used__ GB used (__percent__)",
+ 'format' => 'one line',
+ 'subs' => {
+ 'percent' => sub {
+ my $vars = shift;
+ my $percent = sprintf("%.1f",
+ $vars->{'drive_total_used'} / $vars->{'drive_total_total'} * 100);
+ if ($percent >= $disk_space_warn) {
+ return "$warning$percent\%$normal";
+ } else {
+ return "$safe$percent\%$normal";
+ }
+ }
+ }
+ },
+
# How many hours till the next recording.
{
'name' => 'Time till next recording',
our $tomorrow = substr(ParseDate('tomorrow'), 0, 8);
# A couple of global variables
-my ($xml, $myth);
+my ($xml, $xml_version, $myth);
my $schedule_conflicts_present = 0;
my $title = "MythTV status for $host";
die "Failed to parse XML: $@\n";
}
+ # Pick out the XML version.
+ my $items = $xml->documentElement->find('//Status');
+ $xml_version = @{ $items }[0]->getAttribute('protoVer');
+
return $xml;
}
sub process_xml {
my ($block, $xml) = @_;
+ # Only work on this block if we have received the appropriate version of
+ # the XML.
+ if (defined $block->{'xml_version'}) {
+ my $result = undef;
+
+ # At least one of the version checks must pass.
+ for my $check (@{ $block->{'xml_version'} }) {
+ $result ||= eval ( "$xml_version $check" );
+ }
+
+ return
+ unless defined $result && $result ne '';
+
+ warn "We have the correct version of the XML protocol\n"
+ if defined $verbose;
+ }
+
my $items = $xml->documentElement->find($block->{'xpath'});
# Don't do any work on this block if there is nothing for it.
my $block = shift;
my $vars = shift;
+ my %commify = map { $_ => 1 } @{ $block->{'commify'} }
+ if defined $block->{'commify'};
+
my $template = $block->{'template'};
my $skip = undef;
my ($key, $value);
$value = &{ $block->{'rewrite'}{"&$key"} }($value);
}
+ $value = commify($value)
+ if defined $commify{$key};
+
$template =~ s/__${key}__/$value/g;
}
my ($name, $sub);
while (($name, $sub) = each %{ $block->{'subs'} }) {
- &$sub($vars);
+ $value = &$sub($vars);
+
+ $template =~ s/__${name}__/$value/g
+ if defined $value;
}
return defined $skip ? undef : $template;
}
+# Beautify numbers by sticking commas in.
+sub commify {
+ my ($num) = shift;
+
+ $num = reverse $num;
+ $num =~ s<(\d\d\d)(?=\d)(?!\d*\.)><$1,>g;
+ return reverse $num;
+}
+
sub print_version {
print "mythtv-status, version $VERSION.\n";
print "Written by Andrew Ruthven <andrew\@etc.gen.nz>\n";
The host to check, defaults to localhost.
-=item B<--nostatus>, B<--noencoders>, B<--norecording-now>, B<--noscheduled-recordings>, B<--noschedule-conflicts>, B<--nonext-recording>
+=item B<--nostatus>, B<--noencoders>, B<--norecording-now>, B<--noscheduled-recordings>, B<--noschedule-conflicts>, B<--nonext-recording>, B<--nodisk-space>
Suppress displaying blocks of the output if they would normally be displayed.
Any upcoming schedule conflicts (not just limited to today or tomorrow).
+=item Disk Space
+
+The amount of disk space in total, and used by MythTV.
+
=item Time till next recording
If there are no recordings currently happening, then the amount of time until