Beispiel #1
0
def test_get_class_by_file_invalid_type():
    media = Media.get_class_by_file(None, [Photo, Video, Audio])
    assert media is None

    media = Media.get_class_by_file(False, [Photo, Video, Audio])
    assert media is None

    media = Media.get_class_by_file(True, [Photo, Video, Audio])
    assert media is None
Beispiel #2
0
def test_get_class_by_file_invalid_type():
    media = Media.get_class_by_file(None,
                                    [Photo, Video, Audio])
    assert media is None

    media = Media.get_class_by_file(False,
                                    [Photo, Video, Audio])
    assert media is None

    media = Media.get_class_by_file(True,
                                    [Photo, Video, Audio])
    assert media is None
Beispiel #3
0
def import_file(_file, destination, album_from_folder, trash, allow_duplicates):
    """Set file metadata and move it to destination.
    """
    if not os.path.exists(_file):
        log.warn('Could not find %s' % _file)
        print('{"source":"%s", "error_msg":"Could not find %s"}' % \
            (_file, _file))
        return
    # Check if the source, _file, is a child folder within destination
    elif destination.startswith(os.path.dirname(_file)):
        print('{"source": "%s", "destination": "%s", "error_msg": "Source cannot be in destination"}' % (_file, destination))
        return


    media = Media.get_class_by_file(_file, [Text, Audio, Photo, Video])
    if not media:
        log.warn('Not a supported file (%s)' % _file)
        print('{"source":"%s", "error_msg":"Not a supported file"}' % _file)
        return

    if album_from_folder:
        media.set_album_from_folder()

    dest_path = FILESYSTEM.process_file(_file, destination,
        media, allowDuplicate=allow_duplicates, move=False)
    if dest_path:
        print('%s -> %s' % (_file, dest_path))
    if trash:
        send2trash(_file)

    return dest_path or None
Beispiel #4
0
def test_set_original_name():
    files = ['plain.jpg', 'audio.m4a', 'photo.nef', 'video.mov']

    for file in files:
        ext = os.path.splitext(file)[1]

        temporary_folder, folder = helper.create_working_folder()

        random_file_name = '%s%s' % (helper.random_string(10), ext)
        origin = '%s/%s' % (folder, random_file_name)
        file_path = helper.get_file(file)
        if file_path is False:
            file_path = helper.download_file(file, folder)

        shutil.copyfile(file_path, origin)

        media = Media.get_class_by_file(origin, [Audio, Media, Photo, Video])
        metadata = media.get_metadata()
        media.set_original_name()
        metadata_updated = media.get_metadata()

        shutil.rmtree(folder)

        assert metadata['original_name'] is None, metadata['original_name']
        assert metadata_updated['original_name'] == random_file_name, metadata_updated['original_name']
Beispiel #5
0
def import_file(_file, destination, album_from_folder, trash):
    """Set file metadata and move it to destination.
    """
    if not os.path.exists(_file):
        if constants.debug:
            print 'Could not find %s' % _file
        print '{"source":"%s", "error_msg":"Could not find %s"}' % \
            (_file, _file)
        return

    media = Media.get_class_by_file(_file, [Text, Audio, Photo, Video])
    if not media:
        if constants.debug:
            print 'Not a supported file (%s)' % _file
        print '{"source":"%s", "error_msg":"Not a supported file"}' % _file
        return

    if media.__name__ == 'Video':
        FILESYSTEM.set_date_from_path_video(media)

    if album_from_folder:
        media.set_album_from_folder()

    dest_path = FILESYSTEM.process_file(_file,
                                        destination,
                                        media,
                                        allowDuplicate=False,
                                        move=False)
    if dest_path:
        print '%s -> %s' % (_file, dest_path)
    if trash:
        send2trash(_file)
