diff options
Diffstat (limited to 'rapid')
-rw-r--r-- | rapid/ChangeLog | 23 | ||||
-rw-r--r-- | rapid/config.py | 2 | ||||
-rw-r--r-- | rapid/downloadtracker.py | 30 | ||||
-rw-r--r-- | rapid/errorlog.py | 1 | ||||
-rw-r--r-- | rapid/glade3/rapid.ui | 8 | ||||
-rw-r--r-- | rapid/preferencesdialog.py | 1 | ||||
-rwxr-xr-x | rapid/rapid.py | 48 |
7 files changed, 96 insertions, 17 deletions
diff --git a/rapid/ChangeLog b/rapid/ChangeLog index 944119d..8fce376 100644 --- a/rapid/ChangeLog +++ b/rapid/ChangeLog @@ -1,3 +1,22 @@ +Version 0.4.0 +------------- + +2011-04-28 + +Features added since Release Candiate 1: + +* Allow multiple selection of files to check or uncheck for downloading. +* Automation feature to delete downloaded files from a device. + +Bug fix: translation fixes. + +Bug fix: don't crash when completing download with backups enabled and no backup +devices detected. + +Updated Dutch, French, German, Polish, Russian, Serbian and Spanish +translations. + + Version 0.4.0 RC 1 ------------------ @@ -16,8 +35,8 @@ will rendered during the download itself. Added preferences option to disable thumbnail generation. When auto start is enabled, this can speed-up transfers when downloading from high-speed devices. -Access to the preferences window is now disable while a download is occurring, -as changing preferences when files are being download can cause prolems. +Access to the preferences window is now disabled while a download is occurring, +as changing preferences when files are being download can cause problems. Bug fix: don't crash when downloading some files after having previously downloaded some others in the same session. diff --git a/rapid/config.py b/rapid/config.py index 6019d6a..86a268a 100644 --- a/rapid/config.py +++ b/rapid/config.py @@ -15,7 +15,7 @@ ### along with this program; if not, write to the Free Software ### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -version = '0.4.0~rc1' +version = '0.4.0' GCONF_KEY="/apps/rapid-photo-downloader" diff --git a/rapid/downloadtracker.py b/rapid/downloadtracker.py index 75c9c9d..824a812 100644 --- a/rapid/downloadtracker.py +++ b/rapid/downloadtracker.py @@ -18,6 +18,11 @@ ### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import time + +import multiprocessing +import logging +logger = multiprocessing.get_logger() + from rpdfile import FILE_TYPE_PHOTO, FILE_TYPE_VIDEO from config import STATUS_DOWNLOAD_FAILED, STATUS_DOWNLOADED_WITH_WARNING, \ STATUS_DOWNLOAD_AND_BACKUP_FAILED, STATUS_BACKUP_PROBLEM @@ -59,6 +64,7 @@ class DownloadTracker: self.total_warnings = 0 self.total_bytes_to_download = 0 self.backups_performed_by_unique_id = dict() + self.auto_delete = dict() def set_no_backup_devices(self, no_backup_devices): self.no_backup_devices = no_backup_devices @@ -95,14 +101,31 @@ class DownloadTracker: def get_no_warnings(self, scan_pid): return self.warnings.get(scan_pid, 0) + + def add_to_auto_delete(self, rpd_file): + if rpd_file.scan_pid in self.auto_delete: + self.auto_delete[rpd_file.scan_pid].append(rpd_file.full_file_name) + else: + self.auto_delete[rpd_file.scan_pid] = [rpd_file.full_file_name,] + + def get_files_to_auto_delete(self, scan_pid): + return self.auto_delete[scan_pid] + + def clear_auto_delete(self, scan_pid): + if scan_pid in self.auto_delete: + del self.auto_delete[scan_pid] def file_backed_up(self, unique_id): self.backups_performed_by_unique_id[unique_id] = \ self.backups_performed_by_unique_id.get(unique_id, 0) + 1 def all_files_backed_up(self, unique_id): - v = self.backups_performed_by_unique_id[unique_id] == self.no_backup_devices - return v + if unique_id in self.backups_performed_by_unique_id: + return self.backups_performed_by_unique_id[unique_id] == self.no_backup_devices + else: + logger.critical("Unexpected unique_id in self.backups_performed_by_unique_id") + return True + def file_downloaded_increment(self, scan_pid, file_type, status): self.files_downloaded[scan_pid] += 1 @@ -125,8 +148,7 @@ class DownloadTracker: else: self.video_failures[scan_pid] += 1 self.total_video_failures += 1 - - + def get_percent_complete(self, scan_pid): """ Returns a float representing how much of the download diff --git a/rapid/errorlog.py b/rapid/errorlog.py index 0334465..9b35a52 100644 --- a/rapid/errorlog.py +++ b/rapid/errorlog.py @@ -34,6 +34,7 @@ class ErrorLog(): """ self.builder = gtk.Builder() + self.builder.set_translation_domain(config.APP_NAME) self.builder.add_from_file(paths.share_dir("glade3/errorlog.ui")) self.builder.connect_signals(self) self.widget = self.builder.get_object("errorlog") diff --git a/rapid/glade3/rapid.ui b/rapid/glade3/rapid.ui index bd9638e..1e49e4e 100644 --- a/rapid/glade3/rapid.ui +++ b/rapid/glade3/rapid.ui @@ -24,7 +24,7 @@ <signal name="activate" handler="on_donate_action_activate" swapped="no"/> </object> <object class="GtkAction" id="download_action"> - <property name="label">Download</property> + <property name="label" translatable="yes">Download</property> <property name="icon_name">system-run</property> <property name="sensitive">False</property> <signal name="activate" handler="on_download_action_activate" swapped="no"/> @@ -35,7 +35,7 @@ <signal name="activate" handler="on_get_help_action_activate" swapped="no"/> </object> <object class="GtkAction" id="help_action"> - <property name="label">Help</property> + <property name="label" translatable="yes">Help</property> <signal name="activate" handler="on_help_action_activate" swapped="no"/> </object> <object class="GtkAction" id="next_image_action"> @@ -46,7 +46,7 @@ <signal name="activate" handler="on_next_image_action_activate" swapped="no"/> </object> <object class="GtkAction" id="preferences_action"> - <property name="label">Preferences</property> + <property name="label" translatable="yes">Preferences</property> <signal name="activate" handler="on_preferences_action_activate" swapped="no"/> </object> <object class="GtkAction" id="prev_image_action"> @@ -253,8 +253,8 @@ <property name="use_action_appearance">False</property> <property name="use_underline">True</property> <property name="use_stock">True</property> - <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/> <accelerator key="equal" signal="activate" modifiers="GDK_CONTROL_MASK"/> + <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/> </object> </child> <child> diff --git a/rapid/preferencesdialog.py b/rapid/preferencesdialog.py index 368b064..7289d0e 100644 --- a/rapid/preferencesdialog.py +++ b/rapid/preferencesdialog.py @@ -800,6 +800,7 @@ class PreferencesDialog(): def __init__(self, rapidapp): self.builder = gtk.Builder() + self.builder.set_translation_domain(config.APP_NAME) self.builder.add_from_file(paths.share_dir("glade3/prefs.ui")) self.builder.connect_signals(self) diff --git a/rapid/rapid.py b/rapid/rapid.py index 335db34..17d8335 100755 --- a/rapid/rapid.py +++ b/rapid/rapid.py @@ -83,7 +83,7 @@ import gettext gettext.bindtextdomain(config.APP_NAME) gettext.textdomain(config.APP_NAME) -from gettext import gettext as _ +_ = gettext.gettext from utilities import format_size_for_user @@ -454,7 +454,11 @@ class ThumbnailDisplay(gtk.IconView): self.set_spacing(0) self.set_row_spacing(5) self.set_margin(25) - + + self.set_selection_mode(gtk.SELECTION_MULTIPLE) + self.connect('selection-changed', self.on_selection_changed) + self._selected_items = [] + self.rapid_app = parent_app self.batch_size = 10 @@ -591,12 +595,25 @@ class ThumbnailDisplay(gtk.IconView): def sort_by_timestamp(self): self.liststore.set_sort_column_id(self.TIMESTAMP_COL, gtk.SORT_ASCENDING) + + def on_selection_changed(self, iconview): + self._selected_items = self.get_selected_items() def on_checkbutton_toggled(self, cellrenderertoggle, path): - iter = self.liststore.get_iter(path) - self.liststore.set_value(iter, self.SELECTED_COL, not cellrenderertoggle.get_active()) + paths = [p[0] for p in self._selected_items] + if int(path) not in paths: + self._selected_items = [path,] + + for path in self._selected_items: + iter = self.liststore.get_iter(path) + status = self.liststore.get_value(iter, self.DOWNLOAD_STATUS_COL) + if status == STATUS_NOT_DOWNLOADED: + self.liststore.set_value(iter, self.SELECTED_COL, not cellrenderertoggle.get_active()) + self.select_path(path) + self.rapid_app.set_download_action_sensitivity() + def set_selected(self, unique_id, value): iter = self.get_iter_from_unique_id(unique_id) self.liststore.set_value(iter, self.SELECTED_COL, value) @@ -2294,6 +2311,10 @@ class RapidApp(dbus.service.Object): if not succeeded: self.log_error(config.SERIOUS_ERROR, rpd_file.error_title, rpd_file.error_msg, rpd_file.error_extra_detail) + elif self.prefs.auto_delete: + # record which files to automatically delete when download + # completes + self.download_tracker.add_to_auto_delete(rpd_file) self.thumbnails.update_status_post_download(rpd_file) self.download_tracker.file_downloaded_increment(scan_pid, @@ -2309,6 +2330,10 @@ class RapidApp(dbus.service.Object): # Last file for this scan pid has been downloaded, so clean temp directory logger.debug("Purging temp directories") self._clean_temp_dirs_for_scan_pid(scan_pid) + if self.prefs.auto_delete: + logger.debug("Auto deleting files") + self.auto_delete(scan_pid) + self.download_tracker.clear_auto_delete(scan_pid) self.download_active_by_scan_pid.remove(scan_pid) self.time_remaining.remove(scan_pid) self.notify_downloaded_from_device(scan_pid) @@ -2371,6 +2396,16 @@ class RapidApp(dbus.service.Object): self.rapid_statusbar.pop(self.statusbar_context_id) self.rapid_statusbar.push(self.statusbar_context_id, message) + def auto_delete(self, scan_pid): + """Delete files from download device at completion of download""" + for file in self.download_tracker.get_files_to_auto_delete(scan_pid): + f = gio.File(file) + try: + f.delete(cancellable=None) + except gio.Error, inst: + logger.error("Failure deleting file %s", file) + logger.error(inst) + def file_types_by_number(self, no_photos, no_videos): """ returns a string to be displayed to the user that can be used @@ -2497,7 +2532,7 @@ class RapidApp(dbus.service.Object): files_to_download = self.download_tracker.get_no_files_in_download(scan_pid) file_types = self.download_tracker.get_file_types_present(scan_pid) completed = files_downloaded == files_to_download - if completed and self.prefs.backup_images: + if completed and (self.prefs.backup_images and len(self.backup_devices)): completed = self.download_tracker.all_files_backed_up(unique_id) if completed: @@ -2730,6 +2765,7 @@ class RapidApp(dbus.service.Object): Initialize widgets in the main window, and variables that point to them """ builder = gtk.Builder() + builder.set_translation_domain(config.APP_NAME) self.builder = builder builder.add_from_file(paths.share_dir("glade3/rapid.ui")) self.rapidapp = builder.get_object("rapidapp") @@ -2952,7 +2988,7 @@ class RapidApp(dbus.service.Object): #Used to differentiate between two different file systems #e.g. Free space: 21.3GB (photos); 14.7GB (videos). msg += _("; ") - else: + elif not self.prefs.backup_images: #Inserted at the end of the statusbar message concerning the amount of freespace #Used to differentiate between two different file systems #e.g. Free space: 21.3GB (photos); 14.7GB (videos). |