Merge pull request #131 from jmathai/increase-coverage
gh-40 Add tests to increase coverage in geolocation and photo module
This commit is contained in:
commit
55df0719e8
|
@ -2,3 +2,4 @@
|
||||||
omit =
|
omit =
|
||||||
*/tests/*
|
*/tests/*
|
||||||
*/external/*
|
*/external/*
|
||||||
|
*/tools/*
|
||||||
|
|
|
@ -52,12 +52,6 @@ elodie.media
|
||||||
.. automodule:: elodie.media.video
|
.. automodule:: elodie.media.video
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
elodie.arguments
|
|
||||||
----------------
|
|
||||||
|
|
||||||
.. automodule:: elodie.arguments
|
|
||||||
:members:
|
|
||||||
|
|
||||||
elodie.constants
|
elodie.constants
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
"""
|
|
||||||
Command line argument parsing for helper scripts.
|
|
||||||
"""
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import getopt
|
|
||||||
import sys
|
|
||||||
from re import sub
|
|
||||||
|
|
||||||
|
|
||||||
def parse(argv, options, long_options, usage):
|
|
||||||
"""Parse command line arguments.
|
|
||||||
|
|
||||||
:param list(str) argv: Arguments passed to the program.
|
|
||||||
:param str options: String of characters for allowed short options.
|
|
||||||
:param list(str) long_options: List of strings of allowed long options.
|
|
||||||
:param str usage: Help text, to print in the case of an error or when
|
|
||||||
the user asks for it.
|
|
||||||
:returns: dict
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
opts, args = getopt.getopt(argv, options, long_options)
|
|
||||||
except getopt.GetoptError:
|
|
||||||
print(usage)
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
return_arguments = {}
|
|
||||||
for opt, arg in opts:
|
|
||||||
if opt == '-h':
|
|
||||||
print(usage)
|
|
||||||
sys.exit()
|
|
||||||
else:
|
|
||||||
return_arguments[sub('^-+', '', opt)] = arg
|
|
||||||
|
|
||||||
return return_arguments
|
|
|
@ -10,7 +10,6 @@ from __future__ import absolute_import
|
||||||
import imghdr
|
import imghdr
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from re import compile
|
from re import compile
|
||||||
|
@ -38,28 +37,6 @@ class Photo(Media):
|
||||||
# We only want to parse EXIF once so we store it here
|
# We only want to parse EXIF once so we store it here
|
||||||
self.exif = None
|
self.exif = None
|
||||||
|
|
||||||
def get_duration(self):
|
|
||||||
"""Get the duration of a photo in seconds. Uses ffmpeg/ffprobe.
|
|
||||||
|
|
||||||
:returns: str or None for a non-photo file
|
|
||||||
"""
|
|
||||||
if(not self.is_valid()):
|
|
||||||
return None
|
|
||||||
|
|
||||||
source = self.source
|
|
||||||
result = subprocess.Popen(
|
|
||||||
['ffprobe', source],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.STDOUT
|
|
||||||
)
|
|
||||||
for key in result.stdout.readlines():
|
|
||||||
if 'Duration' in key:
|
|
||||||
return re.search(
|
|
||||||
'(\d{2}:\d{2}.\d{2})',
|
|
||||||
key
|
|
||||||
).group(1).replace('.', ':')
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_date_taken(self):
|
def get_date_taken(self):
|
||||||
"""Get the date which the photo was taken.
|
"""Get the date which the photo was taken.
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ from __future__ import absolute_import
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
# load modules
|
# load modules
|
||||||
from distutils.spawn import find_executable
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -53,21 +52,6 @@ class Video(Media):
|
||||||
self.longitude_ref_key = 'EXIF:GPSLongitudeRef'
|
self.longitude_ref_key = 'EXIF:GPSLongitudeRef'
|
||||||
self.set_gps_ref = False
|
self.set_gps_ref = False
|
||||||
|
|
||||||
def get_avmetareadwrite(self):
|
|
||||||
"""Get path to executable avmetareadwrite binary.
|
|
||||||
|
|
||||||
We wrap this since we call it in a few places and we do a fallback.
|
|
||||||
|
|
||||||
:returns: None or string
|
|
||||||
"""
|
|
||||||
avmetareadwrite = find_executable('avmetareadwrite')
|
|
||||||
if(avmetareadwrite is None):
|
|
||||||
avmetareadwrite = '/usr/bin/avmetareadwrite'
|
|
||||||
if(not os.path.isfile(avmetareadwrite) or not os.access(avmetareadwrite, os.X_OK)): # noqa
|
|
||||||
return None
|
|
||||||
|
|
||||||
return avmetareadwrite
|
|
||||||
|
|
||||||
def get_date_taken(self):
|
def get_date_taken(self):
|
||||||
"""Get the date which the photo was taken.
|
"""Get the date which the photo was taken.
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,20 @@ def test_decimal_to_dms():
|
||||||
|
|
||||||
assert target_decimal_value == check_value, '%s does not match %s' % (check_value, target_decimal_value)
|
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():
|
def test_dms_string_latitude():
|
||||||
|
|
||||||
for x in range(0, 5):
|
for x in range(0, 5):
|
||||||
|
|
|
@ -24,6 +24,14 @@ from elodie.media.video import Video
|
||||||
os.environ['TZ'] = 'GMT'
|
os.environ['TZ'] = 'GMT'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_class_by_file_without_extension():
|
||||||
|
base_file = helper.get_file('withoutextension')
|
||||||
|
|
||||||
|
cls = Base.get_class_by_file(base_file, [Audio, Text, Photo, Video])
|
||||||
|
|
||||||
|
assert cls is None, cls
|
||||||
|
|
||||||
def test_set_album_from_folder_invalid_file():
|
def test_set_album_from_folder_invalid_file():
|
||||||
temporary_folder, folder = helper.create_working_folder()
|
temporary_folder, folder = helper.create_working_folder()
|
||||||
|
|
||||||
|
@ -38,9 +46,63 @@ def test_set_album_from_folder_invalid_file():
|
||||||
|
|
||||||
assert status == False, status
|
assert status == False, status
|
||||||
|
|
||||||
def test_get_class_by_file_without_extension():
|
def test_set_album_from_folder():
|
||||||
base_file = helper.get_file('withoutextension')
|
temporary_folder, folder = helper.create_working_folder()
|
||||||
|
|
||||||
cls = Base.get_class_by_file(base_file, [Audio, Text, Photo, Video])
|
origin = '%s/photo.jpg' % folder
|
||||||
|
shutil.copyfile(helper.get_file('plain.jpg'), origin)
|
||||||
|
|
||||||
assert cls is None, cls
|
photo = Photo(origin)
|
||||||
|
metadata = photo.get_metadata()
|
||||||
|
|
||||||
|
assert metadata['album'] is None, metadata['album']
|
||||||
|
|
||||||
|
new_album_name = os.path.split(folder)[1]
|
||||||
|
status = photo.set_album_from_folder()
|
||||||
|
|
||||||
|
assert status == True, status
|
||||||
|
|
||||||
|
photo_new = Photo(origin)
|
||||||
|
metadata_new = photo_new.get_metadata()
|
||||||
|
|
||||||
|
shutil.rmtree(folder)
|
||||||
|
|
||||||
|
assert metadata_new['album'] == new_album_name, metadata_new['album']
|
||||||
|
|
||||||
|
def test_set_metadata():
|
||||||
|
temporary_folder, folder = helper.create_working_folder()
|
||||||
|
|
||||||
|
origin = '%s/photo.jpg' % folder
|
||||||
|
shutil.copyfile(helper.get_file('plain.jpg'), origin)
|
||||||
|
|
||||||
|
photo = Photo(origin)
|
||||||
|
|
||||||
|
metadata = photo.get_metadata()
|
||||||
|
|
||||||
|
assert metadata['title'] == None, metadata['title']
|
||||||
|
|
||||||
|
new_title = 'Some Title'
|
||||||
|
photo.set_metadata(title = new_title)
|
||||||
|
|
||||||
|
new_metadata = photo.get_metadata()
|
||||||
|
|
||||||
|
assert new_metadata['title'] == new_title, new_metadata['title']
|
||||||
|
|
||||||
|
def test_set_metadata_basename():
|
||||||
|
temporary_folder, folder = helper.create_working_folder()
|
||||||
|
|
||||||
|
origin = '%s/photo.jpg' % folder
|
||||||
|
shutil.copyfile(helper.get_file('plain.jpg'), origin)
|
||||||
|
|
||||||
|
photo = Photo(origin)
|
||||||
|
|
||||||
|
metadata = photo.get_metadata()
|
||||||
|
|
||||||
|
assert metadata['base_name'] == 'photo', metadata['base_name']
|
||||||
|
|
||||||
|
new_basename = 'Some Base Name'
|
||||||
|
photo.set_metadata_basename(new_basename)
|
||||||
|
|
||||||
|
new_metadata = photo.get_metadata()
|
||||||
|
|
||||||
|
assert new_metadata['base_name'] == new_basename, new_metadata['base_name']
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from elodie import arguments
|
|
||||||
from elodie.media.photo import Media
|
|
||||||
from elodie.media.photo import Photo
|
|
||||||
from elodie.media.video import Video
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
args = arguments.parse(argv, None, ['file='], './import.py --file=<path to file>')
|
|
||||||
|
|
||||||
if('file' not in args):
|
|
||||||
print 'No file specified'
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
media = Media.get_class_by_file(args['file'], [Photo, Video])
|
|
||||||
|
|
||||||
if(media is None):
|
|
||||||
print 'Not a valid file'
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
metadata = media.get_metadata()
|
|
||||||
output = {'date_taken': metadata['date_taken']}
|
|
||||||
print '%r' % output
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(sys.argv[1:])
|
|
||||||
sys.exit(0)
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from elodie import arguments
|
|
||||||
from elodie import geolocation
|
|
||||||
from elodie.media.photo import Media
|
|
||||||
from elodie.media.photo import Photo
|
|
||||||
from elodie.media.video import Video
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
args = arguments.parse(argv, None, ['file=','type='], './import.py --type=<photo or video> --file=<path to file>')
|
|
||||||
|
|
||||||
if('file' not in args):
|
|
||||||
print 'No file specified'
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
media = Media.get_class_by_file(args['file'], [Photo, Video])
|
|
||||||
|
|
||||||
if(media is None):
|
|
||||||
print 'Not a valid file'
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
metadata = media.get_metadata()
|
|
||||||
|
|
||||||
place_name = geolocation.place_name(metadata['latitude'], metadata['longitude'])
|
|
||||||
|
|
||||||
output = {'latitude': metadata['latitude'], 'longitude': metadata['longitude'], 'place_name': place_name}
|
|
||||||
print '%r' % output
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main(sys.argv[1:])
|
|
||||||
sys.exit(0)
|
|
Loading…
Reference in New Issue