Beispiel #6
0
def import_file(_file, destination, album_from_folder, trash):
    """Set file metadata and move it to destination.
    """
    if not os.path.exists(_file):
        if constants.debug:
            print 'Could not find %s' % _file
        print '{"source":"%s", "error_msg":"Could not find %s"}' % \
            (_file, _file)
        return

    media = Media.get_class_by_file(_file, [Audio, Photo, Video])
    if not media:
        if constants.debug:
            print 'Not a supported file (%s)' % _file
        print '{"source":"%s", "error_msg":"Not a supported file"}' % _file
        return

    if media.__name__ == 'Video':
        FILESYSTEM.set_date_from_path_video(media)

    if album_from_folder:
        media.set_album_from_folder()

    dest_path = FILESYSTEM.process_file(_file, destination,
        media, allowDuplicate=False, move=False)
    if dest_path:
        print '%s -> %s' % (_file, dest_path)
    if trash:
        send2trash(_file)
Beispiel #7
0
def import_file(file_path,
                config,
                manifest,
                metadata_dict,
                move=False,
                allow_duplicates=False,
                dryrun=False):
    """Set file metadata and move it to destination.
    """
    if not os.path.exists(file_path):
        log.warn('Import_file: Could not find %s' % file_path)
        return

    target = config["targets"][0]
    target_base_path = target["base_path"]

    # Check if the source, _file, is a child folder within destination
    #   .... this is not the right time to be checking for that. Lots of unnecessary checks
    # elif destination.startswith(os.path.abspath(os.path.dirname(_file))+os.sep):
    #     print('{"source": "%s", "destination": "%s", "error_msg": "Source cannot be in destination"}' % (_file, destination))
    #     return

    # Creates an object of the right type, using the file extension ie .jpg -> photo
    media = Media.get_class_by_file(file_path, get_all_subclasses())
    if not media:
        log.warn('Not a supported file (%s)' % file_path)
        return

    # if album_from_folder:
    #     media.set_album_from_folder()

    checksum = manifest.checksum(file_path)
    is_duplicate = (checksum in manifest.entries)

    # Merge it into the manifest regardless of duplicate entries, to record all sources for a given file
    manifest_entry = FILESYSTEM.generate_manifest(file_path, target,
                                                  metadata_dict, media)
    manifest.merge({checksum: manifest_entry})

    if (not allow_duplicates) and is_duplicate:
        log.debug(
            "[ ] File {} already present in manifest; allow_duplicates is false; skipping"
            .format(file_path))
        return True

    if dryrun:
        log.info("Generated manifest: {}".format(file_path))
        return manifest_entry is not None
    else:
        result = FILESYSTEM.execute_manifest(file_path,
                                             manifest_entry,
                                             target_base_path,
                                             move_not_copy=move)
        # if dest_path:
        #     print('%s -> %s' % (_file, dest_path))
        # if trash:
        #     send2trash(_file)

        return result
Beispiel #8
0
def test_get_original_name():
    temporary_folder, folder = helper.create_working_folder()

    origin = '%s/%s' % (folder, 'with-original-name.jpg')
    file = helper.get_file('with-original-name.jpg')
    
    shutil.copyfile(file, origin)

    media = Media.get_class_by_file(origin, [Photo])
    original_name = media.get_original_name()

    assert original_name == 'originalfilename.jpg', original_name
Beispiel #9
0
def test_get_original_name_invalid_file():
    temporary_folder, folder = helper.create_working_folder()

    origin = '%s/%s' % (folder, 'invalid.jpg')
    file = helper.get_file('invalid.jpg')
    
    shutil.copyfile(file, origin)

    media = Media.get_class_by_file(origin, [Photo])
    original_name = media.get_original_name()

    assert original_name is None, original_name
Beispiel #10
0
def test_set_original_name_when_exists():
    temporary_folder, folder = helper.create_working_folder()

    origin = '%s/%s' % (folder, 'with-original-name.jpg')
    file = helper.get_file('with-original-name.jpg')
    
    shutil.copyfile(file, origin)

    media = Media.get_class_by_file(origin, [Photo])
    result = media.set_original_name()

    assert result is None, result
Beispiel #11
0
def add_original_name(source, subclasses):
    media = Media.get_class_by_file(source, subclasses)
    if media is None:
        print('{} is not a valid media object'.format(source))
        return

    metadata = media.get_metadata()
    if metadata['original_name'] is not None:
        print('{} already has OriginalFileName...Skipping'.format(source))
        return

    original_name = parse_original_name_from_media(metadata)
    return media.set_original_name(original_name)
