Fix tests and cleanup
@ -1,154 +0,0 @@
 | 
				
			|||||||
from builtins import range
 | 
					 | 
				
			||||||
from past.utils import old_div
 | 
					 | 
				
			||||||
import hashlib
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import random
 | 
					 | 
				
			||||||
import string
 | 
					 | 
				
			||||||
import tempfile
 | 
					 | 
				
			||||||
import re
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import urllib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from datetime import datetime
 | 
					 | 
				
			||||||
from datetime import timedelta
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie.external.pyexiftool import ExifTool
 | 
					 | 
				
			||||||
from elodie.dependencies import get_exiftool
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ELODIE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def create_working_folder(format=None):
 | 
					 | 
				
			||||||
    temporary_folder = tempfile.gettempdir()
 | 
					 | 
				
			||||||
    folder = tempfile.TemporaryDirectory(prefix='elodie-').name
 | 
					 | 
				
			||||||
    folder = os.path.join(folder, random_string(10, format))
 | 
					 | 
				
			||||||
    os.makedirs(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (temporary_folder, folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def download_file(name, destination):
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        url_to_file = 'https://s3.amazonaws.com/jmathai/github/elodie/{}'.format(name)
 | 
					 | 
				
			||||||
        # urlretrieve works differently for python 2 and 3
 | 
					 | 
				
			||||||
        if constants.python_version < 3:
 | 
					 | 
				
			||||||
            final_name = '{}/{}{}'.format(destination, random_string(10), os.path.splitext(name)[1])
 | 
					 | 
				
			||||||
            urllib.urlretrieve(
 | 
					 | 
				
			||||||
                url_to_file,
 | 
					 | 
				
			||||||
                final_name
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            final_name, headers = urllib.request.urlretrieve(url_to_file)
 | 
					 | 
				
			||||||
        return final_name
 | 
					 | 
				
			||||||
    except Exception as e:
 | 
					 | 
				
			||||||
        return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_file(name):
 | 
					 | 
				
			||||||
    file_path = get_file_path(name)
 | 
					 | 
				
			||||||
    if not os.path.isfile(file_path):
 | 
					 | 
				
			||||||
        return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return file_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_file_path(name):
 | 
					 | 
				
			||||||
    return os.path.join(ELODIE_PATH, 'samples', name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_test_location():
 | 
					 | 
				
			||||||
    return (61.013710, 99.196656, 'Siberia')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def populate_folder(number_of_files, include_invalid=False):
 | 
					 | 
				
			||||||
    temporary_folder, folder = create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for x in range(0, number_of_files):
 | 
					 | 
				
			||||||
        ext = 'jpg' if x % 2 == 0 else 'txt'
 | 
					 | 
				
			||||||
        fname = '%s/%s.%s' % (folder, x, ext)
 | 
					 | 
				
			||||||
        with open(fname, 'a'):
 | 
					 | 
				
			||||||
            os.utime(fname, None)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if include_invalid:
 | 
					 | 
				
			||||||
        fname = '%s/%s' % (folder, 'invalid.invalid')
 | 
					 | 
				
			||||||
        with open(fname, 'a'):
 | 
					 | 
				
			||||||
            os.utime(fname, None)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return folder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def random_string(length, format=None):
 | 
					 | 
				
			||||||
    format_choice = string.ascii_uppercase + string.digits
 | 
					 | 
				
			||||||
    if format == 'int':
 | 
					 | 
				
			||||||
        format_choice = string.digits
 | 
					 | 
				
			||||||
    elif format == 'str':
 | 
					 | 
				
			||||||
        format_choice = string.asci_uppercase
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return ''.join(random.SystemRandom().choice(format_choice) for _ in range(length))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def random_decimal():
 | 
					 | 
				
			||||||
    return random.random()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def random_coordinate(coordinate, precision):
 | 
					 | 
				
			||||||
    # Here we add to the decimal section of the coordinate by a given precision
 | 
					 | 
				
			||||||
    return coordinate + ((old_div(10.0, (10.0**precision))) * random_decimal())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def temp_dir():
 | 
					 | 
				
			||||||
    return tempfile.gettempdir()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def is_windows():
 | 
					 | 
				
			||||||
    return os.name == 'nt'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# path_tz_fix(file_name)
 | 
					 | 
				
			||||||
# Change timestamp in file_name by the offset
 | 
					 | 
				
			||||||
# between UTC and local time, i.e.
 | 
					 | 
				
			||||||
#  2015-12-05_00-59-26-with-title-some-title.jpg ->
 | 
					 | 
				
			||||||
#  2015-12-04_20-59-26-with-title-some-title.jpg
 | 
					 | 
				
			||||||
# (Windows only)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def path_tz_fix(file_name):
 | 
					 | 
				
			||||||
  if is_windows():
 | 
					 | 
				
			||||||
      # Calculate the offset between UTC and local time
 | 
					 | 
				
			||||||
      tz_shift = old_div((datetime.fromtimestamp(0) -
 | 
					 | 
				
			||||||
                  datetime.utcfromtimestamp(0)).seconds,3600)
 | 
					 | 
				
			||||||
      # replace timestamp in file_name
 | 
					 | 
				
			||||||
      m = re.search('(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})',file_name)
 | 
					 | 
				
			||||||
      t_date = datetime.fromtimestamp(time.mktime(time.strptime(m.group(0), '%Y-%m-%d_%H-%M-%S')))
 | 
					 | 
				
			||||||
      s_date_fix = (t_date-timedelta(hours=tz_shift)).strftime('%Y-%m-%d_%H-%M-%S')
 | 
					 | 
				
			||||||
      return re.sub('\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}',s_date_fix,file_name)
 | 
					 | 
				
			||||||
  else:
 | 
					 | 
				
			||||||
      return file_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# time_convert(s_time)
 | 
					 | 
				
			||||||
# Change s_time (struct_time) by the offset
 | 
					 | 
				
			||||||
# between UTC and local time
 | 
					 | 
				
			||||||
# (Windows only)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def time_convert(s_time):
 | 
					 | 
				
			||||||
    if is_windows():
 | 
					 | 
				
			||||||
        return time.gmtime((time.mktime(s_time)))
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
        return s_time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# isclose(a,b,rel_tol)
 | 
					 | 
				
			||||||
# To compare float coordinates a and b
 | 
					 | 
				
			||||||
# with relative tolerance c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def isclose(a, b, rel_tol = 1e-8):
 | 
					 | 
				
			||||||
    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
 | 
					 | 
				
			||||||
        return False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    diff = abs(a - b)
 | 
					 | 
				
			||||||
    return (diff <= abs(rel_tol * a) and
 | 
					 | 
				
			||||||
            diff <= abs(rel_tol * b))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_hash_db(photo_path):
 | 
					 | 
				
			||||||
    return os.path.join(photo_path, '.elodie',constants.hash_db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_location_db(photo_path):
 | 
					 | 
				
			||||||
    return os.path.join(photo_path, '.elodie', constants.location_db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def setup_module():
 | 
					 | 
				
			||||||
    exiftool_addedargs = [
 | 
					 | 
				
			||||||
            u'-config',
 | 
					 | 
				
			||||||
            u'"{}"'.format(constants.exiftool_config)
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    ExifTool(executable_=get_exiftool(), addedargs=exiftool_addedargs).start()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def teardown_module():
 | 
					 | 
				
			||||||
    ExifTool().terminate
 | 
					 | 
				
			||||||
@ -1,208 +0,0 @@
 | 
				
			|||||||
# -*- coding: utf-8
 | 
					 | 
				
			||||||
# Project imports
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
import tempfile
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
from datetime import datetime
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
from elodie.media.video import Video
 | 
					 | 
				
			||||||
from elodie.media.audio import Audio
 | 
					 | 
				
			||||||
from elodie.external.pyexiftool import ExifTool
 | 
					 | 
				
			||||||
from elodie.dependencies import get_exiftool
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os.environ['TZ'] = 'GMT'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def setup_module():
 | 
					 | 
				
			||||||
    exiftool_addedargs = [
 | 
					 | 
				
			||||||
            u'-config',
 | 
					 | 
				
			||||||
            u'"{}"'.format(constants.exiftool_config)
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    ExifTool(executable_=get_exiftool(), addedargs=exiftool_addedargs).start()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def teardown_module():
 | 
					 | 
				
			||||||
    ExifTool().terminate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_audio_extensions():
 | 
					 | 
				
			||||||
    audio = Audio()
 | 
					 | 
				
			||||||
    extensions = audio.extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'm4a' in extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    valid_extensions = Audio.get_valid_extensions()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert extensions == valid_extensions, valid_extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    coordinate = audio.get_coordinate()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate, 29.758938), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_make():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    coordinate = audio.get_camera_make()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert coordinate is None, coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_model():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    coordinate = audio.get_camera_model()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert coordinate is None, coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_latitude():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    coordinate = audio.get_coordinate('latitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate, 29.758938), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_longitude():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    coordinate = audio.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate, -95.3677), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_date_original():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    date_created = audio.get_date_attribute(audio.date_original)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert date_created.strftime('%Y-%m-%d %H:%M:%S') == '2016-01-03 21:23:39', date_created
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_exiftool_attributes():
 | 
					 | 
				
			||||||
    audio = Video(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
    exif = audio.get_exiftool_attributes()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert exif is not None, exif
 | 
					 | 
				
			||||||
    assert exif is not False, exif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_valid():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('audio.m4a'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert audio.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_not_valid():
 | 
					 | 
				
			||||||
    audio = Audio(helper.get_file('photo.png'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert not audio.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_date_original():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    date = datetime(2013, 9, 30, 7, 6, 5)
 | 
					 | 
				
			||||||
    status = audio.set_date_original(date, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_new = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    date_original = metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert date_original == date, date_original
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_location():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    origin_metadata = audio.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Verify that original audio has different location info that what we
 | 
					 | 
				
			||||||
    #   will be setting and checking
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['latitude'], 11.1111111111), origin_metadata['latitude']
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['longitude'], 99.9999999999), origin_metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = audio.set_location(11.1111111111, 99.9999999999, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_new = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['latitude'], 11.1111111111), metadata['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['longitude'], 99.9999999999), metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_location_minus():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    origin_metadata = audio.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Verify that original audio has different location info that what we
 | 
					 | 
				
			||||||
    #   will be setting and checking
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['latitude'], 11.111111), origin_metadata['latitude']
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['longitude'], 99.999999), origin_metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = audio.set_location(-11.111111, -99.999999, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_new = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['latitude'], -11.111111), metadata['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['longitude'], -99.999999), metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_title():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    origin_metadata = audio.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = audio.set_title('my audio title', origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_new = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio_new.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['title'] == 'my audio title', metadata['title']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_title_non_ascii():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    origin_metadata = audio.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unicode_title = u'形声字 / 形聲字'
 | 
					 | 
				
			||||||
    status = audio.set_title(unicode_title, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_new = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['title'] == unicode_title, metadata['title']
 | 
					 | 
				
			||||||
@ -1,271 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import hashlib
 | 
					 | 
				
			||||||
import random
 | 
					 | 
				
			||||||
import re
 | 
					 | 
				
			||||||
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.realpath(__file__)))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import helper
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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_media_class(_file):
 | 
					 | 
				
			||||||
#     pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 not None, cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_exiftool_attribute():
 | 
					 | 
				
			||||||
    file_path = helper.get_file('invalid.jpg')
 | 
					 | 
				
			||||||
    ignore_tags = ('File:FileModifyDate', 'File:FileAccessDate')
 | 
					 | 
				
			||||||
    media = Media.get_class_by_file(file_path, [Photo], ignore_tags)
 | 
					 | 
				
			||||||
    exif = media.get_exiftool_attributes()
 | 
					 | 
				
			||||||
    for tag in ignore_tags:
 | 
					 | 
				
			||||||
        assert tag not in exif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'plain.jpg' in path, path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_class_by_file_photo():
 | 
					 | 
				
			||||||
    media = Media.get_class_by_file(helper.get_file('plain.jpg'), [Photo, Video])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert media.__name__ == 'Photo'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_class_by_file_video():
 | 
					 | 
				
			||||||
    media = Media.get_class_by_file(helper.get_file('video.mov'), [Photo, Video])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert media.__name__ == 'Video'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_class_by_file_unsupported():
 | 
					 | 
				
			||||||
    media = Media.get_class_by_file(helper.get_file('text.txt'), [Photo, Video])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert media is not None, media
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_class_by_file_ds_store():
 | 
					 | 
				
			||||||
    media = Media.get_class_by_file(helper.get_file('.DS_Store'),
 | 
					 | 
				
			||||||
                                    [Photo, Video, Audio])
 | 
					 | 
				
			||||||
    assert media is None, media
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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(origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert result is None, result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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(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
 | 
					 | 
				
			||||||
    assert result is True, result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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(origin, name=new_name)
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
    assert result is True, result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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, Photo, Video])
 | 
					 | 
				
			||||||
        metadata = media.get_metadata()
 | 
					 | 
				
			||||||
        media.set_original_name(origin)
 | 
					 | 
				
			||||||
        metadata_updated = media.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert metadata['original_name'] is None, metadata['original_name']
 | 
					 | 
				
			||||||
        assert metadata_updated['original_name'] == random_file_name, metadata_updated['original_name']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def is_valid():
 | 
					 | 
				
			||||||
    media = Media()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert not media.is_valid()
 | 
					 | 
				
			||||||
@ -1,403 +0,0 @@
 | 
				
			|||||||
# -*- coding: utf-8
 | 
					 | 
				
			||||||
# Project imports
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from datetime import datetime
 | 
					 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
import tempfile
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from nose.plugins.skip import SkipTest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
from elodie.media.photo import Photo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os.environ['TZ'] = 'GMT'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
setup_module = helper.setup_module
 | 
					 | 
				
			||||||
teardown_module = helper.teardown_module
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_photo_extensions():
 | 
					 | 
				
			||||||
    photo = Photo()
 | 
					 | 
				
			||||||
    extensions = photo.extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'arw' in extensions
 | 
					 | 
				
			||||||
    assert 'cr2' in extensions
 | 
					 | 
				
			||||||
    assert 'dng' in extensions
 | 
					 | 
				
			||||||
    assert 'gif' in extensions
 | 
					 | 
				
			||||||
    assert 'heic' in extensions
 | 
					 | 
				
			||||||
    assert 'jpg' in extensions
 | 
					 | 
				
			||||||
    assert 'jpeg' in extensions
 | 
					 | 
				
			||||||
    assert 'nef' in extensions
 | 
					 | 
				
			||||||
    assert 'png' in extensions
 | 
					 | 
				
			||||||
    assert 'rw2' in extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    valid_extensions = Photo.get_valid_extensions()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert extensions == valid_extensions, valid_extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_empty_album():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('plain.jpg'))
 | 
					 | 
				
			||||||
    assert photo.get_album() is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_has_album():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-album.jpg'))
 | 
					 | 
				
			||||||
    album = photo.get_album()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert album == 'Test Album', album
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_valid():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('plain.jpg'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert photo.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_not_valid():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert not photo.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_metadata_of_invalid_photo():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('invalid.jpg'))
 | 
					 | 
				
			||||||
    metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_default():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location.jpg'))
 | 
					 | 
				
			||||||
    coordinate = photo.get_coordinate()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate,37.3667027222), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_latitude():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location.jpg'))
 | 
					 | 
				
			||||||
    coordinate = photo.get_coordinate('latitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate,37.3667027222), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_latitude_minus():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location-inv.jpg'))
 | 
					 | 
				
			||||||
    coordinate = photo.get_coordinate('latitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate,-37.3667027222), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_longitude():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location.jpg'))
 | 
					 | 
				
			||||||
    coordinate = photo.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate,-122.033383611), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_longitude_plus():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location-inv.jpg'))
 | 
					 | 
				
			||||||
    coordinate = photo.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(coordinate,122.033383611), coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinates_without_exif():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('no-exif.jpg'))
 | 
					 | 
				
			||||||
    latitude = photo.get_coordinate('latitude')
 | 
					 | 
				
			||||||
    longitude = photo.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert latitude is None, latitude
 | 
					 | 
				
			||||||
    assert longitude is None, longitude
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinates_with_zero_coordinate():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location-zero-coordinate.jpg'))
 | 
					 | 
				
			||||||
    latitude = photo.get_coordinate('latitude')
 | 
					 | 
				
			||||||
    longitude = photo.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(latitude,51.55325), latitude
 | 
					 | 
				
			||||||
    assert helper.isclose(longitude,-0.00417777777778), longitude
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinates_with_null_coordinate():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-null-coordinates.jpg'))
 | 
					 | 
				
			||||||
    latitude = photo.get_coordinate('latitude')
 | 
					 | 
				
			||||||
    longitude = photo.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert latitude is None, latitude
 | 
					 | 
				
			||||||
    assert longitude is None, longitude
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_date_original():
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_make():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location.jpg'))
 | 
					 | 
				
			||||||
    make = photo.get_camera_make()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert make == 'Canon', make
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_make_not_set():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('no-exif.jpg'))
 | 
					 | 
				
			||||||
    make = photo.get_camera_make()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert make is None, make
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_model():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('with-location.jpg'))
 | 
					 | 
				
			||||||
    model = photo.get_camera_model()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert model == 'Canon EOS REBEL T2i', model
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_model_not_set():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('no-exif.jpg'))
 | 
					 | 
				
			||||||
    model = photo.get_camera_model()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert model is None, model
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_valid_fallback_using_pillow():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('imghdr-error.jpg'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert photo.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_pillow_not_loaded():
 | 
					 | 
				
			||||||
    photo = Photo(helper.get_file('imghdr-error.jpg'))
 | 
					 | 
				
			||||||
    photo.pillow = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert photo.is_valid() == False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_album():
 | 
					 | 
				
			||||||
    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']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = photo.set_album('Test Album', origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata_new = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata_new['album'] == 'Test Album', metadata_new['album']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_date_original_with_missing_datetimeoriginal():
 | 
					 | 
				
			||||||
    # When datetimeoriginal (or other key) is missing we have to add it gh-74
 | 
					 | 
				
			||||||
    # https://github.com/jmathai/elodie/issues/74
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('no-exif.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    time = datetime(2013, 9, 30, 7, 6, 5)
 | 
					 | 
				
			||||||
    status = photo.set_date_original(time, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    date_original = metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #assert date_original == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_original']
 | 
					 | 
				
			||||||
    # assert date_original == helper.time_convert((2013, 9, 30, 7, 6, 5, 0, 273, 0)), metadata['date_original']
 | 
					 | 
				
			||||||
    assert date_original == time, metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_date_original():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    status = photo.set_date_original(datetime(2013, 9, 30, 7, 6, 5), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    date_original = metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #assert date_original == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_original']
 | 
					 | 
				
			||||||
    assert date_original == datetime(2013, 9, 30, 7, 6, 5), metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_location():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    origin_metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Verify that original photo has different location info that what we
 | 
					 | 
				
			||||||
    #   will be setting and checking
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['latitude'], 11.1111111111), origin_metadata['latitude']
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['longitude'], 99.9999999999), origin_metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = photo.set_location(11.1111111111, 99.9999999999, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['latitude'], 11.1111111111), metadata['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['longitude'], 99.9999999999), metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_location_minus():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    origin_metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Verify that original photo has different location info that what we
 | 
					 | 
				
			||||||
    #   will be setting and checking
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['latitude'], 11.1111111111), origin_metadata['latitude']
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['longitude'], 99.9999999999), origin_metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = photo.set_location(-11.1111111111, -99.9999999999, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['latitude'], -11.1111111111), metadata['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['longitude'], -99.9999999999), metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_title():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    origin_metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = photo.set_title('my photo title', origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['title'] == 'my photo title', metadata['title']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_title_non_ascii():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    origin_metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unicode_title = u'形声字 / 形聲字'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = photo.set_title(unicode_title, origin)
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['title'] == unicode_title, metadata['title']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This is a test generator that will test reading and writing to
 | 
					 | 
				
			||||||
# various RAW formats. Each sample file has a different date which
 | 
					 | 
				
			||||||
# is the only information which needs to be added to run the tests
 | 
					 | 
				
			||||||
# for that file type.
 | 
					 | 
				
			||||||
# https://nose.readthedocs.io/en/latest/writing_tests.html#test-generators
 | 
					 | 
				
			||||||
def test_various_types():
 | 
					 | 
				
			||||||
    types = Photo.extensions
 | 
					 | 
				
			||||||
    #extensions = ('arw', 'cr2', 'dng', 'gif', 'jpeg', 'jpg', 'nef', 'rw2')
 | 
					 | 
				
			||||||
    dates = {
 | 
					 | 
				
			||||||
        'arw': datetime(2007, 4, 8, 17, 41, 18),
 | 
					 | 
				
			||||||
        'cr2': datetime(2005, 10, 29, 16, 14, 44),
 | 
					 | 
				
			||||||
        'dng': datetime(2009, 10, 20, 9, 10, 46),
 | 
					 | 
				
			||||||
        'heic': datetime(2019, 5, 26, 10, 33, 20),
 | 
					 | 
				
			||||||
        'nef': datetime(2008, 10, 24, 9, 12, 56),
 | 
					 | 
				
			||||||
        'png': datetime(2015, 1, 18, 12, 1, 1),
 | 
					 | 
				
			||||||
        'rw2': datetime(2014, 11, 19, 23, 7, 44)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for type in types:
 | 
					 | 
				
			||||||
        if type in dates:
 | 
					 | 
				
			||||||
            yield (_test_photo_type_get, type, dates[type])
 | 
					 | 
				
			||||||
            yield (_test_photo_type_set, type, dates[type])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _test_photo_type_get(type, date):
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_name = 'photo.{}'.format(type)
 | 
					 | 
				
			||||||
    photo_file = helper.get_file(photo_name)
 | 
					 | 
				
			||||||
    origin = '{}/{}'.format(folder, photo_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if not photo_file:
 | 
					 | 
				
			||||||
        photo_file = helper.download_file(photo_name, folder)
 | 
					 | 
				
			||||||
        if not photo_file or not os.path.isfile(photo_file):
 | 
					 | 
				
			||||||
            raise SkipTest('{} file not downloaded'.format(type))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # downloading for each test is costly so we save it in the working directory
 | 
					 | 
				
			||||||
        file_path_save_as = helper.get_file_path(photo_name)
 | 
					 | 
				
			||||||
        if os.path.isfile(photo_file):
 | 
					 | 
				
			||||||
            shutil.copyfile(photo_file, file_path_save_as)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.copyfile(photo_file, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['date_original'] == date, metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _test_photo_type_set(type, date):
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_name = 'photo.{}'.format(type)
 | 
					 | 
				
			||||||
    photo_file = helper.get_file(photo_name)
 | 
					 | 
				
			||||||
    origin = '{}/{}'.format(folder, photo_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if not photo_file:
 | 
					 | 
				
			||||||
        photo_file = helper.download_file(photo_name, folder)
 | 
					 | 
				
			||||||
        if not photo_file or not os.path.isfile(photo_file):
 | 
					 | 
				
			||||||
            raise SkipTest('{} file not downloaded'.format(type))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.copyfile(photo_file, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    origin_metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = photo.set_location(11.1111111111, 99.9999999999, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_new = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo_new.get_metadata(update_cache=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['date_original'] == date, metadata['date_original']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['latitude'], 11.1111111111), '{} lat {}'.format(type, metadata['latitude'])
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['longitude'], 99.9999999999), '{} lon {}'.format(type, metadata['latitude'])
 | 
					 | 
				
			||||||
@ -1,200 +0,0 @@
 | 
				
			|||||||
# -*- coding: utf-8
 | 
					 | 
				
			||||||
# Project imports
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
import tempfile
 | 
					 | 
				
			||||||
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.realpath(__file__)))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import helper
 | 
					 | 
				
			||||||
from elodie.media.media import Media
 | 
					 | 
				
			||||||
from elodie.media.video import Video
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os.environ['TZ'] = 'GMT'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_video_extensions():
 | 
					 | 
				
			||||||
    video = Video()
 | 
					 | 
				
			||||||
    extensions = video.extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'avi' in extensions
 | 
					 | 
				
			||||||
    assert 'm4v' in extensions
 | 
					 | 
				
			||||||
    assert 'mov' in extensions
 | 
					 | 
				
			||||||
    assert 'm4v' in extensions
 | 
					 | 
				
			||||||
    assert '3gp' in extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    valid_extensions = Video.get_valid_extensions()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert extensions == valid_extensions, valid_extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_empty_album():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    assert video.get_album() is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_make():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    print(video.get_metadata())
 | 
					 | 
				
			||||||
    make = video.get_camera_make()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert make == 'Apple', make
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_camera_model():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    model = video.get_camera_model()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert model == 'iPhone 5', model
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    coordinate = video.get_coordinate()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert coordinate == 38.1893, coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_latitude():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    coordinate = video.get_coordinate('latitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert coordinate == 38.1893, coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_coordinate_longitude():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    coordinate = video.get_coordinate('longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert coordinate == -119.9558, coordinate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_date_original():
 | 
					 | 
				
			||||||
    media = Media(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    date_original = media.get_date_attribute(['QuickTime:ContentCreateDate'])
 | 
					 | 
				
			||||||
    date = parse('2015-01-19 12:45:11-08:00')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert date_original == date, date_original
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_exiftool_attributes():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
    exif = video.get_exiftool_attributes()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert exif is not None, exif
 | 
					 | 
				
			||||||
    assert exif is not False, exif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_valid():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('video.mov'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert video.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_is_not_valid():
 | 
					 | 
				
			||||||
    video = Video(helper.get_file('photo.png'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert not video.is_valid()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_album():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video = Video(origin)
 | 
					 | 
				
			||||||
    metadata = video.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['album'] is None, metadata['album']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = video.set_album('Test Album', origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video_new = Video(origin)
 | 
					 | 
				
			||||||
    metadata_new = video_new.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata_new['album'] == 'Test Album', metadata_new['album']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_date_original():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    media = Media(origin)
 | 
					 | 
				
			||||||
    status = media.set_date_original(datetime(2013, 9, 30, 7, 6, 5), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    media_new = Media(origin)
 | 
					 | 
				
			||||||
    metadata = media_new.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    date_original = metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert date_original == datetime(2013, 9, 30, 7, 6, 5), metadata['date_original']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video = Video(origin)
 | 
					 | 
				
			||||||
    origin_metadata = video.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Verify that original video has different location info that what we
 | 
					 | 
				
			||||||
    #   will be setting and checking
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['latitude'], 11.1111111111), origin_metadata['latitude']
 | 
					 | 
				
			||||||
    assert not helper.isclose(origin_metadata['longitude'], 99.9999999999), origin_metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = video.set_location(11.1111111111, 99.9999999999, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video_new = Video(origin)
 | 
					 | 
				
			||||||
    metadata = video_new.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['latitude'], 11.1111111111), metadata['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata['longitude'], 99.9999999999), metadata['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_title():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video = Video(origin)
 | 
					 | 
				
			||||||
    origin_metadata = video.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = video.set_title('my video title', origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video_new = Video(origin)
 | 
					 | 
				
			||||||
    metadata = video_new.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['title'] == 'my video title', metadata['title']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_set_title_non_ascii():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video = Video(origin)
 | 
					 | 
				
			||||||
    origin_metadata = video.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unicode_title = u'形声字 / 形聲字' 
 | 
					 | 
				
			||||||
    status = video.set_title(unicode_title, origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video_new = Video(origin)
 | 
					 | 
				
			||||||
    metadata = video_new.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert metadata['title'] == unicode_title, metadata['title']
 | 
					 | 
				
			||||||
@ -1,189 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
import mock
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
from tempfile import gettempdir
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sys.path.insert(0, os.path.abspath(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.config import load_config
 | 
					 | 
				
			||||||
from elodie.plugins.googlephotos.googlephotos import GooglePhotos
 | 
					 | 
				
			||||||
from elodie.media.audio import Audio
 | 
					 | 
				
			||||||
from elodie.media.photo import Photo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Globals to simplify mocking configs
 | 
					 | 
				
			||||||
auth_file = helper.get_file('plugins/googlephotos/auth_file.json')
 | 
					 | 
				
			||||||
secrets_file = helper.get_file('plugins/googlephotos/secrets_file.json')
 | 
					 | 
				
			||||||
config_string = """
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=GooglePhotos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[PluginGooglePhotos]
 | 
					 | 
				
			||||||
auth_file={}
 | 
					 | 
				
			||||||
secrets_file={}
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
config_string_fmt = config_string.format(
 | 
					 | 
				
			||||||
    auth_file,
 | 
					 | 
				
			||||||
    secrets_file
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
setup_module = helper.setup_module
 | 
					 | 
				
			||||||
teardown_module = helper.teardown_module
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-set-session' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_set_session():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-set-session' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert gp.session is None, gp.session
 | 
					 | 
				
			||||||
    gp.set_session()
 | 
					 | 
				
			||||||
    assert gp.session is not None, gp.session
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-after-supported' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_after_supported():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-after-supported' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sample_photo = Photo(helper.get_file('plain.jpg'))
 | 
					 | 
				
			||||||
    sample_metadata = sample_photo.get_metadata()
 | 
					 | 
				
			||||||
    sample_metadata['original_name'] = 'foobar'
 | 
					 | 
				
			||||||
    final_file_path = helper.get_file('plain.jpg')
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
    gp.after('', '', final_file_path, sample_metadata)
 | 
					 | 
				
			||||||
    db_row = gp.db.get(final_file_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db_row == 'foobar', db_row
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-after-unsupported' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_after_unsupported():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-after-unsupported' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    final_file_path = helper.get_file('audio.m4a')
 | 
					 | 
				
			||||||
    sample_photo = Audio(final_file_path)
 | 
					 | 
				
			||||||
    sample_metadata = sample_photo.get_metadata()
 | 
					 | 
				
			||||||
    sample_metadata['original_name'] = 'foobar'
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
    gp.after('', '', final_file_path, sample_metadata)
 | 
					 | 
				
			||||||
    db_row = gp.db.get(final_file_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db_row == None, db_row
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-upload' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_upload():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-upload' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp.set_session()
 | 
					 | 
				
			||||||
    status = gp.upload(helper.get_file('plain.jpg'))
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert status is not None, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-upload-session-fail' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_upload_session_fail():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-upload-session-fail' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp.set_session()
 | 
					 | 
				
			||||||
    status = gp.upload(helper.get_file('plain.jpg'))
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert status is None, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-upload-invalid-empty' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_upload_invalid_empty():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-upload-invalid-empty' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp.set_session()
 | 
					 | 
				
			||||||
    status = gp.upload(helper.get_file('invalid.jpg'))
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert status is None, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-upload-dne' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_upload_dne():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-upload-dne' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    gp.set_session()
 | 
					 | 
				
			||||||
    status = gp.upload('/file/does/not/exist')
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert status is None, status
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-googlephotos-batch' % gettempdir())
 | 
					 | 
				
			||||||
def test_googlephotos_batch():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-googlephotos-batch' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sample_photo = Photo(helper.get_file('plain.jpg'))
 | 
					 | 
				
			||||||
    sample_metadata = sample_photo.get_metadata()
 | 
					 | 
				
			||||||
    sample_metadata['original_name'] = 'foobar'
 | 
					 | 
				
			||||||
    final_file_path = helper.get_file('plain.jpg')
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
    gp.after('', '', final_file_path, sample_metadata)
 | 
					 | 
				
			||||||
    db_row = gp.db.get(final_file_path)
 | 
					 | 
				
			||||||
    assert db_row == 'foobar', db_row
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status, count = gp.batch()
 | 
					 | 
				
			||||||
    db_row_after = gp.db.get(final_file_path)
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert count == 1, count
 | 
					 | 
				
			||||||
    assert db_row_after is None, db_row_after
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
    gp.set_session()
 | 
					 | 
				
			||||||
    status = gp.upload(helper.get_file('invalid.jpg'))
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert status is None, status
 | 
					 | 
				
			||||||
@ -1,4 +0,0 @@
 | 
				
			|||||||
-r ../../requirements.txt
 | 
					 | 
				
			||||||
flake8==2.6.2
 | 
					 | 
				
			||||||
mock==1.3.0
 | 
					 | 
				
			||||||
nose==1.3.7
 | 
					 | 
				
			||||||
@ -1,128 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import unittest 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from mock import patch
 | 
					 | 
				
			||||||
from tempfile import gettempdir
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
from elodie.config import load_config, load_plugin_config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-singleton-success' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_config_singleton_success():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-singleton-success' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Geolocation]
 | 
					 | 
				
			||||||
mapquest_key=your-api-key-goes-here
 | 
					 | 
				
			||||||
prefer_english_names=False
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    config = load_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
    assert config['Geolocation']['mapquest_key'] == 'your-api-key-goes-here', config.get('Geolocation', 'mapquest_key')
 | 
					 | 
				
			||||||
    config.set('Geolocation', 'mapquest_key', 'new-value')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    config = load_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert config['Geolocation']['mapquest_key'] == 'new-value', config.get('Geolocation', 'mapquest_key')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-does-not-exist' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_config_singleton_no_file():
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    config = load_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert config == {}, config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugin-config-unset-backwards-compat' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugin_config_unset_backwards_compat():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugin-config-unset-backwards-compat' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = load_plugin_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins == [], plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugin-config-exists-not-set' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugin_config_exists_not_set():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugin-config-exists-not-set' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = load_plugin_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins == [], plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugin-config-one' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugin_config_one():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugin-config-one' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=Dummy
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = load_plugin_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins == ['Dummy'], plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugin-config-one-with-invalid' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugin_config_one_with_invalid():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugin-config-one' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=DNE
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = load_plugin_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins == [], plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugin-config-many' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugin_config_many():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugin-config-many' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=GooglePhotos,Dummy
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = load_plugin_config(constants.CONFIG_FILE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins == ['GooglePhotos','Dummy'], plugins
 | 
					 | 
				
			||||||
@ -1,110 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import unittest 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    reload  # Python 2.7
 | 
					 | 
				
			||||||
except NameError:
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        from importlib import reload  # Python 3.4+
 | 
					 | 
				
			||||||
    except ImportError:
 | 
					 | 
				
			||||||
        from imp import reload  # Python 3.0 - 3.3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from mock import patch
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_debug():
 | 
					 | 
				
			||||||
    # This seems pointless but on Travis we explicitly modify the file to be True
 | 
					 | 
				
			||||||
    assert constants.debug == constants.debug, constants.debug
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_application_directory_default():
 | 
					 | 
				
			||||||
    if('ELODIE_APPLICATION_DIRECTORY' in os.environ):
 | 
					 | 
				
			||||||
        del os.environ['ELODIE_APPLICATION_DIRECTORY']
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
    expected_path = '{}/.elodie'.format(os.path.expanduser('~'))
 | 
					 | 
				
			||||||
    assert constants.application_directory == expected_path, constants.application_directory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_application_directory_override_invalid():
 | 
					 | 
				
			||||||
    os.environ['ELODIE_APPLICATION_DIRECTORY'] = '/foo/bar'
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
    directory_to_check = constants.application_directory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # reset
 | 
					 | 
				
			||||||
    if('ELODIE_APPLICATION_DIRECTORY' in os.environ):
 | 
					 | 
				
			||||||
        del os.environ['ELODIE_APPLICATION_DIRECTORY']
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    expected_path = '{}/.elodie'.format(os.path.expanduser('~'))
 | 
					 | 
				
			||||||
    assert directory_to_check == expected_path, constants.application_directory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_application_directory_override_valid():
 | 
					 | 
				
			||||||
    cwd = os.getcwd()
 | 
					 | 
				
			||||||
    os.environ['ELODIE_APPLICATION_DIRECTORY'] = cwd
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
    directory_to_check = constants.application_directory
 | 
					 | 
				
			||||||
    hash_db_to_check = os.path.join(cwd, constants.hash_db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # reset
 | 
					 | 
				
			||||||
    if('ELODIE_APPLICATION_DIRECTORY' in os.environ):
 | 
					 | 
				
			||||||
        del os.environ['ELODIE_APPLICATION_DIRECTORY']
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert directory_to_check == cwd, constants.application_directory
 | 
					 | 
				
			||||||
    assert cwd in hash_db_to_check, hash_db_to_check
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_hash_db():
 | 
					 | 
				
			||||||
    assert constants.hash_db == os.path.split(constants.hash_db)[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_location_db():
 | 
					 | 
				
			||||||
    assert constants.location_db == os.path.split(constants.location_db)[1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_script_directory():
 | 
					 | 
				
			||||||
    path = os.path.dirname(os.path.dirname(__file__))
 | 
					 | 
				
			||||||
    assert path == constants.script_directory, constants.script_directory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_exiftool_config():
 | 
					 | 
				
			||||||
    path = constants.script_directory
 | 
					 | 
				
			||||||
    assert '{}/configs/ExifTool_config'.format(path) == constants.exiftool_config, constants.exiftool_config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_mapquest_base_url_default():
 | 
					 | 
				
			||||||
    assert constants.mapquest_base_url == 'https://open.mapquestapi.com', constants.mapquest_base_url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_mapquest_base_url_override():
 | 
					 | 
				
			||||||
    os.environ['ELODIE_MAPQUEST_BASE_URL'] = 'foobar'
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
    url_to_check = constants.mapquest_base_url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # reset
 | 
					 | 
				
			||||||
    if('ELODIE_MAPQUEST_BASE_URL' in os.environ):
 | 
					 | 
				
			||||||
        del os.environ['ELODIE_MAPQUEST_BASE_URL']
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert url_to_check == 'foobar', constants.mapquest_base_url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_mapquest_key_default():
 | 
					 | 
				
			||||||
    if('ELODIE_MAPQUEST_KEY' in os.environ):
 | 
					 | 
				
			||||||
        os.environ['ELODIE_MAPQUEST_KEY'] = None
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
    assert constants.mapquest_key == None, constants.mapquest_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_mapquest_key_override():
 | 
					 | 
				
			||||||
    os.environ['ELODIE_MAPQUEST_KEY'] = 'foobar'
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
    key_to_check = constants.mapquest_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # reset
 | 
					 | 
				
			||||||
    if('ELODIE_MAPQUEST_KEY' in os.environ):
 | 
					 | 
				
			||||||
        del os.environ['ELODIE_MAPQUEST_KEY']
 | 
					 | 
				
			||||||
    reload(constants)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert key_to_check == 'foobar', key_to_check
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_accepted_language():
 | 
					 | 
				
			||||||
    assert constants.accepted_language == 'en', constants.accepted_language
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_python_version():
 | 
					 | 
				
			||||||
    assert constants.python_version == sys.version_info.major, constants.python_version
 | 
					 | 
				
			||||||
@ -1,18 +0,0 @@
 | 
				
			|||||||
import mock
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie.dependencies import get_exiftool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.dependencies.find_executable')
 | 
					 | 
				
			||||||
@mock.patch('elodie.dependencies.os')
 | 
					 | 
				
			||||||
def test_exiftool(mock_os, mock_find_executable):
 | 
					 | 
				
			||||||
    mock_find_executable.return_value = '/path/to/exiftool'
 | 
					 | 
				
			||||||
    assert get_exiftool() == '/path/to/exiftool'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mock_find_executable.return_value = None
 | 
					 | 
				
			||||||
    mock_os.path.isfile.return_value = True
 | 
					 | 
				
			||||||
    mock_os.path.access.return_value = True
 | 
					 | 
				
			||||||
    assert get_exiftool() == '/usr/local/bin/exiftool'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    mock_os.path.isfile.return_value = False
 | 
					 | 
				
			||||||
    assert get_exiftool() is None
 | 
					 | 
				
			||||||
@ -1,678 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
from imp import load_source
 | 
					 | 
				
			||||||
import mock
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from click.testing import CliRunner
 | 
					 | 
				
			||||||
from nose.plugins.skip import SkipTest
 | 
					 | 
				
			||||||
from nose.tools import assert_raises
 | 
					 | 
				
			||||||
from six import text_type, unichr as six_unichr
 | 
					 | 
				
			||||||
from tempfile import gettempdir
 | 
					 | 
				
			||||||
from datetime import datetime
 | 
					 | 
				
			||||||
import unittest
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import helper
 | 
					 | 
				
			||||||
elodie = load_source('elodie', os.path.abspath('{}/../elodie.py'.format(os.path.dirname(os.path.realpath(__file__)))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie.config import load_config
 | 
					 | 
				
			||||||
from elodie.localstorage import Db
 | 
					 | 
				
			||||||
from elodie.media.audio import Audio
 | 
					 | 
				
			||||||
from elodie.media.photo import Photo
 | 
					 | 
				
			||||||
from elodie.media.video import Video
 | 
					 | 
				
			||||||
from elodie.plugins.plugins import Plugins
 | 
					 | 
				
			||||||
from elodie.plugins.googlephotos.googlephotos import GooglePhotos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os.environ['TZ'] = 'GMT'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_audio():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.path_tz_fix(os.path.join('2016-01-Jan','Houston','2016-01-03_21-23-39-audio.m4a')) in dest_path, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_photo():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/plain.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.path_tz_fix(os.path.join('2015-12-Dec','Unknown Location','2015-12-05_00-59-26-plain.jpg')) in dest_path, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_video():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.path_tz_fix(os.path.join('2015-01-Jan','California','2015-01-19_12-45-11-video.mov')) in dest_path, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_path_unicode_checkmark():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = text_type(folder)+u'/unicode\u2713filename.png'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.path_tz_fix(os.path.join('2015-01-Jan','Unknown Location',
 | 
					 | 
				
			||||||
        u'2015-01-18_12-01-01-unicode\u2713filename.png')) in dest_path, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_path_unicode_latin_nbsp():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = text_type(folder)+u'/unicode'+six_unichr(160)+u'filename.png'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert helper.path_tz_fix(os.path.join('2015-01-Jan','Unknown Location',
 | 
					 | 
				
			||||||
        u'2015-01-18_12-01-01-unicode\xa0filename.png')) in dest_path, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_allow_duplicate_false():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/with-original-name.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('with-original-name.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path1 = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
    dest_path2 = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert dest_path1 is not None
 | 
					 | 
				
			||||||
    assert dest_path2 is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_allow_duplicate_true():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/with-original-name.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('with-original-name.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path1 = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, True)
 | 
					 | 
				
			||||||
    dest_path2 = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert dest_path1 is not None
 | 
					 | 
				
			||||||
    assert dest_path2 is not None
 | 
					 | 
				
			||||||
    assert dest_path1 == dest_path2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_send_to_trash_false():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert os.path.isfile(origin), origin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert dest_path is not None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_send_to_trash_true():
 | 
					 | 
				
			||||||
    raise SkipTest("Temporarily disable send2trash test gh-230")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', True, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert not os.path.isfile(origin), origin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert dest_path is not None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_destination_in_source():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    folder_destination = '{}/destination'.format(folder)
 | 
					 | 
				
			||||||
    os.mkdir(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/plain.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert dest_path is None, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_destination_in_source_gh_287():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    folder_destination = '{}-destination'.format(folder)
 | 
					 | 
				
			||||||
    os.mkdir(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    dest_path = elodie.import_file(origin, folder_destination, db, False,
 | 
					 | 
				
			||||||
            'copy', False, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert dest_path is not None, dest_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip("Invalid file disabled")
 | 
					 | 
				
			||||||
def test_import_invalid_file_exit_code():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # use a good and bad
 | 
					 | 
				
			||||||
    origin_invalid = '%s/invalid.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('invalid.jpg'), origin_invalid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--allow-duplicates', origin_invalid, origin_valid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert result.exit_code == 1, result.exit_code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_with_single_exclude():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--exclude-regex', origin_valid[0:5], '--allow-duplicates', origin_valid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         0' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_with_multiple_exclude():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--exclude-regex', 'does not exist in path', '--exclude-regex', origin_valid[0:5], '--allow-duplicates', origin_valid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         0' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_file_with_non_matching_exclude():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--exclude-regex', 'does not exist in path', '--allow-duplicates', origin_valid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         1' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip('to fix')
 | 
					 | 
				
			||||||
def test_import_directory_with_matching_exclude():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
    exclude_regex_list = (os.path.basename(os.path.dirname(folder)))
 | 
					 | 
				
			||||||
    exclude_regex_list = (os.path.dirname(folder))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination',
 | 
					 | 
				
			||||||
        folder_destination, '--source', folder, '--exclude-regex',
 | 
					 | 
				
			||||||
        exclude_regex_list, '--allow-duplicates'])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         0' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_import_directory_with_non_matching_exclude():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--source', folder, '--exclude-regex', 'non-matching', '--allow-duplicates'])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         1' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-import-file-with-single-config-exclude' % gettempdir())
 | 
					 | 
				
			||||||
def test_import_file_with_single_config_exclude():
 | 
					 | 
				
			||||||
    config_string = """
 | 
					 | 
				
			||||||
    [Exclusions]
 | 
					 | 
				
			||||||
    name1=photo
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
    with open('%s/config.ini-import-file-with-single-config-exclude' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--allow-duplicates', origin_valid, '--debug'])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         0' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-import-file-with-multiple-config-exclude' % gettempdir())
 | 
					 | 
				
			||||||
def test_import_file_with_multiple_config_exclude():
 | 
					 | 
				
			||||||
    config_string = """
 | 
					 | 
				
			||||||
    [Exclusions]
 | 
					 | 
				
			||||||
    name1=notvalidatall
 | 
					 | 
				
			||||||
    name2=photo
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
    with open('%s/config.ini-import-file-with-multiple-config-exclude' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, '--allow-duplicates', origin_valid, '--debug'])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         0' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_all_files_in_paths():
 | 
					 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_location_on_audio():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    status = elodie.update_location(audio, origin, 'Sunnyvale, CA', db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_processed = Audio(origin)
 | 
					 | 
				
			||||||
    metadata_processed = audio_processed.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert metadata['latitude'] != metadata_processed['latitude'], metadata_processed['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata_processed['latitude'], 37.36883), metadata_processed['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata_processed['longitude'], -122.03635), metadata_processed['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_location_on_photo():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/plain.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    status = elodie.update_location(photo, origin, 'Sunnyvale, CA', db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_processed = Photo(origin)
 | 
					 | 
				
			||||||
    metadata_processed = photo_processed.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert metadata['latitude'] != metadata_processed['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata_processed['latitude'], 37.36883), metadata_processed['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata_processed['longitude'], -122.03635), metadata_processed['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_location_on_video():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video = Video(origin)
 | 
					 | 
				
			||||||
    metadata = video.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
    status = elodie.update_location(video, origin, 'Sunnyvale, CA', db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video_processed = Video(origin)
 | 
					 | 
				
			||||||
    metadata_processed = video_processed.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert metadata['latitude'] != metadata_processed['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata_processed['latitude'], 37.36883), metadata_processed['latitude']
 | 
					 | 
				
			||||||
    assert helper.isclose(metadata_processed['longitude'], -122.03635), metadata_processed['longitude']
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_time_on_audio():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/audio.m4a' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('audio.m4a'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio = Audio(origin)
 | 
					 | 
				
			||||||
    metadata = audio.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = elodie.update_time(audio, origin, '2000-01-01 12:00:00')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    audio_processed = Audio(origin)
 | 
					 | 
				
			||||||
    metadata_processed = audio_processed.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert metadata['date_original'] != metadata_processed['date_original']
 | 
					 | 
				
			||||||
    assert metadata_processed['date_original'] == datetime(2000, 1, 1, 12, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_time_on_photo():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/plain.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo = Photo(origin)
 | 
					 | 
				
			||||||
    metadata = photo.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = elodie.update_time(photo, origin, '2000-01-01 12:00:00')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photo_processed = Photo(origin)
 | 
					 | 
				
			||||||
    metadata_processed = photo_processed.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert metadata['date_original'] != metadata_processed['date_original']
 | 
					 | 
				
			||||||
    assert metadata_processed['date_original'] == datetime(2000, 1, 1, 12, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_time_on_video():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/video.mov' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('video.mov'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video = Video(origin)
 | 
					 | 
				
			||||||
    metadata = video.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    status = elodie.update_time(video, origin, '2000-01-01 12:00:00')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    video_processed = Video(origin)
 | 
					 | 
				
			||||||
    metadata_processed = video_processed.get_metadata()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status == True, status
 | 
					 | 
				
			||||||
    assert metadata['date_original'] != metadata_processed['date_original']
 | 
					 | 
				
			||||||
    assert metadata_processed['date_original'] == datetime(2000, 1, 1, 12, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_with_directory_passed_in():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', folder_destination, folder])
 | 
					 | 
				
			||||||
    runner2 = CliRunner()
 | 
					 | 
				
			||||||
    result = runner2.invoke(elodie._update, ['--album', 'test', folder_destination])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    updated_file_path = "{}/2015-01-Jan/test/2015-01-18_12-01-01-photo.png".format(folder_destination)
 | 
					 | 
				
			||||||
    updated_file_exists = os.path.isfile(updated_file_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert updated_file_exists, updated_file_path
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip("Invalid file disabled")
 | 
					 | 
				
			||||||
def test_update_invalid_file_exit_code():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
    temporary_folder_destination, folder_destination = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # use a good and bad
 | 
					 | 
				
			||||||
    origin_invalid = '%s/invalid.jpg' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('invalid.jpg'), origin_invalid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('plain.jpg'), origin_valid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._update, ['--album', 'test', origin_invalid, origin_valid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # bugfix deleted by elodie._update....
 | 
					 | 
				
			||||||
    # shutil.rmtree(folder)
 | 
					 | 
				
			||||||
    shutil.rmtree(folder_destination)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert result.exit_code == 1, result.exit_code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_regenerate_db_invalid_source():
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._generate_db, ['--path', '/invalid/path'])
 | 
					 | 
				
			||||||
    assert result.exit_code == 1, result.exit_code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_regenerate_valid_source():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._generate_db, ['--path', folder])
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert result.exit_code == 0, result.exit_code
 | 
					 | 
				
			||||||
    assert '66ca09b5533aba8b4ccdc7243435f2c4638c1a6762940ab9dbe66da185b3513e' in db.hash_db, db.hash_db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip("Invalid file disabled")
 | 
					 | 
				
			||||||
def test_regenerate_valid_source_with_invalid_files():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin_valid = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin_valid)
 | 
					 | 
				
			||||||
    origin_invalid = '%s/invalid.invalid' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('invalid.invalid'), origin_invalid)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._generate_db, ['--path', folder])
 | 
					 | 
				
			||||||
    db = Db(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert result.exit_code == 0, result.exit_code
 | 
					 | 
				
			||||||
    assert '3c19a5d751cf19e093b7447297731124d9cc987d3f91a9d1872c3b1c1b15639a' in db.hash_db, db.hash_db
 | 
					 | 
				
			||||||
    assert 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' not in db.hash_db, db.hash_db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_verify_ok():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    runner.invoke(elodie._generate_db, ['--path', folder])
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._verify, ['--path', folder])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert 'Success         1' in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           0' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_verify_error():
 | 
					 | 
				
			||||||
    temporary_folder, folder = helper.create_working_folder()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    origin = '%s/photo.png' % folder
 | 
					 | 
				
			||||||
    shutil.copyfile(helper.get_file('photo.png'), origin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    runner.invoke(elodie._generate_db, ['--path', folder])
 | 
					 | 
				
			||||||
    with open(origin, 'w') as f:
 | 
					 | 
				
			||||||
        f.write('changed text')
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._verify, ['--path', folder])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    shutil.rmtree(folder)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert origin in result.output, result.output
 | 
					 | 
				
			||||||
    assert 'Error           1' in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip('depreciated')
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-cli-batch-plugin-googlephotos' % gettempdir())
 | 
					 | 
				
			||||||
def test_cli_batch_plugin_googlephotos():
 | 
					 | 
				
			||||||
    auth_file = helper.get_file('plugins/googlephotos/auth_file.json')
 | 
					 | 
				
			||||||
    secrets_file = helper.get_file('plugins/googlephotos/secrets_file.json')
 | 
					 | 
				
			||||||
    config_string = """
 | 
					 | 
				
			||||||
    [Plugins]
 | 
					 | 
				
			||||||
    plugins=GooglePhotos
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [PluginGooglePhotos]
 | 
					 | 
				
			||||||
    auth_file={}
 | 
					 | 
				
			||||||
    secrets_file={}
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
    config_string_fmt = config_string.format(
 | 
					 | 
				
			||||||
        auth_file,
 | 
					 | 
				
			||||||
        secrets_file
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    with open('%s/config.ini-cli-batch-plugin-googlephotos' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write(config_string_fmt)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    final_file_path_1 = helper.get_file('plain.jpg')
 | 
					 | 
				
			||||||
    final_file_path_2 = helper.get_file('no-exif.jpg')
 | 
					 | 
				
			||||||
    sample_metadata_1 = Photo(final_file_path_1).get_metadata()
 | 
					 | 
				
			||||||
    sample_metadata_2 = Photo(final_file_path_2).get_metadata()
 | 
					 | 
				
			||||||
    gp = GooglePhotos()
 | 
					 | 
				
			||||||
    gp.after('', '', final_file_path_1, sample_metadata_1)
 | 
					 | 
				
			||||||
    gp.after('', '', final_file_path_2, sample_metadata_1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._batch)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert "elodie/elodie/tests/files/plain.jpg uploaded successfully.\"}\n" in result.output, result.output
 | 
					 | 
				
			||||||
    assert "elodie/elodie/tests/files/no-exif.jpg uploaded successfully.\"}\n" in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip('to fix')
 | 
					 | 
				
			||||||
def test_cli_debug_import():
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    # import
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', '/does/not/exist', '/does/not/exist'])
 | 
					 | 
				
			||||||
    assert "Could not find /does/not/exist\n" not in result.output, result.output
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._import, ['--destination', '/does/not/exist', '--debug', '/does/not/exist'])
 | 
					 | 
				
			||||||
    assert "Could not find /does/not/exist\n" in result.output, result.output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@unittest.skip('to fix')
 | 
					 | 
				
			||||||
def test_cli_debug_update():
 | 
					 | 
				
			||||||
    runner = CliRunner()
 | 
					 | 
				
			||||||
    # update
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._update, ['--location', 'foobar', '/does/not/exist'])
 | 
					 | 
				
			||||||
    assert "Could not find /does/not/exist\n" not in result.output, result.output
 | 
					 | 
				
			||||||
    result = runner.invoke(elodie._update, ['--location', 'foobar', '--debug', '/does/not/exist'])
 | 
					 | 
				
			||||||
    assert "Could not find /does/not/exist\n" in result.output, result.output
 | 
					 | 
				
			||||||
@ -1,237 +0,0 @@
 | 
				
			|||||||
from __future__ import absolute_import
 | 
					 | 
				
			||||||
from __future__ import division
 | 
					 | 
				
			||||||
from builtins import range
 | 
					 | 
				
			||||||
from past.utils import old_div
 | 
					 | 
				
			||||||
# Project imports
 | 
					 | 
				
			||||||
import mock
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import random
 | 
					 | 
				
			||||||
import re
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
from mock import patch
 | 
					 | 
				
			||||||
from tempfile import gettempdir
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from . import helper
 | 
					 | 
				
			||||||
from elodie import geolocation
 | 
					 | 
				
			||||||
from elodie.localstorage import Db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os.environ['TZ'] = 'GMT'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ELODIE_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_decimal_to_dms():
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for x in range(0, 1000):
 | 
					 | 
				
			||||||
        target_decimal_value = random.uniform(0.0, 180.0)
 | 
					 | 
				
			||||||
        if(x % 2 == 1):
 | 
					 | 
				
			||||||
            target_decimal_value = target_decimal_value * -1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        dms = geolocation.decimal_to_dms(target_decimal_value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        check_value = (dms[0] + dms[1] / 60 + dms[2] / 3600) * dms[3]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        target_decimal_value = round(target_decimal_value, 8)
 | 
					 | 
				
			||||||
        check_value = round(check_value, 8)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert target_decimal_value == check_value, '%s does not match %s' % (check_value, target_decimal_value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_dms_to_decimal_positive_sign():
 | 
					 | 
				
			||||||
    decimal = geolocation.dms_to_decimal(10, 20, 100, 'NE')
 | 
					 | 
				
			||||||
    assert helper.isclose(decimal, 10.3611111111)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    decimal = geolocation.dms_to_decimal(10, 20, 100, 'ne')
 | 
					 | 
				
			||||||
    assert helper.isclose(decimal, 10.3611111111)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_dms_to_decimal_negative_sign():
 | 
					 | 
				
			||||||
    decimal = geolocation.dms_to_decimal(10, 20, 100, 'SW')
 | 
					 | 
				
			||||||
    assert helper.isclose(decimal, -10.3611111111)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    decimal = geolocation.dms_to_decimal(10, 20, 100, 'sw')
 | 
					 | 
				
			||||||
    assert helper.isclose(decimal, -10.3611111111)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_dms_string_latitude():
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for x in range(0, 5):
 | 
					 | 
				
			||||||
        target_decimal_value = random.uniform(0.0, 180.0)
 | 
					 | 
				
			||||||
        if(x % 2 == 1):
 | 
					 | 
				
			||||||
            target_decimal_value = target_decimal_value * -1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        dms = geolocation.decimal_to_dms(target_decimal_value)
 | 
					 | 
				
			||||||
        dms_string = geolocation.dms_string(target_decimal_value, 'latitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        check_value = 'N' if target_decimal_value >= 0 else 'S'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert check_value in dms_string, '%s not in %s' % (check_value, dms_string)
 | 
					 | 
				
			||||||
        assert str(dms[0]) in dms_string, '%s not in %s' % (dms[0], dms_string)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_dms_string_longitude():
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for x in range(0, 5):
 | 
					 | 
				
			||||||
        target_decimal_value = random.uniform(0.0, 180.0)
 | 
					 | 
				
			||||||
        if(x % 2 == 1):
 | 
					 | 
				
			||||||
            target_decimal_value = target_decimal_value * -1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        dms = geolocation.decimal_to_dms(target_decimal_value)
 | 
					 | 
				
			||||||
        dms_string = geolocation.dms_string(target_decimal_value, 'longitude')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        check_value = 'E' if target_decimal_value >= 0 else 'W'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert check_value in dms_string, '%s not in %s' % (check_value, dms_string)
 | 
					 | 
				
			||||||
        assert str(dms[0]) in dms_string, '%s not in %s' % (dms[0], dms_string)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_reverse_lookup_with_valid_key():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_osm(lat=37.368, lon=-122.03)
 | 
					 | 
				
			||||||
    assert res['address']['city'] == 'Sunnyvale', res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_reverse_lookup_with_invalid_lat_lon():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_osm(lat=999, lon=999)
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.geolocation.__KEY__', 'invalid_key')
 | 
					 | 
				
			||||||
def test_reverse_lookup_with_invalid_key():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(lat=37.368, lon=-122.03)
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lookup_with_valid_key():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
 | 
					 | 
				
			||||||
    latLng = res['results'][0]['locations'][0]['latLng']
 | 
					 | 
				
			||||||
    assert latLng['lat'] == 37.36883, latLng
 | 
					 | 
				
			||||||
    assert latLng['lng'] == -122.03635, latLng
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lookup_with_invalid_location():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(location='foobar dne')
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lookup_with_invalid_location():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(location='foobar dne')
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lookup_with_valid_key():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
 | 
					 | 
				
			||||||
    latLng = res['results'][0]['locations'][0]['latLng']
 | 
					 | 
				
			||||||
    assert latLng['lat'] == 37.36883, latLng
 | 
					 | 
				
			||||||
    assert latLng['lng'] == -122.03635, latLng
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.geolocation.__PREFER_ENGLISH_NAMES__', True)
 | 
					 | 
				
			||||||
def test_lookup_with_prefer_english_names_true():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_osm(lat=55.66333, lon=37.61583)
 | 
					 | 
				
			||||||
    assert res['address']['city'] == 'Moscow', res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.geolocation.__PREFER_ENGLISH_NAMES__', False)
 | 
					 | 
				
			||||||
def test_lookup_with_prefer_english_names_false():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_osm(lat=55.66333, lon=37.61583)
 | 
					 | 
				
			||||||
    assert res['address']['city'] == 'Москва', res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.location_db', '%s/location.json-cached' % gettempdir())
 | 
					 | 
				
			||||||
def test_place_name_deprecated_string_cached():
 | 
					 | 
				
			||||||
    # See gh-160 for backwards compatability needed when a string is stored instead of a dict
 | 
					 | 
				
			||||||
    with open('%s/location.json-cached' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[{"lat": 37.3667027222222, "long": -122.033383611111, "name": "OLDVALUE"}]
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    db = Db(ELODIE_DIR)
 | 
					 | 
				
			||||||
    place_name = geolocation.place_name(37.3667027222222, -122.033383611111,
 | 
					 | 
				
			||||||
            db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert place_name['city'] == 'Sunnyvale', place_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.location_db', '%s/location.json-cached' % gettempdir())
 | 
					 | 
				
			||||||
def test_place_name_cached():
 | 
					 | 
				
			||||||
    with open('%s/location.json-cached' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[{"lat": 37.3667027222222, "long": -122.033383611111, "name": {"city": "UNITTEST"}}]
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    db = Db(ELODIE_DIR)
 | 
					 | 
				
			||||||
    place_name = geolocation.place_name(37.3667027222222, -122.033383611111,
 | 
					 | 
				
			||||||
            db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert place_name['city'] == 'UNITTEST', place_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_place_name_no_default():
 | 
					 | 
				
			||||||
    # See gh-160 for backwards compatability needed when a string is stored instead of a dict
 | 
					 | 
				
			||||||
    db = Db(ELODIE_DIR)
 | 
					 | 
				
			||||||
    place_name = geolocation.place_name(123456.000, 123456.000, db)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert place_name['default'] == 'Unknown Location', place_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.geolocation.__KEY__', 'invalid_key')
 | 
					 | 
				
			||||||
def test_lookup_with_invalid_key():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.geolocation.__KEY__', '')
 | 
					 | 
				
			||||||
def test_lookup_with_no_key():
 | 
					 | 
				
			||||||
    res = geolocation.lookup_mapquest(location='Sunnyvale, CA')
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_parse_result_with_error():
 | 
					 | 
				
			||||||
    res = geolocation.parse_result({'error': 'foo'})
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_parse_result_with_city():
 | 
					 | 
				
			||||||
    # http://open.mapquestapi.com/nominatim/v1/reverse.php?lat=37.368&lon=-122.03&key=key_goes_here&format=json
 | 
					 | 
				
			||||||
    results = {
 | 
					 | 
				
			||||||
        "place_id": "60197412",
 | 
					 | 
				
			||||||
        "osm_type": "way",
 | 
					 | 
				
			||||||
        "osm_id": "30907961",
 | 
					 | 
				
			||||||
        "lat": "37.36746105",
 | 
					 | 
				
			||||||
        "lon": "-122.030237558742",
 | 
					 | 
				
			||||||
        "display_name": "111, East El Camino Real, Sunnyvale, Santa Clara County, California, 94087, United States of America",
 | 
					 | 
				
			||||||
        "address": {
 | 
					 | 
				
			||||||
            "house_number": "111",
 | 
					 | 
				
			||||||
            "road": "East El Camino Real",
 | 
					 | 
				
			||||||
            "city": "Sunnyvale",
 | 
					 | 
				
			||||||
            "county": "Santa Clara County",
 | 
					 | 
				
			||||||
            "state": "California",
 | 
					 | 
				
			||||||
            "postcode": "94087",
 | 
					 | 
				
			||||||
            "country": "United States of America",
 | 
					 | 
				
			||||||
            "country_code": "us"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    res = geolocation.parse_result(results)
 | 
					 | 
				
			||||||
    assert res == results, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_parse_result_with_lat_lon():
 | 
					 | 
				
			||||||
    # http://open.mapquestapi.com/geocoding/v1/address?location=abcdefghijklmnopqrstuvwxyz&key=key_goes_here&format=json
 | 
					 | 
				
			||||||
    results = {
 | 
					 | 
				
			||||||
        "results": [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
               "locations": [
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        "latLng": {
 | 
					 | 
				
			||||||
                            "lat": 123.00,
 | 
					 | 
				
			||||||
                            "lng": -142.99
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    res = geolocation.parse_result(results)
 | 
					 | 
				
			||||||
    assert res == results, res
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_parse_result_with_unknown_lat_lon():
 | 
					 | 
				
			||||||
    # http://open.mapquestapi.com/geocoding/v1/address?location=abcdefghijklmnopqrstuvwxyz&key=key_goes_here&format=json
 | 
					 | 
				
			||||||
    results = {
 | 
					 | 
				
			||||||
        "results": [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
               "locations": [
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        "latLng": {
 | 
					 | 
				
			||||||
                            "lat": 39.78373,
 | 
					 | 
				
			||||||
                            "lng": -100.445882
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                ]
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    res = geolocation.parse_result(results)
 | 
					 | 
				
			||||||
    assert res is None, res
 | 
					 | 
				
			||||||
@ -1,263 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from . import helper
 | 
					 | 
				
			||||||
from elodie.localstorage import Db
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os.environ['TZ'] = 'GMT'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PHOTO_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'files')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_init_writes_files():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert os.path.isfile(helper.get_hash_db(PHOTO_PATH)) == True
 | 
					 | 
				
			||||||
    assert os.path.isfile(helper.get_location_db(PHOTO_PATH)) == True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_hash_default_do_not_write():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with default False value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.check_hash(random_key) == True, 'Lookup for hash did not return True'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Instnatiate new db class to confirm random_key does not exist
 | 
					 | 
				
			||||||
    db2 = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    assert db2.check_hash(random_key) == False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_hash_explicit_do_not_write():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with explicit False value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.check_hash(random_key) == True, 'Lookup for hash did not return True'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Instnatiate new db class to confirm random_key does not exist
 | 
					 | 
				
			||||||
    db2 = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    assert db2.check_hash(random_key) == False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_hash_explicit_write():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with explicit True value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value, True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.check_hash(random_key) == True, 'Lookup for hash did not return True'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Instnatiate new db class to confirm random_key exists
 | 
					 | 
				
			||||||
    db2 = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    assert db2.check_hash(random_key) == True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_backup_hash_db():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    backup_file_name = db.backup_hash_db()
 | 
					 | 
				
			||||||
    file_exists = os.path.isfile(backup_file_name)
 | 
					 | 
				
			||||||
    os.remove(backup_file_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert file_exists, backup_file_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_check_hash_exists():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with explicit False value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.check_hash(random_key) == True, 'Lookup for hash did not return True'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_check_hash_does_not_exist():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.check_hash(random_key) == False, 'Lookup for hash that should not exist returned True'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_hash_exists():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with explicit False value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.get_hash(random_key) == random_value, 'Lookup for hash that exists did not return value'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_hash_does_not_exist():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.get_hash(random_key) is None, 'Lookup for hash that should not exist did not return None'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_all():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    db.reset_hash_db()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_keys = []
 | 
					 | 
				
			||||||
    random_values = []
 | 
					 | 
				
			||||||
    for _ in range(10):
 | 
					 | 
				
			||||||
        random_keys.append(helper.random_string(10))
 | 
					 | 
				
			||||||
        random_values.append(helper.random_string(12))
 | 
					 | 
				
			||||||
        db.add_hash(random_keys[-1:][0], random_values[-1:][0], False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    counter = 0
 | 
					 | 
				
			||||||
    for key, value in db.all():
 | 
					 | 
				
			||||||
        assert key in random_keys, key
 | 
					 | 
				
			||||||
        assert value in random_values, value
 | 
					 | 
				
			||||||
        counter += 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert counter == 10, counter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_all_empty():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    db.reset_hash_db()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    counter = 0
 | 
					 | 
				
			||||||
    for key, value in db.all():
 | 
					 | 
				
			||||||
        counter += 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # there's a final iteration because of the generator
 | 
					 | 
				
			||||||
    assert counter == 0, counter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_reset_hash_db():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with explicit False value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value, False)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert random_key in db.hash_db, random_key
 | 
					 | 
				
			||||||
    db.reset_hash_db()
 | 
					 | 
				
			||||||
    assert random_key not in db.hash_db, random_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_update_hash_db():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    random_key = helper.random_string(10)
 | 
					 | 
				
			||||||
    random_value = helper.random_string(12)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Test with default False value as 3rd param
 | 
					 | 
				
			||||||
    db.add_hash(random_key, random_value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert db.check_hash(random_key) == True, 'Lookup for hash did not return True'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Instnatiate new db class to confirm random_key does not exist
 | 
					 | 
				
			||||||
    db2 = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    assert db2.check_hash(random_key) == False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db.update_hash_db()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Instnatiate new db class to confirm random_key exists
 | 
					 | 
				
			||||||
    db3 = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
    assert db3.check_hash(random_key) == True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_checksum():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    src = helper.get_file('plain.jpg')
 | 
					 | 
				
			||||||
    checksum = db.checksum(src)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert checksum == 'd5eb755569ddbc8a664712d2d7d6e0fa1ddfcdb378475e4a6758dc38d5ea9a16', 'Checksum for plain.jpg did not match'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_location():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    latitude, longitude, name = helper.get_test_location()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db.add_location(latitude, longitude, name)
 | 
					 | 
				
			||||||
    retrieved_name = db.get_location_name(latitude, longitude, 5)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert name == retrieved_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_location_name():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    latitude, longitude, name = helper.get_test_location()
 | 
					 | 
				
			||||||
    db.add_location(latitude, longitude, name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # 1 meter
 | 
					 | 
				
			||||||
    retrieved_name = db.get_location_name(latitude, longitude, 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert name == retrieved_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_location_name_within_threshold():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    latitude, longitude, name = helper.get_test_location()
 | 
					 | 
				
			||||||
    db.add_location(latitude, longitude, name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    print(latitude)
 | 
					 | 
				
			||||||
    new_latitude = helper.random_coordinate(latitude, 4)
 | 
					 | 
				
			||||||
    new_longitude = helper.random_coordinate(longitude, 4)
 | 
					 | 
				
			||||||
    print(new_latitude)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # 10 miles
 | 
					 | 
				
			||||||
    retrieved_name = db.get_location_name(new_latitude, new_longitude, 1600*10)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert name == retrieved_name, 'Name (%r) did not match retrieved name (%r)' % (name, retrieved_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_location_name_outside_threshold():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    latitude, longitude, name = helper.get_test_location()
 | 
					 | 
				
			||||||
    db.add_location(latitude, longitude, name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    new_latitude = helper.random_coordinate(latitude, 1)
 | 
					 | 
				
			||||||
    new_longitude = helper.random_coordinate(longitude, 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # 800 meters
 | 
					 | 
				
			||||||
    retrieved_name = db.get_location_name(new_latitude, new_longitude, 800)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert retrieved_name is None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_location_coordinates_exists():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    latitude, longitude, name = helper.get_test_location()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    name = '%s-%s' % (name, helper.random_string(10))
 | 
					 | 
				
			||||||
    latitude = helper.random_coordinate(latitude, 1)
 | 
					 | 
				
			||||||
    longitude = helper.random_coordinate(longitude, 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    db.add_location(latitude, longitude, name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    location = db.get_location_coordinates(name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert location is not None
 | 
					 | 
				
			||||||
    assert location[0] == latitude
 | 
					 | 
				
			||||||
    assert location[1] == longitude
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_get_location_coordinates_does_not_exists():
 | 
					 | 
				
			||||||
    db = Db(PHOTO_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    latitude, longitude, name = helper.get_test_location()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    name = '%s-%s' % (name, helper.random_string(10))
 | 
					 | 
				
			||||||
    latitude = helper.random_coordinate(latitude, 1)
 | 
					 | 
				
			||||||
    longitude = helper.random_coordinate(longitude, 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    location = db.get_location_coordinates(name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert location is None
 | 
					 | 
				
			||||||
@ -1,82 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import unittest 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from json import dumps
 | 
					 | 
				
			||||||
from mock import patch
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    from StringIO import StringIO
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    from io import StringIO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
from elodie import log
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def call_log_and_assert(func, args, expected):
 | 
					 | 
				
			||||||
    saved_stdout = sys.stdout
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        out = StringIO()
 | 
					 | 
				
			||||||
        sys.stdout = out
 | 
					 | 
				
			||||||
        func(*args)
 | 
					 | 
				
			||||||
        output = out.getvalue()
 | 
					 | 
				
			||||||
        assert output == expected, (expected, func, output)
 | 
					 | 
				
			||||||
    finally:
 | 
					 | 
				
			||||||
        sys.stdout = saved_stdout
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def with_new_line(string):
 | 
					 | 
				
			||||||
    return "{}\n".format(string)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.log')
 | 
					 | 
				
			||||||
@patch('elodie.constants.debug', True)
 | 
					 | 
				
			||||||
def test_calls_print_debug_true(fake_log):
 | 
					 | 
				
			||||||
    expected = 'some string'
 | 
					 | 
				
			||||||
    fake_log.info.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.warn.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.error.return_value = expected
 | 
					 | 
				
			||||||
    for func in [log.info, log.warn, log.error]:
 | 
					 | 
				
			||||||
        call_log_and_assert(func, [expected], with_new_line(expected))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    expected_json = {'foo':'bar'}
 | 
					 | 
				
			||||||
    fake_log.info.return_value = expected_json
 | 
					 | 
				
			||||||
    fake_log.warn.return_value = expected_json
 | 
					 | 
				
			||||||
    fake_log.error.return_value = expected_json
 | 
					 | 
				
			||||||
    for func in [log.info_json, log.warn_json, log.error_json]:
 | 
					 | 
				
			||||||
        call_log_and_assert(func, [expected_json], with_new_line(dumps(expected_json)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.log')
 | 
					 | 
				
			||||||
@patch('elodie.constants.debug', False)
 | 
					 | 
				
			||||||
def test_calls_print_debug_false(fake_log):
 | 
					 | 
				
			||||||
    expected = 'some other string'
 | 
					 | 
				
			||||||
    fake_log.info.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.warn.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.error.return_value = expected
 | 
					 | 
				
			||||||
    for func in [log.info, log.warn, log.error]:
 | 
					 | 
				
			||||||
        call_log_and_assert(func, [expected], '')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    expected_json = {'foo':'bar'}
 | 
					 | 
				
			||||||
    fake_log.info.return_value = expected_json
 | 
					 | 
				
			||||||
    fake_log.warn.return_value = expected_json
 | 
					 | 
				
			||||||
    fake_log.error.return_value = expected_json
 | 
					 | 
				
			||||||
    for func in [log.info_json, log.warn_json, log.error_json]:
 | 
					 | 
				
			||||||
        call_log_and_assert(func, [expected_json], '')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.log')
 | 
					 | 
				
			||||||
def test_calls_print_progress_no_new_line(fake_log):
 | 
					 | 
				
			||||||
    expected = 'some other string'
 | 
					 | 
				
			||||||
    fake_log.info.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.warn.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.error.return_value = expected
 | 
					 | 
				
			||||||
    call_log_and_assert(log.progress, [expected], expected)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@patch('elodie.log')
 | 
					 | 
				
			||||||
def test_calls_print_progress_with_new_line(fake_log):
 | 
					 | 
				
			||||||
    expected = "some other string\n"
 | 
					 | 
				
			||||||
    fake_log.info.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.warn.return_value = expected
 | 
					 | 
				
			||||||
    fake_log.error.return_value = expected
 | 
					 | 
				
			||||||
    call_log_and_assert(log.progress, [expected, True], with_new_line(expected))
 | 
					 | 
				
			||||||
@ -1,254 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
import mock
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
from tempfile import gettempdir
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from . import helper
 | 
					 | 
				
			||||||
from elodie.config import load_config
 | 
					 | 
				
			||||||
from elodie.plugins.plugins import Plugins, PluginBase, PluginDb
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugins-unset-backwards-compat' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugins_unset_backwards_compat():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugins-unset-backwards-compat' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins.plugins == [], plugins.plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugins-exists-not-set' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugins_exists_not_set():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugins-exists-not-set' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins.plugins == [], plugins.plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugins-one' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugins_one():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugins-one' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=Dummy
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins.plugins == ['Dummy'], plugins.plugins
 | 
					 | 
				
			||||||
    assert len(plugins.classes) == 1, len(plugins.classes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugins-one-with-invalid' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugins_one_with_invalid():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugins-one' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=DNE
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins.plugins == [], plugins.plugins
 | 
					 | 
				
			||||||
    assert len(plugins.classes) == 0, len(plugins.classes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugins-many' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugins_many():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugins-many' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=ThrowError,Dummy
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins.plugins == ['ThrowError','Dummy'], plugins.plugins
 | 
					 | 
				
			||||||
    assert plugins.classes['ThrowError'].__name__ == 'ThrowError', plugins.classes['ThrowError'].__name__
 | 
					 | 
				
			||||||
    assert plugins.classes['Dummy'].__name__ == 'Dummy', plugins.classes['Dummy'].__name__
 | 
					 | 
				
			||||||
    assert len(plugins.classes) == 2, len(plugins.classes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-load-plugins-many-with-invalid' % gettempdir())
 | 
					 | 
				
			||||||
def test_load_plugins_set_many_with_invalid():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-load-plugins-many-with-invalid' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=ThrowError,Dummy,DNE
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert plugins.plugins == ['ThrowError','Dummy'], plugins.plugins
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-run-before' % gettempdir())
 | 
					 | 
				
			||||||
def test_run_before():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-run-before' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=Dummy
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
    before_ran_1 = plugins.classes['Dummy'].before_ran
 | 
					 | 
				
			||||||
    plugins.run_all_before('', '')
 | 
					 | 
				
			||||||
    before_ran_2 = plugins.classes['Dummy'].before_ran
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert before_ran_1 == False, before_ran_1
 | 
					 | 
				
			||||||
    assert before_ran_2 == True, before_ran_2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-throw-error' % gettempdir())
 | 
					 | 
				
			||||||
def test_throw_error():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-throw-error' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=ThrowError
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
    status_after = plugins.run_all_after('', '', '', '')
 | 
					 | 
				
			||||||
    status_batch = plugins.run_batch()
 | 
					 | 
				
			||||||
    status_before = plugins.run_all_before('', '')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status_after == False, status_after
 | 
					 | 
				
			||||||
    assert status_batch == False, status_batch
 | 
					 | 
				
			||||||
    assert status_before == False, status_before
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-throw-error-one-of-many' % gettempdir())
 | 
					 | 
				
			||||||
def test_throw_error_one_of_many():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-throw-error-one-of-many' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=Dummy,ThrowError
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
    status_after = plugins.run_all_after('', '', '', '')
 | 
					 | 
				
			||||||
    status_batch = plugins.run_batch()
 | 
					 | 
				
			||||||
    status_before = plugins.run_all_before('', '')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status_after == False, status_after
 | 
					 | 
				
			||||||
    assert status_batch == False, status_batch
 | 
					 | 
				
			||||||
    assert status_before == False, status_before
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@mock.patch('elodie.constants.CONFIG_FILE', '%s/config.ini-throw-runtime-error' % gettempdir())
 | 
					 | 
				
			||||||
def test_throw_error_runtime_error():
 | 
					 | 
				
			||||||
    with open('%s/config.ini-throw-runtime-error' % gettempdir(), 'w') as f:
 | 
					 | 
				
			||||||
        f.write("""
 | 
					 | 
				
			||||||
[Plugins]
 | 
					 | 
				
			||||||
plugins=RuntimeError
 | 
					 | 
				
			||||||
        """)
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    plugins = Plugins()
 | 
					 | 
				
			||||||
    plugins.load()
 | 
					 | 
				
			||||||
    status_after = plugins.run_all_after('', '', '', '')
 | 
					 | 
				
			||||||
    status_batch = plugins.run_batch()
 | 
					 | 
				
			||||||
    status_before = plugins.run_all_before('', '')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if hasattr(load_config, 'config'):
 | 
					 | 
				
			||||||
        del load_config.config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert status_after == True, status_after
 | 
					 | 
				
			||||||
    assert status_batch == True, status_batch
 | 
					 | 
				
			||||||
    assert status_before == True, status_before
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_plugin_base_inherits_db():
 | 
					 | 
				
			||||||
    plugin_base = PluginBase()
 | 
					 | 
				
			||||||
    assert hasattr(plugin_base.db, 'get')
 | 
					 | 
				
			||||||
    assert hasattr(plugin_base.db, 'set')
 | 
					 | 
				
			||||||
    assert hasattr(plugin_base.db, 'get_all')
 | 
					 | 
				
			||||||
    assert hasattr(plugin_base.db, 'delete')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_db_initialize_file():
 | 
					 | 
				
			||||||
    db = PluginDb('foobar')
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        os.remove(db.db_file)
 | 
					 | 
				
			||||||
    except OSError:
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
    db = PluginDb('foobar')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_db_get_then_set_then_get_then_delete():
 | 
					 | 
				
			||||||
    db = PluginDb('foobar')
 | 
					 | 
				
			||||||
    foo = db.get('foo')
 | 
					 | 
				
			||||||
    assert foo is None, foo
 | 
					 | 
				
			||||||
    db.set('foo', 'bar')
 | 
					 | 
				
			||||||
    foo = db.get('foo')
 | 
					 | 
				
			||||||
    assert foo == 'bar', foo
 | 
					 | 
				
			||||||
    db.delete('foo')
 | 
					 | 
				
			||||||
    foo = db.get('foo')
 | 
					 | 
				
			||||||
    assert foo is None, foo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_db_get_all():
 | 
					 | 
				
			||||||
    # we initialize the db to get the file path to delete then reinitialize
 | 
					 | 
				
			||||||
    db = PluginDb('foobar')
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        os.remove(db.db_file)
 | 
					 | 
				
			||||||
    except OSError:
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
    db = PluginDb('foobar')
 | 
					 | 
				
			||||||
    db.set('a', '1')
 | 
					 | 
				
			||||||
    db.set('b', '2')
 | 
					 | 
				
			||||||
    db.set('c', '3')
 | 
					 | 
				
			||||||
    db.set('d', '4')
 | 
					 | 
				
			||||||
    all_rows = db.get_all()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    assert all_rows == {'a': '1', 'b': '2', 'c': '3', 'd': '4'}, all_rows
 | 
					 | 
				
			||||||
@ -1,74 +0,0 @@
 | 
				
			|||||||
# Project imports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import os
 | 
					 | 
				
			||||||
import sys
 | 
					 | 
				
			||||||
import unittest 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from json import dumps
 | 
					 | 
				
			||||||
from mock import patch
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    from StringIO import StringIO
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    from io import StringIO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from elodie import constants
 | 
					 | 
				
			||||||
from elodie.result import Result
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def call_result_and_assert(result, expected):
 | 
					 | 
				
			||||||
    saved_stdout = sys.stdout
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        out = StringIO()
 | 
					 | 
				
			||||||
        sys.stdout = out
 | 
					 | 
				
			||||||
        result.write()
 | 
					 | 
				
			||||||
        output = out.getvalue().strip()
 | 
					 | 
				
			||||||
        assert output == expected, output
 | 
					 | 
				
			||||||
    finally:
 | 
					 | 
				
			||||||
        sys.stdout = saved_stdout
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_multiple_rows_with_success():
 | 
					 | 
				
			||||||
    expected = """****** SUMMARY ******
 | 
					 | 
				
			||||||
Metric      Count
 | 
					 | 
				
			||||||
--------  -------
 | 
					 | 
				
			||||||
Success         2
 | 
					 | 
				
			||||||
Error           0"""
 | 
					 | 
				
			||||||
    result = Result()
 | 
					 | 
				
			||||||
    result.append(('id1', '/some/path/1'))
 | 
					 | 
				
			||||||
    result.append(('id2', '/some/path/2'))
 | 
					 | 
				
			||||||
    call_result_and_assert(result, expected)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_multiple_rows_with_failure():
 | 
					 | 
				
			||||||
    expected = """****** ERROR DETAILS ******
 | 
					 | 
				
			||||||
File
 | 
					 | 
				
			||||||
------
 | 
					 | 
				
			||||||
id1
 | 
					 | 
				
			||||||
id2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
****** SUMMARY ******
 | 
					 | 
				
			||||||
Metric      Count
 | 
					 | 
				
			||||||
--------  -------
 | 
					 | 
				
			||||||
Success         0
 | 
					 | 
				
			||||||
Error           2"""
 | 
					 | 
				
			||||||
    result = Result()
 | 
					 | 
				
			||||||
    result.append(('id1', False))
 | 
					 | 
				
			||||||
    result.append(('id2', False))
 | 
					 | 
				
			||||||
    call_result_and_assert(result, expected)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_add_multiple_rows_with_failure_and_success():
 | 
					 | 
				
			||||||
    expected = """****** ERROR DETAILS ******
 | 
					 | 
				
			||||||
File
 | 
					 | 
				
			||||||
------
 | 
					 | 
				
			||||||
id1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
****** SUMMARY ******
 | 
					 | 
				
			||||||
Metric      Count
 | 
					 | 
				
			||||||
--------  -------
 | 
					 | 
				
			||||||
Success         1
 | 
					 | 
				
			||||||
Error           1"""
 | 
					 | 
				
			||||||
    result = Result()
 | 
					 | 
				
			||||||
    result.append(('id1', False))
 | 
					 | 
				
			||||||
    result.append(('id2', '/some/path'))
 | 
					 | 
				
			||||||
    call_result_and_assert(result, expected)
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
{"scopes": ["https://www.googleapis.com/auth/photoslibrary", "https://www.googleapis.com/auth/photoslibrary.appendonly", "https://www.googleapis.com/auth/photoslibrary.sharing"], "id_token": null, "token": "ya29.Gls1B3ymBdURb3tBLAUJgxQtfTzKry0eaUqplbkHxfIYJH9sWvkalLwXprfAW-Ku0Fz8aP3jz7NrncJ2h58idSEgrYXPQ14iVSkwgUGE2gnsxZM6w4TbHz8ny8Yf", "client_id": "1004259275591-ogsk179e96cs0h126qj590mofk86gdqo.apps.googleusercontent.com", "token_uri": "https://oauth2.googleapis.com/token", "client_secret": "p84GOD_i7_PwDGbAmpnbwKiH", "refresh_token": "1/iHiK9Vbq9i5ebXScyQPDZf9_GJrDOWMvu-2zG9wRsDA"}
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
{"installed":{"client_id":"1004259275591-ogsk179e96cs0h126qj590mofk86gdqo.apps.googleusercontent.com","project_id":"elodietestphotos-1561522235041","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"p84GOD_i7_PwDGbAmpnbwKiH","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB  | 
| 
		 Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB  | 
| 
		 Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 222 B  | 
| 
		 Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB  | 
| 
		 Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB  | 
| 
		 Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB  | 
| 
		 Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB  | 
| 
		 Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB  | 
@ -1,9 +1,15 @@
 | 
				
			|||||||
""" pytest test configuration """
 | 
					""" pytest test configuration """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from configparser import RawConfigParser
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					import shutil
 | 
				
			||||||
 | 
					import tempfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dozo import config
 | 
				
			||||||
from dozo.exiftool import _ExifToolProc
 | 
					from dozo.exiftool import _ExifToolProc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DOZO_PATH = Path(__file__).parent.parent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.fixture(autouse=True)
 | 
					@pytest.fixture(autouse=True)
 | 
				
			||||||
def reset_singletons():
 | 
					def reset_singletons():
 | 
				
			||||||
@ -11,3 +17,33 @@ def reset_singletons():
 | 
				
			|||||||
    _ExifToolProc.instance = None
 | 
					    _ExifToolProc.instance = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def copy_sample_files():
 | 
				
			||||||
 | 
					    src_path = tempfile.mkdtemp(prefix='dozo-src')
 | 
				
			||||||
 | 
					    paths = Path(DOZO_PATH, 'samples/test_exif').glob('*')
 | 
				
			||||||
 | 
					    file_paths = [x for x in paths if x.is_file()]
 | 
				
			||||||
 | 
					    for file_path in file_paths:
 | 
				
			||||||
 | 
					        source_path = Path(src_path, file_path.name)
 | 
				
			||||||
 | 
					        shutil.copyfile(file_path, source_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return src_path, file_paths
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@pytest.fixture(scope="module")
 | 
				
			||||||
 | 
					def conf_path():
 | 
				
			||||||
 | 
					    tmp_path = tempfile.mkdtemp(prefix='dozo-')
 | 
				
			||||||
 | 
					    conf = RawConfigParser() 
 | 
				
			||||||
 | 
					    conf['Path'] = {
 | 
				
			||||||
 | 
					            'day_begins': '4',
 | 
				
			||||||
 | 
					            'dirs_path':'%u{%Y-%m}/{city}|{city}-{%Y}/{folders[:1]}/{folder}',
 | 
				
			||||||
 | 
					            'name':'{%Y-%m-%b-%H-%M-%S}-{basename}.%l{ext}'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					    conf['Geolocation'] = {
 | 
				
			||||||
 | 
					            'geocoder': 'Nominatium'
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					    conf_path = Path(tmp_path, "dozo.conf")
 | 
				
			||||||
 | 
					    config.write(conf_path, conf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    yield conf_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    shutil.rmtree(tmp_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
from configparser import RawConfigParser
 | 
					 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
@ -20,28 +19,11 @@ def write_random_file(file_path):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TestConfig:
 | 
					class TestConfig:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module")
 | 
					 | 
				
			||||||
    def conf_path(self):
 | 
					 | 
				
			||||||
        tmp_path = tempfile.mkdtemp(prefix='dozo-')
 | 
					 | 
				
			||||||
        yield Path(tmp_path, "dozo.conf")
 | 
					 | 
				
			||||||
        shutil.rmtree(tmp_path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @pytest.fixture(scope="module")
 | 
					    @pytest.fixture(scope="module")
 | 
				
			||||||
    def conf(self, conf_path):
 | 
					    def conf(self, conf_path):
 | 
				
			||||||
        return config.load_config(conf_path)
 | 
					        return config.load_config(conf_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_write(self, conf_path):
 | 
					    def test_write(self, conf_path):
 | 
				
			||||||
        conf = RawConfigParser() 
 | 
					 | 
				
			||||||
        conf['Path'] = {
 | 
					 | 
				
			||||||
                'day_begins': '4',
 | 
					 | 
				
			||||||
                'dirs_path':'%u{%Y-%m}/{city}|{city}-{%Y}/{folders[:1]}/{folder}',
 | 
					 | 
				
			||||||
                'name':'{%Y-%m-%b-%H-%M-%S}-{basename}.%l{ext}'
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
        conf['Geolocation'] = {
 | 
					 | 
				
			||||||
                'geocoder': 'Nominatium'
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        config.write(conf_path, conf)
 | 
					 | 
				
			||||||
        assert conf_path.is_file()
 | 
					        assert conf_path.is_file()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_load_config(self, conf):
 | 
					    def test_load_config(self, conf):
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,10 @@ import os
 | 
				
			|||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
from sys import platform
 | 
					from sys import platform
 | 
				
			||||||
import tempfile
 | 
					 | 
				
			||||||
from time import sleep
 | 
					from time import sleep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .conftest import copy_sample_files
 | 
				
			||||||
from dozo import constants
 | 
					from dozo import constants
 | 
				
			||||||
from dozo.database import Db
 | 
					from dozo.database import Db
 | 
				
			||||||
from dozo.filesystem import FileSystem
 | 
					from dozo.filesystem import FileSystem
 | 
				
			||||||
@ -16,37 +15,25 @@ from dozo.media.media import Media
 | 
				
			|||||||
from dozo.exiftool import ExifToolCaching, exiftool_is_running, terminate_exiftool
 | 
					from dozo.exiftool import ExifToolCaching, exiftool_is_running, terminate_exiftool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DOZO_PATH = Path(__file__).parent.parent
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@pytest.mark.skip()
 | 
					@pytest.mark.skip()
 | 
				
			||||||
class TestDb:
 | 
					class TestDb:
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestFilesystem:
 | 
					class TestFilesystem:
 | 
				
			||||||
    def setup_class(cls):
 | 
					    def setup_class(cls):
 | 
				
			||||||
        cls.SRCPATH = tempfile.mkdtemp(prefix='dozo-src')
 | 
					        cls.src_paths, cls.file_paths = copy_sample_files()
 | 
				
			||||||
        filenames = ['photo.png', 'plain.jpg', 'text.txt', 'withoutextension',
 | 
					 | 
				
			||||||
                'no-exif.jpg']
 | 
					 | 
				
			||||||
        cls.FILE_PATHS = set()
 | 
					 | 
				
			||||||
        for filename in filenames:
 | 
					 | 
				
			||||||
            source_path = Path(cls.SRCPATH, filename)
 | 
					 | 
				
			||||||
            file_path = Path(DOZO_PATH, 'samples', filename)
 | 
					 | 
				
			||||||
            shutil.copyfile(file_path, source_path)
 | 
					 | 
				
			||||||
            cls.FILE_PATHS.add(source_path)
 | 
					 | 
				
			||||||
        cls.path_format = constants.default_path + '/' + constants.default_name
 | 
					        cls.path_format = constants.default_path + '/' + constants.default_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def teardown_class(self):
 | 
					    def teardown_class(self):
 | 
				
			||||||
        terminate_exiftool()
 | 
					        terminate_exiftool()
 | 
				
			||||||
        assert not exiftool_is_running()
 | 
					        assert not exiftool_is_running()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_part(self):
 | 
					    def test_get_part(self, tmp_path):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Test all parts
 | 
					        Test all parts
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        # Item to search for:
 | 
					        # Item to search for:
 | 
				
			||||||
        filesystem = FileSystem()
 | 
					        filesystem = FileSystem()
 | 
				
			||||||
 | 
					 | 
				
			||||||
        items = filesystem.get_items()
 | 
					        items = filesystem.get_items()
 | 
				
			||||||
        masks = [
 | 
					        masks = [
 | 
				
			||||||
                '{album}',
 | 
					                '{album}',
 | 
				
			||||||
@ -85,59 +72,56 @@ class TestFilesystem:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        subdirs = Path('a', 'b', 'c', 'd')
 | 
					        subdirs = Path('a', 'b', 'c', 'd')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for file_path in self.FILE_PATHS:
 | 
					        for file_path in self.file_paths:
 | 
				
			||||||
            media = Media(str(file_path))
 | 
					            media = Media(str(file_path))
 | 
				
			||||||
            exif_data = ExifToolCaching(str(file_path)).asdict()
 | 
					            exif_data = ExifToolCaching(str(file_path)).asdict()
 | 
				
			||||||
            metadata = media.get_metadata()
 | 
					            metadata = media.get_metadata()
 | 
				
			||||||
 | 
					 | 
				
			||||||
            for item, regex in items.items():
 | 
					            for item, regex in items.items():
 | 
				
			||||||
                for mask in masks:
 | 
					                for mask in masks:
 | 
				
			||||||
                    matched = re.search(regex, mask)
 | 
					                    matched = re.search(regex, mask)
 | 
				
			||||||
                    if matched:
 | 
					                    if matched:
 | 
				
			||||||
                        part = filesystem.get_part(item, mask[1:-1], metadata,
 | 
					                        part = filesystem.get_part(item, mask[1:-1],
 | 
				
			||||||
                                {}, subdirs)
 | 
					                                metadata, Db(tmp_path), subdirs)
 | 
				
			||||||
                        # check if part is correct
 | 
					                        # check if part is correct
 | 
				
			||||||
                        assert isinstance(part, str)
 | 
					                        assert isinstance(part, str), file_path
 | 
				
			||||||
                        expected_part = ''
 | 
					 | 
				
			||||||
                        if item == 'basename':
 | 
					                        if item == 'basename':
 | 
				
			||||||
                            expected_part = file_path.stem
 | 
					                            assert part == file_path.stem, file_path
 | 
				
			||||||
                        elif item == 'date':
 | 
					                        elif item == 'date':
 | 
				
			||||||
                            assert datetime.strptime(part, mask[1:-1])
 | 
					                            assert datetime.strptime(part, mask[1:-1])
 | 
				
			||||||
                            expected_part = part
 | 
					 | 
				
			||||||
                        elif item == 'folder':
 | 
					                        elif item == 'folder':
 | 
				
			||||||
                            expected_part = subdirs.name
 | 
					                            assert part == subdirs.name, file_path
 | 
				
			||||||
                        elif item == 'folders':
 | 
					                        elif item == 'folders':
 | 
				
			||||||
                            if platform == "win32":
 | 
					                            if platform == "win32":
 | 
				
			||||||
                                assert '\\' in part
 | 
					                                assert '\\' in part, file_path
 | 
				
			||||||
                            else:
 | 
					                            else:
 | 
				
			||||||
                                assert '/' in part
 | 
					                                assert '/' in part, file_path
 | 
				
			||||||
                            expected_part = part
 | 
					 | 
				
			||||||
                        elif item == 'ext':
 | 
					                        elif item == 'ext':
 | 
				
			||||||
                            expected_part = file_path.suffix[1:]
 | 
					                            assert part == file_path.suffix[1:], file_path
 | 
				
			||||||
                        if item == 'name':
 | 
					                        elif item == 'name':
 | 
				
			||||||
                            expected_part = file_path.stem
 | 
					                            expected_part = file_path.stem
 | 
				
			||||||
                            for i, rx in filesystem.match_date_from_string(expected_part):
 | 
					                            for i, rx in filesystem.match_date_from_string(expected_part):
 | 
				
			||||||
                                expected_part = re.sub(rx, '', expected_part)
 | 
					                                part = re.sub(rx, '', expected_part)
 | 
				
			||||||
 | 
					                            assert part == expected_part, file_path
 | 
				
			||||||
                        elif item == 'custom':
 | 
					                        elif item == 'custom':
 | 
				
			||||||
                            expected_part = mask[2:-2]
 | 
					                            assert part == mask[2:-2], file_path
 | 
				
			||||||
                        elif item in ('city', 'country', 'location', 'state'):
 | 
					                        elif item in ('city', 'country', 'location', 'state'):
 | 
				
			||||||
                            expected_part = part
 | 
					                            pass
 | 
				
			||||||
                        elif item in exif_tags.keys():
 | 
					                        elif item in exif_tags.keys():
 | 
				
			||||||
                            f = False
 | 
					                            f = False
 | 
				
			||||||
                            for key in exif_tags[item]:
 | 
					                            for key in exif_tags[item]:
 | 
				
			||||||
                                if key in exif_data:
 | 
					                                if key in exif_data:
 | 
				
			||||||
                                    f = True
 | 
					                                    f = True
 | 
				
			||||||
                                    expected_part = exif_data[key]
 | 
					                                    assert part == exif_data[key], file_path
 | 
				
			||||||
                                    break
 | 
					                                    break
 | 
				
			||||||
                            if f == False:
 | 
					                            if f == False:
 | 
				
			||||||
                                expected_part = ''
 | 
					                                assert part == '', file_path
 | 
				
			||||||
 | 
					                        else:
 | 
				
			||||||
                        assert part == expected_part
 | 
					                            assert part == '', file_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_date_taken(self):
 | 
					    def test_get_date_taken(self):
 | 
				
			||||||
        filesystem = FileSystem()
 | 
					        filesystem = FileSystem()
 | 
				
			||||||
        for file_path in self.FILE_PATHS:
 | 
					        for file_path in self.file_paths:
 | 
				
			||||||
            exif_data = ExifToolCaching(str(file_path)).asdict()
 | 
					            exif_data = ExifToolCaching(str(file_path)).asdict()
 | 
				
			||||||
            media = Media(str(file_path))
 | 
					            media = Media(str(file_path))
 | 
				
			||||||
            metadata = media.get_metadata()
 | 
					            metadata = media.get_metadata()
 | 
				
			||||||
@ -167,7 +151,7 @@ class TestFilesystem:
 | 
				
			|||||||
        db = Db(tmp_path)
 | 
					        db = Db(tmp_path)
 | 
				
			||||||
        filesystem = FileSystem(path_format=self.path_format)
 | 
					        filesystem = FileSystem(path_format=self.path_format)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        summary, has_errors = filesystem.sort_files([self.SRCPATH], tmp_path, db)
 | 
					        summary, has_errors = filesystem.sort_files([self.src_paths], tmp_path, db)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Summary is created and there is no errors
 | 
					        # Summary is created and there is no errors
 | 
				
			||||||
        assert summary, summary
 | 
					        assert summary, summary
 | 
				
			||||||
@ -181,7 +165,7 @@ class TestFilesystem:
 | 
				
			|||||||
        for mode in 'copy', 'move':
 | 
					        for mode in 'copy', 'move':
 | 
				
			||||||
            filesystem = FileSystem(path_format=self.path_format, mode=mode)
 | 
					            filesystem = FileSystem(path_format=self.path_format, mode=mode)
 | 
				
			||||||
            # copy mode
 | 
					            # copy mode
 | 
				
			||||||
            src_path = Path(self.SRCPATH, 'photo.png')
 | 
					            src_path = Path(self.src_paths, 'photo.png')
 | 
				
			||||||
            dest_path = Path(tmp_path,'photo_copy.png')
 | 
					            dest_path = Path(tmp_path,'photo_copy.png')
 | 
				
			||||||
            src_checksum = filesystem.checksum(src_path)
 | 
					            src_checksum = filesystem.checksum(src_path)
 | 
				
			||||||
            result_copy = filesystem.sort_file(src_path, dest_path)
 | 
					            result_copy = filesystem.sort_file(src_path, dest_path)
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ from pathlib import Path
 | 
				
			|||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
import tempfile
 | 
					import tempfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .conftest import copy_sample_files
 | 
				
			||||||
from dozo import constants
 | 
					from dozo import constants
 | 
				
			||||||
from dozo.media.media import Media
 | 
					from dozo.media.media import Media
 | 
				
			||||||
from dozo.media.audio import Audio
 | 
					from dozo.media.audio import Audio
 | 
				
			||||||
@ -16,15 +17,7 @@ DOZO_PATH = Path(__file__).parent.parent
 | 
				
			|||||||
class TestMetadata:
 | 
					class TestMetadata:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_class(cls):
 | 
					    def setup_class(cls):
 | 
				
			||||||
        cls.SRCPATH = tempfile.mkdtemp(prefix='dozo-src')
 | 
					        cls.src_paths, cls.file_paths = copy_sample_files()
 | 
				
			||||||
        filenames = ['invalid.jpg', 'photo.png', 'plain.jpg', 'text.txt', 'withoutextension']
 | 
					 | 
				
			||||||
        cls.file_paths = set()
 | 
					 | 
				
			||||||
        for filename in filenames:
 | 
					 | 
				
			||||||
            source_path = Path(cls.SRCPATH, filename)
 | 
					 | 
				
			||||||
            file_path = Path(DOZO_PATH, 'samples', filename)
 | 
					 | 
				
			||||||
            shutil.copyfile(file_path, source_path)
 | 
					 | 
				
			||||||
            cls.file_paths.add(source_path)
 | 
					 | 
				
			||||||
        cls.path_format = constants.default_path + '/' + constants.default_name
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_get_exiftool_attribute(self, tmp_path):
 | 
					    def test_get_exiftool_attribute(self, tmp_path):
 | 
				
			||||||
        for file_path in self.file_paths:
 | 
					        for file_path in self.file_paths:
 | 
				
			||||||
 | 
				
			|||||||