def get_paths_and_settings(paths, settings, drop=False): """Ask the user for paths and settings. In the GUI this shows the execute dialog box. :param paths: initial value of the paths (eg to fill in dialog) :type paths: list of strings :param settings: settings :type settings: dictionary :param drop: True in case files were dropped or phatch is started as a droplet. :type drop: bool """ if drop or (paths is None): result = {} send.frame_show_execute_dialog(result, settings, paths) if result['cancel']: return paths = settings['paths'] if not paths: send.frame_show_error(_('No files or folder selected.')) return None return paths
def open_actionlist(filename): """Open the action list from a file. :param filename: the filename of the action list :type filename: string :returns: action list :rtype: dictionary """ #read source f = open(filename, 'rb') source = f.read() f.close() #load data data = safe.eval_safe(source) if not data.get('version', '').startswith('0.2'): send.frame_show_error(ERROR_INCOMPATIBLE_ACTIONLIST % ct.INFO) return None result = [] invalid_labels = [] actions = data['actions'] for action in actions: actionLabel = action['label'] actionFields = action['fields'] newAction = ACTIONS[actionLabel]() invalid_labels.extend(['- %s (%s)' % (label, actionLabel) for label in newAction.load(actionFields)]) result.append(newAction) warning = assert_safe(result) data['actions'] = result data['invalid labels'] = invalid_labels return data, warning
def get_image_infos(paths, info_file, extensions, recursive): """Get all image info dictionaries from a mix of folder and file paths. :param paths: file and/or folderpaths :type paths: list of strings :param extensions: extensions (without ``.``) :type extensions: list of strings :param recursive: include subfolders :type recursive: bool :returns: list of image file info :rtype: list of dictionaries .. see also:: :func:`get_image_infos_from_folder` """ image_infos = [] for path in paths: path = os.path.abspath(path.strip()) if os.path.isfile(path): #single image file info = {'folderindex': 0} info.update(info_file.dump(path)) image_infos.append(info) elif os.path.isdir(path): #folder of image files image_infos.extend(get_image_infos_from_folder( path, info_file, extensions, recursive)) else: #not a file or folder?! probably does not exist send.frame_show_error('Sorry, "%s" is not a valid path.' \ % ensure_unicode(path)) return [] image_infos.sort(key=operator.itemgetter('path')) return image_infos
def verify_images(image_infos, repeat): """Filter invalid images out. Verify if images are not corrupt. Show the invalid images to the user. If no valid images are found, show an error to the user. Otherwise show the valid images to the user. :param image_infos: list of image info dictionaries :type image_infos: list of dictionaries :returns: None for error, valid image info dictionaries otherwise """ #show dialog send.frame_show_progress(title=_("Checking images"), parent_max=len(image_infos), message=PROGRESS_MESSAGE) #verify files valid = [] invalid = [] for index, image_info in enumerate(image_infos): result = {} send.progress_update_filename(result, index, image_info['path']) if not result['keepgoing']: return openImage.verify_image(image_info, valid, invalid) send.progress_close() #show invalid files to the user if invalid: result = {} send.frame_show_files_message(result, message=_('Phatch can not handle %d image(s):') % len(invalid), title=ct.FRAME_TITLE % ('', _('Invalid images')), files=invalid) if result['cancel']: return #Display an error when no files are left if not valid: send.frame_show_error(_("Sorry, no valid files found")) return #number valid items for index, image_info in enumerate(valid): image_info['index'] = index * repeat #show valid images to the user in tree structure result = {} send.frame_show_image_tree(result, valid, widths=(200, 40, 200, 200, 200, 200, 60), headers=TREE_HEADERS, ok_label=_('C&ontinue'), buttons=True) if result['answer']: return valid
def init_actions(actions): """Initializes all actions. Shows an error to the user if an action fails to initialize. :param actions: actions :type actions: list of :class:`core.models.Action` :returns: False, if one action fails, True otherwise :rtype: bool """ for action in actions: try: action.init() except Exception, details: reason = exception_to_unicode(details) message = u'%s\n\n%s' % ( _("Can not apply action %(a)s:") \ % {'a': _(action.label)}, reason) send.frame_show_error(message) return False
def log_error(message, input='*', action=None, show=True, exception=False): """Writer error message to log file. Helper function for :func:`flush_log`, :func:`process_error`. :param message: error message :type message: string :param input: input image :type input: string :returns: error log details :rtype: string """ global ERROR_LOG_COUNTER if ERROR_LOG_COUNTER == None: # doctests return if action: action = pprint.pformat(action.dump()) if exception: traceback_details = ensure_unicode(traceback.format_exc()) else: traceback_details = '' message = ensure_unicode(message) details = ensure_unicode( ERROR_MESSAGE % { 'number': ERROR_LOG_COUNTER + 1, 'message': message, 'input': input, 'action': action, 'details': traceback_details, }) logging.error( unicode(details.encode(ENCODING, 'replace'), ENCODING, 'replace')) ERROR_LOG_COUNTER += 1 if show: # keep this for last as in console mode phatch quits on an error send.frame_show_error(message) return details
def check_actionlist(actions, settings): """Verifies action list before executing. It checks whether: * the action list is not empty * all actions are not disabled * if there is a save action at the end or only file actions * overwriting images is forced :param actions: actions of the action list :type actions: list of :class:`core.models.Action` :param settings: execution settings :type settings: dictionary >>> settings = {'no_save':False} >>> check_actionlist([], settings) is None True >>> from actions import canvas, save >>> canvas_action = canvas.Action() >>> save_action = save.Action() >>> check_actionlist([canvas_action,save_action], ... {'no_save':False}) is None False >>> check_actionlist([canvas_action], settings) is None True >>> settings = {'no_save':True} >>> check_actionlist([canvas_action], settings) is None False >>> settings['overwrite_existing_images_forced'] False .. see also:: :func:`check_actionlist_file_only` """ #Check if there is something to do if actions == []: send.frame_show_error('%s %s' % (_('Nothing to do.'), _('The action list is empty.'))) return None #Check if the actionlist is safe if formField.get_safe(): warnings = assert_safe(actions) if warnings: send.frame_show_error('%s\n\n%s\n%s' % ( ERROR_UNSAFE_ACTIONLIST_INTRO, warnings, ERROR_UNSAFE_ACTIONLIST_DISABLE_SAFE)) return None #Skip disabled actions actions = [action for action in actions if action.is_enabled()] if actions == []: send.frame_show_error('%s %s' % (_('Nothing to do.'), _('There is no action enabled.'))) return None #Check if there is a save statement last_action = actions[-1] if not (last_action.valid_last or check_actionlist_file_only(actions)\ or settings['no_save']): send.frame_append_save_action(actions) return None #Check if overwrite is forced settings['overwrite_existing_images_forced'] = \ (not settings['no_save']) and \ actions[-1].is_overwrite_existing_images_forced() return actions