Merge pull request #64 from noonat/friendly-dep-errors
Added friendly errors when dependencies are not installed
This commit is contained in:
commit
1d86856a07
|
@ -7,7 +7,7 @@ before_install:
|
|||
- "sudo apt-get update -qq"
|
||||
- "sudo apt-get install python-dev python-pip python-pyexiv2 libimage-exiftool-perl -y"
|
||||
install:
|
||||
- "sudo pip install docopt LatLon nose requests"
|
||||
- "sudo pip install docopt LatLon mock nose requests"
|
||||
# command to run tests
|
||||
# test mapquest key
|
||||
before_script:
|
||||
|
|
|
@ -7,6 +7,12 @@ import sys
|
|||
from datetime import datetime
|
||||
from docopt import docopt
|
||||
|
||||
# Verify that external dependencies are present first, so the user gets a
|
||||
# more user-friendly error instead of an ImportError traceback.
|
||||
from elodie.dependencies import verify_dependencies
|
||||
if not verify_dependencies():
|
||||
sys.exit(1)
|
||||
|
||||
from elodie import constants
|
||||
from elodie import geolocation
|
||||
from elodie.media.media import Media
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
"""Helpers for checking external dependencies."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
|
||||
EXIFTOOL_ERROR = u"""
|
||||
It looks like you don't have exiftool installed, which Elodie requires.
|
||||
Please take a look at the installation steps in the readme:
|
||||
|
||||
https://github.com/jmathai/elodie#install-everything-you-need
|
||||
""".lstrip()
|
||||
|
||||
PYEXIV2_ERROR = u"""
|
||||
{error_class_name}: {error}
|
||||
|
||||
It looks like you don't have pyexiv2 installed, which Elodie requires for
|
||||
geolocation. Please take a look at the installation steps in the readme:
|
||||
|
||||
https://github.com/jmathai/elodie#install-everything-you-need
|
||||
""".lstrip()
|
||||
|
||||
|
||||
def get_exiftool():
|
||||
"""Get path to executable exiftool binary.
|
||||
|
||||
We wrap this since we call it in a few places and we do a fallback.
|
||||
|
||||
@returns, None or string
|
||||
"""
|
||||
path = find_executable('exiftool')
|
||||
# If exiftool wasn't found we try to brute force the homebrew location
|
||||
if path is None:
|
||||
path = '/usr/local/bin/exiftool'
|
||||
if not os.path.isfile(path) or not os.access(path, os.X_OK):
|
||||
return None
|
||||
return path
|
||||
|
||||
|
||||
def verify_dependencies():
|
||||
"""Verify that external dependencies are installed.
|
||||
|
||||
Prints a message to stderr and returns False if any dependencies are
|
||||
missing.
|
||||
|
||||
@returns, bool
|
||||
"""
|
||||
exiftool = get_exiftool()
|
||||
if exiftool is None:
|
||||
print >>sys.stderr, EXIFTOOL_ERROR
|
||||
return False
|
||||
|
||||
try:
|
||||
import pyexiv2
|
||||
except ImportError as e:
|
||||
print >>sys.stderr, PYEXIV2_ERROR.format(
|
||||
error_class_name=e.__class__.__name__, error=e)
|
||||
return False
|
||||
|
||||
return True
|
|
@ -4,8 +4,8 @@ Media package that's a parent class for media objects
|
|||
"""
|
||||
|
||||
# load modules
|
||||
from distutils.spawn import find_executable
|
||||
from elodie import constants
|
||||
from elodie.dependencies import get_exiftool
|
||||
|
||||
import mimetypes
|
||||
import os
|
||||
|
@ -48,22 +48,6 @@ class Media(object):
|
|||
|
||||
return exiftool_attributes['album']
|
||||
|
||||
"""
|
||||
Get path to executable exiftool binary.
|
||||
We wrap this since we call it in a few places and we do a fallback.
|
||||
|
||||
@returns, None or string
|
||||
"""
|
||||
def get_exiftool(self):
|
||||
exiftool = find_executable('exiftool')
|
||||
# If exiftool wasn't found we try to brute force the homebrew location
|
||||
if(exiftool is None):
|
||||
exiftool = '/usr/local/bin/exiftool'
|
||||
if(not os.path.isfile(exiftool) or not os.access(exiftool, os.X_OK)): # noqa
|
||||
return None
|
||||
|
||||
return exiftool
|
||||
|
||||
"""
|
||||
Get the full path to the video.
|
||||
|
||||
|
@ -103,7 +87,7 @@ class Media(object):
|
|||
if(self.exiftool_attributes is not None):
|
||||
return self.exiftool_attributes
|
||||
|
||||
exiftool = self.get_exiftool()
|
||||
exiftool = get_exiftool()
|
||||
if(exiftool is None):
|
||||
return False
|
||||
|
||||
|
@ -222,7 +206,7 @@ class Media(object):
|
|||
if(name is None):
|
||||
return False
|
||||
|
||||
exiftool = self.get_exiftool()
|
||||
exiftool = get_exiftool()
|
||||
if(exiftool is None):
|
||||
return False
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import time
|
|||
|
||||
from elodie import constants
|
||||
from elodie import plist_parser
|
||||
from elodie.dependencies import get_exiftool
|
||||
from media import Media
|
||||
|
||||
|
||||
|
@ -145,7 +146,7 @@ class Video(Media):
|
|||
@returns, string or None if exiftool is not found
|
||||
"""
|
||||
def get_exif(self):
|
||||
exiftool = self.get_exiftool()
|
||||
exiftool = get_exiftool()
|
||||
if(exiftool is None):
|
||||
return None
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
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
|
|
@ -21,11 +21,6 @@ from elodie.media.video import Video
|
|||
|
||||
os.environ['TZ'] = 'GMT'
|
||||
|
||||
def test_exiftool():
|
||||
media = Media()
|
||||
exiftool = media.get_exiftool()
|
||||
|
||||
assert exiftool is not None, exiftool
|
||||
|
||||
def test_get_file_path():
|
||||
media = Media(helper.get_file('plain.jpg'))
|
||||
|
|
Loading…
Reference in New Issue