/[soft]/mgaonline/trunk/mgaapplet
ViewVC logotype

Contents of /mgaonline/trunk/mgaapplet

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8550 - (show annotations) (download)
Fri Jun 21 23:52:29 2013 UTC (10 years, 11 months ago) by tv
File size: 31514 byte(s)
simplify
1 #!/usr/bin/perl
2 ################################################################################
3 # Mandriva Online #
4 # #
5 # Copyright (C) 2003-2010 Mandriva #
6 # #
7 # Daouda Lo #
8 # Thierry Vignaud <tvignaud at mandriva dot com> #
9 # #
10 # This program is free software; you can redistribute it and/or modify #
11 # it under the terms of the GNU General Public License Version 2 as #
12 # published by the Free Software Foundation. #
13 # #
14 # This program is distributed in the hope that it will be useful, #
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
17 # GNU General Public License for more details. #
18 # #
19 # You should have received a copy of the GNU General Public License #
20 # along with this program; if not, write to the Free Software #
21 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
22 ################################################################################
23
24 use strict;
25 use POSIX ":sys_wait_h";
26 use lib qw(/usr/lib/libDrakX);
27 use standalone; # for explanations
28 use common;
29 use run_program;
30 use feature 'state';
31
32 BEGIN { unshift @::textdomains, 'mgaonline' }
33
34 use mygtk2 qw(gtknew); #- do not import gtkadd which conflicts with ugtk2 version
35 use ugtk2 qw(:all);
36 use lib qw(/usr/lib/libDrakX/drakfirsttime);
37 use mgaonline;
38 use mgaapplet_gui;
39 use Gtk2::Notify '-init', 'mgaapplet';
40 use Net::DBus qw(:typing);
41 use Rpmdrake::open_db;
42
43 if (!find { $_ eq '--auto-update' } @ARGV) {
44 if (my $pid = mgaonline::is_running('mgaapplet')) {
45 if ($::testing) {
46 warn "mgaapplet already running ($pid)\n";
47 } else {
48 die "mgaapplet already running ($pid)\n";
49 }
50 }
51 }
52
53
54 my $online_site = "http://www.mageia.org/";
55 my ($menu, $timeout, $network_timeout, $state_global, $sub_state);
56 my ($download_dir);
57 {
58 my $temp_urpm = Rpmdrake::open_db::fast_open_urpmi_db();
59 $root = $temp_urpm->{root};
60 $download_dir = $temp_urpm->{cachedir};
61 }
62
63 read_sys_config();
64 $config{UPDATE_FREQUENCY} ||= 3*60*60; # default to 3hours
65 if ($::testing || -f "$root/var/lib/mageia-prepare-upgrade/state") {
66 $config{FIRST_CHECK_DELAY} = 1 * 1000; # 1 second
67 } else {
68 $config{FIRST_CHECK_DELAY} ||= 5 * 60 * 1000; # default to 5 minutes
69 }
70 $config{DISTRO_CHECK_DELAY} ||= 60*60*24; # default : one day
71
72 my %state = (
73 delayed => {
74 colour => [ 'busy' ],
75 menu => [ 'check' ],
76 do_not_use_bubble => 1,
77 tt => [
78 #-PO: here %s will be replaced by the local time (eg: "Will check updates at 14:03:50"
79 N("Will check updates at %s", POSIX::strftime("%T", localtime(time() + $config{FIRST_CHECK_DELAY}/1000)))
80 ],
81 },
82
83 okay => {
84 colour => [ 'okay' ],
85 menu => [ 'check' ],
86 do_not_use_bubble => 1,
87 tt => [ N_("Your system is up-to-date") ]
88 },
89 critical => {
90 colour => [ 'noconf' ],
91 menu => [ 'check' ],
92 tt => [ N_("Service configuration problem. Please check logs and send mail to support\@mageiaonline.com") ]
93 },
94 busy => {
95 colour => [ 'busy' ],
96 menu => [],
97 do_not_use_bubble => 1,
98 tt => [ N_("Please wait, finding available packages...") ]
99 },
100 updates => {
101 colour => [ 'error' ],
102 menu => [ 'update', 'check' ],
103 tt => [ N_("New updates are available for your system") ]
104 },
105 new_distribution => {
106 colour => [ 'bundle' ],
107 menu => [ 'upgrade_distro', 'check' ],
108 urgency => 'low',
109 tt => [ N("A new version of Mageia distribution has been released") ]
110 },
111 no_more_supported => {
112 colour => [ 'disabled' ],
113 menu => [ 'check' ],
114 urgency => 'low',
115 tt => []
116 },
117 disconnected => {
118 colour => [ 'disconnect' ],
119 menu => [ 'confNetwork' ],
120 tt => [ N_("Network is down. Please configure your network") ],
121 do_not_use_bubble => mgaonline::is_running('net_applet'),
122 },
123 disabled => {
124 colour => [ 'disabled' ],
125 menu => [],
126 tt => [ N_("Service is not activated. Please click on \"Online Website\"") ]
127 },
128 locked => {
129 colour => [ 'noconf' ],
130 menu => [ 'check' ],
131 tt => [ N_("urpmi database locked") ],
132 do_not_use_bubble => 1,
133 },
134 loop_locked => {
135 colour => [ 'noconf' ],
136 menu => [ 'check' ],
137 tt => [ N_("urpmi database locked") ],
138 },
139 notsupported => {
140 colour => [ 'disabled' ],
141 menu => [],
142 tt => [ N_("Release not supported (too old release, or development release)") ]
143 },
144 no_update_medium => {
145 colour => [ 'noconf' ],
146 menu => [ 'check' ],
147 tt => [ N_("No medium found. You must add some media through 'Software Media Manager'.") ],
148 },
149 no_enabled_medium => {
150 colour => [ 'noconf' ],
151 menu => [ 'check' ],
152 tt => [ N("You already have at least one update medium configured, but
153 all of them are currently disabled. You should run the Software
154 Media Manager to enable at least one (check it in the \"%s\"
155 column).
156
157 Then, restart \"%s\".", N("Enabled"), 'mgaapplet') ],
158 },
159 );
160
161 my %comm_codes = (
162 locked => {
163 code => 2,
164 status => 'locked',
165 log => "urpmi database locked, skipping updating urpmi database",
166 },
167 error_updating => {
168 code => 3,
169 status => 'critical',
170 log => N_("Error updating media"),
171 },
172 no_update_medium => {
173 code => 4,
174 status => 'no_update_medium',
175 log => "no update media configured",
176 },
177 no_enabled_medium => {
178 code => 5,
179 status => 'no_enabled_medium',
180 log => "all update media are disabled",
181 },
182 updates => {
183 code => 6,
184 status => 'updates',
185 log => "Checking... Updates are available\n\n",
186 },
187 uptodate => {
188 code => 7,
189 status => 'okay',
190 log => "Packages are up to date\n",
191 },
192 db_not_open => {
193 code => 8,
194 status => 'critical',
195 log => "Failed to open urpmi database\n",
196 },
197 );
198
199 my %actions = (
200 'update' => { name => N("Install updates"), launch => \&installUpdates },
201 'check' => { name => N("Check Updates"), launch => \&checkUpdates },
202 'confNetwork' => { name => N("Configure Network"), launch => \&configNetwork },
203 'upgrade_distro' => { name => N("Upgrade the system"), launch => \&upgrade },
204 );
205
206 my $icon = Gtk2::StatusIcon->new;
207 #$icon->shape_combine_mask($img, 0, 0);
208 $icon->signal_connect(popup_menu => sub {
209 my ($_icon, $button, $time) = @_;
210 $menu and $menu->popup(undef, undef, undef, undef, $button, $time);
211 });
212 $icon->signal_connect(activate => sub {
213 my %click_actions = (
214 no_update_medium => \&add_media,
215 no_enabled_medium => \&add_media,
216 updates => \&installUpdates,
217 new_distribution => \&upgrade,
218 no_more_supported => \&no_more_supported,
219 );
220 my $action = $state_global;
221 # default to updates rather than distro upgrade:
222 if ($action eq 'new_distribution' && $sub_state eq 'updates') {
223 $action = 'updates';
224 }
225
226 $click_actions{$action}->() if ref $click_actions{$action};
227 });
228 foreach my $opt (@ARGV) {
229 if (member($opt, qw(--force -f))) { setAutoStart('TRUE') }
230 if ($opt =~ /--(rpm-root|urpmi-root)=(.*)/) {
231 $::rpmdrake_options{$1}[0] = $2;
232 }
233 }
234
235 my ($download_all);
236 my ($new_distro, $no_more_supported);
237 my ($current_apimdv_distro);
238
239 get_product_id();
240
241 shouldStart() or die "$localfile should be set to TRUE: please use --force or -f option to launch applet\n";
242
243 go2State('delayed');
244
245 Glib::Timeout->add_seconds($config{FIRST_CHECK_DELAY}/1000, sub {
246 # schedule future checks:
247 setup_cyclic_check();
248 # perform a test after initial delay:
249 checkNetwork();
250 checkUpdates();
251 0;
252 });
253
254
255 $SIG{USR1} = 'IGNORE';
256 $SIG{USR2} = 'IGNORE';
257 $SIG{CHLD} = \&harvester;
258 $SIG{HUP} = \&restart_applet;
259
260 run_program::raw({ detach => 1 }, 'ionice', '-p', $$, '-n7');
261
262
263 Gtk2->main;
264
265 ugtk2::exit(0);
266
267 sub gnome_shell_exit_overview() {
268 eval { Net::DBus->session->get_service('org.gnome.Shell')->get_object('/org/gnome/Shell', 'org.freedesktop.DBus.Properties')->Set('org.gnome.Shell', 'OverviewActive', dbus_boolean(0)) };
269 }
270
271 sub is_there_a_new_distributions() {
272 # sanity check for cooker/cauldron:
273 return if $product_id->{branch} eq 'Devel';
274
275 my @distros = get_distro_list();
276 return if !@distros;
277
278 # do not do anything if current distribution isn't listed on api.mdv.com:
279 return if !member($product_id->{version}, map { $_->{version} } @distros);
280
281 # only compare first distro: if it's not the same as the currently installed one,
282 # then it's the most recent release:
283 my $new_distribution = $distros[0];
284
285 if (-e get_stale_upgrade_filename()) {
286 $new_distro = $new_distribution;
287 return 1;
288 }
289
290 $current_apimdv_distro = find_current_distro(@distros);
291 $no_more_supported = $current_apimdv_distro->{obsoleted_by};
292 refresh_no_more_supported_msg();
293 if ($no_more_supported) {
294 $new_distro = find { $_->{version} eq $no_more_supported } @distros;
295 }
296
297 if ($new_distribution && $new_distribution->{version} ne $product_id->{version}) {
298 $new_distro = $new_distribution;
299 log::explanations(sprintf("new '%s' distribution was released on %s", $new_distro->{version}, $new_distro->{release_date}));
300 return 1;
301 }
302 }
303
304
305 my ($mdv_update_pid, $checker_pid, $media_manager_pid, $locked_count);
306
307 # FIXME: flushing a hash would be less error prone when adding new stuff:
308 sub clean_distro_cache() {
309 undef $new_distro;
310 undef $no_more_supported;
311 }
312
313 sub is_false {
314 my ($s) = @_;
315 !text2bool($s) && $s != 1;
316 }
317
318 sub process_state {
319 my ($state) = @_;
320 log::explanations($state->{log});
321 $sub_state = $state->{status};
322
323 if ($sub_state eq 'locked') {
324 $locked_count++;
325 $sub_state = 'loop_locked' if $locked_count > 10;
326 } else {
327 $locked_count = 0;
328 }
329
330 # busy critical delayed disabled disconnected locked loop_locked new_distribution no_enabled_medium no_more_supported no_update_medium notsupported okay update
331 if (!member($sub_state, qw(okay))) {
332 go2State($sub_state);
333 } elsif ($no_more_supported
334 && !text2bool($local_config{DO_NOT_ASK_FOR_NO_MORE_SUPPORTED})) {
335 go2State('no_more_supported');
336 } elsif ($new_distro && is_false($config{DO_NOT_ASK_FOR_DISTRO_UPGRADE})
337 && is_false($local_config{DO_NOT_ASK_FOR_DISTRO_UPGRADE})) {
338 go2State('new_distribution');
339 } else {
340 go2State($sub_state);
341 }
342 }
343
344 # Signal management
345 sub harvester {
346 my ($_signame, $_clean) = @_;
347 my ($childpid, @pids);
348 my $schedule_checks;
349 do {
350 $childpid = waitpid(-1, &WNOHANG);
351 my $status = $? >> 8;
352 if ($mdv_update_pid && $mdv_update_pid == $childpid) {
353 undef $mdv_update_pid;
354 # make sure to not report new distro after distro upgrade:
355 clean_distro_cache();
356 $schedule_checks = 1;
357 } elsif ($checker_pid && $checker_pid == $childpid) {
358 undef $checker_pid;
359 my ($state) = grep { $_->{code} eq $status } values %comm_codes;
360 if ($state) {
361 process_state($state);
362 }
363 } elsif ($media_manager_pid && $media_manager_pid == $childpid) {
364 undef $media_manager_pid;
365 $schedule_checks = 1;
366 }
367 push @pids, $childpid;
368 } while $childpid > 0;
369 Glib::Timeout->add(200, sub { silentCheck(); 0 }) if $schedule_checks;
370 return @pids;
371 }
372
373 sub restart_applet() {
374 local $SIG{CHLD} = 'DEFAULT';
375 log::explanations(N("Received SIGHUP (probably an upgrade has finished), restarting applet."));
376 { redo if wait() > 0 }
377 exec($0, '--auto-update');
378 }
379
380 # FIXME: we can run many drakconnect when network is down:
381 sub configNetwork() {
382 log::explanations(N_("Launching drakconnect\n"));
383 fork_exec("/usr/sbin/drakconnect");
384 }
385
386 sub confirm_upgrade() {
387 local $mygtk2::left_padding = 0;
388 my $warn_me = text2bool($local_config{DO_NOT_ASK_FOR_DISTRO_UPGRADE});
389 my $w = new_portable_dialog(N("New version of Mageia distribution"));
390 my ($temp_dir, $box);
391
392 my $browse;
393 $browse = gtksignal_connect(
394 Gtk2::FileChooserButton->new(N("Browse"), 'select-folder'),
395 'current-folder-changed' => sub {
396 $temp_dir = $_[0]->get_current_folder;
397 my $ok = -d $temp_dir && ! -l $temp_dir && ((stat($temp_dir))[4] == 0);
398 $ok or ask_warn(N("Error"), N("You must choose a directory owned by the super administrator!"));
399 });
400 $browse->set_current_folder($download_dir);
401
402 my $res = fill_n_run_portable_dialog($w,
403 [
404 get_banner(),
405 gtknew('Label_Left', text => N("A new version of Mageia distribution has been released."), @common),
406 gtknew('HButtonBox', layout => 'start', children_tight => [
407 new_link_button($new_distro->{url}, N("More info about this new version")),
408 ]),
409 gtknew('Label_Left', text => N("Do you want to upgrade to the '\%s' distribution?",
410 $new_distro->{name} || $new_distro->{version}), @common),
411 gtknew('CheckButton', text => N("Do not ask me next time"), active_ref => \$warn_me),
412 gtknew('CheckButton', text => N("Download all packages at once") . "\n" .
413 N("(Warning: You will need quite a lot of free space)"),
414 active_ref => \$download_all, sensitive_ref => \$browse,
415 toggled => sub { $box and $box->set_sensitive($download_all) },
416 ),
417 $box = gtknew('HBox', sensitive => $download_all, children => [
418 0, gtknew('Label_Left', text => N("Where to download packages:")),
419 1, $browse,
420 ]),
421 create_okcancel($w, N("Next"), N("Cancel")),
422 ]);
423
424 setVar('DO_NOT_ASK_FOR_DISTRO_UPGRADE', bool2text($warn_me));
425 $local_config{DO_NOT_ASK_FOR_DISTRO_UPGRADE} = bool2text($warn_me);
426 if ($res) {
427 my $ok = -d $temp_dir && ! -l $temp_dir && ((stat($temp_dir))[4] == 0);
428 $ok or goto &confirm_upgrade;
429 $download_dir = $temp_dir;
430 really_confirm_upgrade();
431 } else {
432 return 0;
433 }
434 }
435
436
437 sub get_obsolete_message_() {
438 N("Maintenance for this Mageia version has ended. No more updates will be delivered for this system.");
439 }
440
441 sub get_obsolete_message() {
442 join("\n\n",
443 get_obsolete_message_(),
444 N("In order to keep your system secure, you can:"),
445 );
446 }
447
448 sub refresh_no_more_supported_msg() {
449 my $basic_msg = get_obsolete_message_();
450 my $distro = N("Mageia");
451 my $msg = N("You should upgrade to a newer version of the %s distribution.", $distro);
452 $state{no_more_supported}{tt}[0] = join(' ', $basic_msg, $msg);
453 }
454
455 sub no_more_supported_choice() {
456 local $mygtk2::left_padding = 0;
457 my $warn_me = text2bool($local_config{DO_NOT_ASK_FOR_NO_MORE_SUPPORTED});
458 # FIXME: just tell radio buttons' children to wrap instead:
459 local $mgaapplet_gui::width = 580;
460 my $w = new_portable_dialog(N("Your distribution is no longer supported"));
461 my ($b1, $b2);
462 my $choice = $no_more_supported ne 'none' ? 'upgrade' : undef;
463
464 my @widgets = (
465 get_banner(N("New version of Mageia distribution")),
466 gtknew('Label_Left',
467 text => get_obsolete_message() . "\n", @common),
468 ($no_more_supported ne 'none' ? (
469 gtknew('VBox', children_tight => [
470 $b2 = gtknew('RadioButton',
471 text => N("Do you want to upgrade to the '\%s' distribution?",
472 $new_distro->{name} || $new_distro->{version}),
473 toggled => sub {
474 ($choice, $warn_me) = ('upgrade', undef) if $_[0]->get_active;
475 },
476 if_($b1, group => $b1)),
477 new_link_button($new_distro->{url}, N("More info about this new version")),
478 ]),
479 gtknew('HSeparator'),
480 ) : ()),
481 gtknew('RadioButton', text => N("Do not ask me next time"),
482 toggled => sub {
483 $choice = 'nothing' if $_[0]->get_active;
484 $warn_me = $_[0]->get_active },
485 group => $b1 || $b2),
486 create_okcancel($w, N("Next"), N("Cancel")),
487 );
488
489 #$_ and $_->set_border_width(8) foreach $b1, $b2, $b3;
490
491 # explicitely wrap too long message:
492 foreach ($b1, $b2) {
493 next if !$_ || !$_->child;
494 $_->child->set_line_wrap(1);
495 $_->child->set_size_request($width-50, -1);
496 }
497
498 my $res = fill_n_run_portable_dialog($w, \@widgets);
499
500 setVar('DO_NOT_ASK_FOR_NO_MORE_SUPPORTED', bool2text($warn_me));
501 $local_config{DO_NOT_ASK_FOR_NO_MORE_SUPPORTED} = bool2text($warn_me);
502 if ($res) {
503 return $choice;
504 } else {
505 return 0;
506 }
507 }
508
509
510 my $no_more_supported_wip;
511 sub no_more_supported() {
512 return if $mdv_update_pid || $no_more_supported_wip;
513 gnome_shell_exit_overview();
514 $no_more_supported_wip = 1;
515 my $choice = no_more_supported_choice();
516 if ($choice eq 'upgrade') {
517 really_confirm_upgrade() and real_upgrade();
518 } elsif ($choice eq 'nothing') {
519 $icon->set_visible(0);
520 }
521 undef $no_more_supported_wip;
522 }
523
524 sub really_confirm_upgrade() {
525 local $mygtk2::left_padding = 0;
526 my $w = ugtk2->new(N("New version of Mageia distribution"), width => $width + 20);
527
528 # estimated package size:
529 my $c;
530 foreach (run_program::get_stdout('rpm', '-qa', '--qf', '%{Archivesize}\n')) {
531 $c += $_;
532 }
533 $c = formatXiB($c);
534
535 {
536 # use wizard button order (for both 2008.1 & 2009.0):
537 local $::isWizard = 1;
538 local $w->{pop_it} = 0;
539 local $::isInstall = 1;
540 gtkadd($w->{window},
541 gtknew('VBox', children_tight => [
542 get_banner(),
543 gtknew('Label_Left', text => N("This upgrade requires high bandwidth network connection (cable, xDSL, ...) and may take several hours to complete."),
544 @common),
545 gtknew('Label_Left', text => N("Estimated download data will be %s", $c), @common),
546 gtknew('Label_Left', text => N("You should close all other running applications before continuing.") .
547 (detect_devices::isLaptop() ?
548 ' ' .
549 N("You should put your laptop on AC and favor ethernet connection over wifi, if available.")
550 : ''),
551 @common),
552 create_okcancel($w, N("Next"), N("Cancel")),
553 ]),
554 );
555 }
556 $w->{ok}->grab_focus;
557 return $w->main;
558 }
559
560 sub upgrade() {
561 return if $mdv_update_pid;
562 gnome_shell_exit_overview();
563 return if !confirm_upgrade();
564 real_upgrade();
565 }
566
567 sub real_upgrade() {
568 $mdv_update_pid = fork_exec('mgaapplet-upgrade-helper', "--new_distro_version=$new_distro->{version}",
569 if_($::testing, '--testing'),
570 if_($download_all, "--download-all=$download_dir"),
571 if_($root, "--urpmi-root=$root"));
572 }
573
574 sub add_media() {
575 return if $media_manager_pid;
576 log::explanations("Launching 'Software Media Manager'");
577 gnome_shell_exit_overview();
578 $media_manager_pid = fork_exec('/usr/sbin/edit-urpm-sources.pl', '--no-splash', if_($root, "--urpmi-root=$root"));
579 }
580
581 sub installUpdates() {
582 return if $mdv_update_pid;
583 log::explanations(N_("Launching MageiaUpdate\n"));
584 gnome_shell_exit_overview();
585 my $program = find { -x "/usr/bin/$_" } qw(MageiaUpdate MandrivaUpdate);
586 $mdv_update_pid = fork_exec($program, '--no-media-update', '--no-confirmation', '--no-splash',
587 if_($root, "--urpmi-root=$root"));
588 silentCheck(); gtkflush();
589 }
590
591 sub checker_exit {
592 my ($state) = @_;
593 POSIX::_exit($comm_codes{$state}{code});
594 }
595
596 sub update_backport_media {
597 my ($urpm) = @_;
598 # update inactive backport media:
599 my @inactive_backport_media = Rpmdrake::open_db::get_inactive_backport_media($urpm);
600 return if !@inactive_backport_media;
601 log::explanations("updating inactive backport media " . join(', ', @inactive_backport_media));
602 foreach (@inactive_backport_media) {
603 run_program::run('urpmi.update', if_($root, "--urpmi-root=$root"), $_);
604 }
605 }
606
607 sub silentCheck() {
608 state $check_time;
609 my $new_time = time();
610 if (!$check_time || $new_time - $check_time > $config{DISTRO_CHECK_DELAY}) {
611 clean_distro_cache();
612 $check_time = $new_time;
613 is_there_a_new_distributions();
614 }
615
616 return if $mdv_update_pid || $checker_pid;
617 log::explanations(N_("Computing new updates...\n"));
618 go2State('busy');
619
620 # are there any updates ?
621
622 $checker_pid = fork();
623 if (defined $checker_pid) {
624 return if $checker_pid; # parent
625
626 # immediate exit, else forked gtk+ object destructors will badly catch up parent applet
627 my $_safe = before_leaving {
628 my $err = $@;
629 log::explanations("mgaapplet check crashed: $err ");
630 warn "Error: $err\n" . common::backtrace();
631 POSIX::_exit(0);
632 };
633
634 # be nice with other processes:
635 setpriority(0, $$, 7); # 0 is PRIO_PROCESS
636
637 my $will_not_update_media;
638 require urpm;
639 require urpm::lock;
640 # so that get_inactive_backport_media() doesn't vivify $urpm->{media}:
641 my $urpm = Rpmdrake::open_db::fast_open_urpmi_db();
642 {
643 local $urpm->{fatal} = sub {
644 print "Fatal: @_\n";
645 $will_not_update_media = 1;
646 };
647 local $urpm->{error} = $urpm->{fatal};
648
649 urpm::lock::urpmi_db($urpm, 'exclusive', 1);
650 }
651 checker_exit('locked') if $will_not_update_media;
652
653 my $is_it_a_devel_distro = is_it_a_devel_distro();
654
655 my $media = $is_it_a_devel_distro ? '-a' : '--update';
656 if (!run_program::run('urpmi.update', $media, if_($root, "--urpmi-root=$root"))) {
657 checker_exit('error_updating') if $will_not_update_media;
658 }
659
660 update_backport_media($urpm);
661
662 require urpm::select;
663 require urpm::media;
664 # this eats 52Mb of RAM on 64bit:
665 # (hence we do it in the forked helper so that the applet doesn't eat too much RAM)
666 urpm::media::configure($urpm, if_(!$is_it_a_devel_distro, update => 1));
667
668 my @update_medias = get_update_medias($urpm);
669
670 if (!@update_medias) {
671 checker_exit('no_update_medium');
672 } elsif (!any { ! $_->{ignore} } @update_medias) {
673 checker_exit('no_enabled_medium');
674 }
675
676 if (my $_db = urpm::db_open_or_die($urpm)) {
677 my $requested = {};
678 my $state = {};
679 my $need_restart = urpm::select::resolve_dependencies(
680 $urpm, $state, $requested,
681 callback_choices => sub { 0 },
682 priority_upgrade => $urpm->{options}{'priority-upgrade'},
683 auto_select => 1,
684 );
685 my @requested_strict = map { scalar $_->fullname } @{$urpm->{depslist}}[keys %{$state->{selected}}];
686
687 if ($need_restart || @requested_strict) {
688 # FIXME: log first found pkgs?
689 warn ">> need_restart=$need_restart, updates=" . join(', ', @requested_strict) . "\n";
690 checker_exit('updates');
691 } else {
692 checker_exit('uptodate');
693 }
694 } else {
695 checker_exit('db_not_open');
696 }
697 checker_exit('updates');
698 } else {
699 log::explanations("cannot fork: %s", "update checker ($!)");
700 go2State('critical');
701 }
702 }
703
704 sub setup_cyclic_check() {
705 $network_timeout = Glib::Timeout->add(2000, sub { checkNetwork(); 1 });
706 $timeout = Glib::Timeout->add_seconds($config{UPDATE_FREQUENCY}, sub {
707 checkUpdates();
708 1;
709 });
710 }
711
712 sub getTime() {
713 my $d = localtime();
714 $d =~ s/\s+/_/g;
715 $d;
716 }
717
718 sub setLastTime() {
719 my $date = getTime();
720 setVar('LASTCHECK', $date);
721 }
722
723 sub checkNetwork() {
724 return if $checker_pid;
725 require network::tools;
726
727 if (!network::tools::has_network_connection()) {
728 # do not notify if already done:
729 return if member($state_global, qw(disconnected));
730 log::explanations(N_("Checking Network: seems disabled\n"));
731 go2State('disconnected');
732 } elsif (member($state_global, qw(disconnected))) {
733 silentCheck(); #- state has changed, update
734 }
735 }
736
737 sub checkUpdates() {
738 member($state_global, qw(disconnected)) or silentCheck();
739 }
740
741 sub go2State {
742 my ($state) = @_;
743 $menu->destroy if $menu;
744 $menu = setState($state);
745 $state_global = $state;
746 gtkflush();
747 }
748
749 sub shouldStart() {
750 to_bool($local_config{AUTOSTART} ne 'FALSE');
751 }
752
753 sub about_dialog() {
754 my $ver = 1; # automatically set from spec file
755 my $url = $online_site;
756 $url =~ s/^https:/http:/;
757 my $w = gtknew('AboutDialog', name => N("Mageia Online %s", $ver),
758 copyright => N("Copyright (C) %s by %s", 'Mandriva', '2001-2010') . "\n" .
759 N("Copyright (C) %s by %s", 'Mageia', '2010-2011'),
760 license => join('', cat_('/usr/share/common-licenses/GPL')),
761 icon => '/usr/share/icons/mini/mgaonline.png',
762 comments => N("Mageia Online gives access to Mageia web services."),
763 website => $url,
764 website_label => N("Online WebSite"),
765 authors => 'Thierry Vignaud <vignaud@mandriva.com>',
766 artists => 'Hélène Durosini',
767 translator_credits =>
768 #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>")
769 N("_: Translator(s) name(s) & email(s)\n"),
770 transient_for => $::main_window, modal => 1, position_policy => 'center-on-parent',
771 );
772
773 $w->show_all;
774 $w->run;
775 return 1;
776 }
777
778 sub setState {
779 my ($state) = @_;
780 my $checkme;
781 state $previous_state;
782 my @arr = @{$state{$state}{menu}};
783 my $tmp = eval { gtkcreate_pixbuf($state{$state}{colour}[0]) };
784 $icon->set_from_pixbuf($tmp) if $tmp;
785 $icon->set_tooltip(formatAlaTeX(translate($state{$state}{tt}[0])));
786 my @invisible_states = qw(delayed okay disconnected locked);
787 $icon->set_visible(!member($state, @invisible_states));
788
789 # do not show icon while checking if previously hidden:
790 $icon->set_visible(0) if $state eq 'busy' && member($previous_state, @invisible_states);
791
792 $previous_state = $state;
793
794 gtkflush(); # so that bubbles are displayed on right icon
795
796 if ($state{$state}{tt}[0] && $icon->isa('Gtk2::StatusIcon') && !$state{$state}{do_not_use_bubble}) {
797 my $bubble = Gtk2::Notify->new(N("Warning"), formatAlaTeX(translate($state{$state}{tt}[0])) . "\n",
798 '/usr/share/icons/mgaonline.png');
799 if ($state eq 'new_distribution') {
800 $bubble->add_action('clicked', N("More Information"), \&upgrade);
801 if ($sub_state eq 'updates') {
802 push @arr, 'update';
803 }
804 } elsif ($state eq 'no_more_supported') {
805 $bubble->add_action('clicked', N("More Information"), \&no_more_supported);
806 if ($sub_state eq 'updates') {
807 push @arr, 'update';
808 }
809 } elsif ($state eq 'updates') {
810 unshift @arr, 'upgrade_distro' if $new_distro;
811 $bubble->add_action('clicked', N("Install updates"), \&installUpdates);
812 } elsif (member($state, qw(no_enabled_medium no_update_medium))) {
813 $bubble->add_action('clicked', N("Add media"), \&add_media);
814 }
815
816 $bubble->set_urgency($state{$state}{urgency}) if $state{$state}{urgency};
817 $bubble->set_timeout(5000);
818 eval { $bubble->show };
819 }
820
821 my $menu = Gtk2::Menu->new;
822 foreach (@arr) {
823 my $action = $actions{$_};
824 next if !ref($action->{launch});
825 $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label($action->{name})), activate => $action->{launch}));
826 }
827 $menu->append(gtkshow(Gtk2::SeparatorMenuItem->new));
828 $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("About..."))),
829 activate => \&about_dialog));
830 $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("Updates Configuration"))),
831 activate => sub { run_program::raw({ detach => 1 }, 'mgaapplet-config') }));
832 $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))) }));
833 $checkme->show;
834 $menu->append(gtksignal_connect(gtkshow(Gtk2::MenuItem->new_with_label(N("Quit"))), activate => sub { mainQuit() }));
835 $menu;
836 }
837
838 sub setAutoStart {
839 my $state = shift;
840 my $date = getTime();
841 if (-f $localfile) {
842 setVar('AUTOSTART', $state);
843 } else {
844 output_p($localfile,
845 qq(AUTOSTART=$state
846 LASTCHECK=$date
847 ));
848 }
849 }
850
851 sub mainQuit() {
852 # setAutoStart('FALSE');
853 Glib::Source->remove($timeout) if $timeout;
854 Glib::Source->remove($network_timeout) if $network_timeout;
855 Gtk2->main_quit;
856 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.30