示例#1
0
文件: api.py 项目: sean-abbott/phatch
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:
        log_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
示例#2
0
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
示例#3
0
def apply_actions_to_photos(actions, settings, paths=None, drop=False,
        update=None):
    """Apply all the actions to the photos in path.

    :param actions: actions
    :type actions: list of :class:`core.models.Action`
    :param settings: process settings (writable, eg recursion, ...)
    :type settings: dictionary
    :param paths:

        paths where the images are located. If they are not specified,
        Phatch will ask them to the user.

    :type paths: list of strings
    :param drop:

        True in case files were dropped or phatch is started as a
        droplet.

    :type drop: bool
    """
    # Start log file
    init_error_log_file()

    # Check action list
    actions = check_actionlist(actions, settings)
    if not actions:
        return

    # Get paths (and update settings) -> show execute dialog
    paths = get_paths_and_settings(paths, settings, drop=drop)
    if not paths:
        return

    # retrieve all necessary variables in one time
    vars = set(pil.BASE_VARS).union(get_vars(actions))
    if settings['check_images_first']:
        # we need some extra vars for the list control
        vars = TREE_VARS.union(vars)
    vars_file, vars_not_file = metadata.InfoFile.split_vars(list(vars))
    info_file = metadata.InfoFile(vars=list(vars_file))

    # Check if all files exist
    # folderindex is set here in filter_image_infos
    image_infos = get_image_infos(paths, info_file,
        settings['extensions'], settings['recursive'])
    if not image_infos:
        return

    # Check if all the images are valid
    #  -> show invalid to user
    #  -> show valid to user in tree dialog (optional)
    if settings['check_images_first']:
        image_infos = verify_images(image_infos, settings['repeat'])
        if not image_infos:
            return

    # Initialize actions
    if not init_actions(actions):
        return

    # Retrieve settings
    skip_existing_images = not (settings['overwrite_existing_images'] or\
        settings['overwrite_existing_images_forced']) and\
        not settings['no_save']
    result = {
        'stop_for_errors': settings['stop_for_errors'],
        'last_answer': None,
    }

    # only keep static vars
    vars_not_file = pil.split_vars_static_dynamic(vars_not_file)[0]

    # create parent info instance
    #  -> will be used by different files with the open method
    info_not_file = metadata.InfoExtract(vars=vars_not_file)

    # Execute action list
    image_amount = len(image_infos)
    actions_amount = len(actions) + 1  # open image is extra action
    cache = {}
    is_done = actions[-1].is_done  # checking method for resuming
    read_only_settings = ReadOnlyDict(settings)

    # Start progress dialog
    repeat = settings['repeat']
    send.frame_show_progress(title=_("Executing action list"),
        parent_max=image_amount * repeat,
        child_max=actions_amount,
        message=PROGRESS_MESSAGE)
    report = []
    start = time.time()
    for image_index, image_info in enumerate(image_infos):
        statement = apply_actions_to_photo(actions, image_info, info_not_file,
            cache, read_only_settings, skip_existing_images, result, report,
            is_done, image_index, repeat)
        # reraise statement
        if statement == 'return':
            send.progress_close()
            return
        elif statement == 'break':
            break
        if update:
            update()
    send.progress_close()
    if update:
        update()

    # mention amount of photos and duration
    delta = time.time() - start
    duration = timedelta(seconds=int(delta))
    if image_amount == 1:
        message = _('One image done in %s') % duration
    else:
        message = _('%(amount)d images done in %(duration)s')\
            % {'amount': image_amount, 'duration': duration}
    # add error status
    if ERROR_LOG_COUNTER == 1:
        message += '\n' + _('One issue was logged')
    elif ERROR_LOG_COUNTER:
        message += '\n' + _('%d issues were logged')\
            % ERROR_LOG_COUNTER

    # show notification
    send.frame_show_notification(message, report=report)

    # show status dialog
    if ERROR_LOG_COUNTER == 0:
        if settings['always_show_status_dialog']:
            send.frame_show_status(message, log=False)
    else:
        message = '%s\n\n%s' % (message, SEE_LOG)
        send.frame_show_status(message)