Refactoring media class
This commit is contained in:
		
							parent
							
								
									6b2d2b31c3
								
							
						
					
					
						commit
						cb8a4cd24e
					
				
							
								
								
									
										20
									
								
								elodie.py
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								elodie.py
									
									
									
									
									
								
							@ -155,8 +155,8 @@ def _import(destination, source, file, album_from_folder, trash,
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
@click.command('generate-db')
 | 
			
		||||
@click.option('--source', type=click.Path(file_okay=False),
 | 
			
		||||
              required=True, help='Source of your photo library.')
 | 
			
		||||
@click.option('--path', type=click.Path(file_okay=False),
 | 
			
		||||
              required=True, help='Path of your photo library.')
 | 
			
		||||
@click.option('--debug', default=False, is_flag=True,
 | 
			
		||||
              help='Override the value in constants.py with True.')
 | 
			
		||||
def _generate_db(path, debug):
 | 
			
		||||
@ -164,17 +164,17 @@ def _generate_db(path, debug):
 | 
			
		||||
    """
 | 
			
		||||
    constants.debug = debug
 | 
			
		||||
    result = Result()
 | 
			
		||||
    source = os.path.abspath(os.path.expanduser(source))
 | 
			
		||||
    path = os.path.abspath(os.path.expanduser(path))
 | 
			
		||||
 | 
			
		||||
    if not os.path.isdir(source):
 | 
			
		||||
        log.error('Source is not a valid directory %s' % source)
 | 
			
		||||
    if not os.path.isdir(path):
 | 
			
		||||
        log.error('path is not a valid directory %s' % path)
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
    db = Db(path)
 | 
			
		||||
    db.backup_hash_db()
 | 
			
		||||
    db.reset_hash_db()
 | 
			
		||||
 | 
			
		||||
    for current_file in FILESYSTEM.get_all_files(source):
 | 
			
		||||
    for current_file in FILESYSTEM.get_all_files(path):
 | 
			
		||||
        result.append((current_file, True))
 | 
			
		||||
        db.add_hash(db.checksum(current_file), current_file)
 | 
			
		||||
        log.progress()
 | 
			
		||||
@ -184,9 +184,11 @@ def _generate_db(path, debug):
 | 
			
		||||
    result.write()
 | 
			
		||||
 | 
			
		||||
@click.command('verify')
 | 
			
		||||
@click.option('--path', type=click.Path(file_okay=False),
 | 
			
		||||
              required=True, help='Path of your photo library.')
 | 
			
		||||
@click.option('--debug', default=False, is_flag=True,
 | 
			
		||||
              help='Override the value in constants.py with True.')
 | 
			
		||||
def _verify(debug):
 | 
			
		||||
def _verify(path, debug):
 | 
			
		||||
    constants.debug = debug
 | 
			
		||||
    result = Result()
 | 
			
		||||
    db = Db(path)
 | 
			
		||||
@ -216,7 +218,7 @@ def update_location(media, file_path, location_name, db):
 | 
			
		||||
    if location_coords and 'latitude' in location_coords and \
 | 
			
		||||
            'longitude' in location_coords:
 | 
			
		||||
        location_status = media.set_location(location_coords[
 | 
			
		||||
            'latitude'], location_coords['longitude'])
 | 
			
		||||
            'latitude'], location_coords['longitude'], file_path)
 | 
			
		||||
        if not location_status:
 | 
			
		||||
            log.error('Failed to update location')
 | 
			
		||||
            log.all(('{"source":"%s",' % file_path,
 | 
			
		||||
@ -307,7 +309,7 @@ def _update(album, location, time, title, paths, debug):
 | 
			
		||||
            update_time(media, current_file, time)
 | 
			
		||||
            updated = True
 | 
			
		||||
        if album:
 | 
			
		||||
            media.set_album(album)
 | 
			
		||||
            media.set_album(album, current_file)
 | 
			
		||||
            updated = True
 | 
			
		||||
 | 
			
		||||
        import ipdb; ipdb.set_trace()
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ from elodie.config import load_config
 | 
			
		||||
from elodie import constants
 | 
			
		||||
 | 
			
		||||
from elodie.localstorage import Db
 | 
			
		||||
from elodie.media import base
 | 
			
		||||
from elodie.media import media
 | 
			
		||||
from elodie.plugins.plugins import Plugins
 | 
			
		||||
 | 
			
		||||
class FileSystem(object):
 | 
			
		||||
@ -94,7 +94,7 @@ class FileSystem(object):
 | 
			
		||||
        # If extensions is None then we get all supported extensions
 | 
			
		||||
        if not extensions:
 | 
			
		||||
            extensions = set()
 | 
			
		||||
            subclasses = base.get_all_subclasses()
 | 
			
		||||
            subclasses = media.get_all_subclasses()
 | 
			
		||||
            for cls in subclasses:
 | 
			
		||||
                extensions.update(cls.extensions)
 | 
			
		||||
 | 
			
		||||
@ -679,7 +679,9 @@ class FileSystem(object):
 | 
			
		||||
            if album_from_folder:
 | 
			
		||||
                media.set_album_from_folder(dest_path)
 | 
			
		||||
 | 
			
		||||
        db.add_hash(checksum, dest_path)
 | 
			
		||||
        # get checksum of dest file
 | 
			
		||||
        dest_checksum = db.checksum(dest_path)
 | 
			
		||||
        db.add_hash(dest_checksum, dest_path)
 | 
			
		||||
        db.update_hash_db()
 | 
			
		||||
 | 
			
		||||
        # Run `after()` for every loaded plugin and if any of them raise an exception
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,15 @@
 | 
			
		||||
"""
 | 
			
		||||
The audio module contains classes specifically for dealing with audio files.
 | 
			
		||||
The :class:`Audio` class inherits from the :class:`~elodie.media.video.Video`
 | 
			
		||||
The :class:`Audio` class inherits from the :class:`~elodie.media.Media`
 | 
			
		||||
class.
 | 
			
		||||
 | 
			
		||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from .video import Video
 | 
			
		||||
from .media import Media
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Audio(Video):
 | 
			
		||||
class Audio(Media):
 | 
			
		||||
 | 
			
		||||
    """An audio object.
 | 
			
		||||
 | 
			
		||||
@ -22,4 +22,7 @@ class Audio(Video):
 | 
			
		||||
    extensions = ('m4a',)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, source=None):
 | 
			
		||||
        super(Audio, self).__init__(source)
 | 
			
		||||
        super().__init__(source)
 | 
			
		||||
 | 
			
		||||
    def is_valid(self):
 | 
			
		||||
        return super().is_valid()
 | 
			
		||||
 | 
			
		||||
@ -1,264 +0,0 @@
 | 
			
		||||
"""
 | 
			
		||||
The base module provides a base :class:`Base` class for all objects that
 | 
			
		||||
are tracked by Elodie. The Base class provides some base functionality used
 | 
			
		||||
by all the media types, but isn't itself used to represent anything. Its
 | 
			
		||||
sub-classes (:class:`~elodie.media.audio.Audio`,
 | 
			
		||||
:class:`~elodie.media.photo.Photo`, :class:`~elodie.media.video.Video`)
 | 
			
		||||
are used to represent the actual files.
 | 
			
		||||
 | 
			
		||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import mimetypes
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
try:        # Py3k compatibility
 | 
			
		||||
    basestring
 | 
			
		||||
except NameError:
 | 
			
		||||
    basestring = (bytes, str)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Base(object):
 | 
			
		||||
 | 
			
		||||
    """The base class for all media objects.
 | 
			
		||||
 | 
			
		||||
    :param str source: The fully qualified path to the video file.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __name__ = 'Base'
 | 
			
		||||
 | 
			
		||||
    PHOTO = ('arw', 'cr2', 'dng', 'gif', 'heic', 'jpeg', 'jpg', 'nef', 'png', 'rw2')
 | 
			
		||||
    AUDIO = ('m4a',)
 | 
			
		||||
    VIDEO = ('avi', 'm4v', 'mov', 'mp4', 'mpg', 'mpeg', '3gp', 'mts')
 | 
			
		||||
 | 
			
		||||
    extensions = PHOTO + AUDIO + VIDEO
 | 
			
		||||
 | 
			
		||||
    def __init__(self, source=None):
 | 
			
		||||
        self.source = source
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
 | 
			
		||||
    def format_metadata(self, **kwargs):
 | 
			
		||||
        """Method to consistently return a populated metadata dictionary.
 | 
			
		||||
 | 
			
		||||
        :returns: dict
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def get_album(self):
 | 
			
		||||
        """Base method for getting an album
 | 
			
		||||
 | 
			
		||||
        :returns: None
 | 
			
		||||
        """
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_file_path(self):
 | 
			
		||||
        """Get the full path to the video.
 | 
			
		||||
 | 
			
		||||
        :returns: string
 | 
			
		||||
        """
 | 
			
		||||
        return self.source
 | 
			
		||||
 | 
			
		||||
    def get_coordinate(self, type):
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_extension(self):
 | 
			
		||||
        """Get the file extension as a lowercased string.
 | 
			
		||||
 | 
			
		||||
        :returns: string or None for a non-video
 | 
			
		||||
        """
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
        return os.path.splitext(source)[1][1:].lower()
 | 
			
		||||
 | 
			
		||||
    def get_camera_make(self):
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_camera_model(self):
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_metadata(self, update_cache=False):
 | 
			
		||||
        """Get a dictionary of metadata for any file.
 | 
			
		||||
 | 
			
		||||
        All keys will be present and have a value of None if not obtained.
 | 
			
		||||
 | 
			
		||||
        :returns: dict or None for non-text files
 | 
			
		||||
        """
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        if(isinstance(self.metadata, dict) and update_cache is False):
 | 
			
		||||
            return self.metadata
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
        folder = os.path.basename(os.path.dirname(source))
 | 
			
		||||
        album = self.get_album()
 | 
			
		||||
        album_from_folder = True
 | 
			
		||||
        if album_from_folder and (album is None or album == ''):
 | 
			
		||||
            album = folder
 | 
			
		||||
 | 
			
		||||
        self.metadata = {
 | 
			
		||||
            'date_original': self.get_date_attribute(self.date_original),
 | 
			
		||||
            'date_created': self.get_date_attribute(self.date_created),
 | 
			
		||||
            'date_modified': self.get_date_attribute(self.date_modified),
 | 
			
		||||
            'camera_make': self.get_camera_make(),
 | 
			
		||||
            'camera_model': self.get_camera_model(),
 | 
			
		||||
            'latitude': self.get_coordinate('latitude'),
 | 
			
		||||
            'longitude': self.get_coordinate('longitude'),
 | 
			
		||||
            'album': album,
 | 
			
		||||
            'title': self.get_title(),
 | 
			
		||||
            'mime_type': self.get_mimetype(),
 | 
			
		||||
            'original_name': self.get_original_name(),
 | 
			
		||||
            'base_name': folder,
 | 
			
		||||
            'extension': self.get_extension(),
 | 
			
		||||
            'directory_path': os.path.dirname(source)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self.metadata
 | 
			
		||||
 | 
			
		||||
    def get_mimetype(self):
 | 
			
		||||
        """Get the mimetype of the file.
 | 
			
		||||
 | 
			
		||||
        :returns: str or None for unsupported files.
 | 
			
		||||
        """
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
        mimetype = mimetypes.guess_type(source)
 | 
			
		||||
        if(mimetype is None):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        return mimetype[0]
 | 
			
		||||
 | 
			
		||||
    def get_original_name(self):
 | 
			
		||||
        """Get the original name of the file from before it was imported.
 | 
			
		||||
        Does not include the extension.
 | 
			
		||||
        Overridden by Media class for files with EXIF.
 | 
			
		||||
 | 
			
		||||
        :returns: str or None for unsupported files.
 | 
			
		||||
        """
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_title(self):
 | 
			
		||||
        """Base method for getting the title of a file
 | 
			
		||||
 | 
			
		||||
        :returns: None
 | 
			
		||||
        """
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def is_valid(self):
 | 
			
		||||
        """Check the file extension against valid file extensions.
 | 
			
		||||
 | 
			
		||||
        The list of valid file extensions come from self.extensions.
 | 
			
		||||
 | 
			
		||||
        :returns: bool
 | 
			
		||||
        """
 | 
			
		||||
        source = self.source
 | 
			
		||||
        return os.path.splitext(source)[1][1:].lower() in self.extensions
 | 
			
		||||
 | 
			
		||||
    def reset_cache(self):
 | 
			
		||||
        """Resets any internal cache
 | 
			
		||||
        """
 | 
			
		||||
        self.metadata = None
 | 
			
		||||
 | 
			
		||||
    def set_album(self, name):
 | 
			
		||||
        """Base method for setting the album of a file
 | 
			
		||||
 | 
			
		||||
        :returns: None
 | 
			
		||||
        """
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def set_album_from_folder(self, path):
 | 
			
		||||
        """Set the album attribute based on the leaf folder name
 | 
			
		||||
 | 
			
		||||
        :returns: bool
 | 
			
		||||
        """
 | 
			
		||||
        metadata = self.get_metadata()
 | 
			
		||||
 | 
			
		||||
        # If this file has an album already set we do not overwrite EXIF
 | 
			
		||||
        if(not isinstance(metadata, dict) or metadata['album'] is not None):
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        folder = os.path.basename(metadata['directory_path'])
 | 
			
		||||
        # If folder is empty we skip
 | 
			
		||||
        if(len(folder) == 0):
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        self.set_album(folder)
 | 
			
		||||
        if status == False:
 | 
			
		||||
            return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def set_metadata_basename(self, new_basename):
 | 
			
		||||
        """Update the basename attribute in the metadata dict for this instance.
 | 
			
		||||
 | 
			
		||||
        This is used for when we update the EXIF title of a media file. Since
 | 
			
		||||
        that determines the name of a file if we update the title of a file
 | 
			
		||||
        more than once it appends to the file name.
 | 
			
		||||
 | 
			
		||||
        i.e. 2015-12-31_00-00-00-my-first-title-my-second-title.jpg
 | 
			
		||||
 | 
			
		||||
        :param str new_basename: New basename of file (with the old title
 | 
			
		||||
            removed).
 | 
			
		||||
        """
 | 
			
		||||
        self.get_metadata()
 | 
			
		||||
        self.metadata['base_name'] = new_basename
 | 
			
		||||
 | 
			
		||||
    def set_metadata(self, **kwargs):
 | 
			
		||||
        """Method to manually update attributes in metadata.
 | 
			
		||||
 | 
			
		||||
        :params dict kwargs: Named parameters to update.
 | 
			
		||||
        """
 | 
			
		||||
        metadata = self.get_metadata()
 | 
			
		||||
        for key in kwargs:
 | 
			
		||||
            if(key in metadata):
 | 
			
		||||
                self.metadata[key] = kwargs[key]
 | 
			
		||||
 | 
			
		||||
    def set_original_name(self):
 | 
			
		||||
        """Stores the original file name into EXIF/metadata.
 | 
			
		||||
        :returns: bool
 | 
			
		||||
        """
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_class_by_file(cls, _file, classes):
 | 
			
		||||
        """Static method to get a media object by file.
 | 
			
		||||
        """
 | 
			
		||||
        if not isinstance(_file, basestring) or not os.path.isfile(_file):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        extension = os.path.splitext(_file)[1][1:].lower()
 | 
			
		||||
 | 
			
		||||
        if len(extension) > 0:
 | 
			
		||||
            for i in classes:
 | 
			
		||||
                if(extension in i.extensions):
 | 
			
		||||
                    return i(_file)
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_valid_extensions(cls):
 | 
			
		||||
        """Static method to access static extensions variable.
 | 
			
		||||
 | 
			
		||||
        :returns: tuple(str)
 | 
			
		||||
        """
 | 
			
		||||
        return cls.extensions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_all_subclasses(cls=None):
 | 
			
		||||
    """Module method to get all subclasses of Base.
 | 
			
		||||
    """
 | 
			
		||||
    subclasses = set()
 | 
			
		||||
 | 
			
		||||
    this_class = Base
 | 
			
		||||
    if cls is not None:
 | 
			
		||||
        this_class = cls
 | 
			
		||||
 | 
			
		||||
    subclasses.add(this_class)
 | 
			
		||||
 | 
			
		||||
    this_class_subclasses = this_class.__subclasses__()
 | 
			
		||||
    for child_class in this_class_subclasses:
 | 
			
		||||
        subclasses.update(get_all_subclasses(child_class))
 | 
			
		||||
 | 
			
		||||
    return subclasses
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
"""
 | 
			
		||||
The media module provides a base :class:`Media` class for media objects that
 | 
			
		||||
are tracked by Elodie. The Media class provides some base functionality used
 | 
			
		||||
by all the media types, but isn't itself used to represent anything. Its
 | 
			
		||||
sub-classes (:class:`~elodie.media.audio.Audio`,
 | 
			
		||||
:class:`~elodie.media.photo.Photo`, and :class:`~elodie.media.video.Video`)
 | 
			
		||||
by all the media types. Its sub-classes (:class:`~elodie.media.Audio`,
 | 
			
		||||
:class:`~elodie.media.Photo`, and :class:`~elodie.media.Video`)
 | 
			
		||||
are used to represent the actual files.
 | 
			
		||||
 | 
			
		||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import mimetypes
 | 
			
		||||
import os
 | 
			
		||||
import six
 | 
			
		||||
 | 
			
		||||
@ -17,11 +17,17 @@ from elodie import log
 | 
			
		||||
from dateutil.parser import parse
 | 
			
		||||
import re
 | 
			
		||||
from elodie.external.pyexiftool import ExifTool
 | 
			
		||||
from elodie.media.base import Base
 | 
			
		||||
 | 
			
		||||
class Media(Base):
 | 
			
		||||
# TODO remove
 | 
			
		||||
# try:        # Py3k compatibility
 | 
			
		||||
#     basestring
 | 
			
		||||
# except NameError:
 | 
			
		||||
#     basestring = (bytes, str)
 | 
			
		||||
 | 
			
		||||
    """The base class for all media objects.
 | 
			
		||||
 | 
			
		||||
class Media():
 | 
			
		||||
 | 
			
		||||
    """The media class for all media objects.
 | 
			
		||||
 | 
			
		||||
    :param str source: The fully qualified path to the video file.
 | 
			
		||||
    """
 | 
			
		||||
@ -33,23 +39,221 @@ class Media(Base):
 | 
			
		||||
        'longitude': 'longitude_ref'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def __init__(self, source=None):
 | 
			
		||||
        super(Media, self).__init__(source)
 | 
			
		||||
        self.date_original = ['EXIF:DateTimeOriginal']
 | 
			
		||||
        self.date_created = ['EXIF:CreateDate', 'QuickTime:CreateDate']
 | 
			
		||||
    PHOTO = ('arw', 'cr2', 'dng', 'gif', 'heic', 'jpeg', 'jpg', 'nef', 'png', 'rw2')
 | 
			
		||||
    AUDIO = ('m4a',)
 | 
			
		||||
    VIDEO = ('avi', 'm4v', 'mov', 'mp4', 'mpg', 'mpeg', '3gp', 'mts')
 | 
			
		||||
 | 
			
		||||
    extensions = PHOTO + AUDIO + VIDEO
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def __init__(self, sources=None):
 | 
			
		||||
        self.source = sources
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
        self.date_original = [
 | 
			
		||||
            'EXIF:DateTimeOriginal',
 | 
			
		||||
            'H264:DateTimeOriginal',
 | 
			
		||||
            'QuickTime:ContentCreateDate'
 | 
			
		||||
        ]
 | 
			
		||||
        self.date_created = [
 | 
			
		||||
            'EXIF:CreateDate',
 | 
			
		||||
            'QuickTime:CreationDate',
 | 
			
		||||
            'QuickTime:CreateDate',
 | 
			
		||||
            'QuickTime:CreationDate-und-US',
 | 
			
		||||
            'QuickTime:MediaCreateDate'
 | 
			
		||||
        ]
 | 
			
		||||
        self.date_modified = ['File:FileModifyDate', 'QuickTime:ModifyDate']
 | 
			
		||||
        self.camera_make_keys = ['EXIF:Make', 'QuickTime:Make']
 | 
			
		||||
        self.camera_model_keys = ['EXIF:Model', 'QuickTime:Model']
 | 
			
		||||
        self.album_keys = ['XMP-xmpDM:Album', 'XMP:Album']
 | 
			
		||||
        self.title_key = 'XMP:Title'
 | 
			
		||||
        self.latitude_keys = ['EXIF:GPSLatitude']
 | 
			
		||||
        self.longitude_keys = ['EXIF:GPSLongitude']
 | 
			
		||||
        self.title_keys = ['XMP:Title', 'XMP:DisplayName']
 | 
			
		||||
        self.latitude_keys = [
 | 
			
		||||
            'EXIF:GPSLatitude',
 | 
			
		||||
            'XMP:GPSLatitude',
 | 
			
		||||
            # 'QuickTime:GPSLatitude',
 | 
			
		||||
            'Composite:GPSLatitude'
 | 
			
		||||
        ]
 | 
			
		||||
        self.longitude_keys = [
 | 
			
		||||
            'EXIF:GPSLongitude',
 | 
			
		||||
            'XMP:GPSLongitude',
 | 
			
		||||
            # 'QuickTime:GPSLongitude',
 | 
			
		||||
            'Composite:GPSLongitude'
 | 
			
		||||
        ]
 | 
			
		||||
        self.latitude_ref_key = 'EXIF:GPSLatitudeRef'
 | 
			
		||||
        self.longitude_ref_key = 'EXIF:GPSLongitudeRef'
 | 
			
		||||
        self.original_name_key = 'XMP:OriginalFileName'
 | 
			
		||||
        self.set_gps_ref = True
 | 
			
		||||
        self.metadata = None
 | 
			
		||||
        self.exif_metadata = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def format_metadata(self, **kwargs):
 | 
			
		||||
        """Method to consistently return a populated metadata dictionary.
 | 
			
		||||
 | 
			
		||||
        :returns: dict
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
    def get_file_path(self):
 | 
			
		||||
        """Get the full path to the video.
 | 
			
		||||
 | 
			
		||||
        :returns: string
 | 
			
		||||
        """
 | 
			
		||||
        return self.source
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_extension(self):
 | 
			
		||||
        """Get the file extension as a lowercased string.
 | 
			
		||||
 | 
			
		||||
        :returns: string or None for a non-video
 | 
			
		||||
        """
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
        return os.path.splitext(source)[1][1:].lower()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_metadata(self, update_cache=False, album_from_folder=False):
 | 
			
		||||
        """Get a dictionary of metadata for any file.
 | 
			
		||||
 | 
			
		||||
        All keys will be present and have a value of None if not obtained.
 | 
			
		||||
 | 
			
		||||
        :returns: dict or None for non-text files
 | 
			
		||||
        """
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        if(isinstance(self.metadata, dict) and update_cache is False):
 | 
			
		||||
            return self.metadata
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
        folder = os.path.basename(os.path.dirname(source))
 | 
			
		||||
        album = self.get_album()
 | 
			
		||||
        if album_from_folder and (album is None or album == ''):
 | 
			
		||||
            album = folder
 | 
			
		||||
 | 
			
		||||
        self.metadata = {
 | 
			
		||||
            'date_original': self.get_date_attribute(self.date_original),
 | 
			
		||||
            'date_created': self.get_date_attribute(self.date_created),
 | 
			
		||||
            'date_modified': self.get_date_attribute(self.date_modified),
 | 
			
		||||
            'camera_make': self.get_camera_make(),
 | 
			
		||||
            'camera_model': self.get_camera_model(),
 | 
			
		||||
            'latitude': self.get_coordinate('latitude'),
 | 
			
		||||
            'longitude': self.get_coordinate('longitude'),
 | 
			
		||||
            'album': album,
 | 
			
		||||
            'title': self.get_title(),
 | 
			
		||||
            'mime_type': self.get_mimetype(),
 | 
			
		||||
            'original_name': self.get_original_name(),
 | 
			
		||||
            'base_name': os.path.basename(os.path.splitext(source)[0]),
 | 
			
		||||
            'extension': self.get_extension(),
 | 
			
		||||
            'directory_path': os.path.dirname(source)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self.metadata
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_mimetype(self):
 | 
			
		||||
        """Get the mimetype of the file.
 | 
			
		||||
 | 
			
		||||
        :returns: str or None for unsupported files.
 | 
			
		||||
        """
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
        mimetype = mimetypes.guess_type(source)
 | 
			
		||||
        if(mimetype is None):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        return mimetype[0]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def is_valid(self):
 | 
			
		||||
        """Check the file extension against valid file extensions.
 | 
			
		||||
 | 
			
		||||
        The list of valid file extensions come from self.extensions.
 | 
			
		||||
 | 
			
		||||
        :returns: bool
 | 
			
		||||
        """
 | 
			
		||||
        source = self.source
 | 
			
		||||
        return os.path.splitext(source)[1][1:].lower() in self.extensions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def set_album_from_folder(self, path):
 | 
			
		||||
        """Set the album attribute based on the leaf folder name
 | 
			
		||||
 | 
			
		||||
        :returns: bool
 | 
			
		||||
        """
 | 
			
		||||
        metadata = self.get_metadata()
 | 
			
		||||
 | 
			
		||||
        # If this file has an album already set we do not overwrite EXIF
 | 
			
		||||
        if(not isinstance(metadata, dict) or metadata['album'] is not None):
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        folder = os.path.basename(metadata['directory_path'])
 | 
			
		||||
        # If folder is empty we skip
 | 
			
		||||
        if(len(folder) == 0):
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        status = self.set_album(folder, path)
 | 
			
		||||
        if status == False:
 | 
			
		||||
            return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def set_metadata_basename(self, new_basename):
 | 
			
		||||
        """Update the basename attribute in the metadata dict for this instance.
 | 
			
		||||
 | 
			
		||||
        This is used for when we update the EXIF title of a media file. Since
 | 
			
		||||
        that determines the name of a file if we update the title of a file
 | 
			
		||||
        more than once it appends to the file name.
 | 
			
		||||
 | 
			
		||||
        i.e. 2015-12-31_00-00-00-my-first-title-my-second-title.jpg
 | 
			
		||||
 | 
			
		||||
        :param str new_basename: New basename of file (with the old title
 | 
			
		||||
            removed).
 | 
			
		||||
        """
 | 
			
		||||
        self.get_metadata()
 | 
			
		||||
        self.metadata['base_name'] = new_basename
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def set_metadata(self, **kwargs):
 | 
			
		||||
        """Method to manually update attributes in metadata.
 | 
			
		||||
 | 
			
		||||
        :params dict kwargs: Named parameters to update.
 | 
			
		||||
        """
 | 
			
		||||
        metadata = self.get_metadata()
 | 
			
		||||
        for key in kwargs:
 | 
			
		||||
            if(key in metadata):
 | 
			
		||||
                self.metadata[key] = kwargs[key]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_class_by_file(cls, _file, classes):
 | 
			
		||||
        """Static method to get a media object by file.
 | 
			
		||||
        """
 | 
			
		||||
        basestring = (bytes, str)
 | 
			
		||||
        if not isinstance(_file, basestring) or not os.path.isfile(_file):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        extension = os.path.splitext(_file)[1][1:].lower()
 | 
			
		||||
 | 
			
		||||
        if len(extension) > 0:
 | 
			
		||||
            for i in classes:
 | 
			
		||||
                if(extension in i.extensions):
 | 
			
		||||
                    return i(_file)
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_valid_extensions(cls):
 | 
			
		||||
        """Static method to access static extensions variable.
 | 
			
		||||
 | 
			
		||||
        :returns: tuple(str)
 | 
			
		||||
        """
 | 
			
		||||
        return cls.extensions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_album(self):
 | 
			
		||||
        """Get album from EXIF
 | 
			
		||||
 | 
			
		||||
@ -68,6 +272,7 @@ class Media(Base):
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_coordinate(self, type='latitude'):
 | 
			
		||||
        """Get latitude or longitude of media from EXIF
 | 
			
		||||
 | 
			
		||||
@ -114,6 +319,7 @@ class Media(Base):
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_exiftool_attributes(self):
 | 
			
		||||
        """Get attributes for the media object from exiftool.
 | 
			
		||||
 | 
			
		||||
@ -185,6 +391,7 @@ class Media(Base):
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_camera_model(self):
 | 
			
		||||
        """Get the camera make stored in EXIF.
 | 
			
		||||
 | 
			
		||||
@ -204,6 +411,7 @@ class Media(Base):
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_original_name(self):
 | 
			
		||||
        """Get the original name stored in EXIF.
 | 
			
		||||
 | 
			
		||||
@ -222,6 +430,7 @@ class Media(Base):
 | 
			
		||||
 | 
			
		||||
        return exiftool_attributes[self.original_name_key]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_title(self):
 | 
			
		||||
        """Get the title for a photo of video
 | 
			
		||||
 | 
			
		||||
@ -235,17 +444,19 @@ class Media(Base):
 | 
			
		||||
        if exiftool_attributes is None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        if(self.title_key not in exiftool_attributes):
 | 
			
		||||
            return None
 | 
			
		||||
        for title_key in self.title_keys:
 | 
			
		||||
            if title_key in exiftool_attributes:
 | 
			
		||||
                return exiftool_attributes[title_key]
 | 
			
		||||
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
        return exiftool_attributes[self.title_key]
 | 
			
		||||
 | 
			
		||||
    def reset_cache(self):
 | 
			
		||||
        """Resets any internal cache
 | 
			
		||||
        """
 | 
			
		||||
        self.exiftool_attributes = None
 | 
			
		||||
        self.exif_metadata = None
 | 
			
		||||
        super(Media, self).reset_cache()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def set_album(self, name, path):
 | 
			
		||||
        """Set album EXIF tag if not already set.
 | 
			
		||||
@ -255,12 +466,16 @@ class Media(Base):
 | 
			
		||||
        if self.get_album() is not None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        tags = {self.album_keys[0]: name}
 | 
			
		||||
        status = ExifTool().set_tags(tags, path)
 | 
			
		||||
        tags = {}
 | 
			
		||||
        for key in self.album_keys:
 | 
			
		||||
            tags[key] = name
 | 
			
		||||
        status = self.__set_tags(tags, path)
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
        return status != ''
 | 
			
		||||
 | 
			
		||||
    def set_date_original(self, time):
 | 
			
		||||
        return status
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def set_date_original(self, time, path):
 | 
			
		||||
        """Set the date/time a photo was taken.
 | 
			
		||||
 | 
			
		||||
        :param datetime time: datetime object of when the photo was taken
 | 
			
		||||
@ -274,31 +489,39 @@ class Media(Base):
 | 
			
		||||
        for key in self.date_original:
 | 
			
		||||
            tags[key] = formatted_time
 | 
			
		||||
 | 
			
		||||
        status = self.__set_tags(tags)
 | 
			
		||||
        status = self.__set_tags(tags, path)
 | 
			
		||||
        if status == False:
 | 
			
		||||
            # exif attribute date_original d'ont exist
 | 
			
		||||
            for key in self.date_created:
 | 
			
		||||
                tags[key] = formatted_time
 | 
			
		||||
 | 
			
		||||
            status = self.__set_tags(tags)
 | 
			
		||||
            status = self.__set_tags(tags, path)
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
        return status
 | 
			
		||||
 | 
			
		||||
    def set_location(self, latitude, longitude):
 | 
			
		||||
 | 
			
		||||
    def set_location(self, latitude, longitude, path):
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        # The lat/lon _keys array has an order of precedence.
 | 
			
		||||
        # The first key is writable and we will give the writable
 | 
			
		||||
        #   key precence when reading.
 | 
			
		||||
        tags = {
 | 
			
		||||
            self.latitude_keys[0]: latitude,
 | 
			
		||||
            self.longitude_keys[0]: longitude,
 | 
			
		||||
        }
 | 
			
		||||
        # TODO check
 | 
			
		||||
        # tags = {
 | 
			
		||||
        #     self.latitude_keys[0]: latitude,
 | 
			
		||||
        #     self.longitude_keys[0]: longitude,
 | 
			
		||||
        # }
 | 
			
		||||
        tags = {}
 | 
			
		||||
        for key in self.latitude_keys:
 | 
			
		||||
            tags[key] = latitude
 | 
			
		||||
        for key in self.longitude_keys:
 | 
			
		||||
            tags[key] = longitude
 | 
			
		||||
 | 
			
		||||
        # If self.set_gps_ref == True then it means we are writing an EXIF
 | 
			
		||||
        #   GPS tag which requires us to set the reference key.
 | 
			
		||||
        # That's because the lat/lon are absolute values.
 | 
			
		||||
        # TODO set_gps_ref = False for Video ?
 | 
			
		||||
        if self.set_gps_ref:
 | 
			
		||||
            if latitude < 0:
 | 
			
		||||
                tags[self.latitude_ref_key] = 'S'
 | 
			
		||||
@ -306,12 +529,13 @@ class Media(Base):
 | 
			
		||||
            if longitude < 0:
 | 
			
		||||
                tags[self.longitude_ref_key] = 'W'
 | 
			
		||||
 | 
			
		||||
        status = self.__set_tags(tags)
 | 
			
		||||
        status = self.__set_tags(tags, path)
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
 | 
			
		||||
        return status
 | 
			
		||||
 | 
			
		||||
    def set_original_name(self, path):
 | 
			
		||||
 | 
			
		||||
    def set_original_name(self, path, name=None):
 | 
			
		||||
        """Sets the original name EXIF tag if not already set.
 | 
			
		||||
 | 
			
		||||
        :returns: True, False, None
 | 
			
		||||
@ -320,14 +544,17 @@ class Media(Base):
 | 
			
		||||
        if self.get_original_name() is not None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        name = os.path.basename(path)
 | 
			
		||||
        if name == None:
 | 
			
		||||
            name = os.path.basename(self.source)
 | 
			
		||||
 | 
			
		||||
        tags = {self.original_name_key: name}
 | 
			
		||||
        status = ExifTool().set_tags(tags, path)
 | 
			
		||||
        status = self.__set_tags(tags, path)
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
        return status != ''
 | 
			
		||||
 | 
			
		||||
    def set_title(self, title):
 | 
			
		||||
        return status
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def set_title(self, title, path):
 | 
			
		||||
        """Set title for a photo.
 | 
			
		||||
 | 
			
		||||
        :param str title: Title of the photo.
 | 
			
		||||
@ -339,23 +566,43 @@ class Media(Base):
 | 
			
		||||
        if(title is None):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        tags = {self.title_key: title}
 | 
			
		||||
        status = self.__set_tags(tags)
 | 
			
		||||
        tags = {}
 | 
			
		||||
        for key in self.title_keys:
 | 
			
		||||
            tags[key] = title
 | 
			
		||||
        status = self.__set_tags(tags, path)
 | 
			
		||||
        self.reset_cache()
 | 
			
		||||
 | 
			
		||||
        return status
 | 
			
		||||
 | 
			
		||||
    def __set_tags(self, tags):
 | 
			
		||||
 | 
			
		||||
    def __set_tags(self, tags, path):
 | 
			
		||||
        if(not self.is_valid()):
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        source = self.source
 | 
			
		||||
 | 
			
		||||
        status = ''
 | 
			
		||||
        status = ExifTool().set_tags(tags,source)
 | 
			
		||||
        status = ExifTool().set_tags(tags, path)
 | 
			
		||||
        if status.decode().find('unchanged') != -1 or status == '':
 | 
			
		||||
            return False
 | 
			
		||||
        if status.decode().find('error') != -1:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_all_subclasses(cls=None):
 | 
			
		||||
    """Module method to get all subclasses of Media.
 | 
			
		||||
    """
 | 
			
		||||
    subclasses = set()
 | 
			
		||||
 | 
			
		||||
    this_class = Media
 | 
			
		||||
    if cls is not None:
 | 
			
		||||
        this_class = cls
 | 
			
		||||
 | 
			
		||||
    subclasses.add(this_class)
 | 
			
		||||
 | 
			
		||||
    this_class_subclasses = this_class.__subclasses__()
 | 
			
		||||
    for child_class in this_class_subclasses:
 | 
			
		||||
        subclasses.update(get_all_subclasses(child_class))
 | 
			
		||||
 | 
			
		||||
    return subclasses
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ class Photo(Media):
 | 
			
		||||
    extensions = ('arw', 'cr2', 'dng', 'gif', 'heic', 'jpeg', 'jpg', 'nef', 'png', 'rw2')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, source=None):
 | 
			
		||||
        super(Photo, self).__init__(source)
 | 
			
		||||
        super().__init__(source)
 | 
			
		||||
 | 
			
		||||
        # We only want to parse EXIF once so we store it here
 | 
			
		||||
        self.exif = None
 | 
			
		||||
 | 
			
		||||
@ -28,31 +28,9 @@ class Video(Media):
 | 
			
		||||
    extensions = ('avi', 'm4v', 'mov', 'mp4', 'mpg', 'mpeg', '3gp', 'mts')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, source=None):
 | 
			
		||||
        super(Video, self).__init__(source)
 | 
			
		||||
        self.date_original = [
 | 
			
		||||
            'EXIF:DateTimeOriginal',
 | 
			
		||||
            'H264:DateTimeOriginal',
 | 
			
		||||
            'QuickTime:ContentCreateDate'
 | 
			
		||||
        ]
 | 
			
		||||
        self.date_created = [
 | 
			
		||||
            'EXIF:CreateDate',
 | 
			
		||||
            'QuickTime:CreationDate',
 | 
			
		||||
            'QuickTime:CreateDate',
 | 
			
		||||
            'QuickTime:CreationDate-und-US',
 | 
			
		||||
            'QuickTime:MediaCreateDate'
 | 
			
		||||
        ]
 | 
			
		||||
        self.date_modified = ['File:FileModifyDate']
 | 
			
		||||
        self.title_key = 'XMP:DisplayName'
 | 
			
		||||
        self.latitude_keys = [
 | 
			
		||||
            'XMP:GPSLatitude',
 | 
			
		||||
            # 'QuickTime:GPSLatitude',
 | 
			
		||||
            'Composite:GPSLatitude'
 | 
			
		||||
        ]
 | 
			
		||||
        self.longitude_keys = [
 | 
			
		||||
            'XMP:GPSLongitude',
 | 
			
		||||
            # 'QuickTime:GPSLongitude',
 | 
			
		||||
            'Composite:GPSLongitude'
 | 
			
		||||
        ]
 | 
			
		||||
        self.latitude_ref_key = 'EXIF:GPSLatitudeRef'
 | 
			
		||||
        self.longitude_ref_key = 'EXIF:GPSLongitudeRef'
 | 
			
		||||
        self.set_gps_ref = False
 | 
			
		||||
        super().__init__(source)
 | 
			
		||||
        # self.set_gps_ref = False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def is_valid(self):
 | 
			
		||||
        return super().is_valid()
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,7 @@ from elodie import log
 | 
			
		||||
from elodie.compatability import _decode
 | 
			
		||||
from elodie.filesystem import FileSystem
 | 
			
		||||
from elodie.localstorage import Db
 | 
			
		||||
from elodie.media.base import Base, get_all_subclasses
 | 
			
		||||
from elodie.media.media import Media
 | 
			
		||||
from elodie.media.media import Media, get_all_subclasses
 | 
			
		||||
from elodie.media.audio import Audio
 | 
			
		||||
from elodie.media.photo import Photo
 | 
			
		||||
from elodie.media.video import Video
 | 
			
		||||
 | 
			
		||||
@ -1,138 +0,0 @@
 | 
			
		||||
# Project imports
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import hashlib
 | 
			
		||||
import random
 | 
			
		||||
import re
 | 
			
		||||
import shutil
 | 
			
		||||
import string
 | 
			
		||||
import tempfile
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
 | 
			
		||||
 | 
			
		||||
import helper
 | 
			
		||||
from elodie.media.base import Base, get_all_subclasses
 | 
			
		||||
from elodie.media.media import Media
 | 
			
		||||
from elodie.media.audio import Audio
 | 
			
		||||
from elodie.media.photo import Photo
 | 
			
		||||
from elodie.media.video import Video
 | 
			
		||||
 | 
			
		||||
os.environ['TZ'] = 'GMT'
 | 
			
		||||
 | 
			
		||||
setup_module = helper.setup_module
 | 
			
		||||
teardown_module = helper.teardown_module
 | 
			
		||||
 | 
			
		||||
def test_get_all_subclasses():
 | 
			
		||||
    subclasses = get_all_subclasses(Base)
 | 
			
		||||
    expected = {Media, Base, Photo, Video, Audio}
 | 
			
		||||
    assert subclasses == expected, subclasses
 | 
			
		||||
 | 
			
		||||
def test_get_class_by_file_without_extension():
 | 
			
		||||
    base_file = helper.get_file('withoutextension')
 | 
			
		||||
 | 
			
		||||
    cls = Base.get_class_by_file(base_file, [Audio, Photo, Video])
 | 
			
		||||
    
 | 
			
		||||
    assert cls is None, cls
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
def test_set_album_from_folder_invalid_file():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    base_file = helper.get_file('invalid.jpg')
 | 
			
		||||
    origin = '%s/invalid.jpg' % folder
 | 
			
		||||
 | 
			
		||||
    shutil.copyfile(base_file, origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
    status = media.set_album_from_folder()
 | 
			
		||||
 | 
			
		||||
    assert status == False, status
 | 
			
		||||
 | 
			
		||||
def test_set_album_from_folder():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    photo = Photo(origin)
 | 
			
		||||
    metadata = photo.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert metadata['album'] is None, metadata['album']
 | 
			
		||||
 | 
			
		||||
    new_album_name = os.path.split(folder)[1]
 | 
			
		||||
    status = photo.set_album_from_folder()
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata_new = photo_new.get_metadata()
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
    assert metadata_new['album'] == new_album_name, metadata_new['album']
 | 
			
		||||
 | 
			
		||||
def test_set_metadata():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    photo = Photo(origin)
 | 
			
		||||
 | 
			
		||||
    metadata = photo.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert metadata['title'] == None, metadata['title']
 | 
			
		||||
 | 
			
		||||
    new_title = 'Some Title'
 | 
			
		||||
    photo.set_metadata(title = new_title)
 | 
			
		||||
 | 
			
		||||
    new_metadata = photo.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert new_metadata['title'] == new_title, new_metadata['title']
 | 
			
		||||
 | 
			
		||||
def test_set_metadata_basename():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    photo = Photo(origin)
 | 
			
		||||
 | 
			
		||||
    metadata = photo.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert metadata['base_name'] == 'photo', metadata['base_name']
 | 
			
		||||
 | 
			
		||||
    new_basename = 'Some Base Name'
 | 
			
		||||
    photo.set_metadata_basename(new_basename)
 | 
			
		||||
 | 
			
		||||
    new_metadata = photo.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert new_metadata['base_name'] == new_basename, new_metadata['base_name']
 | 
			
		||||
@ -8,7 +8,6 @@ import tempfile
 | 
			
		||||
import time
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
 | 
			
		||||
 | 
			
		||||
import helper
 | 
			
		||||
@ -100,16 +99,16 @@ def test_set_date_original():
 | 
			
		||||
    origin = '%s/audio.m4a' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
    audio = Audio(origin)
 | 
			
		||||
    date = datetime(2013, 9, 30, 7, 6, 5)
 | 
			
		||||
    status = media.set_date_original(date)
 | 
			
		||||
    status = audio.set_date_original(date)
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    audio_new = Audio(origin)
 | 
			
		||||
    metadata = audio_new.get_metadata()
 | 
			
		||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    date_original = metadata['date_created']
 | 
			
		||||
    date_original = metadata['date_original']
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -134,7 +133,7 @@ def test_set_location():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    audio_new = Audio(origin)
 | 
			
		||||
    metadata = audio_new.get_metadata()
 | 
			
		||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -160,7 +159,7 @@ def test_set_location_minus():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    audio_new = Audio(origin)
 | 
			
		||||
    metadata = audio_new.get_metadata()
 | 
			
		||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -202,7 +201,7 @@ def test_set_title_non_ascii():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    audio_new = Audio(origin)
 | 
			
		||||
    metadata = audio_new.get_metadata()
 | 
			
		||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -9,13 +9,13 @@ import shutil
 | 
			
		||||
import string
 | 
			
		||||
import tempfile
 | 
			
		||||
import time
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
 | 
			
		||||
 | 
			
		||||
import helper
 | 
			
		||||
from elodie.media.media import Media, get_all_subclasses
 | 
			
		||||
from elodie.media.audio import Audio
 | 
			
		||||
from elodie.media.media import Media
 | 
			
		||||
from elodie.media.photo import Photo
 | 
			
		||||
from elodie.media.video import Video
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,119 @@ os.environ['TZ'] = 'GMT'
 | 
			
		||||
setup_module = helper.setup_module
 | 
			
		||||
teardown_module = helper.teardown_module
 | 
			
		||||
 | 
			
		||||
def test_get_all_subclasses():
 | 
			
		||||
    subclasses = get_all_subclasses(Media)
 | 
			
		||||
    expected = {Media, Photo, Video, Audio}
 | 
			
		||||
    assert subclasses == expected, subclasses
 | 
			
		||||
 | 
			
		||||
def test_get_class_by_file_without_extension():
 | 
			
		||||
    base_file = helper.get_file('withoutextension')
 | 
			
		||||
 | 
			
		||||
    cls = Media.get_class_by_file(base_file, [Audio, Photo, Video])
 | 
			
		||||
 | 
			
		||||
    assert cls is None, cls
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
def test_set_album_from_folder_invalid_file():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    base_file = helper.get_file('invalid.jpg')
 | 
			
		||||
    origin = '%s/invalid.jpg' % folder
 | 
			
		||||
 | 
			
		||||
    shutil.copyfile(base_file, origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
    status = media.set_album_from_folder(origin)
 | 
			
		||||
 | 
			
		||||
    assert status == False, status
 | 
			
		||||
 | 
			
		||||
def test_set_album_from_folder():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
    metadata = media.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert metadata['album'] is None, metadata['album']
 | 
			
		||||
 | 
			
		||||
    new_album_name = os.path.split(folder)[1]
 | 
			
		||||
    status = media.set_album_from_folder(origin)
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    media_new = Media(origin)
 | 
			
		||||
    metadata_new = media_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
    assert metadata_new['album'] == new_album_name, metadata_new['album']
 | 
			
		||||
 | 
			
		||||
def test_set_metadata():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
 | 
			
		||||
    metadata = media.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert metadata['title'] == None, metadata['title']
 | 
			
		||||
 | 
			
		||||
    new_title = 'Some Title'
 | 
			
		||||
    media.set_metadata(title = new_title)
 | 
			
		||||
 | 
			
		||||
    new_metadata = media.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert new_metadata['title'] == new_title, new_metadata['title']
 | 
			
		||||
 | 
			
		||||
def test_set_metadata_basename():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
 | 
			
		||||
    metadata = media.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert metadata['base_name'] == 'photo', metadata['base_name']
 | 
			
		||||
 | 
			
		||||
    new_basename = 'Some Base Name'
 | 
			
		||||
    media.set_metadata_basename(new_basename)
 | 
			
		||||
 | 
			
		||||
    new_metadata = media.get_metadata()
 | 
			
		||||
 | 
			
		||||
    assert new_metadata['base_name'] == new_basename, new_metadata['base_name']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_get_file_path():
 | 
			
		||||
    media = Media(helper.get_file('plain.jpg'))
 | 
			
		||||
    path = media.get_file_path()
 | 
			
		||||
@ -63,32 +176,6 @@ def test_get_class_by_file_invalid_type():
 | 
			
		||||
                                    [Photo, Video, Audio])
 | 
			
		||||
    assert media is None
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
def test_set_original_name_when_exists():
 | 
			
		||||
    temporary_folder, folder = helper.create_working_folder()
 | 
			
		||||
 | 
			
		||||
@ -98,7 +185,7 @@ def test_set_original_name_when_exists():
 | 
			
		||||
    shutil.copyfile(file, origin)
 | 
			
		||||
 | 
			
		||||
    media = Media.get_class_by_file(origin, [Photo])
 | 
			
		||||
    result = media.set_original_name()
 | 
			
		||||
    result = media.set_original_name(origin)
 | 
			
		||||
 | 
			
		||||
    assert result is None, result
 | 
			
		||||
 | 
			
		||||
@ -112,8 +199,8 @@ def test_set_original_name_when_does_not_exist():
 | 
			
		||||
 | 
			
		||||
    media = Media.get_class_by_file(origin, [Photo])
 | 
			
		||||
    metadata_before = media.get_metadata()
 | 
			
		||||
    result = media.set_original_name()
 | 
			
		||||
    metadata_after = media.get_metadata()
 | 
			
		||||
    result = media.set_original_name(origin)
 | 
			
		||||
    metadata_after = media.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    assert metadata_before['original_name'] is None, metadata_before
 | 
			
		||||
    assert metadata_after['original_name'] == 'plain.jpg', metadata_after
 | 
			
		||||
@ -132,7 +219,7 @@ def test_set_original_name_with_arg():
 | 
			
		||||
    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()
 | 
			
		||||
    metadata_after = media.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    assert metadata_before['original_name'] is None, metadata_before
 | 
			
		||||
    assert metadata_after['original_name'] == new_name, metadata_after
 | 
			
		||||
@ -154,10 +241,10 @@ def test_set_original_name():
 | 
			
		||||
 | 
			
		||||
        shutil.copyfile(file_path, origin)
 | 
			
		||||
 | 
			
		||||
        media = Media.get_class_by_file(origin, [Audio, Media, Photo, Video])
 | 
			
		||||
        media = Media.get_class_by_file(origin, [Audio, Photo, Video])
 | 
			
		||||
        metadata = media.get_metadata()
 | 
			
		||||
        media.set_original_name()
 | 
			
		||||
        metadata_updated = media.get_metadata()
 | 
			
		||||
        media.set_original_name(origin)
 | 
			
		||||
        metadata_updated = media.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
        shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ import time
 | 
			
		||||
 | 
			
		||||
from nose.plugins.skip import SkipTest
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
 | 
			
		||||
 | 
			
		||||
import helper
 | 
			
		||||
@ -122,8 +121,8 @@ def test_get_coordinates_with_null_coordinate():
 | 
			
		||||
    assert longitude is None, longitude
 | 
			
		||||
 | 
			
		||||
def test_get_date_original():
 | 
			
		||||
    media = Media(helper.get_file('plain.jpg'))
 | 
			
		||||
    date_original = media.get_date_attribute(['EXIF:DateTimeOriginal'])
 | 
			
		||||
    photo = Photo(helper.get_file('plain.jpg'))
 | 
			
		||||
    date_original = photo.get_date_attribute(['EXIF:DateTimeOriginal'])
 | 
			
		||||
 | 
			
		||||
    #assert date_original == (2015, 12, 5, 0, 59, 26, 5, 339, 0), date_original
 | 
			
		||||
    assert date_original == datetime(2015, 12, 5, 0, 59, 26), date_original
 | 
			
		||||
@ -174,12 +173,12 @@ def test_set_album():
 | 
			
		||||
 | 
			
		||||
    assert metadata['album'] is None, metadata['album']
 | 
			
		||||
 | 
			
		||||
    status = photo.set_album('Test Album')
 | 
			
		||||
    status = photo.set_album('Test Album', origin)
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata_new = photo_new.get_metadata()
 | 
			
		||||
    metadata_new = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -193,14 +192,14 @@ def test_set_date_original_with_missing_datetimeoriginal():
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('no-exif.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
    photo = Photo(origin)
 | 
			
		||||
    time = datetime(2013, 9, 30, 7, 6, 5)
 | 
			
		||||
    status = media.set_date_original(time)
 | 
			
		||||
    status = photo.set_date_original(time)
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata()
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    date_original = metadata['date_original']
 | 
			
		||||
 | 
			
		||||
@ -216,13 +215,13 @@ def test_set_date_original():
 | 
			
		||||
    origin = '%s/photo.jpg' % folder
 | 
			
		||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
			
		||||
 | 
			
		||||
    media = Media(origin)
 | 
			
		||||
    status = media.set_date_original(datetime(2013, 9, 30, 7, 6, 5))
 | 
			
		||||
    photo = Photo(origin)
 | 
			
		||||
    status = photo.set_date_original(datetime(2013, 9, 30, 7, 6, 5))
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    media_new = Media(origin)
 | 
			
		||||
    metadata = media_new.get_metadata()
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    date_original = metadata['date_original']
 | 
			
		||||
 | 
			
		||||
@ -250,7 +249,7 @@ def test_set_location():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata()
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -276,7 +275,7 @@ def test_set_location_minus():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata()
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -297,7 +296,7 @@ def test_set_title():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata()
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -318,7 +317,7 @@ def test_set_title_non_ascii():
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata()
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -395,7 +394,7 @@ def _test_photo_type_set(type, date):
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
    photo_new = Photo(origin)
 | 
			
		||||
    metadata = photo_new.get_metadata()
 | 
			
		||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
			
		||||
 | 
			
		||||
    shutil.rmtree(folder)
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,6 @@ import time
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from dateutil.parser import parse
 | 
			
		||||
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))
 | 
			
		||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
 | 
			
		||||
 | 
			
		||||
import helper
 | 
			
		||||
@ -102,7 +101,7 @@ def test_set_album():
 | 
			
		||||
 | 
			
		||||
    assert metadata['album'] is None, metadata['album']
 | 
			
		||||
 | 
			
		||||
    status = video.set_album('Test Album')
 | 
			
		||||
    status = video.set_album('Test Album', origin)
 | 
			
		||||
 | 
			
		||||
    assert status == True, status
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user