#!/usr/bin/perl ################################################################################ # MandrakeOnline # # # # Copyright (C) 2003-2004 MandrakeSoft # # # # Daouda Lo # # # # 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 lib qw(/usr/lib/libDrakX); use common; BEGIN { unshift @::textdomains, 'mdkonline' } use Gtk2::TrayIcon; eval { require ugtk2; ugtk2->import(qw(:all)); require Gtk2::Pango; }; if ($@) { print "This program cannot be run in console mode.\n"; c::_exit(0); #- skip ugtk2::END } my ($eventbox, $img); add_icon_path("/usr/share/mdkonline/pixmaps/"); my ($menu, $url, $timeout, $refreshtm); my $nowindow = 1; my $arch = arch(); my $av_pkgs; my $update_label; my ($need_update, $raisedwindow, $isAvailable) = (0, 0, 0); my $conffile = '/etc/sysconfig/mdkonline'; my %state = ( okay => { colour => [ 'green' ], changes => [ 'busy', 'critical', 'disconnected' ], menu => [ 'update', 'configureApplet', 'check', 'weblink' ], tt => [ N("No updates available for your system") ] }, critical => { colour => [ 'orange' ], changes => [ 'okay', 'busy', 'critical', 'disconnected' ], menu => [ 'configureApplet', 'check', 'weblink' ], tt => [ N("Config problems. Launch \"configure\" again") ] }, busy => { colour => [ 'orange' ], changes => [ 'okay', 'critical', 'error', 'disconnected' ], menu => [ ], tt => [ N("System is busy. Wait ...") ] }, error => { colour => [ 'red' ], changes => [ 'okay' ], menu => [ 'update', 'check', 'weblink' ], tt => [ N("%s packages available for update", $av_pkgs) ] }, noconfig => { colour => [ 'orange' ], changes => [ 'okay' ], menu => [ 'weblink', 'register' ], tt => [ N("Service not available. Click on \"configuration\"") ] }, disconnected => { colour => [ 'orange' ], changes => [ 'okay', 'busy', 'critical', 'error' ], menu => [ 'confNetwork' ], tt => [ N("Network is down. Click on \"configure Network\"") ] }, disabled => { colour => [ 'red' ], changes => [ 'okay', 'busy', 'critical', 'error' ], menu => [ 'configureApplet', 'weblink' ], tt => [ N("Service deactivated. Waiting for payment...") ] } ); my %actions = ( 'update' => { name => N("Launch Mandrake Update"), launch => sub { installUpdates() } }, 'configureApplet' => { name => N("Configuration"), launch => sub { configure() } }, 'check' => { name => N("Check Updates"), launch => sub { checkUpdates() } }, 'weblink' => { name => N("Online WebSite"), launch => sub { getSite() } }, 'confNetwork' => { name => N("Configure Network"), launch => sub { configNetwork() } }, 'register' => { name => N("Configure Now!"), launch => sub { configure() } } ); gtkadd(my $icon = Gtk2::TrayIcon->new("MdkApplet"), gtkadd($eventbox = Gtk2::EventBox->new, gtkpack($img = Gtk2::Image->new) ) ); #$icon->shape_combine_mask($img, 0, 0); $eventbox->signal_connect(button_press_event => sub { if (!$raisedwindow) { if ($_[1]->button == 1) { if (-e $conffile) { $raisedwindow = 1; showMainWindow() } else { $raisedwindow = 0; configure() } } } $_[1]->button == 3 && $menu and $menu->popup(undef, undef, undef, undef, $_[1]->button, $_[1]->time); }); my ($opt) = @ARGV; if ($opt eq '--force' || $opt eq '-f') { setAutoStart('TRUE') }; shouldStart() or die "$ENV{HOME}/.mdkonline should be set to TRUE"; checkUpdates(); cronUpdate(); $icon->show_all; Gtk2->main; ugtk2::exit(0); sub showMainWindow() { my $w = Gtk2::Window->new('toplevel'); $w->set_title(N("Mandrake Updates Applet")); $w->signal_connect(delete_event => sub { $w->destroy; $raisedwindow = 0 }); $w->set_position('center'); $w->set_icon(Gtk2::Gdk::Pixbuf->new_from_file('/usr/share/icons/mini/mdkonline.png')); my ($choice, $time); my $autocheck; gtkadd($w, gtkpack__(Gtk2::VBox->new(0,5), gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Actions")), 'etched_in'), gtkpack_(Gtk2::VBox->new(0, 3), 1, gtksignal_connect(Gtk2::Button->new(N("Install updates")), clicked => sub { installUpdates() }), 1, gtksignal_connect(Gtk2::Button->new(N("Configure")), clicked => sub { configure() }), 1, gtksignal_connect(Gtk2::Button->new(N("Check updates")), clicked => sub { setLabel(N("Checking...")); checkUpdates(); setLabel($isAvailable ? N("Available") : N("Not Available")) }), 1, gtksignal_connect(Gtk2::Button->new(N("See logs")), clicked => sub { displayLogs() }), ) ), gtkadd(gtkset_shadow_type(Gtk2::Frame->new(N("Status")), 'etched_in'), gtkpack_(Gtk2::VBox->new(0, 3), 0, gtkpack_(Gtk2::HBox->new(0, 3), 0, Gtk2::Label->new(N("Network Connection: ")), 0, Gtk2::Label->new(isNetwork() ? N("Up") : N("Down")) ), 0, gtkpack_(Gtk2::HBox->new(0, 3), 0, Gtk2::Label->new(N("New Updates: ")), 0, $update_label = Gtk2::Label->new($isAvailable ? N("Available") : N("Not Available")) ), 0, gtkpack_(Gtk2::HBox->new(0, 3), 0, Gtk2::Label->new(N("Last check: ")), 0, Gtk2::Label->new(lastCheck()) ), ) ), gtkpack(Gtk2::HSeparator->new), gtkpack(gtksignal_connect(Gtk2::Button->new(N("Close")), clicked => sub { $w->destroy; $raisedwindow = 0; }) ) )); $w->show_all } sub setLabel { my $label = shift; $update_label->set_label($label); } sub confNetwork { system "/usr/sbin/drakconnect &" } sub launchUpdate { system "/usr/sbin/MandrakeUpdate &" } sub installUpdates { system "/usr/sbin/mdkupdate", "--applet" } sub silentCheck { my $link = "http://www.mandrakeonline.net/online3_RemoteAction.php" . '?action=UpdateList'; my %h = getVarsFromSh($conffile); my $u; require LWP::UserAgent; require HTTP::Request::Common; require HTTP::Request; my $ua = LWP::UserAgent->new; $ua->agent("MdkAppletAgent/0.1" . $ua->agent); $ua->env_proxy; # my $request = HTTP::Request->new(GET => $link . '&log=' . "ayomigration" . '&host=' . "online"); my $request = HTTP::Request->new(GET => $link . '&log=' . $h{LOGIN} . '&host=' . $h{MACHINE}); my $lnk = $link . '&log=' . $h{LOGIN} . '&host=' . $h{MACHINE}; my $response = $ua->request($request); my $ct = $response->content; # print "\nCONTENTS = $ct; link = $lnk \n"; if ($ct =~ /rpm/) { $u = 11 } elsif ($ct =~ m/(\d+)/) { $u = sprintf("%d",$1); } else { $u = 10 }; # 99 - log or host or action or pass empty, wrong action # 98 - wrong pass # 97 - host not active my $retcode = { 10 => sub { $isAvailable = 0; go2State('okay') }, 11 => sub { my @contents = sort ( split /\n/, $ct); my @t = split /\n/, `rpm -qa`; foreach my $cand (@contents) { $cand =~ s/\.(i586|ppc|ia64).rpm//; $cand =~ /(.*)-(.*)-(.*)$/; my ($name, $ver, $rel) = ($1, $2, $3); my $comp = compareWithInstalled($name, $ver, $rel, \@t); if ($comp) { $isAvailable = 1; go2State('error') and last } } }, 97 => sub { go2State('disabled'); }, 98 => sub { go2State('critical'); }, 99 => sub { go2State('critical'); } }; $retcode->{$u}->(); } sub compareWithInstalled { my ($name, $ver, $rel, $t) = @_; my $isUpdate = 0; foreach my $p (@{$t}) { $p =~ /(.*)-(.*)-(.*)$/; if ($name eq $1 ) { if ($ver ne $2 || $rel ne $3) { $isUpdate = 1 and last; } } } $isUpdate } sub cronUpdate { my ($to) = shift; $timeout = Glib::Timeout->add(60*60*1000, sub { checkUpdates(); 1; }); } sub lastCheck { my %h = getVarsFromSh($conffile); my ($t, $l); $t = $h{LASTCHECK} ; $t =~ s/\_/ /g; $t ? $t : N("No check") } sub checkUpdates { if (!isNetwork()) { go2State('disconnected') } elsif (!-e $conffile) { go2State('noconfig') } else { silentCheck(); } } sub go2State { my $state = shift; $menu && $menu->destroy; $menu = setState($state); } sub isNetwork { my $network; $network = gethostbyname("mandrakeonline.net") ? 1 : 0; $network; } sub configure { system "/usr/sbin/mdkonline &"; $refreshtm = Glib::Timeout->add(1*60*1000, sub { -e $conffile and Glib::Source->remove($refreshtm); silentCheck(); 1; }); } sub getSite { my $b = browser(); system("$b " . "https://www.mandrakeonline.net" . "&") } sub browser { require any; my $wm = any::running_window_manager(); member ($wm, 'kwin', 'gnome-session') or $wm = 'other'; my %Br = ( 'kwin' => 'konqueror', 'gnome-session' => 'mozilla', 'other' => $ENV{BROWSER} || find { -x "/usr/bin/$_"} qw(mozilla konqueror galeon) ); $Br{$wm} } sub displayLogs { system "/usr/sbin/logdrake --explain=drakxtools &" } sub shouldStart() { my %p = getVarsFromSh("$ENV{HOME}/.mdkonline"); my $ret = $p{AUTOSTART} eq 'FALSE' ? 0 : 1; $ret } sub setState { my $state_type = shift; my $arr = $state{$state_type}{menu}; my $tmp = gtkcreate_pixbuf($state{$state_type}{colour}->[0]); $img->set_from_pixbuf($tmp); #my $tooltip = Gtk2::Tooltips->new; gtkset_tip(new Gtk2::Tooltips, $eventbox, formatAlaTeX($state{$state_type}{tt}->[0])); my $menu = Gtk2::Menu->new; foreach (@$arr) { my $l = $actions{$_}{name}; $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 { about() })); $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("Quit"))), activate => sub { mainQuit() })); $menu } sub about { my $b = browser(); system("$b " . "https://mandrakeonline.net/info.php" . "&") } sub setAutoStart { my $state = shift; my $file = "$ENV{HOME}/.mdkonline"; if (-f $file) { my %s = getVarsFromSh($file); $s{AUTOSTART} = $state; setVarsInSh($file, \%s); } else { output_p $file, qq(AUTOSTART=$state ); } } sub mainQuit() { setAutoStart('FALSE'); Gtk2->main_quit }