Chnaged setbg to report to ~/.setbg.hist to show the history of images
displayed over the course of a run.
Also changed it to output ~/.setbg.stats to display statistics about how
many images have been displayed and are available.
use DateUtils;
use Display;
use DateUtils;
use Display;
use Utils;
my $VERSION = '$Revision: 1.10 $';
use Utils;
my $VERSION = '$Revision: 1.10 $';
my $processes = new Proc::ProcessTable;
my @imgDirs;
my $processes = new Proc::ProcessTable;
my @imgDirs;
foreach my $process (@{$processes->table}) {
if ($process->cmndline =~ /setbg/ and
foreach my $process (@{$processes->table}) {
if ($process->cmndline =~ /setbg/ and
+sub displayStats () {
+ my $statsFile = Logger->new(
+ name => ".$FindBin::Script.stats",
+ path => $ENV{HOME},
+ extension => '',
+ );
+
+ $statsFile->log('At ' . localtime());
+
+ Stats \%totals, $statsFile;
+
+ return;
+} # displayStats
+
sub fillPictures () {
my @images;
sub fillPictures () {
my @images;
foreach (@imgDirs) {
my @pics = `find "$_" -type f -name "*.jpg"`;
foreach (@imgDirs) {
my @pics = `find "$_" -type f -name "*.jpg"`;
chomp @pics;
push @images, @pics;
} # foreach
chomp @pics;
push @images, @pics;
} # foreach
+ $totals{images} = scalar @images;
+
+ displayStats;
+
+ return @images;
+sub updateSetBG ($) {
+ my ($image) = @_;
+
+ open my $log, '>', "$ENV{HOME}/.$FindBin::Script"
+ or error "Unable to open $ENV{HOME}/.$FindBin::Script for writing - $!", 1;
+
+ display $image, $log;
+
+ close $log;
+
+ open $log, '>>', "$ENV{HOME}/.$FindBin::Script.hist"
+ or error "Unable to open $ENV{HOME}/.$FindBin::Script.hist for append - $!", 1;
+
+ my $msg = localtime() . ":$image";
+
+ display $msg, $log;
+
+ close $log;
+
+ return;
+} # updateSetBG
+
$0 = "$FindBin::Script " . join ' ', @ARGV;
verbose "$FindBin::Script v$VERSION";
$0 = "$FindBin::Script " . join ' ', @ARGV;
verbose "$FindBin::Script v$VERSION";
for (my $i = 0; $i < scalar @imgDirs; $i++) {
error "$imgDirs[$i] is not a directory", 1 unless -d $imgDirs[$i];
for (my $i = 0; $i < scalar @imgDirs; $i++) {
error "$imgDirs[$i] is not a directory", 1 unless -d $imgDirs[$i];
$imgDirs[$i] = File::Spec->rel2abs ($imgDirs[$i]);
} # foreach
# Using gsettings
$imgDirs[$i] = File::Spec->rel2abs ($imgDirs[$i]);
} # foreach
# Using gsettings
-my $setbg = "gsettings";
-my $setbgOpts = "set org.gnome.desktop.background picture-uri \"file://";
+my $setbg = "gsettings";
+my $setbgOpts= "set org.gnome.desktop.background picture-uri \"file://";
my @images = fillPictures;
Usage "No images to display. Must specify -bgdir" unless @images;
my @images = fillPictures;
Usage "No images to display. Must specify -bgdir" unless @images;
sub SwitchWallPaper {
# We don't need to do anything here, just handle the interrupt and
# let the while loop continue.
debug 'SwitchWallPaper: Interrupt received';
sub SwitchWallPaper {
# We don't need to do anything here, just handle the interrupt and
# let the while loop continue.
debug 'SwitchWallPaper: Interrupt received';
} # SwitchWallPaper
$SIG{USR2} = \&SwitchWallPaper;
} # SwitchWallPaper
$SIG{USR2} = \&SwitchWallPaper;
my $debugger = $DB::OUT;
my $today;
my $debugger = $DB::OUT;
my $today;
+truncate "$ENV{HOME}/.$FindBin::Script.hist", 0;
+
EnterDaemonMode unless defined $DB::OUT;
while () {
my $image = escapeHTML ($images[int (rand $#images)]);
EnterDaemonMode unless defined $DB::OUT;
while () {
my $image = escapeHTML ($images[int (rand $#images)]);
- open my $log, '>', "$ENV{HOME}/.$FindBin::Script"
- or error "Unable to open $ENV{HOME}/.$FindBin::Script for writing - $!", 1;
-
- display $image, $log;
-
my $cmd = "$setbg $setbgOpts$image\" 2> /dev/null";
my @output = `$cmd`;
if ($? != 0) {
my $cmd = "$setbg $setbgOpts$image\" 2> /dev/null";
my @output = `$cmd`;
if ($? != 0) {
- display "ERROR Trying to set background - command used \"$cmd\"", $log;
- display "Output:";
- display join "\n", @output, $log;
+ error "Trying to set background - command used \"$cmd\"\n\nOutput\n\n" .
+ join "\n", @output;
+ $totals{errors}++;
+ } else {
+ $totals{'Images displayed'}++;
+
+ updateSetBG $image;
-
- close $log;
-
- $today = YMD;
-
if ($today ne YMD){
@images = fillPictures;
} # if
if ($today ne YMD){
@images = fillPictures;
} # if
BEGIN {
# Extract relative path and basename from script name.
$me = $FindBin::Script;
BEGIN {
# Extract relative path and basename from script name.
$me = $FindBin::Script;
# Remove .pl for Perl scripts that have that extension
$me =~ s/\.pl$//;
} # BEGIN
# Remove .pl for Perl scripts that have that extension
$me =~ s/\.pl$//;
} # BEGIN
my $disposition = $parms{disposition} ? $parms{disposition} : 'perm';
my $timestamped = $parms{timestamped} ? $parms{timestamped} : 'FALSE';
my $append = $parms{append} ? '>>' : '>';
my $disposition = $parms{disposition} ? $parms{disposition} : 'perm';
my $timestamped = $parms{timestamped} ? $parms{timestamped} : 'FALSE';
my $append = $parms{append} ? '>>' : '>';
- my $extension = $parms{extension} ? $parms{extension} : 'log';
- $name = "$name.$extension";
+ if (defined $parms{extension}) {
+ $name .= ".$parms{extension}" unless $parms{extension} eq '';
+ } # if
open $logfile, $append, "$path/$name"
or error "Unable to open logfile $path/$name - $!", 1;
open $logfile, $append, "$path/$name"
or error "Unable to open logfile $path/$name - $!", 1;
# Set unbuffered output
$logfile->autoflush ();
# Set unbuffered output
$logfile->autoflush ();
- set_verbose
- if $ENV{VERBOSE};
- set_debug
- if $ENV{DEBUG};
+ set_verbose if $ENV{VERBOSE};
+ set_debug if $ENV{DEBUG};
return bless {
path => $path,
return bless {
path => $path,
return;
} # append
sub name () {
my ($self) = @_;
return;
} # append
sub name () {
my ($self) = @_;
sub fullname () {
my ($self) = @_;
sub fullname () {
my ($self) = @_;
=cut
$self->log ($msg, $nolinefeed);
=cut
$self->log ($msg, $nolinefeed);
verbose $msg, undef, $nolinefeed;
verbose $msg, undef, $nolinefeed;
=cut
$self->log ($msg, $nolinefeed);
=cut
$self->log ($msg, $nolinefeed);
display $msg, undef, $nolinefeed;
display $msg, undef, $nolinefeed;
$self->{errors} += $increment;
$self->{errors} += $increment;
} # incrementErr
sub err ($;$) {
my ($self, $msg, $errno) = @_;
} # incrementErr
sub err ($;$) {
my ($self, $msg, $errno) = @_;
=pod
=head3 err ($msg, $errno)
=pod
=head3 err ($msg, $errno)
} # if
$self->log ($msg);
} # if
$self->log ($msg);
footing => $footing,
data => $logfile
);
footing => $footing,
data => $logfile
);
close $logfile
or error "Unable to close logfile $log_filename", 1;
close $logfile
or error "Unable to close logfile $log_filename", 1;
$msg = "$me: " . YMDHM . ": $msg" if $self->{timestamped};
display $msg, $self->{handle}, $nolinefeed;
$msg = "$me: " . YMDHM . ": $msg" if $self->{timestamped};
display $msg, $self->{handle}, $nolinefeed;
sub loglines () {
my ($self) = @_;
sub loglines () {
my ($self) = @_;
=cut
warning $msg, $warnno;
=cut
warning $msg, $warnno;
if ($warnno) {
$msg = "WARNING #$warnno: $msg";
} else {
if ($warnno) {
$msg = "WARNING #$warnno: $msg";
} else {
$self->log ($msg);
$self->{warnings}++;
$self->log ($msg);
$self->{warnings}++;
return;
} # warn
sub errors () {
my ($self) = @_;
return;
} # warn
sub errors () {
my ($self) = @_;
sub warnings () {
my ($self) = @_;
sub warnings () {
my ($self) = @_;
if ($self->{disposition} eq 'temp') {
if ($self->{errors} == 0 and
if ($self->{disposition} eq 'temp') {
if ($self->{errors} == 0 and
- $self->{warnings} == 0) {
+ $self->{warnings} == 0) {
unlink $self->fullname;
} # if
} # if
unlink $self->fullname;
} # if
} # if
sub _restoreTerm () {
# In case the user hits Ctrl-C
print "\nControl-C\n";
sub _restoreTerm () {
# In case the user hits Ctrl-C
print "\nControl-C\n";
$errorlog ||= $NULL;
my $file;
$errorlog ||= $NULL;
my $file;
# Redirect STDIN to $NULL
open STDIN, '<', $NULL
or error "Can't read $NULL ($!)", 1;
# Redirect STDIN to $NULL
open STDIN, '<', $NULL
or error "Can't read $NULL ($!)", 1;
# Now the parent exits
exit if $pid;
# Now the parent exits
exit if $pid;
# Write pidfile if specified
if ($pidfile) {
$pidfile = File::Spec->rel2abs ($pidfile);
# Write pidfile if specified
if ($pidfile) {
$pidfile = File::Spec->rel2abs ($pidfile);
or warning "Unable to open pidfile $pidfile for writing - $!";
print $file "$$\n";
or warning "Unable to open pidfile $pidfile for writing - $!";
print $file "$$\n";
# Set process to be session leader
setsid ()
or error "Can't start a new session ($!)", 1;
# Set process to be session leader
setsid ()
or error "Can't start a new session ($!)", 1;
return;
} # EnterDaemonMode
return;
} # EnterDaemonMode
my @output = `$cmd`;
my $status = $?;
my @output = `$cmd`;
my $status = $?;
local $SIG{CHLD} = $sigchld;
chomp @output;
local $SIG{CHLD} = $sigchld;
chomp @output;
$SIG{INT} = \&_restoreTerm;
$SIG{INT} = \&_restoreTerm;
ReadMode 'cbreak';
while () {
my $key;
ReadMode 'cbreak';
while () {
my $key;
while (not defined ($key = ReadKey -1)) { }
if ($key =~ /(\r|\n)/) {
while (not defined ($key = ReadKey -1)) { }
if ($key =~ /(\r|\n)/) {
$password .= $key;
} # while
$password .= $key;
} # while
ReadMode 'restore'; # Reset tty mode before exiting.
$SIG{INT} = 'DEFAULT';
ReadMode 'restore'; # Reset tty mode before exiting.
$SIG{INT} = 'DEFAULT';
return $password;
} # GetPassword
return $password;
} # GetPassword
# TODO: Make it work on Windows...
return if $^O =~ /win/i;
# TODO: Make it work on Windows...
return if $^O =~ /win/i;
open my $loadAvg, '/proc/loadavg'
or croak "Unable to open /proc/loadavg\n";
open my $loadAvg, '/proc/loadavg'
or croak "Unable to open /proc/loadavg\n";
my @loadAvgs = split /\s/, $load;
my @loadAvgs = split /\s/, $load;
if (wantarray) {
return @loadAvgs;
} else {
if (wantarray) {
return @loadAvgs;
} else {
if ($existingPipe) {
close $existingPipe;
if ($existingPipe) {
close $existingPipe;
open $existingPipe, '|-', $to
or error "Unable to open pipe - $!", 1;
open $existingPipe, '|-', $to
or error "Unable to open pipe - $!", 1;
return $existingPipe;
} else {
open $pipe, '|-', $to
return $existingPipe;
} else {
open $pipe, '|-', $to
$pipeToStop ||= $pipe;
close $pipeToStop if $pipeToStop;
$pipeToStop ||= $pipe;
close $pipeToStop if $pipeToStop;
sub RedirectOutput ($$@) {
my ($to, $mode, @output) = @_;
sub RedirectOutput ($$@) {
my ($to, $mode, @output) = @_;
=pod
=head2 RedirectOutput ($to, @ouput)
=pod
=head2 RedirectOutput ($to, @ouput)
chomp;
print $out "$_\n";
} # foreach
chomp;
print $out "$_\n";
} # foreach
return;
} # RedirectOutput
return;
} # RedirectOutput
open my $file, '<', $filename
or error "Unable to open $filename ($!)", 1;
open my $file, '<', $filename
or error "Unable to open $filename ($!)", 1;
if (wantarray) {
local $/ = "\n";
my @lines = <$file>;
if (wantarray) {
local $/ = "\n";
my @lines = <$file>;
close $file
or error "Unable to close $filename ($!)", 1;
close $file
or error "Unable to close $filename ($!)", 1;
foreach (@lines) {
chomp;
chop if /\r/;
push @cleansed_lines, $_ if !/^#/; # Discard comment lines
} # foreach
foreach (@lines) {
chomp;
chop if /\r/;
push @cleansed_lines, $_ if !/^#/; # Discard comment lines
} # foreach
return @cleansed_lines;
} else {
local $/ = undef;
return @cleansed_lines;
} else {
local $/ = undef;
return <$file>;
} # if
} # ReadFile
return <$file>;
} # if
} # ReadFile
=cut
my $msg = "$FindBin::Script Run Statistics:";
=cut
my $msg = "$FindBin::Script Run Statistics:";
if ($log and ref $log eq 'Logger') {
$total->{errors} = $log->{errors};
$total->{warnings} = $log->{warnings};
} # if
if ($log and ref $log eq 'Logger') {
$total->{errors} = $log->{errors};
$total->{warnings} = $log->{warnings};
} # if
if (keys %$total) {
# Display statistics (if any)
if ($log) {
if (keys %$total) {
# Display statistics (if any)
if ($log) {
foreach (sort keys %$total) {
$msg = $total->{$_} . "\t $_";
foreach (sort keys %$total) {
$msg = $total->{$_} . "\t $_";
if ($log) {
$log->msg ($total->{$_} . "\t $_");
} else {
if ($log) {
$log->msg ($total->{$_} . "\t $_");
} else {
} # if
} # foreach
} # if
} # if
} # foreach
} # if