Python 3 compartibility added
This commit is contained in:
parent
4f19c0c00d
commit
af36de091e
|
@ -2,14 +2,15 @@ language: python
|
||||||
dist: trusty
|
dist: trusty
|
||||||
python:
|
python:
|
||||||
- "2.7"
|
- "2.7"
|
||||||
|
- "3.4"
|
||||||
virtualenv:
|
virtualenv:
|
||||||
system_site_packages: true
|
system_site_packages: true
|
||||||
before_install:
|
before_install:
|
||||||
- "sudo apt-get update -qq"
|
- "sudo apt-get update -qq"
|
||||||
- "sudo apt-get install python-dev python-pip libimage-exiftool-perl -y"
|
- "sudo apt-get install python-dev python-pip libimage-exiftool-perl -y"
|
||||||
install:
|
install:
|
||||||
- "sudo pip install -r elodie/tests/requirements.txt"
|
- "pip install -r elodie/tests/requirements.txt"
|
||||||
- "sudo pip install coveralls"
|
- "pip install coveralls"
|
||||||
# command to run tests
|
# command to run tests
|
||||||
# test mapquest key
|
# test mapquest key
|
||||||
before_script:
|
before_script:
|
||||||
|
|
35
elodie.py
35
elodie.py
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
@ -35,16 +36,16 @@ def import_file(_file, destination, album_from_folder, trash):
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(_file):
|
if not os.path.exists(_file):
|
||||||
if constants.debug:
|
if constants.debug:
|
||||||
print 'Could not find %s' % _file
|
print('Could not find %s' % _file)
|
||||||
print '{"source":"%s", "error_msg":"Could not find %s"}' % \
|
print('{"source":"%s", "error_msg":"Could not find %s"}' % \
|
||||||
(_file, _file)
|
(_file, _file))
|
||||||
return
|
return
|
||||||
|
|
||||||
media = Media.get_class_by_file(_file, [Text, Audio, Photo, Video])
|
media = Media.get_class_by_file(_file, [Text, Audio, Photo, Video])
|
||||||
if not media:
|
if not media:
|
||||||
if constants.debug:
|
if constants.debug:
|
||||||
print 'Not a supported file (%s)' % _file
|
print('Not a supported file (%s)' % _file)
|
||||||
print '{"source":"%s", "error_msg":"Not a supported file"}' % _file
|
print('{"source":"%s", "error_msg":"Not a supported file"}' % _file)
|
||||||
return
|
return
|
||||||
|
|
||||||
if media.__name__ == 'Video':
|
if media.__name__ == 'Video':
|
||||||
|
@ -56,7 +57,7 @@ def import_file(_file, destination, album_from_folder, trash):
|
||||||
dest_path = FILESYSTEM.process_file(_file, destination,
|
dest_path = FILESYSTEM.process_file(_file, destination,
|
||||||
media, allowDuplicate=False, move=False)
|
media, allowDuplicate=False, move=False)
|
||||||
if dest_path:
|
if dest_path:
|
||||||
print '%s -> %s' % (_file, dest_path)
|
print('%s -> %s' % (_file, dest_path))
|
||||||
if trash:
|
if trash:
|
||||||
send2trash(_file)
|
send2trash(_file)
|
||||||
|
|
||||||
|
@ -109,9 +110,9 @@ def update_location(media, file_path, location_name):
|
||||||
'latitude'], location_coords['longitude'])
|
'latitude'], location_coords['longitude'])
|
||||||
if not location_status:
|
if not location_status:
|
||||||
if constants.debug:
|
if constants.debug:
|
||||||
print 'Failed to update location'
|
print('Failed to update location')
|
||||||
print ('{"source":"%s",' % file_path,
|
print(('{"source":"%s",' % file_path,
|
||||||
'"error_msg":"Failed to update location"}')
|
'"error_msg":"Failed to update location"}'))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -125,8 +126,8 @@ def update_time(media, file_path, time_string):
|
||||||
elif re.match(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}\d{2}$', time_string):
|
elif re.match(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}\d{2}$', time_string):
|
||||||
msg = ('Invalid time format. Use YYYY-mm-dd hh:ii:ss or YYYY-mm-dd')
|
msg = ('Invalid time format. Use YYYY-mm-dd hh:ii:ss or YYYY-mm-dd')
|
||||||
if constants.debug:
|
if constants.debug:
|
||||||
print msg
|
print(msg)
|
||||||
print '{"source":"%s", "error_msg":"%s"}' % (file_path, msg)
|
print('{"source":"%s", "error_msg":"%s"}' % (file_path, msg))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
time = datetime.strptime(time_string, time_format)
|
time = datetime.strptime(time_string, time_format)
|
||||||
|
@ -150,9 +151,9 @@ def _update(album, location, time, title, files):
|
||||||
for file_path in files:
|
for file_path in files:
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
if constants.debug:
|
if constants.debug:
|
||||||
print 'Could not find %s' % file_path
|
print('Could not find %s' % file_path)
|
||||||
print '{"source":"%s", "error_msg":"Could not find %s"}' % \
|
print('{"source":"%s", "error_msg":"Could not find %s"}' % \
|
||||||
(file_path, file_path)
|
(file_path, file_path))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
file_path = os.path.expanduser(file_path)
|
file_path = os.path.expanduser(file_path)
|
||||||
|
@ -209,9 +210,9 @@ def _update(album, location, time, title, files):
|
||||||
dest_path = FILESYSTEM.process_file(file_path, destination,
|
dest_path = FILESYSTEM.process_file(file_path, destination,
|
||||||
updated_media, move=True, allowDuplicate=True)
|
updated_media, move=True, allowDuplicate=True)
|
||||||
if constants.debug:
|
if constants.debug:
|
||||||
print u'%s -> %s' % (file_path, dest_path)
|
print(u'%s -> %s' % (file_path, dest_path))
|
||||||
print '{"source":"%s", "destination":"%s"}' % (file_path,
|
print('{"source":"%s", "destination":"%s"}' % (file_path,
|
||||||
dest_path)
|
dest_path))
|
||||||
# If the folder we moved the file out of or its parent are empty
|
# If the folder we moved the file out of or its parent are empty
|
||||||
# we delete it.
|
# we delete it.
|
||||||
FILESYSTEM.delete_directory_if_empty(os.path.dirname(file_path))
|
FILESYSTEM.delete_directory_if_empty(os.path.dirname(file_path))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Command line argument parsing for helper scripts.
|
Command line argument parsing for helper scripts.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import getopt
|
import getopt
|
||||||
import sys
|
import sys
|
||||||
|
@ -20,13 +21,13 @@ def parse(argv, options, long_options, usage):
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(argv, options, long_options)
|
opts, args = getopt.getopt(argv, options, long_options)
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
print usage
|
print(usage)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
return_arguments = {}
|
return_arguments = {}
|
||||||
for opt, arg in opts:
|
for opt, arg in opts:
|
||||||
if opt == '-h':
|
if opt == '-h':
|
||||||
print usage
|
print(usage)
|
||||||
sys.exit()
|
sys.exit()
|
||||||
else:
|
else:
|
||||||
return_arguments[sub('^-+', '', opt)] = arg
|
return_arguments[sub('^-+', '', opt)] = arg
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Helpers for checking for an interacting with external dependencies. These are
|
Helpers for checking for an interacting with external dependencies. These are
|
||||||
things that Elodie requires, but aren't installed automatically for the user.
|
things that Elodie requires, but aren't installed automatically for the user.
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -43,7 +44,7 @@ def verify_dependencies():
|
||||||
"""
|
"""
|
||||||
exiftool = get_exiftool()
|
exiftool = get_exiftool()
|
||||||
if exiftool is None:
|
if exiftool is None:
|
||||||
print >>sys.stderr, EXIFTOOL_ERROR
|
print(EXIFTOOL_ERROR, file=sys.stderr)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -273,8 +273,7 @@ class ExifTool(object):
|
||||||
"""
|
"""
|
||||||
if not self.running:
|
if not self.running:
|
||||||
raise ValueError("ExifTool instance not running.")
|
raise ValueError("ExifTool instance not running.")
|
||||||
cmd_txt = b"\n".join(params + (b"-execute\n",))
|
self._process.stdin.write(b"\n".join(params + (b"-execute\n",)))
|
||||||
self._process.stdin.write(cmd_txt.encode("utf-8"))
|
|
||||||
self._process.stdin.flush()
|
self._process.stdin.flush()
|
||||||
output = b""
|
output = b""
|
||||||
fd = self._process.stdout.fileno()
|
fd = self._process.stdout.fileno()
|
||||||
|
@ -403,11 +402,13 @@ class ExifTool(object):
|
||||||
"an iterable of strings")
|
"an iterable of strings")
|
||||||
|
|
||||||
params = []
|
params = []
|
||||||
|
params_b = []
|
||||||
for tag, value in tags.items():
|
for tag, value in tags.items():
|
||||||
params.append(u'-%s=%s' % (tag, value))
|
params.append(u'-%s=%s' % (tag, value))
|
||||||
|
|
||||||
params.extend(filenames)
|
params.extend(filenames)
|
||||||
return self.execute(*params)
|
params_b = [x.encode('utf-8') for x in params]
|
||||||
|
return self.execute(*params_b)
|
||||||
|
|
||||||
def set_tags(self, tags, filename):
|
def set_tags(self, tags, filename):
|
||||||
"""Writes the values of the specified tags for the given file.
|
"""Writes the values of the specified tags for the given file.
|
||||||
|
|
|
@ -3,6 +3,8 @@ General file system methods.
|
||||||
|
|
||||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import object
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -176,7 +178,7 @@ class FileSystem(object):
|
||||||
allow_duplicate = kwargs['allowDuplicate']
|
allow_duplicate = kwargs['allowDuplicate']
|
||||||
|
|
||||||
if(not media.is_valid()):
|
if(not media.is_valid()):
|
||||||
print '%s is not a valid media file. Skipping...' % _file
|
print('%s is not a valid media file. Skipping...' % _file)
|
||||||
return
|
return
|
||||||
|
|
||||||
metadata = media.get_metadata()
|
metadata = media.get_metadata()
|
||||||
|
@ -191,17 +193,17 @@ class FileSystem(object):
|
||||||
checksum = db.checksum(_file)
|
checksum = db.checksum(_file)
|
||||||
if(checksum is None):
|
if(checksum is None):
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print 'Could not get checksum for %s. Skipping...' % _file
|
print('Could not get checksum for %s. Skipping...' % _file)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If duplicates are not allowed and this hash exists in the db then we
|
# If duplicates are not allowed and this hash exists in the db then we
|
||||||
# return
|
# return
|
||||||
if(allow_duplicate is False and db.check_hash(checksum) is True):
|
if(allow_duplicate is False and db.check_hash(checksum) is True):
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print '%s already exists at %s. Skipping...' % (
|
print('%s already exists at %s. Skipping...' % (
|
||||||
_file,
|
_file,
|
||||||
db.get_hash(checksum)
|
db.get_hash(checksum)
|
||||||
)
|
))
|
||||||
return
|
return
|
||||||
|
|
||||||
self.create_directory(dest_directory)
|
self.create_directory(dest_directory)
|
||||||
|
|
|
@ -1,32 +1,21 @@
|
||||||
"""Look up geolocation information for media objects."""
|
"""Look up geolocation information for media objects."""
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
from future import standard_library
|
||||||
|
standard_library.install_aliases()
|
||||||
|
from past.utils import old_div
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from ConfigParser import ConfigParser
|
from configparser import ConfigParser
|
||||||
import fractions
|
import fractions
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import urllib
|
import urllib.request, urllib.parse, urllib.error
|
||||||
|
|
||||||
from elodie import constants
|
from elodie import constants
|
||||||
from elodie.localstorage import Db
|
from elodie.localstorage import Db
|
||||||
|
|
||||||
|
|
||||||
class Fraction(fractions.Fraction):
|
|
||||||
|
|
||||||
"""Only create Fractions from floats.
|
|
||||||
|
|
||||||
Should be compatible with Python 2.6, though untested.
|
|
||||||
|
|
||||||
>>> Fraction(0.3)
|
|
||||||
Fraction(3, 10)
|
|
||||||
>>> Fraction(1.1)
|
|
||||||
Fraction(11, 10)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __new__(cls, value, ignore=None):
|
|
||||||
return fractions.Fraction.from_float(value).limit_denominator(99999)
|
|
||||||
|
|
||||||
|
|
||||||
def coordinates_by_name(name):
|
def coordinates_by_name(name):
|
||||||
# Try to get cached location first
|
# Try to get cached location first
|
||||||
db = Db()
|
db = Db()
|
||||||
|
@ -88,7 +77,7 @@ def dms_to_decimal(degrees, minutes, seconds, direction=' '):
|
||||||
if(direction[0] in 'WSws'):
|
if(direction[0] in 'WSws'):
|
||||||
sign = -1
|
sign = -1
|
||||||
return (
|
return (
|
||||||
float(degrees) + float(minutes) / 60 + float(seconds) / 3600
|
float(degrees) + old_div(float(minutes), 60) + old_div(float(seconds), 3600)
|
||||||
) * sign
|
) * sign
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,17 +148,17 @@ def reverse_lookup(lat, lon):
|
||||||
headers = {"Accept-Language": constants.accepted_language}
|
headers = {"Accept-Language": constants.accepted_language}
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
'http://open.mapquestapi.com/nominatim/v1/reverse.php?%s' %
|
'http://open.mapquestapi.com/nominatim/v1/reverse.php?%s' %
|
||||||
urllib.urlencode(params), headers=headers
|
urllib.parse.urlencode(params),headers=headers
|
||||||
)
|
)
|
||||||
return r.json()
|
return r.json()
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print e
|
print(e)
|
||||||
return None
|
return None
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print r.text
|
print(r.text)
|
||||||
print e
|
print(e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,18 +171,18 @@ def lookup(name):
|
||||||
try:
|
try:
|
||||||
params = {'format': 'json', 'key': key, 'location': name}
|
params = {'format': 'json', 'key': key, 'location': name}
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print 'http://open.mapquestapi.com/geocoding/v1/address?%s' % urllib.urlencode(params) # noqa
|
print('http://open.mapquestapi.com/geocoding/v1/address?%s' % urllib.parse.urlencode(params)) # noqa
|
||||||
r = requests.get(
|
r = requests.get(
|
||||||
'http://open.mapquestapi.com/geocoding/v1/address?%s' %
|
'http://open.mapquestapi.com/geocoding/v1/address?%s' %
|
||||||
urllib.urlencode(params)
|
urllib.parse.urlencode(params)
|
||||||
)
|
)
|
||||||
return r.json()
|
return r.json()
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print e
|
print(e)
|
||||||
return None
|
return None
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print r.text
|
print(r.text)
|
||||||
print e
|
print(e)
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
"""
|
"""
|
||||||
Methods for interacting with information Elodie caches about stored media.
|
Methods for interacting with information Elodie caches about stored media.
|
||||||
"""
|
"""
|
||||||
|
from builtins import map
|
||||||
|
from builtins import object
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
|
@ -141,17 +143,17 @@ class Db(object):
|
||||||
the given latitude and longitude.
|
the given latitude and longitude.
|
||||||
:returns: str, or None if a matching location couldn't be found.
|
:returns: str, or None if a matching location couldn't be found.
|
||||||
"""
|
"""
|
||||||
last_d = sys.maxint
|
last_d = sys.maxsize
|
||||||
name = None
|
name = None
|
||||||
for data in self.location_db:
|
for data in self.location_db:
|
||||||
# As threshold is quite small use simple math
|
# As threshold is quite small use simple math
|
||||||
# From http://stackoverflow.com/questions/15736995/how-can-i-quickly-estimate-the-distance-between-two-latitude-longitude-points # noqa
|
# From http://stackoverflow.com/questions/15736995/how-can-i-quickly-estimate-the-distance-between-two-latitude-longitude-points # noqa
|
||||||
# convert decimal degrees to radians
|
# convert decimal degrees to radians
|
||||||
|
|
||||||
lon1, lat1, lon2, lat2 = map(
|
lon1, lat1, lon2, lat2 = list(map(
|
||||||
radians,
|
radians,
|
||||||
[longitude, latitude, data['long'], data['lat']]
|
[longitude, latitude, data['long'], data['lat']]
|
||||||
)
|
))
|
||||||
|
|
||||||
r = 6371000 # radius of the earth in m
|
r = 6371000 # radius of the earth in m
|
||||||
x = (lon2 - lon1) * cos(0.5 * (lat2 + lat1))
|
x = (lon2 - lon1) * cos(0.5 * (lat2 + lat1))
|
||||||
|
|
|
@ -5,8 +5,9 @@ class.
|
||||||
|
|
||||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
||||||
"""
|
"""
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from video import Video
|
from .video import Video
|
||||||
|
|
||||||
|
|
||||||
class Audio(Video):
|
class Audio(Video):
|
||||||
|
|
|
@ -13,6 +13,10 @@ are used to represent the actual files.
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
try:
|
||||||
|
basestring
|
||||||
|
except NameError:
|
||||||
|
basestring = str
|
||||||
|
|
||||||
class Base(object):
|
class Base(object):
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ are used to represent the actual files.
|
||||||
|
|
||||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
from builtins import object
|
||||||
|
|
||||||
# load modules
|
# load modules
|
||||||
from elodie import constants
|
from elodie import constants
|
||||||
|
|
|
@ -4,6 +4,9 @@ image objects (JPG, DNG, etc.).
|
||||||
|
|
||||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from builtins import str
|
||||||
|
|
||||||
import imghdr
|
import imghdr
|
||||||
import os
|
import os
|
||||||
|
@ -15,7 +18,7 @@ from re import compile
|
||||||
|
|
||||||
|
|
||||||
from elodie import constants
|
from elodie import constants
|
||||||
from media import Media
|
from .media import Media
|
||||||
|
|
||||||
|
|
||||||
class Photo(Media):
|
class Photo(Media):
|
||||||
|
@ -95,7 +98,7 @@ class Photo(Media):
|
||||||
break
|
break
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print e
|
print(e)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if(seconds_since_epoch == 0):
|
if(seconds_since_epoch == 0):
|
||||||
|
|
|
@ -123,7 +123,7 @@ class Text(Base):
|
||||||
self.metadata_line = parsed_json
|
self.metadata_line = parsed_json
|
||||||
except ValueError:
|
except ValueError:
|
||||||
if(constants.debug is True):
|
if(constants.debug is True):
|
||||||
print 'Could not parse JSON from first line: %s' % first_line
|
print('Could not parse JSON from first line: %s' % first_line)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write_metadata(self, **kwargs):
|
def write_metadata(self, **kwargs):
|
||||||
|
|
|
@ -4,6 +4,12 @@ objects (AVI, MOV, etc.).
|
||||||
|
|
||||||
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
.. moduleauthor:: Jaisen Mathai <jaisen@jmathai.com>
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from builtins import str
|
||||||
|
from builtins import object
|
||||||
|
from past.utils import old_div
|
||||||
|
|
||||||
# load modules
|
# load modules
|
||||||
from distutils.spawn import find_executable
|
from distutils.spawn import find_executable
|
||||||
|
@ -13,7 +19,7 @@ import os
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from media import Media
|
from .media import Media
|
||||||
|
|
||||||
|
|
||||||
class Video(Media):
|
class Video(Media):
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
# Project imports
|
# Project imports
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -11,7 +12,7 @@ import mock
|
||||||
|
|
||||||
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.dirname(os.path.realpath(__file__))))))
|
||||||
|
|
||||||
import helper
|
from . import helper
|
||||||
from elodie.filesystem import FileSystem
|
from elodie.filesystem import FileSystem
|
||||||
from elodie.media.media import Media
|
from elodie.media.media import Media
|
||||||
from elodie.media.photo import Photo
|
from elodie.media.photo import Photo
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from builtins import range
|
||||||
|
from past.utils import old_div
|
||||||
# Project imports
|
# Project imports
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
@ -6,7 +10,7 @@ import sys
|
||||||
|
|
||||||
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.dirname(os.path.realpath(__file__))))))
|
||||||
|
|
||||||
import helper
|
from . import helper
|
||||||
from elodie import geolocation
|
from elodie import geolocation
|
||||||
|
|
||||||
os.environ['TZ'] = 'GMT'
|
os.environ['TZ'] = 'GMT'
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from builtins import range
|
||||||
|
from past.utils import old_div
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
@ -12,7 +16,7 @@ from datetime import timedelta
|
||||||
|
|
||||||
def checksum(file_path, blocksize=65536):
|
def checksum(file_path, blocksize=65536):
|
||||||
hasher = hashlib.sha256()
|
hasher = hashlib.sha256()
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'rb') as f:
|
||||||
buf = f.read(blocksize)
|
buf = f.read(blocksize)
|
||||||
|
|
||||||
while len(buf) > 0:
|
while len(buf) > 0:
|
||||||
|
@ -73,7 +77,7 @@ def random_decimal():
|
||||||
|
|
||||||
def random_coordinate(coordinate, precision):
|
def random_coordinate(coordinate, precision):
|
||||||
# Here we add to the decimal section of the coordinate by a given precision
|
# Here we add to the decimal section of the coordinate by a given precision
|
||||||
return coordinate + ((10.0 / (10.0**precision)) * random_decimal())
|
return coordinate + ((old_div(10.0, (10.0**precision))) * random_decimal())
|
||||||
|
|
||||||
def temp_dir():
|
def temp_dir():
|
||||||
return tempfile.gettempdir()
|
return tempfile.gettempdir()
|
||||||
|
@ -91,8 +95,8 @@ def is_windows():
|
||||||
def path_tz_fix(file_name):
|
def path_tz_fix(file_name):
|
||||||
if is_windows():
|
if is_windows():
|
||||||
# Calculate the offset between UTC and local time
|
# Calculate the offset between UTC and local time
|
||||||
tz_shift = (datetime.fromtimestamp(0) -
|
tz_shift = old_div((datetime.fromtimestamp(0) -
|
||||||
datetime.utcfromtimestamp(0)).seconds/3600
|
datetime.utcfromtimestamp(0)).seconds,3600)
|
||||||
# replace timestamp in file_name
|
# replace timestamp in file_name
|
||||||
m = re.search('(\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2})',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')))
|
t_date = datetime.fromtimestamp(time.mktime(time.strptime(m.group(0), '%Y-%m-%d_%H-%M-%S')))
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import absolute_import
|
||||||
# Project imports
|
# Project imports
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
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.dirname(os.path.realpath(__file__))))))
|
||||||
|
|
||||||
import helper
|
from . import helper
|
||||||
from elodie.localstorage import Db
|
from elodie.localstorage import Db
|
||||||
from elodie import constants
|
from elodie import constants
|
||||||
|
|
||||||
|
@ -154,10 +156,10 @@ def test_get_location_name_within_threshold():
|
||||||
latitude, longitude, name = helper.get_test_location()
|
latitude, longitude, name = helper.get_test_location()
|
||||||
db.add_location(latitude, longitude, name)
|
db.add_location(latitude, longitude, name)
|
||||||
|
|
||||||
print latitude
|
print(latitude)
|
||||||
new_latitude = helper.random_coordinate(latitude, 4)
|
new_latitude = helper.random_coordinate(latitude, 4)
|
||||||
new_longitude = helper.random_coordinate(longitude, 4)
|
new_longitude = helper.random_coordinate(longitude, 4)
|
||||||
print new_latitude
|
print(new_latitude)
|
||||||
|
|
||||||
# 10 miles
|
# 10 miles
|
||||||
retrieved_name = db.get_location_name(new_latitude, new_longitude, 1600*10)
|
retrieved_name = db.get_location_name(new_latitude, new_longitude, 1600*10)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8
|
# -*- coding: utf-8
|
||||||
# Project imports
|
# Project imports
|
||||||
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ def test_get_date_taken():
|
||||||
audio = Audio(helper.get_file('audio.m4a'))
|
audio = Audio(helper.get_file('audio.m4a'))
|
||||||
date_taken = audio.get_date_taken()
|
date_taken = audio.get_date_taken()
|
||||||
|
|
||||||
print '%r' % date_taken
|
print('%r' % date_taken)
|
||||||
assert date_taken == (2016, 1, 4, 5, 24, 15, 0, 19, 0), date_taken
|
assert date_taken == (2016, 1, 4, 5, 24, 15, 0, 19, 0), date_taken
|
||||||
|
|
||||||
def test_get_exiftool_attributes():
|
def test_get_exiftool_attributes():
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8
|
# -*- coding: utf-8
|
||||||
# Project imports
|
# Project imports
|
||||||
|
from __future__ import unicode_literals
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
click>=6.2,<7.0
|
click>=6.2,<7.0
|
||||||
requests>=2.9.1,<3.0
|
requests>=2.9.1,<3.0
|
||||||
send2trash>=1.3.0,<2.0
|
send2trash>=1.3.0,<2.0
|
||||||
|
future
|
||||||
|
|
Loading…
Reference in New Issue