diff options
Diffstat (limited to 'draksnapshot-applet')
-rwxr-xr-x | draksnapshot-applet | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/draksnapshot-applet b/draksnapshot-applet new file mode 100755 index 0000000..60bf89a --- /dev/null +++ b/draksnapshot-applet @@ -0,0 +1,269 @@ +#!/usr/bin/perl +################################################################################ +# Backup Applet # +# # +# Copyright (C) 2008 Mandriva # +# # +# Thierry Vignaud <tvignaud at mandriva dot com> # +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License Version 2 as # +# published by the Free Software Foundation. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # +################################################################################ + +use strict; +use POSIX ":sys_wait_h"; +use Config; +use lib qw(/usr/lib/libDrakX); +use standalone; # for explanations +use interactive; +use common; +use run_program; +use detect_devices; +use feature 'state'; + +use Gtk2::Pango; + +BEGIN { unshift @::textdomains, 'draksnapshot' } + +use mygtk2 qw(gtknew); #- do not import gtkadd which conflicts with ugtk2 version +use ugtk2 qw(:all); +use lib qw(/usr/lib/libDrakX/drakfirsttime); +use Gtk2::Notify '-init', 'draksnapshot'; + +ugtk2::add_icon_path("/usr/share/draksnapshot/pixmaps/"); + +my ($menu, $timeout, @discs); + +my $localfile = "$ENV{HOME}/.draksnapshot"; + +my $insensitive_while_running_a_child; + +my %state = ( + + okay => { + menu => [], + do_not_use_bubble => 1, + }, + disk_found => { + menu => [ 'configure' ], + tt => [ N_("USB discs are availlable for backups") ] + }, + config_in_progress => { + menu => [], + do_not_use_bubble => 1, + tt => [ N_("Configurator is currently running") ] + }, + ); + + +my %actions = ( + 'configure' => { name => N("Configure"), launch => \&configure } +); + +my $icon = Gtk2::StatusIcon->new; +$icon->signal_connect(popup_menu => sub { + my ($_icon, $button, $time) = @_; + $menu and $menu->popup(undef, undef, undef, undef, $button, $time); + }); +$icon->signal_connect(activate => \&configure); +my ($opt) = @ARGV; +if ($opt eq '--force' || $opt eq '-f') { setAutoStart('TRUE') } + +shouldStart() or die "$localfile should be set to TRUE: please use --force or -f option to launch applet\n"; + +go2State('okay'); +gtkflush(); +silentCheck(); +Glib::Timeout->add(4000, sub { silentCheck(); 0 }); +setup_cyclic_check(); + + +$SIG{USR1} = 'IGNORE'; +$SIG{USR2} = 'IGNORE'; +$SIG{CHLD} = \&harvester; + +run_program::raw({ detach => 1 }, 'ionice', '-p', $$, '-n7'); +Gtk2->main; + +ugtk2::exit(0); + +my $config_pid; + +# Signal management +sub harvester { + my ($_signame, $_clean) = @_; + my ($childpid, @pids); + my $configurator_returned; + do { + $childpid = waitpid(-1, &WNOHANG); + if ($config_pid && $config_pid == $childpid) { + undef $config_pid; + $configurator_returned = 1; + # we should better check it has really been configured indeed. + setAutoStart('FALSE'); + ugtk2::exit(0); + } + push @pids, $childpid; + WIFEXITED($?) and refresh_gui(1); + } while $childpid > 0; + Glib::Timeout->add(200, sub { silentCheck(); 0 }) if $configurator_returned; + return @pids; +} + +sub fork_exec { + my $pid = run_program::raw({ detach => 1 }, @_); + refresh_gui(1); + return $pid; +} + +sub refresh_gui { + my ($sens) = @_; + #!$conf_launched and silentCheck(); $conf_launched = 0; + my $w = $::main_window ? $::main_window->window : undef; + $insensitive_while_running_a_child = !$sens; + $sens ? gtkset_mousecursor_normal($w) : gtkset_mousecursor_wait($w); + gtkflush(); +} + +sub configure() { + $config_pid = fork_exec('/usr/sbin/draksnapshot-config'); + go2State('config_in_progress'); +} + +sub silentCheck() { + return if $config_pid; + my $w = $::main_window ? $::main_window->window : undef; + gtkset_mousecursor_wait($w); + + # are there any updates ? + + if (@discs = grep { $_->{usb_bus} } detect_devices::hds()) { + go2State('disk_found'); + } + gtkset_mousecursor_normal($w) if !$insensitive_while_running_a_child; +} + +sub setup_cyclic_check() { + $timeout = Glib::Timeout->add( + 5*60 * 1000, + sub { # default to 5 minutes + my $first_run if 0; + if (!$first_run) { + $first_run = 1; + return 1; + } + silentCheck(); + 1; + }); +} + +sub go2State { + my $state = shift; + $menu->destroy if $menu; + $menu = setState($state); +} + +sub isNetwork() { + require network::network; + require network::tools; + my $net = {}; + network::network::read_net_conf($net); + my ($_gw_intf, $_is_up, $gw_address, $_dns_server) = network::tools::get_internet_connection($net); + to_bool($gw_address); +} + +sub shouldStart() { + my %p = getVarsFromSh($localfile); + to_bool($p{AUTOSTART} ne 'FALSE'); +} + +sub setState { + my ($state_type) = @_; + my $checkme; + my $arr = $state{$state_type}{menu}; + state $pixbuf; + if (!$pixbuf) { + $pixbuf = gtkcreate_pixbuf('draksnapshot'); + $icon->set_from_pixbuf($pixbuf); + } + $icon->set_tooltip(formatAlaTeX(translate($state{$state_type}{tt}[0]))); + $icon->set_visible($state_type ne 'okay'); + gtkflush(); # so that bubbles are displayed on right icon + + if ($state{$state_type}{tt}[0] && $icon->isa('Gtk2::StatusIcon') && !$state{$state_type}{do_not_use_bubble}) { + my $bubble = Gtk2::Notify->new_with_status_icon(N("Warning"), formatAlaTeX(translate($state{$state_type}{tt}[0])) . "\n", + '/usr/share/icons/draksnapshot.png', $icon); + $bubble->set_timeout(5000); + $bubble->show; + } + + my $menu = Gtk2::Menu->new; + foreach (@$arr) { + $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label($actions{$_}{name})), activate => $actions{$_}{launch})); + } + $menu->append(gtkshow(Gtk2::SeparatorMenuItem->new)); + $menu->append( + gtksignal_connect( + gtkshow(Gtk2::MenuItem->new_with_label(N("About..."))), + activate => sub { + my $ver = 1; # automatically set from spec file + my $w = gtknew('AboutDialog', name => N("DrakSnapshot %s", $ver), + copyright => N("Copyright (C) %s by Mandriva", '2001-2007'), + license => join('', cat_('/usr/share/common-licenses/GPL')), + icon => '/usr/share/icons/mini/draksnapshot.png', + comments => N("DrakSnapshot enables to backup your machine through periodic snapshots."), + website => 'http://www.mandriva.com', + website_label => N("Mandriva WebSite"), + authors => 'Thierry Vignaud <vignaud@mandriva.com>', + translator_credits => + #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>") + N("_: Translator(s) name(s) & email(s)\n"), + transient_for => $::main_window, modal => 1, position_policy => 'center-on-parent', + ); + + $w->show_all; + $w->run; + return 1; + + })); + $menu->append(gtksignal_connect(gtkset_active($checkme = Gtk2::CheckMenuItem->new_with_label(N("Always launch on startup")), shouldStart()), toggled => sub { setAutoStart(uc(bool2text($checkme->get_active))) })); + $checkme->show; + $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("Quit"))), activate => sub { mainQuit() })); + $menu; + +} +sub logIt { + my $log = shift; + log::explanations($log); +} + +sub setVar { + my ($file, $var, $st) = @_; + my %s = getVarsFromSh($file); + $s{$var} = $st; + setVarsInSh($file, \%s); +} + +sub setAutoStart { + my ($state) = @_; + if (-f $localfile) { + setVar($localfile, 'AUTOSTART', $state); + } else { + output_p($localfile, "AUTOSTART=$state\n"); + } +} + +sub mainQuit() { + Glib::Source->remove($timeout) if $timeout; + Gtk2->main_quit; +} |