Beispiel #12
0
def test_set_original_name_when_does_not_exist():
    temporary_folder, folder = helper.create_working_folder()

    origin = '%s/%s' % (folder, 'plain.jpg')
    file = helper.get_file('plain.jpg')
    
    shutil.copyfile(file, origin)

    media = Media.get_class_by_file(origin, [Photo])
    metadata_before = media.get_metadata()
    result = media.set_original_name()
    metadata_after = media.get_metadata()

    assert metadata_before['original_name'] is None, metadata_before
    assert metadata_after['original_name'] == 'plain.jpg', metadata_after
    assert result is True, result
Beispiel #13
0
def test_set_original_name_with_arg():
    temporary_folder, folder = helper.create_working_folder()

    origin = '%s/%s' % (folder, 'plain.jpg')
    file = helper.get_file('plain.jpg')
    
    shutil.copyfile(file, origin)

    new_name = helper.random_string(15)

    media = Media.get_class_by_file(origin, [Photo])
    metadata_before = media.get_metadata()
    result = media.set_original_name(new_name)
    metadata_after = media.get_metadata()

    assert metadata_before['original_name'] is None, metadata_before
    assert metadata_after['original_name'] == new_name, metadata_after
    assert result is True, result
Beispiel #14
0
def import_file(_file, destination, album_from_folder, trash,
                allow_duplicates):

    _file = _decode(_file)
    destination = _decode(destination)
    """Set file metadata and move it to destination.
    """
    if not os.path.exists(_file):
        log.warn('Could not find %s' % _file)
        log.all('{"source":"%s", "error_msg":"Could not find %s"}' %
                (_file, _file))
        return
    # Check if the source, _file, is a child folder within destination
    elif destination.startswith(
            os.path.abspath(os.path.dirname(_file)) + os.sep):
        log.all(
            '{"source": "%s", "destination": "%s", "error_msg": "Source cannot be in destination"}'
            % (_file, destination))
        return

    media = Media.get_class_by_file(_file, get_all_subclasses())
    if not media:
        log.warn('Not a supported file (%s)' % _file)
        log.all('{"source":"%s", "error_msg":"Not a supported file"}' % _file)
        return

    if album_from_folder:
        media.set_album_from_folder()

    dest_path = FILESYSTEM.process_file(_file,
                                        destination,
                                        media,
                                        allowDuplicate=allow_duplicates,
                                        move=False)
    if dest_path:
        log.all('%s -> %s' % (_file, dest_path))
    if trash:
        send2trash(_file)

    return dest_path or None
Beispiel #15
0
def test_get_class_by_file_video():
    media = Media.get_class_by_file(helper.get_file('video.mov'),
                                    [Photo, Video])

    assert media.__name__ == 'Video'
Beispiel #16
0
def test_get_class_by_file_photo():
    media = Media.get_class_by_file(helper.get_file('plain.jpg'),
                                    [Photo, Video])

    assert media.__name__ == 'Photo'
Beispiel #17
0
def test_get_file_path():
    media = Media(helper.get_file('plain.jpg'))
    path = media.get_file_path()

    assert 'plain.jpg' in path, path
Beispiel #18
0
def test_exiftool():
    media = Media()
    exiftool = media.get_exiftool()

    assert exiftool is not None, exiftool
