Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ orbs:

jobs:
build_and_test:
executor: python/default
docker:
- image: cimg/python:3.13
steps:
- checkout
- run:
Expand Down
4 changes: 2 additions & 2 deletions elodie/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import os
import sys
from distutils.spawn import find_executable
import shutil


#: Error to print when exiftool can't be found.
Expand All @@ -25,7 +25,7 @@ def get_exiftool():

:returns: str or None
"""
path = find_executable('exiftool')
path = shutil.which('exiftool')
# If exiftool wasn't found we try to brute force the homebrew location
if path is None:
path = '/usr/local/bin/exiftool'
Expand Down
10 changes: 3 additions & 7 deletions elodie/geolocation.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
"""Look up geolocation information for media objects."""
from __future__ import print_function
from __future__ import division
from future import standard_library
from past.utils import old_div

standard_library.install_aliases() # noqa

from os import path

Expand Down Expand Up @@ -84,8 +80,8 @@ def dms_to_decimal(degrees, minutes, seconds, direction=' '):
if(direction[0] in 'WSws'):
sign = -1
return (
float(degrees) + old_div(float(minutes), 60) +
old_div(float(seconds), 3600)
float(degrees) + (float(minutes) / 60) +
(float(seconds) / 3600)
) * sign


Expand Down Expand Up @@ -147,7 +143,7 @@ def place_name(lat, lon):

# Try to get cached location first
db = Db()
# 3km distace radious for a match
# 3km distance radius for a match
cached_place_name = db.get_location_name(lat, lon, 3000)
# We check that it's a dict to coerce an upgrade of the location
# db from a string location to a dictionary. See gh-160.
Expand Down
34 changes: 9 additions & 25 deletions elodie/media/photo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from __future__ import print_function
from __future__ import absolute_import

import imghdr
import os
import re
import time
Expand Down Expand Up @@ -72,7 +71,7 @@ def get_date_taken(self):
for key in self.exif_map['date_taken']:
try:
if(key in exif):
if(re.match('\d{4}(-|:)\d{2}(-|:)\d{2}', exif[key]) is not None): # noqa
if(re.match(r'\d{4}(-|:)\d{2}(-|:)\d{2}', exif[key]) is not None): # noqa
dt, tm = exif[key].split(' ')
dt_list = compile(r'-|:').split(dt)
dt_list = dt_list + compile(r'-|:').split(tm)
Expand Down Expand Up @@ -105,28 +104,13 @@ def is_valid(self):
if(extension != 'heic'):
# gh-4 This checks if the source file is an image.
# It doesn't validate against the list of supported types.
# We check with imghdr and pillow.
if(imghdr.what(source) is None):
# Pillow is used as a fallback and if it's not available we trust
# what imghdr returned.
if(self.pillow is None):
return False
else:
# imghdr won't detect all variants of images (https://bugs.python.org/issue28591)
# see https://github.com/jmathai/elodie/issues/281
# before giving up, we use `pillow` imaging library to detect file type
#
# It is important to note that the library doesn't decode or load the
# raster data unless it really has to. When you open a file,
# the file header is read to determine the file format and extract
# things like mode, size, and other properties required to decode the file,
# but the rest of the file is not processed until later.
try:
im = self.pillow.open(source)
except IOError:
return False

if(im.format is None):
return False
# We use pillow imaging library to detect file type
try:
im = self.pillow.open(source)
except IOError:
return False

if(im.format is None):
return False

return extension in self.extensions
8 changes: 4 additions & 4 deletions elodie/tests/dependencies_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
from elodie.dependencies import get_exiftool


@mock.patch('elodie.dependencies.find_executable')
@mock.patch('elodie.dependencies.shutil')
@mock.patch('elodie.dependencies.os')
def test_exiftool(mock_os, mock_find_executable):
mock_find_executable.return_value = '/path/to/exiftool'
def test_exiftool(mock_os, mock_shutil):
mock_shutil.which.return_value = '/path/to/exiftool'
assert get_exiftool() == '/path/to/exiftool'

mock_find_executable.return_value = None
mock_shutil.which.return_value = None
mock_os.path.isfile.return_value = True
mock_os.path.access.return_value = True
assert get_exiftool() == '/usr/local/bin/exiftool'
Expand Down
7 changes: 5 additions & 2 deletions elodie/tests/elodie_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Project imports
from imp import load_source
import importlib.util
import unittest.mock as mock
import os
import sys
Expand All @@ -15,7 +15,10 @@
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))

import helper
elodie = load_source('elodie', os.path.abspath('{}/../../elodie.py'.format(os.path.dirname(os.path.realpath(__file__)))))
elodie_path = os.path.abspath('{}/../../elodie.py'.format(os.path.dirname(os.path.realpath(__file__))))
spec = importlib.util.spec_from_file_location('elodie', elodie_path)
elodie = importlib.util.module_from_spec(spec)
spec.loader.exec_module(elodie)

from elodie.config import load_config
from elodie.localstorage import Db
Expand Down
1 change: 0 additions & 1 deletion elodie/tests/geolocation_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from __future__ import division
from builtins import range
import pytest
from past.utils import old_div
# Project imports
import unittest.mock as mock
import os
Expand Down
11 changes: 5 additions & 6 deletions elodie/tests/helper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import division
from __future__ import unicode_literals
from builtins import range
from past.utils import old_div
import hashlib
import os
import random
Expand Down Expand Up @@ -98,7 +97,7 @@ def random_decimal():

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())
return coordinate + (((10.0 / (10.0**precision))) * random_decimal())

def temp_dir():
return tempfile.gettempdir()
Expand All @@ -116,13 +115,13 @@ def is_windows():
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)
tz_shift = (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)
m = re.search(r'(\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)
return re.sub(r'\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}',s_date_fix,file_name)
else:
return file_name

Expand Down
5 changes: 0 additions & 5 deletions elodie/tests/media/photo_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,6 @@ def test_is_valid_fallback_using_pillow():

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()
Expand Down
7 changes: 4 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
click==6.6
requests==2.20.0
requests==2.32.5
urllib3==2.5.0
Send2Trash==1.3.0
future==0.16.0
configparser==3.5.0
tabulate==0.7.7
tabulate==0.9.0
Pillow==6.2.2; python_version == '2.7'
Pillow==10.4.0; python_version >= '3.6'
six==1.9
six>=1.16.0