diff options
Diffstat (limited to 'rapid/problemnotification.py')
-rwxr-xr-x | rapid/problemnotification.py | 186 |
1 files changed, 106 insertions, 80 deletions
diff --git a/rapid/problemnotification.py b/rapid/problemnotification.py index ee0be5d..5982a6d 100755 --- a/rapid/problemnotification.py +++ b/rapid/problemnotification.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -*- coding: latin1 -*- -### Copyright (C) 2010-2012 Damon Lynch <damonlynch@gmail.com> +### Copyright (C) 2010-2014 Damon Lynch <damonlynch@gmail.com> ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by @@ -27,37 +27,38 @@ from gettext import gettext as _ SUBFOLDER_COMPONENT = _('subfolder') FILENAME_COMPONENT = _('filename') -# problem categories -METADATA_PROBLEM = 1 +# problem categories +METADATA_PROBLEM = 1 FILE_PROBLEM = 2 -GENERATION_PROBLEM = 3 -DOWNLOAD_PROBLEM = 4 -DOWNLOAD_PROBLEM_W_NO = 5 -DIFFERENT_EXIF = 6 -FILE_ALREADY_EXISTS = 7 -UNIQUE_IDENTIFIER_CAT = 8 +GENERATION_PROBLEM = 3 +DOWNLOAD_PROBLEM = 4 +DOWNLOAD_PROBLEM_W_NO = 5 +DIFFERENT_EXIF = 6 +FILE_ALREADY_EXISTS = 7 +UNIQUE_IDENTIFIER_CAT = 8 BACKUP_PROBLEM = 9 BACKUP_OK = 10 FILE_ALREADY_DOWN_CAT = 11 +VERIFICATION_PROBLEM = 12 # problem text -MISSING_METADATA = 1 -INVALID_DATE_TIME = 2 -MISSING_FILE_EXTENSION = 3 -MISSING_IMAGE_NUMBER = 4 -ERROR_IN_GENERATION = 5 +MISSING_METADATA = 1 +INVALID_DATE_TIME = 2 +MISSING_FILE_EXTENSION = 3 +MISSING_IMAGE_NUMBER = 4 +ERROR_IN_GENERATION = 5 -CANNOT_DOWNLOAD_BAD_METADATA = 6 +CANNOT_DOWNLOAD_BAD_METADATA = 6 ERROR_IN_NAME_GENERATION = 7 -DOWNLOAD_COPYING_ERROR = 8 -DOWNLOAD_COPYING_ERROR_W_NO = 9 +DOWNLOAD_COPYING_ERROR = 8 +DOWNLOAD_COPYING_ERROR_W_NO = 9 -FILE_ALREADY_EXISTS_NO_DOWNLOAD = 10 -UNIQUE_IDENTIFIER_ADDED = 11 -BACKUP_EXISTS = 12 -BACKUP_EXISTS_OVERWRITTEN = 13 +FILE_ALREADY_EXISTS_NO_DOWNLOAD = 10 +UNIQUE_IDENTIFIER_ADDED = 11 +BACKUP_EXISTS = 12 +BACKUP_EXISTS_OVERWRITTEN = 13 NO_BACKUP_PERFORMED = 14 BACKUP_ERROR = 15 BACKUP_DIRECTORY_CREATION = 16 @@ -66,6 +67,9 @@ SAME_FILE_DIFFERENT_EXIF = 17 NO_DOWNLOAD_WAS_BACKED_UP = 18 FILE_ALREADY_DOWNLOADED = 19 +FILE_VERIFICATION_FAILED = 20 +BACKUP_VERIFICATION_FAILED = 21 + #extra details UNIQUE_IDENTIFIER = '__1' EXISTING_FILE = '__2' @@ -76,30 +80,33 @@ BACKUP_OK_TYPE = '__6' # category, text, duplicates allowed problem_definitions = { - + MISSING_METADATA: (METADATA_PROBLEM, "%s", True), INVALID_DATE_TIME: (METADATA_PROBLEM, _('Date time value %s appears invalid.'), False), MISSING_FILE_EXTENSION: (METADATA_PROBLEM, _("Filename does not have an extension."), False), # a number component is something like the 8346 in IMG_8346.JPG MISSING_IMAGE_NUMBER: (METADATA_PROBLEM, _("Filename does not have a number component."), False), ERROR_IN_GENERATION: (METADATA_PROBLEM, _("Error generating component %s."), False), # a generic problem - + CANNOT_DOWNLOAD_BAD_METADATA: (FILE_PROBLEM, _("%(filetype)s metadata cannot be read"), False), - + ERROR_IN_NAME_GENERATION: (GENERATION_PROBLEM, _("%(filetype)s %(area)s could not be generated"), False), - + DOWNLOAD_COPYING_ERROR: (DOWNLOAD_PROBLEM, _("An error occurred when copying the %(filetype)s"), False), DOWNLOAD_COPYING_ERROR_W_NO: (DOWNLOAD_PROBLEM_W_NO, _("An error occurred when copying the %(filetype)s"), False), - + + FILE_VERIFICATION_FAILED: (VERIFICATION_PROBLEM, _("The %(filetype)s did not download correctly"), False), + BACKUP_VERIFICATION_FAILED: (BACKUP_PROBLEM, "%s", True), + FILE_ALREADY_EXISTS_NO_DOWNLOAD:(FILE_ALREADY_EXISTS, _("%(filetype)s already exists"), False), UNIQUE_IDENTIFIER_ADDED: (UNIQUE_IDENTIFIER_CAT, _("%(filetype)s already exists"), False), - BACKUP_EXISTS: (BACKUP_PROBLEM, "%s", True), - BACKUP_EXISTS_OVERWRITTEN: (BACKUP_PROBLEM, "%s", True), + BACKUP_EXISTS: (BACKUP_PROBLEM, "%s", True), + BACKUP_EXISTS_OVERWRITTEN: (BACKUP_PROBLEM, "%s", True), NO_BACKUP_PERFORMED: (BACKUP_PROBLEM, _("%(filetype)s could not be backed up because no suitable backup locations were found."), False), BACKUP_ERROR: (BACKUP_PROBLEM, "%s", True), BACKUP_DIRECTORY_CREATION: (BACKUP_PROBLEM, "%s", True), NO_DOWNLOAD_WAS_BACKED_UP: (BACKUP_OK, "%s", True), - + SAME_FILE_DIFFERENT_EXIF: (DIFFERENT_EXIF, _("%(image1)s was taken on %(image1_date)s at %(image1_time)s, and %(image2)s on %(image2_date)s at %(image2_time)s."), False), FILE_ALREADY_DOWNLOADED: (FILE_ALREADY_DOWN_CAT, _('%(filetype)s was already downloaded'), False), } @@ -116,23 +123,23 @@ extra_detail_definitions = { class Problem: """ Collect problems with subfolder and filename generation, download errors, and so forth - + Problems are human readable """ - + def __init__(self): self.problems = {} self.categories = {} self.components = [] self.extra_detail = {} - + def add_problem(self, component, problem_definition, *args): added = True if problem_definition not in problem_definitions: sys.stderr.write("FIXME: unknown problem definition!\n") else: category, problem, duplicates_ok = problem_definitions[problem_definition] - + if args: # check for special case of named arguments in a dictionary if isinstance(args[0], types.DictType): @@ -152,12 +159,12 @@ class Problem: added = False else: self.problems[problem_definition] = [problem_details] - + if category not in self.categories or not added: self.categories[category] = 1 else: self.categories[category] += 1 - + if (component is not None) and (component not in self.components): self.components.append(component) @@ -166,7 +173,7 @@ class Problem: self.extra_detail[extra_detail] = args[0] else: detail = extra_detail_definitions[extra_detail] - + if args: if isinstance(args[0], types.DictType): extra_details = detail % args[0] @@ -174,33 +181,37 @@ class Problem: extra_details = detail % args else: extra_details = detail - + self.extra_detail[extra_detail] = extra_details - - + + def has_problem(self): return len(self.problems) > 0 - + def get_problems(self): """ Returns a string with the problems encountered in downloading the file. """ - + def get_backup_error_inst(volume): if ('%s%s' % (BACKUP_ERROR, volume)) in self.extra_detail: return self.extra_detail['%s%s' % (BACKUP_ERROR, volume)] else: return '' - + def get_dir_creation_inst(volume): return self.extra_detail['%s%s' % (BACKUP_DIRECTORY_CREATION, volume)] - + v = '' - + # special cases + + if VERIFICATION_PROBLEM in self.categories: + return _("File verification failed. The downloaded version is different from the original.") + if FILE_PROBLEM in self.categories: return _("The metadata might be corrupt.") - + if FILE_ALREADY_DOWN_CAT in self.categories: return _("The filename, extension and Exif information indicate it has already been downloaded.") @@ -208,16 +219,16 @@ class Problem: if EXISTING_FILE in self.extra_detail: v = self.extra_detail[EXISTING_FILE] - + if UNIQUE_IDENTIFIER_CAT in self.categories: v = self.extra_detail[UNIQUE_IDENTIFIER] - + if DOWNLOAD_PROBLEM in self.categories: v = self.extra_detail[DOWNLOAD_COPYING_ERROR_DETAIL] - + if DOWNLOAD_PROBLEM_W_NO in self.categories: v = self.extra_detail[DOWNLOAD_COPYING_ERROR_W_NO_DETAIL] - + if BACKUP_OK in self.categories: details = self.problems[NO_DOWNLOAD_WAS_BACKED_UP] if len(self.problems[NO_DOWNLOAD_WAS_BACKED_UP]) == 1: @@ -227,30 +238,30 @@ class Problem: for d in details[:-1]: vv += _("%s, ") % d vv = _("%(volumes)s and %(final_volume)s.") % \ - {'volumes': vv[:-2], + {'volumes': vv[:-2], 'final_volume': details[-1]} \ + ' ' v += vv if GENERATION_PROBLEM in self.categories: v = self.extra_detail[NO_DATA_TO_NAME] - + if DIFFERENT_EXIF in self.categories: - v = self.problems[SAME_FILE_DIFFERENT_EXIF][0] + v = self.problems[SAME_FILE_DIFFERENT_EXIF][0] if METADATA_PROBLEM in self.categories: v = _('Photos detected with the same filenames, but taken at different times: %(details)s' ) % {'details':v} - + # Problems backing up if BACKUP_PROBLEM in self.categories: vv = '' for p in self.problems: details = self.problems[p] - + if p == NO_BACKUP_PERFORMED: vv = details[0] elif p == BACKUP_ERROR: - + if len(details) == 1: volume = details[0] inst = get_backup_error_inst(volume) @@ -270,16 +281,16 @@ class Problem: inst = get_backup_error_inst(volume) if inst: vv = _("%(volumes)s and %(volume)s (%(inst)s).") % \ - {'volumes': vv[:-2], + {'volumes': vv[:-2], 'volume': volume, 'inst': get_inst(volume)} else: vv = _("%(volumes)s and %(volume)s.") % \ - {'volumes': vv[:-2], + {'volumes': vv[:-2], 'volume': volume} \ + ' ' - - + + elif p == BACKUP_EXISTS: if len(details) == 1: vv += _("Backup already exists on %(volume)s.") % {'volume': details[0]} + ' ' @@ -288,10 +299,10 @@ class Problem: for d in details[:-1]: vv += _("%s, ") % d vv = _("%(volumes)s and %(final_volume)s.") % \ - {'volumes': vv[:-2], + {'volumes': vv[:-2], 'final_volume': details[-1]} \ + ' ' - + elif p == BACKUP_EXISTS_OVERWRITTEN: if len(details) == 1: vv += _("Backup overwritten on %(volume)s.") % {'volume': details[0]} + ' ' @@ -300,10 +311,10 @@ class Problem: for d in details[:-1]: vv += _("%s, ") % d vv = _("%(volumes)s and %(final_volume)s.") % \ - {'volumes': vv[:-2], + {'volumes': vv[:-2], 'final_volume': details[-1]} \ + ' ' - + elif p == BACKUP_DIRECTORY_CREATION: if len(details) == 1: volume = details[0] @@ -314,24 +325,37 @@ class Problem: vv += _("%(volume)s (%(inst)s), ") % {'volume': volume, 'inst': get_dir_creation_inst(volume)} volume = details[-1] vv = _("%(volumes)s and %(volume)s (%(inst)s).") % \ - {'volumes': vv[:-2], + {'volumes': vv[:-2], 'volume': volume, 'inst': get_dir_creation_inst(volume)} \ + ' ' + elif p == BACKUP_VERIFICATION_FAILED: + if len(details) == 1: + vv += _("File verification failed on %(volume)s. The backed up version is different from the downloaded version.") % {'volume': details[0]} + ' ' + else: + vv += _("File verification failed on these devices: ") + for d in details[:-1]: + vv += _("%s, ") % d + vv = _("%(volumes)s and %(final_volume)s.") % \ + {'volumes': vv[:-2], + 'final_volume': details[-1]} \ + + ' ' + + if v: v = _('%(previousproblem)s Additionally, %(newproblem)s') % {'previousproblem': v, 'newproblem': vv[0].lower() + vv[1:]} else: - v = vv + v = vv + - if v and METADATA_PROBLEM in self.categories: vv = self._get_generation_title() if self.categories[METADATA_PROBLEM] > 1: v += _(' Furthermore, there were %(problems)s.') % {'problems': vv[0].lower() + vv[1:]} else: v += _(' Furthermore, there was a %(problem)s.') % {'problem': vv[0].lower() + vv[1:]} - + # Problems generating file / subfolder names if METADATA_PROBLEM in self.categories: for p in self.problems: @@ -345,18 +369,18 @@ class Problem: for d in details[:-1]: vv += ("%s, ") % d vv = _("%(missing_metadata_elements)s and %(final_missing_metadata_element)s.") % \ - {'missing_metadata_elements': vv[:-2], + {'missing_metadata_elements': vv[:-2], 'final_missing_metadata_element': details[-1]} - - + + elif p in [MISSING_IMAGE_NUMBER, ERROR_IN_GENERATION, INVALID_DATE_TIME]: vv = details[0] v += ' ' + vv - + v = v.strip() return v - + def _get_generation_title(self): if self.components: if len(self.components) > 1: @@ -374,14 +398,16 @@ class Problem: def get_title(self): v = '' - + if BACKUP_OK in self.categories: if FILE_ALREADY_EXISTS in self.categories: v = _('%(filetype)s already exists, but it was backed up') % {'filetype': self.extra_detail[BACKUP_OK_TYPE]} else: v = _('An error occurred when copying the %(filetype)s, but it was backed up') % {'filetype': self.extra_detail[BACKUP_OK_TYPE]} - + # High priority problems + elif VERIFICATION_PROBLEM in self.categories: + v = self.problems[FILE_VERIFICATION_FAILED][0] elif FILE_ALREADY_DOWN_CAT in self.categories: v = self.problems[FILE_ALREADY_DOWNLOADED][0] elif DOWNLOAD_PROBLEM in self.categories: @@ -389,14 +415,14 @@ class Problem: elif DOWNLOAD_PROBLEM_W_NO in self.categories: v = self.problems[DOWNLOAD_COPYING_ERROR_W_NO][0] elif GENERATION_PROBLEM in self.categories: - v = self.problems[ERROR_IN_NAME_GENERATION][0] + v = self.problems[ERROR_IN_NAME_GENERATION][0] elif FILE_ALREADY_EXISTS in self.categories: v = self.problems[FILE_ALREADY_EXISTS_NO_DOWNLOAD][0] elif UNIQUE_IDENTIFIER_CAT in self.categories: v = self.problems[UNIQUE_IDENTIFIER_ADDED][0] elif FILE_PROBLEM in self.categories: v = self.problems[CANNOT_DOWNLOAD_BAD_METADATA][0] - + # Lesser priority elif len(self.categories) > 1: v = _('Multiple problems were encountered') @@ -404,7 +430,7 @@ class Problem: v = _('Photos detected with the same filenames, but taken at different times') elif METADATA_PROBLEM in self.categories: v = self._get_generation_title() - + if BACKUP_PROBLEM in self.categories: if self.categories[BACKUP_PROBLEM] >1: vp = _("there were errors backing up") @@ -413,13 +439,13 @@ class Problem: vp = _("there was an error backing up") vv = _("There was an error backing up") if v: - # e.g. + # e.g. v = _("%(previousproblem)s, and %(backinguperror)s") % {'previousproblem': v, 'backinguperror':vp} else: v = vv - + return v - + if __name__ == '__main__': |