Beispiel #19
0
def _update(album, location, time, title, files):
    """Update files.
    """
    for file_path in files:
        if not os.path.exists(file_path):
            if constants.debug:
                print 'Could not find %s' % file_path
            print '{"source":"%s", "error_msg":"Could not find %s"}' % \
                (file_path, file_path)
            continue

        file_path = os.path.expanduser(file_path)
        destination = os.path.expanduser(
            os.path.dirname(os.path.dirname(os.path.dirname(file_path))))

        media = Media.get_class_by_file(file_path, [Text, Audio, Photo, Video])
        if not media:
            continue

        updated = False
        if location:
            update_location(media, file_path, location)
            updated = True
        if time:
            update_time(media, file_path, time)
            updated = True
        if album:
            media.set_album(album)
            updated = True

        # Updating a title can be problematic when doing it 2+ times on a file.
        # You would end up with img_001.jpg -> img_001-first-title.jpg ->
        # img_001-first-title-second-title.jpg.
        # To resolve that we have to track the prior title (if there was one.
        # Then we massage the updated_media's metadata['base_name'] to remove
        # the old title.
        # Since FileSystem.get_file_name() relies on base_name it will properly
        #  rename the file by updating the title instead of appending it.
        remove_old_title_from_name = False
        if title:
            # We call get_metadata() to cache it before making any changes
            metadata = media.get_metadata()
            title_update_status = media.set_title(title)
            original_title = metadata['title']
            if title_update_status and original_title:
                # @TODO: We should move this to a shared method since
                # FileSystem.get_file_name() does it too.
                original_title = re.sub(r'\W+', '-', original_title.lower())
                original_base_name = metadata['base_name']
                remove_old_title_from_name = True
            updated = True

        if updated:
            updated_media = Media.get_class_by_file(
                file_path, [Text, Audio, Photo, Video])
            # See comments above on why we have to do this when titles
            # get updated.
            if remove_old_title_from_name and len(original_title) > 0:
                updated_media.get_metadata()
                updated_media.set_metadata_basename(
                    original_base_name.replace('-%s' % original_title, ''))

            dest_path = FILESYSTEM.process_file(file_path,
                                                destination,
                                                updated_media,
                                                move=True,
                                                allowDuplicate=True)
            if constants.debug:
                print u'%s -> %s' % (file_path, dest_path)
            print '{"source":"%s", "destination":"%s"}' % (file_path,
                                                           dest_path)
            # If the folder we moved the file out of or its parent are empty
            # we delete it.
            FILESYSTEM.delete_directory_if_empty(os.path.dirname(file_path))
            FILESYSTEM.delete_directory_if_empty(
                os.path.dirname(os.path.dirname(file_path)))
Beispiel #20
0
def _update(params):
    """Update files.
    """
    for file_path in params['INPUT']:
        if not os.path.exists(file_path):
            if constants.debug:
                print 'Could not find %s' % file_path
            print '{"source":"%s", "error_msg":"Could not find %s"}' % \
                (file_path, file_path)
            continue

        file_path = os.path.expanduser(file_path)
        destination = os.path.expanduser(os.path.dirname(os.path.dirname(
                                         os.path.dirname(file_path))))

        media = Media.get_class_by_file(file_path, [Audio, Photo, Video])
        if not media:
            continue

        updated = False
        if params['--location']:
            updated = update_location(media, file_path, params['--location'])
        if params['--time']:
            updated = update_time(media, file_path, params['--time'])
        if params['--album']:
            media.set_album(params['--album'])
            updated = True

        # Updating a title can be problematic when doing it 2+ times on a file.
        # You would end up with img_001.jpg -> img_001-first-title.jpg ->
        # img_001-first-title-second-title.jpg.
        # To resolve that we have to track the prior title (if there was one.
        # Then we massage the updated_media's metadata['base_name'] to remove
        # the old title.
        # Since FileSystem.get_file_name() relies on base_name it will properly
        #  rename the file by updating the title instead of appending it.
        remove_old_title_from_name = False
        if params['--title']:
            # We call get_metadata() to cache it before making any changes
            metadata = media.get_metadata()
            title_update_status = media.set_title(params['--title'])
            original_title = metadata['title']
            if title_update_status and original_title:
                # @TODO: We should move this to a shared method since
                # FileSystem.get_file_name() does it too.
                original_title = re.sub(r'\W+', '-', original_title.lower())
                original_base_name = metadata['base_name']
                remove_old_title_from_name = True
            updated = True

        if updated:
            updated_media = Media.get_class_by_file(file_path, [Audio, Photo, Video])
            # See comments above on why we have to do this when titles
            # get updated.
            if remove_old_title_from_name and len(original_title) > 0:
                updated_media.get_metadata()
                updated_media.set_metadata_basename(
                    original_base_name.replace('-%s' % original_title, ''))

            dest_path = FILESYSTEM.process_file(file_path, destination,
                updated_media, move=True, allowDuplicate=True)
            if constants.debug:
                print u'%s -> %s' % (file_path, dest_path)
            print '{"source":"%s", "destination":"%s"}' % (file_path,
                dest_path)
            # If the folder we moved the file out of or its parent are empty
            # we delete it.
            FILESYSTEM.delete_directory_if_empty(os.path.dirname(file_path))
            FILESYSTEM.delete_directory_if_empty(
                os.path.dirname(os.path.dirname(file_path)))
