--- Emerge-Progress_0.1.12.perl 2006-02-27 17:14:02.000000000 +0100 +++ Emerge-Progress_0.99.perl 2006-04-16 21:32:31.943597313 +0200 @@ -7,23 +7,26 @@ use Gtk2::GladeXML; use locale; use POSIX qw(locale_h); +use Glib qw /TRUE FALSE/; setlocale(LC_NUMERIC, "C"); use strict; use FileHandle; +#use threads; use Data::Dumper; # for debugging purposes +#use Linux::Inotify; +#my $notifier = Linux::Inotify->new(); +#my $watch = $notifier->add_watch('filename', Linux::Inotify::MASK); my $glade = Gtk2::GladeXML -> new("/home/users/t/theemperor/Projects/project1/project1.glade"); - #Definering av ting.. -my $version = '0.1.11'; my $logfile = "/var/log/emerge.log"; my @package_list; my $lastline; -my $status; -my $tag; +my @logfile; +my $packages = (); +my @new_package_list; +my @comp_package_list; my $updatetag; -my $noclickupdate = 0; -my $progresstring = '.'; my @cols = ( { title => 'Name', type => 'Glib::String', }, { title => 'Started', type => 'Glib::String', }, @@ -43,29 +46,27 @@ my $swindow = $glade -> get_widget("scrolledwindow1"); my $swindow2 = $glade -> get_widget("scrolledwindow2"); my $vbox = $glade -> get_widget("vbox1"); -my $buttonbox = $glade -> get_widget("hbuttonbox1"); -my $exitbutton = $glade -> get_widget("button2"); -my $updatebutton = $glade -> get_widget("button1"); my $treeview = $glade -> get_widget("treeview1"); $treeview -> set_model($store); my $treeviewdone = $glade -> get_widget("treeview2"); $treeviewdone -> set_model($storedone); -my $statusbar = $glade -> get_widget("statusbar1"); -#sette parametre.. -$exitbutton->signal_connect(clicked => sub { Gtk2->main_quit; }); -$updatebutton->signal_connect(clicked => sub { &updatesystem; }); -$window->signal_connect(destroy => sub { Gtk2->main_quit; }); +$window->signal_connect(destroy => sub { &quit; }); #Start programmet.. &sett_opp; Gtk2->main; +sub quit +{ + Gtk2 -> main_quit; +} + sub sett_opp { &sett_opp_kolonner; - &parselog("emerge"); - my $timer = Glib::Timeout->add(10000, \&test); + &parselog_test; + my $timer = Glib::Timeout->add(5000, \&test); } sub sett_opp_kolonner @@ -107,277 +108,255 @@ return 1; } -sub updatesystem +sub parselog_test { - unless($noclickupdate eq 1) - { - my $updatewindow = Gtk2::Window->new; - my $vbox = Gtk2::VBox->new; - my $label = Gtk2::Label->new("Sync should only be done once a day.\nIf sync is selected, emerge world will automagically be run."); - my $buttonbox = Gtk2::HButtonBox->new; - my $syncbutton = Gtk2::Button->new('Sync'); - my $emergebutton = Gtk2::Button->new('emerge'); - $syncbutton->signal_connect(clicked => sub { - $statusbar->push('1','Running emerge --sync, this will take some time.'); - $noclickupdate = 1; - &sync; - $updatewindow->destroy; - }); - $emergebutton->signal_connect(clicked => sub { - $statusbar->push('1','Running emerge world, this will take some time.'); - $noclickupdate = 1; - &emergeworld; - $updatewindow->destroy; - }); - $updatewindow->add($vbox); - $vbox->pack_start($label,0,0,0); - $vbox->pack_start($buttonbox,0,0,0); - $buttonbox->add($syncbutton); - $buttonbox->add($emergebutton); - $updatewindow->show_all; - } - return 1; + my $fh = FileHandle -> new; + my $tag; + open($fh, " add_watch($fh -> fileno, 'in', sub { parselog_test_callback($fh,$tag); }); + return TRUE; } -sub sync +sub parselog_test_callback { - my $fh = FileHandle->new; - open($fh, q^emerge --sync|^); - $updatetag = Gtk2::Helper->add_watch ( $fh->fileno, 'in', sub { update_callback($fh,$updatetag); }); - return 1; -} - -sub update_callback -{ - my ( $fh, $updatetag) = @_; - - if ( eof($fh)) + my ($fh,$tag) = @_; + if(eof($fh)) { - Gtk2::Helper->remove_watch ($updatetag) or &error("Kunne ikke gi slipp på Gtk2::Helper."); + Gtk2::Helper -> remove_watch ($tag) or &error("Kunne ikke gi slipp på Gtk2::Helper.."); close($fh); - $statusbar->push('1','Done running emerge --sync, running emerge world..'); - &emergeworld; - return 1; + foreach my $pkg(keys %$packages) + { + if($packages -> {$pkg}) { &add_to_list($pkg); } + } + return TRUE; } - my $line = <$fh>; - if($progresstring eq '.............') { $progresstring = '.'; } - $statusbar->push('1','Running emerge sync'."$progresstring"); - $progresstring = "$progresstring".'.'; - return 1; -} + else + { + my $line = <$fh>; + push(@logfile,$line); -sub emergeworld -{ - $statusbar->push('1','Running emerge world, this WILL take some time..'); - my $fh = FileHandle->new; - open($fh, q^emerge -q world|^); - $updatetag = Gtk2::Helper->add_watch ( $fh->fileno, 'in', sub { emergeworld_callback($fh,$updatetag); }); - return 1; + if($line =~ ">>> emerge") + { + my $pkg = (split / /, $line)[7]; + my $pkg_cat = (split /\//, $pkg)[0]; + $pkg = (split /\//, $pkg)[1]; + my $time = (split /:/, (split /\ /, $line)[0])[0]; + + $packages -> {$pkg} -> {'name'} = $pkg; + $packages -> {$pkg} -> {'category'} = $pkg_cat; + $packages -> {$pkg} -> {'start_time'} = $time; + if(keys %$packages > @package_list) + { + push(@package_list, $pkg); + &clean_package_list; + } + } + } + 1; } -sub emergeworld_callback +sub clean_package_list { - my ( $fh, $updatetag) = @_; - - if ( eof($fh)) + if($#package_list >= 10) { - Gtk2::Helper->remove_watch ($updatetag) or &error("Kunne ikke gi slipp på Gtk2::Helper."); - close($fh); - $statusbar->push('1','Done running emerge world.. You should open a terminal, and as root type "etc-update" to update your config files.'); - $noclickupdate = 0; - return 1; + foreach my $pkg(@package_list[0..($#package_list - 10)]) + { + delete $packages -> {$pkg}; + shift(@package_list); + } } - my $line = <$fh>; - if($progresstring eq '.............') { $progresstring = '.'; } - $statusbar->push('1','Running emerge world'."$progresstring"); - $progresstring = "$progresstring".'.'; - return 1; + 1; } -sub parselog +sub update_list { - my $fh = FileHandle->new; - $lastline = `tail -n1 $logfile`; - chomp($lastline) or &error("Kunne ikke lese /var/log/emerge.log,\nEr du i portage-gruppen?"); - if($_[0] eq 'emerge') - { -# open($fh, q^tail -n100 "/var/log/emerge.log" | grep ">>> emerge"| sort -k7 -u| tail -n10|^); - open($fh, q^tail -n100 "/var/log/emerge.log" | grep ">>> emerge" | tail -n10|^); - } - $tag = Gtk2::Helper->add_watch ( $fh->fileno, 'in', sub - { - watcher_callback( $fh, $tag ); - }); - return 1; + @new_package_list = @package_list; + my $tag; + my $fh = FileHandle -> new; + open($fh,q^tail -n50 /var/log/emerge.log|^); + $tag = Gtk2::Helper->add_watch ( $fh->fileno, 'in', sub { update_list_callback($fh,$tag); }); + 1; } -sub watcher_callback +sub update_list_callback { - my ( $fh, $tag) = @_; - - if ( eof($fh)) + my ($fh,$tag) = @_; + if(eof($fh)) { - Gtk2::Helper->remove_watch ($tag) or &error("Kunne ikke gi slipp på Gtk2::Helper."); + Gtk2::Helper -> remove_watch ($tag) or &error("Could not release Gtk2::Helper"); close($fh); - return 1; + @comp_package_list = @new_package_list; + 1; } - - my $line = <$fh>; - my $time = (split /:/, $line)[0]; - my $package = (split /\//, $line)[1]; - $package = (split /\ /, $package)[0]; - my $package_group = (split/\//, $line)[0]; - $package_group = (split /\ /, $package_group)[7]; - my $status = &status_package($package); - my $completed = 0; - if(defined($status)) + else { - if((split / /,$status)[0] eq 'completed') + my $line = <$fh>; + unless(@comp_package_list = @new_package_list) { - my $tidting = (split / /,$status)[1]; - $status = &gettime($tidting - $time); - $completed = 1; + push(@new_package_list, $line); + print "njaa\n"; } } - my $tid = sprintf("%d",$time); - $tid = gmtime($tid); - - my @data=( - { Name => "$package", Time => "$tid", Status => "$status" } - ); + 1; +} - foreach(@data) - { - if($completed) - { - my $iterdone = $storedone->append; - $storedone->set($iterdone, - 0, $_->{'Name'}, - 1, $_->{'Time'}, - 2, $_->{'Status'} - ); - } - else +sub add_to_list +{ + my $pkg = $_[0]; + my $package_id = $packages -> {$pkg} -> {'id'}; + my $package_name = $packages -> {$pkg} -> {'name'}; + my $package_category = $packages -> {$pkg} -> {'category'}; + + my $package_start_time = gmtime($packages -> {$pkg} -> {'start_time'}); + my $package_status = &status_package($pkg); + unless(defined($package_status)) { $package_status = 'Unknown'; } + my @data=( + { Name => "$package_name", Time => "$package_start_time", Status => "$package_status" } + ); + foreach (@data) { - my $iter = $store->append; - $store->set($iter, - 0, $_->{'Name'}, - 1, $_->{'Time'}, - 2, $_->{'Status'} - ); - push(@package_list, int($time)); - push(@package_list, "$package_group"); - push(@package_list, "$package"); + unless($package_status =~ "Completed" or $package_status =~ "Terminated") + { + my $iter = $store -> append; + $store->set($iter, + 0, $_->{'Name'}, + 1, $_->{'Time'}, + 2, $_->{'Status'} + ); + } + else + { + my $iter = $storedone -> append; + $storedone -> set($iter, + 0, $_->{'Name'}, + 1, $_->{'Time'}, + 2, $_->{'Status'} + ); + } } - } - return 1; } sub test { my $testline = `tail -n1 $logfile`; + my $testline2 = $logfile[$#logfile]; chomp($testline); - if($testline eq $lastline) + chomp($testline2); + if($testline eq $testline2) { my $testi = 0; my $pathi = 0; - while($testi < scalar(@package_list)) + while($testi < $#package_list + 1) { - my $path; - my $iter; - $status = &status_package($package_list[$testi + 2]); - my $eta = &eta($package_list[$testi],$status); - if($eta) { $status = "$status ETA: $eta"; } - if(defined($testi)) - { - my $path = Gtk2::TreePath->new_from_string($pathi); - if(defined($path)) - { - my $iter = $store->get_iter($path); - if(defined($iter)) - { - $store->set($iter, 2, $status); - } - } + unless($packages -> {$package_list[$testi]} -> {'status'} =~ "Completed" or $packages -> {$package_list[$testi]} -> {'status'} =~ "Terminated") + { + my $pkg = $packages -> {$package_list[$testi]} -> {'name'}; + &eta($pkg); + my $eta = &gettime($packages -> {$pkg} -> {'eta'}); + my $percent = $packages -> {$pkg} -> {'percent'}; + my $string = "$percent% ETA: $eta"; + my $status = $packages -> {$package_list[$testi]} -> {'status'}; + my $path = Gtk2::TreePath->new_from_string($testi); + my $iter = $store->get_iter($path); + $store->set($iter, 2, "$string"); } $testi++; - $testi++; - $testi++; - $pathi++; } return 1; } - else - { - @package_list = (); - $store->clear; - $storedone->clear; - &parselog("emerge"); - } + else + { + @package_list = (); + $store->clear; + $storedone->clear; + &parselog_test; + } } sub status_package { return 0 unless($_[0]); - my $test = `tail -n100 $logfile | grep "$_[0]"| tail -n1`; -# my $isdone = `tail -n100 $logfile | grep "$_[0]" | grep "completed" | tail -n1`; - my $isdone = (split /:::/, $test)[1]; - unless(defined($isdone)) -# if($isdone eq '') - { - my $antatt_status = (split / /, $test)[6]; - my $alternativ_status = (split / /, $test)[3]; - if($antatt_status eq "Compiling/Merging") + my $pkg = $_[0]; + my $searchfor_pkg = $pkg; + $searchfor_pkg =~ tr/\+/./; + for(my $line_i = 0; $line_i < @logfile; $line_i++) + { + my $line = $logfile[$line_i]; + if($line =~ m/$searchfor_pkg/) { - my $prosent = &prosent($_[0]); - if($prosent eq "Ukjent status..") + if($line =~ m/Cleaning/) { - return($antatt_status); + $packages -> {$pkg} -> {'status'} = "Cleaning"; } - else + if($line =~ m/Compiling\/Merging/) { - return($prosent); + $packages -> {$pkg} -> {'status'} = "Compiling/Merging"; } - } - else - { - return($antatt_status); + if($line =~ m/Post-Build Cleaning/) + { + $packages -> {$pkg} -> {'status'} = "Post-Build Cleaning"; + } + if($line =~ m/AUTOCLEAN/) + { + $packages -> {$pkg} -> {'status'} = "Autocleaning"; + } + if($line =~ m/completed emerge/) + { + my $whendone = (split /:::/, $line)[0]; + $whendone = (split /:/, $whendone)[0]; + $whendone = &gettime($whendone - $packages -> {$pkg} -> {'start_time'}); + $packages -> {$pkg} -> {'status'} = "Completed after $whendone"; + } + if($logfile[$line_i + 1] =~ 'terminating') #if the line after one telling about the status of the package is *** terminating, we can be pretty sure the emerge has been stopped, and that package will NOT be completed... + { + $packages -> {$pkg} -> {'status'} = "Terminated"; + } +#this will loop for all logfile entries concerning the package, it may be many :) {'status'} will change a lot... probably there is MANY better ways to do this :)... anyhow, it will only return one value, and that is the last entry.., so the routine will only inform you about the last status of the package... } } - else + unless($packages -> {$pkg} -> {'status'} eq "Compiling/Merging") { - my $whendone = (split /:::/, $test)[0]; - $whendone = (split /:/, $whendone)[0]; - return("completed $whendone"); + my $testi = 0; + foreach my $tmp(@package_list) + { + if($tmp eq $pkg) + { + splice(@package_list,$testi,1); + } + $testi++; + } } + return $packages -> {$pkg} -> {'status'}; } sub eta { - my $start_time = $_[0]; - my $p = $_[1]; + my $pkg = $_[0]; + my $start_time = $packages -> {$pkg} -> {'start_time'}; + my $p = &percent($pkg); my $t = time(); - my $tt; if(defined($p)) { - $p = (split /%/, $p)[0]; + my $tt; my $ss = ($t - $start_time); # time since start my $per_sec = ($p / $ss); # percent per second if($per_sec > 0) { $tt = ((100 - $p) / ($per_sec)); } # estimated time until 100% else { return 0; } - return &gettime($tt); + $packages -> {$pkg} -> {'eta'} = $tt; + return TRUE; } } -sub prosent +sub percent { return 0 unless $_[0]; + my $pkg = $_[0]; my $progress; - my $total = `find /var/tmp/portage/$_[0] -iname "*.c" -or -iname "*.cpp" -or -iname "*.cc" | wc -l`; + my $total = `find /var/tmp/portage/$pkg -iname "*.c" -or -iname "*.cpp" -or -iname "*.cc" | wc -l`; chomp($total); unless($total eq "0") { - $progress = `find /var/tmp/portage/$_[0] -iname "*.o" | wc -l`; + $progress = `find /var/tmp/portage/$pkg -iname "*.o" | wc -l`; chomp($progress); } if(defined($progress)) @@ -388,11 +367,12 @@ { my $prosent = ($progress / $total * 100); $prosent = sprintf("%.2f", $prosent); - return("$prosent%"); + $packages -> {$pkg} -> {'percent'} = $prosent; + return TRUE; } else { - return("Ukjent status.."); + return FALSE; } } }