5 =head1 NAME $RCSfile: setbg,v $
15 Andrew DeFaria <Andrew@ClearSCM.com>
23 Fri Mar 18 01:14:38 PST 2005
27 $Date: 2012/11/09 15:31:30 $
33 Usage: setbg [-u|sage] [-h|elp] [-ve|rbose] [-d|ebug] [-s|leep <n>]
34 [-bgdirs <bgdir> -bgdirs ...]
38 -u|sage: Displays this usage
39 -h|elp: Display full help
41 -d|ebug: Output debug messages
43 -s|leep: Number of minutes to sleep between setting the background
45 -l|ockscreen: Change lockscreen backround (Default: False)
46 -b|gdirs: Directories to scan for images
50 This script sets the background image randomly based on images found in bgdirs.
51 Note if this script is run again it senses that it was previously run and sends
52 the previous script a SIGUSR2 which the script intrprets as "Change the
53 background now", then exits.
55 Data is written to the following files:
57 ~/.setbg: Contains the filename of the current background image
58 ~/.setbg.hist Contains a history of all images displayed for this run
59 ~/.setbg.stats Contains statistical information for the current run
61 Also note that this script will process a SIGUSR1 to mean "re-evaluate the
62 contents of the bgdirs incase it has changed and display a new image". This is
63 useful for script to be able to alert setbg that something has changed. For
64 example, a script named rmbg might look at ~/.setbg to get the name of the
65 current background image file and remove it then signal setbg with SIGUSR1 to
66 have it re-evaluate the state of bgdirs.
68 Finally setbg will perform the this re-evaluation at midnight everyday. This is
69 useful because we point setbg to look at -bgdirs from Dropbox where Camera
70 Uploads is included and new pictures can arrive everyday.
76 use experimental qw(signatures);
80 use Proc::ProcessTable;
82 use CGI qw/:standard/;
84 use lib "$FindBin::Bin/../lib";
93 my $VERSION = '$Revision: 1.12 $';
94 ($VERSION) = ($VERSION =~ /\$Revision: (.*) /);
96 my $processes = Proc::ProcessTable->new;
100 usage => sub { pod2usage },
101 help => sub { pod2usage (-verbose => 2)},
102 verbose => sub { set_verbose },
103 debug => sub { set_debug },
109 my $statsFile = Logger->new(
110 name => ".$FindBin::Script.stats",
115 $statsFile->log('At ' . localtime());
116 $statsFile->log('Sleep: ' . $opts{sleep});
117 $statsFile->log('Image directories:');
119 for (my $i = 0; $i < scalar @{$opts{bgdirs}}; $i++) {
120 $statsFile->log("\t$opts{bgdirs}[$i]: $opts{bgdircnt}[$i]")
123 Stats \%totals, $statsFile;
128 sub fillPictures($signame = undef) {
133 for (@{$opts{bgdirs}}) {
134 my ($status, @pics) = Execute "find \"$_/\" -type f";
138 push @images, grep(/jpg$|png$|gif$/i, @pics);
140 @pics = grep(/jpg$|png$|gif$/i, @pics);
142 push @{$opts{bgdircnt}}, scalar @pics;
147 $totals{images} = scalar @images;
154 sub writeHistory($msg) {
155 open my $hist, '>>', "$ENV{HOME}/.$FindBin::Script.hist"
156 or error "Unable to open $ENV{HOME}/.$FindBin::Script.hist for append - $!", 1;
158 $msg = localtime() . $msg;
160 print $hist "$msg\n";
165 sub writeSetBG($filename, $image) {
166 open my $file, '>', $filename
167 or error "Unable to open $filename for writing - $!", 1;
169 print $file "$image\n";
174 sub updateSetBG($bgimage, $lockimage) {
175 writeSetBG "$ENV{HOME}/.$FindBin::Script", $bgimage;
176 writeSetBG "$ENV{HOME}/.$FindBin::Script.lock", $lockimage;
178 my $msg = ":$bgimage";
179 $msg .= " lock:$lockimage" if $opts{lockscreen};
186 sub SwitchWallPaper($saigname) {
187 # We don't need to do anything here, just handle the interrupt and
188 # let the while loop continue.
189 debug 'SwitchWallPaper: Interrupt received';
196 verbose "$FindBin::Script v$VERSION";
198 my @argvCopy = @ARGV;
212 local $0 = "$FindBin::Script " . join ' ', @argvCopy;
214 for my $process (@{$processes->table}) {
215 if ($process->cmndline =~ /setbg/ and
216 $process->pid != $$) {
217 kill 12, $process->pid;
223 for (my $i = 0; $i < scalar @{$opts{bgdirs}}; $i++) {
224 error "$opts{bgdirs}[$i] is not a directory", 1 unless -d $opts{bgdirs}[$i];
226 $opts{bgdirs}[$i] = File::Spec->rel2abs ($opts{bgdirs}[$i]);
230 my $setbg = "gsettings";
232 my ($setbgOpts, $setLockOpts);
235 $setbgOpts = 'set org.mate.background picture-filename ';
236 $setLockOpts = 'set org.mate.screensaver picture-filename ';
238 $setbgOpts = "set org.gnome.desktop.background picture-uri \"file://";
239 $setLockOpts = "set org.gnome.desktop.screensaver picture-uri \"file://";
242 my @images = fillPictures;
244 Usage "No images to display. Must specify -bgdirs" unless @images;
246 $SIG{USR2} = \&SwitchWallPaper;
247 $SIG{USR1} = \&fillPictures;
249 my $debugger = $DB::OUT;
252 truncate "$ENV{HOME}/.$FindBin::Script.hist", 0;
254 EnterDaemonMode unless defined $DB::OUT;
256 my $pickNewImages = 1;
257 my ($bgimage, $lockimage);
260 if ($pickNewImages) {
261 $bgimage = escapeHTML ($images[int (rand $#images)]);
262 $lockimage = escapeHTML ($images[int (rand $#images)]);
267 my ($status, @output) = Execute("xset q | grep Monitor | awk '{print \$3}'");
269 if ($status or $output[0] eq 'Off') {
270 writeHistory ":Monitor off, not setting background to $bgimage - will keep trying";
276 my $cmd = $opts{mate} ? "$setbg $setbgOpts\"$bgimage\" 2> /dev/null"
277 : "$setbg $setbgOpts$bgimage\" 2> /dev/null";
279 ($status, @output) = Execute $cmd;
282 error "Trying to set background - command used \"$cmd\"\n\nOutput\n\n" .
286 $totals{'Images displayed'}++;
289 if ($opts{lockscreen}) {
290 $cmd = $opts{mate} ? "$setbg $setLockOpts\"$lockimage\" 2> /dev/null"
291 : "$setbg $setLockOpts$lockimage\" 2> /dev/null";
293 ($status, @output) = Execute $cmd;
296 error "Trying to set lock screen - command used \"$cmd\"\n\nOutput\n\n" .
300 $totals{'Lock screens displayed'}++;
304 updateSetBG $bgimage, $lockimage;
311 sleep $opts{sleep} * 60;
314 @images = fillPictures;