Beispiel #21
0
def test_get_class_by_file_photo():
    media = Media.get_class_by_file(helper.get_file('plain.jpg'), [Photo, Video])

    assert media.__name__ == 'Photo'
Beispiel #22
0
def test_get_class_by_file_video():
    media = Media.get_class_by_file(helper.get_file('video.mov'), [Photo, Video])

    assert media.__name__ == 'Video'
Beispiel #23
0
def test_get_class_by_file_unsupported():
    media = Media.get_class_by_file(helper.get_file('text.txt'), [Photo, Video])

    assert media is None
Beispiel #24
0
def test_get_class_by_file_empty():
    media = Media.get_class_by_file(helper.get_file('.DS_Store'),
                                    [Photo, Video, Audio])
    assert media is None
Beispiel #25
0
def is_valid():
    media = Media()

    assert not media.is_valid()
Beispiel #26
0
def test_get_class_by_file_unsupported():
    media = Media.get_class_by_file(helper.get_file('text.txt'),
                                    [Photo, Video])

    assert media is None
Beispiel #27
0
def test_get_file_path():
    media = Media(helper.get_file('plain.jpg'))
    path = media.get_file_path()

    assert 'plain.jpg' in path, path
Beispiel #28
0
def test_get_class_by_file_empty():
    media = Media.get_class_by_file(helper.get_file('.DS_Store'),
                                    [Photo, Video, Audio])
    assert media is None
Beispiel #29
0
def is_valid():
    media = Media()

    assert not media.is_valid()
Beispiel #30
0
def _update(album, location, time, title, paths, debug):
    """Update a file's EXIF. Automatically modifies the file's location and file name accordingly.
    """
    constants.debug = debug
    has_errors = False
    result = Result()

    files = set()
    for path in paths:
        path = os.path.expanduser(path)
        if os.path.isdir(path):
            files.update(FILESYSTEM.get_all_files(path, None))
        else:
            files.add(path)

    for current_file in files:
        if not os.path.exists(current_file):
            has_errors = True
            result.append((current_file, False))
            log.warn('Could not find %s' % current_file)
            log.all('{"source":"%s", "error_msg":"Could not find %s"}' %
                      (current_file, current_file))
            continue

        current_file = os.path.expanduser(current_file)

        # The destination folder structure could contain any number of levels
        #  So we calculate that and traverse up the tree.
        # '/path/to/file/photo.jpg' -> '/path/to/file' ->
        #  ['path','to','file'] -> ['path','to'] -> '/path/to'
        current_directory = os.path.dirname(current_file)
        destination_depth = -1 * len(FILESYSTEM.get_folder_path_definition())
        destination = os.sep.join(
                          os.path.normpath(
                              current_directory
                          ).split(os.sep)[:destination_depth]
                      )

        media = Media.get_class_by_file(current_file, get_all_subclasses())
        if not media:
            continue

        updated = False
        if location:
            update_location(media, current_file, location)
            updated = True
        if time:
            update_time(media, current_file, time)
            updated = True
        if album:
            media.set_album(album)
            updated = True

        # Updating a title can be problematic when doing it 2+ times on a file.
        # You would end up with img_001.jpg -> img_001-first-title.jpg ->
        # img_001-first-title-second-title.jpg.
        # To resolve that we have to track the prior title (if there was one.
        # Then we massage the updated_media's metadata['base_name'] to remove
        # the old title.
        # Since FileSystem.get_file_name() relies on base_name it will properly
        #  rename the file by updating the title instead of appending it.
        remove_old_title_from_name = False
        if title:
            # We call get_metadata() to cache it before making any changes
            metadata = media.get_metadata()
            title_update_status = media.set_title(title)
            original_title = metadata['title']
            if title_update_status and original_title:
                # @TODO: We should move this to a shared method since
                # FileSystem.get_file_name() does it too.
                original_title = re.sub(r'\W+', '-', original_title.lower())
                original_base_name = metadata['base_name']
                remove_old_title_from_name = True
            updated = True

        if updated:
            updated_media = Media.get_class_by_file(current_file,
                                                    get_all_subclasses())
            # See comments above on why we have to do this when titles
            # get updated.
            if remove_old_title_from_name and len(original_title) > 0:
                updated_media.get_metadata()
                updated_media.set_metadata_basename(
                    original_base_name.replace('-%s' % original_title, ''))

            dest_path = FILESYSTEM.process_file(current_file, destination,
                updated_media, move=True, allowDuplicate=True)
            log.info(u'%s -> %s' % (current_file, dest_path))
            log.all('{"source":"%s", "destination":"%s"}' % (current_file,
                                                               dest_path))
            # If the folder we moved the file out of or its parent are empty
            # we delete it.
            FILESYSTEM.delete_directory_if_empty(os.path.dirname(current_file))
            FILESYSTEM.delete_directory_if_empty(
                os.path.dirname(os.path.dirname(current_file)))
            result.append((current_file, dest_path))
            # Trip has_errors to False if it's already False or dest_path is.
            has_errors = has_errors is True or not dest_path
        else:
            has_errors = False
            result.append((current_file, False))

    result.write()
    
    if has_errors:
        sys.exit(1)
