Added scripts to capture screen or area and save the file under a dated file name...
[clearscm.git] / bin / setbg
1 #!/usr/bin/perl
2
3 =pod
4
5 =head1 NAME $RCSfile: setbg,v $
6
7 Set background
8
9 =head1 VERSION
10
11 =over
12
13 =item Author
14
15 Andrew DeFaria <Andrew@ClearSCM.com>
16
17 =item Revision:
18
19 $Revision: 1.10 $
20
21 =item Created:
22
23 Fri Mar 18 01:14:38 PST 2005
24
25 =item Modified:
26
27 $Date: 2012/11/09 15:31:30 $
28
29 =back
30
31 =head1 SYNOPSIS
32
33  Usage: setbg [-u|sage] [-h|elp] [-ve|rbose] [-d|ebug] [-s|leep <n>]
34               [-bgdirs <bgdir> -bgdirs ...]
35
36  Where:
37
38  -u|sage:      Displays this usage
39  -h|elp:       Display full help
40  -ve|rbose:    Be verbose
41  -d|ebug:      Output debug messages
42
43  -s|leep:      Number of minutes to sleep between setting the background
44                (Default: 1 hour)
45  -l|ockscreen: Change lockscreen backround (Default: False)
46  -b|gdirs:     Directories to scan for images
47
48 =head1 DESCRIPTION
49
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.
54
55 Data is written to the following files:
56
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
60
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. 
67
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.
71
72 =cut
73
74 use strict;
75 use warnings;
76
77 use FindBin;
78 use Getopt::Long;
79 use Proc::ProcessTable;
80 use File::Spec;
81 use CGI qw/:standard/;
82
83 use lib "$FindBin::Bin/../lib";
84
85 use Pod::Usage;
86
87 use DateUtils;
88 use Display;
89 use Logger;
90 use Utils;
91
92 my $VERSION  = '$Revision: 1.12 $';
93   ($VERSION) = ($VERSION =~ /\$Revision: (.*) /);
94
95 my $processes = Proc::ProcessTable->new;
96 my %opts = (
97   sleep      => 60,
98   lockscreen => 0,
99   usage      => sub { pod2usage },
100   help       => sub { pod2usage (-verbose => 2)},
101   verbose    => sub { set_verbose },
102   debug      => sub { set_debug },
103 );
104
105 my %totals;
106
107 sub displayStats () {
108   my $statsFile = Logger->new(
109     name      => ".$FindBin::Script.stats",
110     path      => $ENV{HOME},
111     extension => '',
112   );
113
114   $statsFile->log('At ' . localtime());
115   $statsFile->log('Sleep: ' . $opts{sleep});
116   $statsFile->log('Image directories:');
117
118   for (my $i = 0; $i < scalar @{$opts{bgdirs}}; $i++) {
119     $statsFile->log("\t$opts{bgdirs}[$i]: $opts{bgdircnt}[$i]")
120   } # for
121
122   Stats \%totals, $statsFile;
123
124   return;
125 } # displayStats
126
127 sub fillPictures () {
128   my @images;
129
130   $totals{bgdirs} = 0;
131
132   for (@{$opts{bgdirs}}) {
133     my ($status, @pics) = Execute "find \"$_/\" -type f";
134
135     chomp @pics;
136
137     push @images, grep(/jpg$|png$|gif$/i, @pics);
138
139     @pics = grep(/jpg$|png$|gif$/i, @pics);
140
141     push @{$opts{bgdircnt}}, scalar @pics;
142
143     $totals{bgdirs}++;
144   } # for
145
146   $totals{images} = scalar @images;
147
148   displayStats;
149
150   return @images;
151 } # fillPictures
152
153 sub writeHistory($) {
154   my ($msg) = @_;
155
156   open my $hist, '>>', "$ENV{HOME}/.$FindBin::Script.hist"
157     or error "Unable to open $ENV{HOME}/.$FindBin::Script.hist for append - $!", 1;
158
159   $msg = localtime() . $msg;
160
161   display $msg, $hist;
162
163   close $hist;
164 } # writeHistory
165
166 sub updateSetBG($$) {
167   my ($bgimage, $lockimage) = @_;
168
169   open my $setbg, '>', "$ENV{HOME}/.$FindBin::Script"
170     or error "Unable to open $ENV{HOME}/.$FindBin::Script for writing - $!", 1;
171
172   display $bgimage, $setbg;
173
174   close $setbg;
175
176   my $msg  = ":$bgimage";
177      $msg .= " lock:$lockimage" if $opts{lockscreen};
178
179   writeHistory $msg;
180
181   return;
182 } # updateSetBG
183
184 sub SwitchWallPaper {
185   # We don't need to do anything here, just handle the interrupt and
186   # let the while loop continue.
187   debug 'SwitchWallPaper: Interrupt received';
188   displayStats;
189
190   return;
191 } # SwitchWallPaper
192
193 ## Main
194 verbose "$FindBin::Script v$VERSION";
195
196 my @argvCopy = @ARGV;
197
198 GetOptions (
199   \%opts,
200   'usage',
201   'help',
202   'verbose',
203   'debug',
204   'sleep=i',
205   'lockscreen',
206   'bgdirs=s@',
207   'mate',
208 ) || Usage;
209
210 local $0 = "$FindBin::Script " . join ' ', @argvCopy;
211
212 for my $process (@{$processes->table}) {
213   if ($process->cmndline =~ /setbg/ and
214       $process->pid != $$) { 
215     kill 12, $process->pid;
216
217     exit 0;
218   } # if
219 } # for
220
221 for (my $i = 0; $i < scalar @{$opts{bgdirs}}; $i++) {
222   error "$opts{bgdirs}[$i] is not a directory", 1 unless -d $opts{bgdirs}[$i];
223
224   $opts{bgdirs}[$i] = File::Spec->rel2abs ($opts{bgdirs}[$i]);
225 } # for
226
227 # Using gsettings
228 my $setbg       = "gsettings";
229
230 my ($setbgOpts, $setLockOpts);
231
232 if ($opts{mate}) {
233   $setbgOpts   = 'set org.mate.background picture-filename ';
234   $setLockOpts = 'set org.mate.background picture-filename ';
235 } else {
236   $setbgOpts   = "set org.gnome.desktop.background picture-uri \"file://";
237   $setLockOpts = "set org.gnome.desktop.screensaver picture-uri \"file://";
238 } # if
239
240 my @images = fillPictures;
241
242 Usage "No images to display. Must specify -bgdirs" unless @images;
243
244 $SIG{USR2} = \&SwitchWallPaper;
245 $SIG{USR1} = \&fillPictures;
246
247 my $debugger = $DB::OUT;
248 my $today;
249
250 truncate "$ENV{HOME}/.$FindBin::Script.hist", 0;
251
252 EnterDaemonMode unless defined $DB::OUT;
253
254 my $pickNewImages = 1;
255 my ($bgimage, $lockimage);
256
257 while () {
258   if ($pickNewImages) {
259     $bgimage   = escapeHTML ($images[int (rand $#images)]);
260     $lockimage = escapeHTML ($images[int (rand $#images)]);
261   } # if
262
263   my $monitorIsOn;
264
265   my ($status, @output) = Execute("xset q | grep Monitor | awk '{print \$3}'");
266
267   if ($status or $output[0] eq 'Off') {
268     writeHistory ":Monitor off, not setting background to $bgimage - will keep trying";
269
270     $pickNewImages = 0;
271   } else {
272     $pickNewImages = 1;
273
274     my $cmd = $opts{mate} ? "$setbg $setbgOpts\"$bgimage\" 2> /dev/null"
275                           : "$setbg $setbgOpts$bgimage\" 2> /dev/null";
276
277     ($status, @output) = Execute $cmd;
278
279     if ($status) {
280       error "Trying to set background - command used \"$cmd\"\n\nOutput\n\n" . 
281         join "\n", @output;
282       $totals{errors}++;
283     } else {
284       $totals{'Images displayed'}++;
285     } # if
286
287     if ($opts{lockscreen}) {
288       $cmd = $opts{mate} ? "$setbg $setLockOpts\"$lockimage\" 2> /dev/null"
289                          : "$setbg $setLockOpts$lockimage\" 2> /dev/null";
290
291       ($status, @output) = Execute $cmd;
292
293       if ($status != 0) {
294         error "Trying to set lock screen - command used \"$cmd\"\n\nOutput\n\n" .
295           join "\n", @output;
296         $totals{errors}++;
297       } else {
298         $totals{'Lock screens displayed'}++;
299       } # if
300     } # if
301
302     updateSetBG $bgimage, $lockimage;
303   } # if
304
305   displayStats;
306
307   $today = YMD;
308
309   sleep $opts{sleep} * 60;
310
311   if ($today ne YMD){
312     @images = fillPictures;
313
314     displayStats;
315   } # if
316 } # while