diff --git a/CHANGES b/CHANGES index adee464..7be714a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,16 @@ CHANGELOG for ClamTk: +5.11 - Oct 31 2014 +----------------- + * Fix for clamtk.py to right-click scan files with + special characters + * Minor improvements to the Update dialog; the new benefit + is one-click signature updating vice two + * Minor updates to help documentation (PUAs) + * Minor improvement in Update Assistant + * Updated language files: German (de), Brazilian + Portuguese (pt_BR), Bulgarian (bg) + 5.10 - Oct 2 2014 ------------------ * Display total number of signatures properly. Thanks, Natalia! @@ -190,17 +201,17 @@ CHANGELOG for ClamTk: 4.44 - Dec 22 2012 ------------------ * Update gvfs directory location, which moved from - /home/$user/.gvfs to /run/user/$user/gvfs. This is - standard now with Ubuntu 12.10 and Fedora 17 + /home/$user/.gvfs to /run/user/$user/gvfs. This is + standard now with Ubuntu 12.10 and Fedora 17 * Add missing ignore-gvfs-mounts option to scheduled - scans. Thanks, Matthew! + scans. Thanks, Matthew! * Copy bytecode.cld when changing to manual updates. * Updated Finnish (fi) language file. Thanks, Jiri! 4.43 - Dec 2 2012 ------------------ * Begin using Keyword entry in .desktop file - (Launchpad #1050803) + (Launchpad #1050803) * Added Afrikaans (af) language file. Thanks, Dawid! * Added Marathi (mr) language file. Thanks, Shashank! * Updated Greek (el_GR) language file. Thanks, Sterios! diff --git a/clamtk.py b/clamtk.py index 87530bf..182acc6 100755 --- a/clamtk.py +++ b/clamtk.py @@ -14,6 +14,7 @@ import os import urllib +import re import locale locale.setlocale(locale.LC_ALL, '') @@ -27,6 +28,7 @@ class OpenTerminalExtension(GObject.GObject, Nautilus.MenuProvider): def _open_scanner(self, file): filename = urllib.unquote(file.get_uri()[7:]) + filename = re.escape(filename) #os.chdir(filename) os.system('clamtk %s &' % filename) diff --git a/latest b/latest index e0180bf..21df8b3 100644 --- a/latest +++ b/latest @@ -1 +1 @@ -5.09 +5.11 diff --git a/lib/Analysis.pm b/lib/Analysis.pm index 286a9cc..a351f7a 100644 --- a/lib/Analysis.pm +++ b/lib/Analysis.pm @@ -514,8 +514,8 @@ sub check_for_existing { return ( $return, $new_window, $is_error ); $data->{ response_code } = -4; } - warn "response_code from submission >", $data->{ response_code }, - "<\n"; + # warn "response_code from submission >", $data->{ response_code }, + # "<\n"; # Response codes: # 0 = not present in dataset # -2 = queued for analysis diff --git a/lib/App.pm b/lib/App.pm index cacfd6b..0dfec0f 100644 --- a/lib/App.pm +++ b/lib/App.pm @@ -24,7 +24,7 @@ use Encode 'decode'; sub get_TK_version { # Stick with %.2f format - 4.50 vice 4.5 - return '5.10'; + return '5.11'; } sub get_path { diff --git a/lib/Assistant.pm b/lib/Assistant.pm index 27b36f0..ae0f023 100644 --- a/lib/Assistant.pm +++ b/lib/Assistant.pm @@ -99,6 +99,9 @@ sub show_window { $infobar->signal_connect( response => sub { my ( $bar, $sig ) = @_; + Gtk2->main_iteration while Gtk2->events_pending; + $label->set_text( _('Please wait...') ); + Gtk2->main_iteration while Gtk2->events_pending; if ( save() ) { set_infobar_text( TRUE, $bar ); } else { diff --git a/lib/GUI.pm b/lib/GUI.pm index c907666..9cf5a50 100644 --- a/lib/GUI.pm +++ b/lib/GUI.pm @@ -150,11 +150,13 @@ sub startup { # are updates, we need to show it Gtk2->main_iteration while Gtk2->events_pending; set_infobar_mode( $message_type, $message ); + $window->queue_draw; $window->resize( 340, 400 ); $infobar->show; $window->queue_draw; Gtk2->main_iteration while Gtk2->events_pending; + $window->resize( 340, 400 ); } sub set_infobar_mode { @@ -518,7 +520,20 @@ sub swap_button { my $change_to = shift; if ( $change_to ) { $infobar->add_button( 'gtk-go-back', -5 ); - $infobar->signal_connect( 'response' => \&add_default_view ); + # $infobar->signal_connect( 'response' => \&add_default_view ); + $infobar->signal_connect( + response => sub { + my ( $package, $filename, $line ) = caller; + add_default_view(); + # Only do this if we're coming from + # Update.pm - this will show the user + # if the sigs were updated + if ( $package eq 'ClamTk::Update' ) { + warn "caller; going to startup\n"; + startup(); + } + } + ); } else { for my $a ( $infobar->get_action_area ) { for my $b ( $a->get_children ) { diff --git a/lib/Update.pm b/lib/Update.pm index a25e74f..48f8ada 100644 --- a/lib/Update.pm +++ b/lib/Update.pm @@ -24,16 +24,20 @@ use Locale::gettext; my $infobar; # Gtk2::InfoBar for status my $pb; # Gtk2::ProgressBar my $liststore; # Information on current and remote versions +my $iter_hash; # Must be global to update sig area my $updated = 0; sub show_window { my $box = Gtk2::VBox->new( FALSE, 5 ); + my $top_box = Gtk2::VBox->new( FALSE, 5 ); + $box->pack_start( $top_box, TRUE, TRUE, 0 ); + my $scrolled = Gtk2::ScrolledWindow->new( undef, undef ); $scrolled->set_policy( 'never', 'never' ); $scrolled->set_shadow_type( 'etched-out' ); - $box->pack_start( $scrolled, FALSE, TRUE, 2 ); + $top_box->pack_start( $scrolled, FALSE, TRUE, 2 ); # update available images: # gtk-yes = yes @@ -43,10 +47,9 @@ sub show_window { $liststore = Gtk2::ListStore->new( # product, local version, 'Glib::String', 'Glib::String', - # remote version, update available image - 'Glib::String', 'Glib::String', ); + # Product column my $view = Gtk2::TreeView->new_with_model( $liststore ); $view->set_can_focus( FALSE ); $scrolled->add( $view ); @@ -56,78 +59,67 @@ sub show_window { text => 0, ); $view->append_column( $column ); + + # Installed version column $column = Gtk2::TreeViewColumn->new_with_attributes( _( 'Installed' ), Gtk2::CellRendererText->new, text => 1, ); $view->append_column( $column ); - $column = Gtk2::TreeViewColumn->new_with_attributes( - _( 'Available' ), - Gtk2::CellRendererText->new, - text => 2, - ); - $view->append_column( $column ); - $column = Gtk2::TreeViewColumn->new_with_attributes( - _( 'Update Available' ), - Gtk2::CellRendererPixbuf->new, - stock_id => 3, - ); - $view->append_column( $column ); # Get local information my $local_sig_version = ClamTk::App->get_local_sig_version(); - my $local_tk_version = ClamTk::App->get_TK_version(); #<<< my @data = ( { product => _( 'Antivirus signatures' ), local => $local_sig_version, - remote => _('Unknown'), - update => 'gtk-dialog-error', - }, - { - product => _( 'Graphical interface' ), - local => $local_tk_version, - remote => _('Unknown'), - update => 'gtk-dialog-error', - }, - { - product => ' ', - local => ' ', - remote => ' ', - update => ' ', }, ); for my $item ( @data ) { my $iter = $liststore->append; + + # make a copy for updating + $iter_hash = $iter; + $liststore->set( $iter, 0, $item->{ product }, 1, $item->{ local }, - 2, $item->{ remote }, - 3, $item->{ update }, ); } #>>> $infobar = Gtk2::InfoBar->new; $infobar->set_message_type( 'other' ); - $infobar->add_button( 'gtk-ok', -5 ); + + my $text = ''; + if ( ClamTk::Prefs->get_preference( 'Update' ) eq 'shared' ) { + $text = _( 'You are configured to automatically receive updates' ); + } else { + $text = _( 'Check for updates' ); + $infobar->add_button( 'gtk-ok', -5 ); + } my $label = Gtk2::Label->new; - $label->set_text( _( 'Check for updates' ) ); + $label->set_text( $text ); $label->set_alignment( 0.0, 0.5 ); $infobar->get_content_area()->add( $label ); #<<< $infobar->signal_connect( response => sub { - update_store(); + # update_store(); + update_signatures(); } ); #>>> + $box->pack_start( + Gtk2::VBox->new, TRUE, TRUE, 5 + ); + $pb = Gtk2::ProgressBar->new; $box->pack_start( $infobar, FALSE, FALSE, 0 ); $box->pack_start( $pb, FALSE, FALSE, 0 ); @@ -137,180 +129,6 @@ sub show_window { return $box; } -sub update_store { - my $web_version = get_web_info(); - my ( $remote_tk_version ) = get_remote_TK_version(); - - # Reset the liststore - $liststore->clear; - - # Get local information - my $local_sig_version ||= ClamTk::App->get_local_sig_version(); - my $local_tk_version ||= ClamTk::App->get_TK_version(); - - # Keep track if we have updates available - my @updates; - - my $sig_update_available = 'gtk-dialog-error'; - # Ensure we have info for both - if ( $web_version && $web_version ne _( 'Unknown' ) ) { - # The only thing we have to check is if - # the web version is more - then update is available - if ( $web_version > $local_sig_version ) { - $sig_update_available = 'gtk-yes'; - push( @updates, 'sigs' ); - } else { - # Everything else is 'gtk-no'. I think. - $sig_update_available = 'gtk-no'; - } - } else { - $web_version = _( 'Unknown' ); - } - - my $gui_update_available = 'gtk-dialog-error'; - # We assume we can easily get the local version - if ( $remote_tk_version ) { - my ( $local_chopped, $remote_chopped ); - ( $local_chopped = $local_tk_version ) =~ s/[^0-9]//; - ( $remote_chopped = $remote_tk_version ) =~ s/[^0-9]//; - # The only thing we have to check is if - # the web version is more - then update is available - if ( $remote_chopped > $local_chopped ) { - $gui_update_available = 'gtk-yes'; - push( @updates, 'gui' ); - } else { - # Everything else is 'gtk-no'. I think. - $gui_update_available = 'gtk-no'; - } - } else { - # warn "unknown tk status\n"; - $remote_tk_version = _( 'Unknown' ); - } - - #<<< - my @data = ( - { - product => _( 'Antivirus signatures' ), - local => $local_sig_version, - remote => $web_version, - update => $sig_update_available, - }, - { - product => _( 'Graphical interface' ), - local => $local_tk_version, - remote => $remote_tk_version, - update => $gui_update_available, - }, - ); - - for my $item ( @data ) { - my $iter = $liststore->append; - $liststore->set( $iter, - 0, $item->{ product }, - 1, $item->{ local }, - 2, $item->{ remote }, - 3, $item->{ update }, - ); - } - #>>> - - # Can we update? shared or single - my $update_pref = ''; - # Return value to see if updates were applied. - # If so, refresh the store - my $updated = 0; - if ( @updates ) { - my $text = _( 'Updates are available' ); - if ( ClamTk::Prefs->get_preference( 'Update' ) eq 'shared' ) { - $text .= "\n"; - #<<< - $text - .= _( 'You are configured to automatically receive updates' ); - #>>> - $update_pref = 'shared'; - } else { - $update_pref = 'single'; - } - - set_infobar_text( 'warning', $text ); - - # We only show the update button if the update preference - # is "single" (user updates manually) or the user is root. - # Also, as Google Issue #4 showed, !only! when - # there is a sigs update and not when only a GUI update. - if ( @updates && grep ( /sigs/, @updates ) ) { - if ( $update_pref eq 'single' or $> == 0 ) { - #set_infobar_button( 'gtk-apply', -5 ); - destroy_button(); - my $button = Gtk2::Button->new( _( 'Update' ) ); - $infobar->get_action_area->add( $button ); - $button->show; - $button->signal_connect( - clicked => sub { - Gtk2->main_iteration while Gtk2->events_pending; - set_infobar_text( 'info', _( 'Please wait...' ) ); - Gtk2->main_iteration while Gtk2->events_pending; - $updated - = update_signatures( $local_sig_version, - $web_version ); - # Now we returned from updating signatures... - # clear rows (liststore) and display updated info - if ( $updated ) { - $liststore->clear; - # Wonder if this is bad? Too recursive? - update_store(); - Gtk2->main_iteration while Gtk2->events_pending; - ClamTk::GUI->startup(); - Gtk2->main_iteration while Gtk2->events_pending; - } else { - set_infobar_text( 'error', - _( 'Error updating: try again later' ) ); - destroy_button(); - } - } - ); - } else { - # Remove buttons if they exist, since this - # user cannot update signatures - # warn "removing button, cannot update\n"; - destroy_button(); - } - } else { - # warn "no updates available\n"; - #set_infobar_text( 'info', _( 'No updates are available.' ) ); - destroy_button(); - } - } -} - -sub get_web_info { - # Get clamav.net info - # my $page = 'http://www.clamav.net/lang/en/'; - my $page = 'http://lurker.clamav.net/list/clamav-virusdb.html'; - - my $ua = add_ua_proxy(); - - Gtk2->main_iteration while Gtk2->events_pending; - my $response = $ua->get( $page ); - Gtk2->main_iteration while Gtk2->events_pending; - my $code = ''; - - if ( $response->is_success ) { - $code = $response->decoded_content; - } else { - warn "problems getting ClamAV version: ", $response->status_line, - "\n"; - return FALSE; - } - return FALSE if ( !$code ); - - if ( $code =~ /daily: (\d{5,})/ ) { - return $1; - } else { - return FALSE; - } -} - sub get_remote_TK_version { my $url = 'https://bitbucket.org/dave_theunsub/clamtk/raw/master/latest'; # my $url = 'http://clamtk.googlecode.com/git/latest'; @@ -335,13 +153,11 @@ sub get_remote_TK_version { } sub update_signatures { - my ( $local_version, $web_version ) = @_; + $pb->{ timer } = Glib::Timeout->add( 100, \&progress_timeout, $pb ); $pb->show; #$pb->set_show_text( TRUE ); - $pb->set_text( _( 'Downloading...' ) ); - - my $step = 1 / ( $web_version - $local_version ); + $pb->set_text( _( 'Please wait...' ) ); my $freshclam = get_freshclam_path(); @@ -378,19 +194,19 @@ sub update_signatures { # and try to sum it up. while ( defined( my $line = <$update> ) ) { + $pb->set_text( _( 'Downloading...' ) ); Gtk2->main_iteration while Gtk2->events_pending; chomp( $line ); - if ( $line =~ /^Downloading daily/ ) { - Gtk2->main_iteration while Gtk2->events_pending; - my $fraction = $pb->get_fraction; - $fraction += $step; - if ( $fraction < 1.0 ) { - $pb->set_fraction( $fraction ); - } else { - $pb->set_fraction( 1.0 ); - } + if ( $line =~ /^Downloading daily-(\d+)/ ) { + my $new_daily = $1; Gtk2->main_iteration while Gtk2->events_pending; + + $liststore->set( $iter_hash, + 0, _( 'Antivirus signatures' ), + 1, $new_daily, + ); + } elsif ( $line =~ /Database updated/ ) { Gtk2->main_iteration while Gtk2->events_pending; $pb->set_fraction( 1.0 ); @@ -401,17 +217,25 @@ sub update_signatures { } Gtk2->main_iteration while Gtk2->events_pending; } - $updated++; + # Get local information. It would probably be okay to just + # keep the same number we saw during the update, but this + # gives the "for sure" sig version installed: + my $local_sig_version = ClamTk::App->get_local_sig_version(); + + $liststore->set( $iter_hash, + 0, _( 'Antivirus signatures' ), + 1, $local_sig_version, + ); + Glib::Source->remove( $pb->{ timer } ); $pb->set_fraction( 1.0 ); $pb->set_text( _( 'Complete' ) ); # Update infobar type and text; remove button - set_infobar_text( 'info', _( 'Signatures are current' ) ); - $pb->hide; - destroy_button(); - - # Update frontpage infobar - ClamTk::GUI->startup(); + Gtk2->main_iteration while Gtk2->events_pending; + set_infobar_text( 'info', _( '' ) ); + ClamTk::GUI::set_infobar_mode( 'info', '' ); + # $pb->hide; + # destroy_button(); return TRUE; } @@ -475,6 +299,14 @@ sub destroy_button { } } +sub progress_timeout { + Gtk2->main_iteration while Gtk2->events_pending; + $pb->pulse; + Gtk2->main_iteration while Gtk2->events_pending; + + return TRUE; +} + sub add_ua_proxy { my $agent = LWP::UserAgent->new( ssl_opts => { verify_hostname => 1 } ); $agent->timeout( 20 );