Beispiel #31
0
def _update(album, location, time, title, files):
    """Update a file's EXIF. Automatically modifies the file's location and file name accordingly.
    """
    result = Result()
    for current_file in files:
        if not os.path.exists(current_file):
            if constants.debug:
                print('Could not find %s' % current_file)
            print('{"source":"%s", "error_msg":"Could not find %s"}' % \
                (current_file, current_file))
            continue

        current_file = os.path.expanduser(current_file)
        destination = os.path.expanduser(os.path.dirname(os.path.dirname(
                                         os.path.dirname(current_file))))

        media = Media.get_class_by_file(current_file, [Text, Audio, Photo, Video])
        if not media:
            continue

        updated = False
        if location:
            update_location(media, current_file, location)
            updated = True
        if time:
            update_time(media, current_file, time)
            updated = True
        if album:
            media.set_album(album)
            updated = True

        # Updating a title can be problematic when doing it 2+ times on a file.
        # You would end up with img_001.jpg -> img_001-first-title.jpg ->
        # img_001-first-title-second-title.jpg.
        # To resolve that we have to track the prior title (if there was one.
        # Then we massage the updated_media's metadata['base_name'] to remove
        # the old title.
        # Since FileSystem.get_file_name() relies on base_name it will properly
        #  rename the file by updating the title instead of appending it.
        remove_old_title_from_name = False
        if title:
            # We call get_metadata() to cache it before making any changes
            metadata = media.get_metadata()
            title_update_status = media.set_title(title)
            original_title = metadata['title']
            if title_update_status and original_title:
                # @TODO: We should move this to a shared method since
                # FileSystem.get_file_name() does it too.
                original_title = re.sub(r'\W+', '-', original_title.lower())
                original_base_name = metadata['base_name']
                remove_old_title_from_name = True
            updated = True

        if updated:
            updated_media = Media.get_class_by_file(current_file,
                                                    [Text, Audio, Photo, Video])
            # See comments above on why we have to do this when titles
            # get updated.
            if remove_old_title_from_name and len(original_title) > 0:
                updated_media.get_metadata()
                updated_media.set_metadata_basename(
                    original_base_name.replace('-%s' % original_title, ''))

            dest_path = FILESYSTEM.process_file(current_file, destination,
                updated_media, move=True, allowDuplicate=True)
            log.info(u'%s -> %s' % (current_file, dest_path))
            print('{"source":"%s", "destination":"%s"}' % (current_file,
                dest_path))
            # If the folder we moved the file out of or its parent are empty
            # we delete it.
            FILESYSTEM.delete_directory_if_empty(os.path.dirname(current_file))
            FILESYSTEM.delete_directory_if_empty(
                os.path.dirname(os.path.dirname(current_file)))
            result.append((current_file, dest_path))
        else:
            result.append((current_file, False))

    result.write()