Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Determine timezone offset for date_taken using latitude and longitude gh-54 gh-293 #310

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
57 changes: 48 additions & 9 deletions elodie/media/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

import mimetypes
import os
from datetime import datetime, timedelta
from pytz import timezone
from time import mktime
from tzwhere.tzwhere import tzwhere

from elodie.config import load_config

try: # Py3k compatibility
basestring
Expand Down Expand Up @@ -47,12 +53,40 @@ def get_album(self):
"""
return None

def get_file_path(self):
"""Get the full path to the video.
def get_camera_make(self):
return None

:returns: string
def get_camera_model(self):
return None

def get_date_taken_adjusted(self, date_taken, latitude, longitude):
"""Returns date taken and adjust based on time zone if needed.
Time zone conversion is based on a configurable value from config.ini.

:returns: int
"""
return self.source
config = load_config()

# Check if use_location config is true and file has lat/lon
# Else default to returning date_taken directly from file
if(
'Timezone' in config and
'use_location' in config['Timezone'] and
config['Timezone'].getboolean('use_location') is True and
latitude is not None and
longitude is not None
):
timezone_string = tzwhere().tzNameAt(
latitude,
longitude
)
date_taken_as_time = datetime.fromtimestamp(mktime(date_taken))
now_in_timezone = datetime.now(timezone(timezone_string))
seconds_offset = now_in_timezone.utcoffset().total_seconds()
adjusted_date_taken = date_taken_as_time - timedelta(seconds = seconds_offset)
return adjusted_date_taken.timetuple()

return date_taken

def get_coordinate(self, type):
return None
Expand All @@ -68,11 +102,12 @@ def get_extension(self):
source = self.source
return os.path.splitext(source)[1][1:].lower()

def get_camera_make(self):
return None
def get_file_path(self):
"""Get the full path to the video.

def get_camera_model(self):
return None
:returns: string
"""
return self.source

def get_metadata(self, update_cache=False):
"""Get a dictionary of metadata for any file.
Expand Down Expand Up @@ -103,7 +138,11 @@ def get_metadata(self, update_cache=False):
'extension': self.get_extension(),
'directory_path': os.path.dirname(source)
}

self.metadata['date_taken_adjusted'] = self.get_date_taken_adjusted(
self.metadata['date_taken'],
self.metadata['latitude'],
self.metadata['longitude']
)
return self.metadata

def get_mimetype(self):
Expand Down
3 changes: 2 additions & 1 deletion elodie/tests/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
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.config import load_config

BASE_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

@patch('elodie.config.config_file', '%s/config.ini-sample' % BASE_PATH)
def test_load_config_singleton_success():
from elodie.config import load_config
config = load_config()
assert config['MapQuest']['key'] == 'your-api-key-goes-here', config.get('MapQuest', 'key')
config.set('MapQuest', 'key', 'new-value')
Expand All @@ -27,5 +27,6 @@ def test_load_config_singleton_success():

@patch('elodie.config.config_file', '%s/config.ini-does-not-exist' % BASE_PATH)
def test_load_config_singleton_no_file():
from elodie.config import load_config
config = load_config()
assert config == {}, config
86 changes: 85 additions & 1 deletion elodie/tests/media/photo_test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# -*- coding: utf-8
# Project imports
from __future__ import unicode_literals
import mock
import os
import sys

from datetime import datetime
import shutil
import tempfile
import time

from nose.plugins.skip import SkipTest
from tempfile import gettempdir

sys.path.insert(0, os.path.abspath(os.path.dirname(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__)))))
Expand Down Expand Up @@ -57,6 +58,89 @@ def test_is_not_valid():

assert not photo.is_valid()

@mock.patch('elodie.config.config_file', '%s/config.ini-date-taken-adjusted-no-config' % gettempdir())
def test_get_date_taken_adjusted_no_config():
from elodie.config import load_config
with open('%s/config.ini-date-taken-adjusted-no-config' % gettempdir(), 'w') as f:
f.write("""
""")

if hasattr(load_config, 'config'):
del load_config.config

photo = Photo(helper.get_file('plain.jpg'))
metadata = photo.get_metadata()
date_taken_adj = photo.get_date_taken_adjusted(metadata['date_taken'], metadata['latitude'], metadata['longitude'])

if hasattr(load_config, 'config'):
del load_config.config

@mock.patch('elodie.config.config_file', '%s/config.ini-date-taken-adjusted-do-not-use-location' % gettempdir())
def test_get_date_taken_adjusted_do_not_use_location():
from elodie.config import load_config
with open('%s/config.ini-date-taken-adjusted-do-not-use-location' % gettempdir(), 'w') as f:
f.write("""
[Timezone]
use_location=False
""")

if hasattr(load_config, 'config'):
del load_config.config

photo = Photo(helper.get_file('plain.jpg'))
metadata = photo.get_metadata()
date_taken_adj = photo.get_date_taken_adjusted(metadata['date_taken'], metadata['latitude'], metadata['longitude'])

if hasattr(load_config, 'config'):
del load_config.config

assert date_taken_adj == helper.time_convert((2015, 12, 5, 0, 59, 26, 5, 339, 0)), date_taken_adj

@mock.patch('elodie.config.config_file', '%s/config.ini-date-taken-adjusted-without-exif-location' % gettempdir())
def test_get_date_taken_adjusted_without_exif_location():
from elodie.config import load_config
with open('%s/config.ini-date-taken-adjusted-without-exif-location' % gettempdir(), 'w') as f:
f.write("""
[Timezone]
use_location=True
""")

if hasattr(load_config, 'config'):
del load_config.config

photo = Photo(helper.get_file('plain.jpg'))
metadata = photo.get_metadata()
date_taken_adj = photo.get_date_taken_adjusted(metadata['date_taken'], metadata['latitude'], metadata['longitude'])

if hasattr(load_config, 'config'):
del load_config.config

assert date_taken_adj == helper.time_convert((2015, 12, 5, 0, 59, 26, 5, 339, 0)), date_taken_adj

@mock.patch('elodie.config.config_file', '%s/config.ini-date-taken-adjusted-for-timestamp-use-location' % gettempdir())
def test_get_date_taken_adjusted_for_timestamp_use_location():
from elodie.config import load_config
with open('%s/config.ini-date-taken-adjusted-for-timestamp-use-location' % gettempdir(), 'w') as f:
f.write("""
[Timezone]
use_location=True
""")

if hasattr(load_config, 'config'):
del load_config.config

photo = Photo(helper.get_file('with-location.jpg'))
metadata = photo.get_metadata()
date_taken_adj = photo.get_date_taken_adjusted(metadata['date_taken'], metadata['latitude'], metadata['longitude'])
date_taken_adj_from_metadata = photo.get_metadata()['date_taken_adjusted']
is_dst = date_taken_adj.tm_isdst

if hasattr(load_config, 'config'):
del load_config.config

assert date_taken_adj == date_taken_adj_from_metadata, (date_taken_adj, date_taken_adj_from_metadata)
assert date_taken_adj == helper.time_convert((2015, 12, 5, 7, 59, 26, 5, 339, is_dst)), date_taken_adj

def test_get_metadata_of_invalid_photo():
photo = Photo(helper.get_file('invalid.jpg'))
metadata = photo.get_metadata()
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ Send2Trash==1.3.0
future==0.16.0
configparser==3.5.0
tabulate==0.7.7
pytz==2019.1
tzwhere==3.0.3
numpy==1.16.3