Completed
Pull Request — master (#352)
by
unknown
01:56
created

elodie.tests.media.photo_test.teardown_module()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8
2
# Project imports
3
from __future__ import unicode_literals
4
import os
5
import sys
6
7
from datetime import datetime
8
import shutil
9
import tempfile
10
import time
11
12
from nose.plugins.skip import SkipTest
13
14
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))))
15
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
16
17
import helper
18
from elodie.media.media import Media
19
from elodie.media.photo import Photo
20
from elodie.external.pyexiftool import ExifTool
21
from elodie.dependencies import get_exiftool
22
from elodie import constants
23
24
os.environ['TZ'] = 'GMT'
25
26
def setup_module():
27
    exiftool_addedargs = [
28
            u'-config',
29
            u'"{}"'.format(constants.exiftool_config)
30
        ]
31
    ExifTool(executable_=get_exiftool(), addedargs=exiftool_addedargs).start()
32
33
def teardown_module():
34
    ExifTool().terminate
35
36
def test_photo_extensions():
37
    photo = Photo()
38
    extensions = photo.extensions
39
40
    assert 'arw' in extensions
41
    assert 'cr2' in extensions
42
    assert 'dng' in extensions
43
    assert 'gif' in extensions
44
    assert 'heic' in extensions
45
    assert 'jpg' in extensions
46
    assert 'jpeg' in extensions
47
    assert 'nef' in extensions
48
    assert 'rw2' in extensions
49
50
    valid_extensions = Photo.get_valid_extensions()
51
52
    assert extensions == valid_extensions, valid_extensions
53
54
def test_empty_album():
55
    photo = Photo(helper.get_file('plain.jpg'))
56
    assert photo.get_album() is None
57
58
def test_has_album():
59
    photo = Photo(helper.get_file('with-album.jpg'))
60
    album = photo.get_album()
61
62
    assert album == 'Test Album', album
63
64
def test_is_valid():
65
    photo = Photo(helper.get_file('plain.jpg'))
66
67
    assert photo.is_valid()
68
69
def test_is_not_valid():
70
    photo = Photo(helper.get_file('text.txt'))
71
72
    assert not photo.is_valid()
73
74
def test_get_metadata_of_invalid_photo():
75
    photo = Photo(helper.get_file('invalid.jpg'))
76
    metadata = photo.get_metadata()
77
78
    assert metadata is None
79
80
def test_get_coordinate_default():
81
    photo = Photo(helper.get_file('with-location.jpg'))
82
    coordinate = photo.get_coordinate()
83
84
    assert helper.isclose(coordinate,37.3667027222), coordinate
85
86
def test_get_coordinate_latitude():
87
    photo = Photo(helper.get_file('with-location.jpg'))
88
    coordinate = photo.get_coordinate('latitude')
89
90
    assert helper.isclose(coordinate,37.3667027222), coordinate
91
92
def test_get_coordinate_latitude_minus():
93
    photo = Photo(helper.get_file('with-location-inv.jpg'))
94
    coordinate = photo.get_coordinate('latitude')
95
96
    assert helper.isclose(coordinate,-37.3667027222), coordinate
97
98
def test_get_coordinate_longitude():
99
    photo = Photo(helper.get_file('with-location.jpg'))
100
    coordinate = photo.get_coordinate('longitude')
101
102
    assert helper.isclose(coordinate,-122.033383611), coordinate
103
104
def test_get_coordinate_longitude_plus():
105
    photo = Photo(helper.get_file('with-location-inv.jpg'))
106
    coordinate = photo.get_coordinate('longitude')
107
108
    assert helper.isclose(coordinate,122.033383611), coordinate
109
110
def test_get_coordinates_without_exif():
111
    photo = Photo(helper.get_file('no-exif.jpg'))
112
    latitude = photo.get_coordinate('latitude')
113
    longitude = photo.get_coordinate('longitude')
114
115
    assert latitude is None, latitude
116
    assert longitude is None, longitude
117
118
def test_get_coordinates_with_zero_coordinate():
119
    photo = Photo(helper.get_file('with-location-zero-coordinate.jpg'))
120
    latitude = photo.get_coordinate('latitude')
121
    longitude = photo.get_coordinate('longitude')
122
123
    assert helper.isclose(latitude,51.55325), latitude
124
    assert helper.isclose(longitude,-0.00417777777778), longitude
125
126
def test_get_date_taken():
127
    photo = Photo(helper.get_file('plain.jpg'))
128
    date_taken = photo.get_date_taken()
129
130
    #assert date_taken == (2015, 12, 5, 0, 59, 26, 5, 339, 0), date_taken
131
    assert date_taken == helper.time_convert((2015, 12, 5, 0, 59, 26, 5, 339, 0)), date_taken
132
133
def test_get_date_taken_without_exif():
134
    source = helper.get_file('no-exif.jpg')
135
    photo = Photo(source)
136
    date_taken = photo.get_date_taken()
137
138
    date_taken_from_file = time.gmtime(min(os.path.getmtime(source), os.path.getctime(source)))
139
140
    assert date_taken == date_taken_from_file, date_taken
141
142
def test_get_camera_make():
143
    photo = Photo(helper.get_file('with-location.jpg'))
144
    make = photo.get_camera_make()
145
146
    assert make == 'Canon', make
147
148
def test_get_camera_make_not_set():
149
    photo = Photo(helper.get_file('no-exif.jpg'))
150
    make = photo.get_camera_make()
151
152
    assert make is None, make
153
154
def test_get_camera_model():
155
    photo = Photo(helper.get_file('with-location.jpg'))
156
    model = photo.get_camera_model()
157
158
    assert model == 'Canon EOS REBEL T2i', model
159
160
def test_get_camera_model_not_set():
161
    photo = Photo(helper.get_file('no-exif.jpg'))
162
    model = photo.get_camera_model()
163
164
    assert model is None, model
165
166
def test_is_valid():
167
    photo = Photo(helper.get_file('with-location.jpg'))
168
169
    assert photo.is_valid()
170
171
def test_is_not_valid():
172
    photo = Photo(helper.get_file('text.txt'))
173
174
    assert not photo.is_valid()
175
176
def test_is_valid_fallback_using_pillow():
177
    photo = Photo(helper.get_file('imghdr-error.jpg'))
178
179
    assert photo.is_valid()
180
181
def test_pillow_not_loaded():
182
    photo = Photo(helper.get_file('imghdr-error.jpg'))
183
    photo.pillow = None
184
185
    assert photo.is_valid() == False
186
187 View Code Duplication
def test_set_album():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
188
    temporary_folder, folder = helper.create_working_folder()
189
190
    origin = '%s/photo.jpg' % folder
191
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
192
193
    photo = Photo(origin)
194
    metadata = photo.get_metadata()
195
196
    assert metadata['album'] is None, metadata['album']
197
198
    status = photo.set_album('Test Album')
199
200
    assert status == True, status
201
202
    photo_new = Photo(origin)
203
    metadata_new = photo_new.get_metadata()
204
205
    shutil.rmtree(folder)
206
207
    assert metadata_new['album'] == 'Test Album', metadata_new['album']
208
209
def test_set_date_taken_with_missing_datetimeoriginal():
210
    # When datetimeoriginal (or other key) is missing we have to add it gh-74
211
    # https://github.com/jmathai/elodie/issues/74
212
    temporary_folder, folder = helper.create_working_folder()
213
214
    origin = '%s/photo.jpg' % folder
215
    shutil.copyfile(helper.get_file('no-exif.jpg'), origin)
216
217
    photo = Photo(origin)
218
    status = photo.set_date_taken(datetime(2013, 9, 30, 7, 6, 5))
219
220
    assert status == True, status
221
222
    photo_new = Photo(origin)
223
    metadata = photo_new.get_metadata()
224
225
    date_taken = metadata['date_taken']
226
227
    shutil.rmtree(folder)
228
229
    #assert date_taken == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_taken']
230
    assert date_taken == helper.time_convert((2013, 9, 30, 7, 6, 5, 0, 273, 0)), metadata['date_taken']
231
232 View Code Duplication
def test_set_date_taken():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
233
    temporary_folder, folder = helper.create_working_folder()
234
235
    origin = '%s/photo.jpg' % folder
236
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
237
238
    photo = Photo(origin)
239
    status = photo.set_date_taken(datetime(2013, 9, 30, 7, 6, 5))
240
241
    assert status == True, status
242
243
    photo_new = Photo(origin)
244
    metadata = photo_new.get_metadata()
245
246
    date_taken = metadata['date_taken']
247
248
    shutil.rmtree(folder)
249
250
    #assert date_taken == (2013, 9, 30, 7, 6, 5, 0, 273, 0), metadata['date_taken']
251
    assert date_taken == helper.time_convert((2013, 9, 30, 7, 6, 5, 0, 273, 0)), metadata['date_taken']
252
253 View Code Duplication
def test_set_location():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
254
    temporary_folder, folder = helper.create_working_folder()
255
256
    origin = '%s/photo.jpg' % folder
257
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
258
259
    photo = Photo(origin)
260
    origin_metadata = photo.get_metadata()
261
262
    # Verify that original photo has different location info that what we
263
    #   will be setting and checking
264
    assert not helper.isclose(origin_metadata['latitude'], 11.1111111111), origin_metadata['latitude']
265
    assert not helper.isclose(origin_metadata['longitude'], 99.9999999999), origin_metadata['longitude']
266
267
    status = photo.set_location(11.1111111111, 99.9999999999)
268
269
    assert status == True, status
270
271
    photo_new = Photo(origin)
272
    metadata = photo_new.get_metadata()
273
274
    shutil.rmtree(folder)
275
276
    assert helper.isclose(metadata['latitude'], 11.1111111111), metadata['latitude']
277
    assert helper.isclose(metadata['longitude'], 99.9999999999), metadata['longitude']
278
279 View Code Duplication
def test_set_location_minus():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
280
    temporary_folder, folder = helper.create_working_folder()
281
282
    origin = '%s/photo.jpg' % folder
283
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
284
285
    photo = Photo(origin)
286
    origin_metadata = photo.get_metadata()
287
288
    # Verify that original photo has different location info that what we
289
    #   will be setting and checking
290
    assert not helper.isclose(origin_metadata['latitude'], 11.1111111111), origin_metadata['latitude']
291
    assert not helper.isclose(origin_metadata['longitude'], 99.9999999999), origin_metadata['longitude']
292
293
    status = photo.set_location(-11.1111111111, -99.9999999999)
294
295
    assert status == True, status
296
297
    photo_new = Photo(origin)
298
    metadata = photo_new.get_metadata()
299
300
    shutil.rmtree(folder)
301
302
    assert helper.isclose(metadata['latitude'], -11.1111111111), metadata['latitude']
303
    assert helper.isclose(metadata['longitude'], -99.9999999999), metadata['longitude']
304
305 View Code Duplication
def test_set_title():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
306
    temporary_folder, folder = helper.create_working_folder()
307
308
    origin = '%s/photo.jpg' % folder
309
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
310
311
    photo = Photo(origin)
312
    origin_metadata = photo.get_metadata()
313
314
    status = photo.set_title('my photo title')
315
316
    assert status == True, status
317
318
    photo_new = Photo(origin)
319
    metadata = photo_new.get_metadata()
320
321
    shutil.rmtree(folder)
322
323
    assert metadata['title'] == 'my photo title', metadata['title']
324
325 View Code Duplication
def test_set_title_non_ascii():
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
326
    temporary_folder, folder = helper.create_working_folder()
327
328
    origin = '%s/photo.jpg' % folder
329
    shutil.copyfile(helper.get_file('plain.jpg'), origin)
330
331
    photo = Photo(origin)
332
    origin_metadata = photo.get_metadata()
333
334
    unicode_title = u'形声字 / 形聲字'
335
336
    status = photo.set_title(unicode_title)
337
    assert status == True, status
338
339
    photo_new = Photo(origin)
340
    metadata = photo_new.get_metadata()
341
342
    shutil.rmtree(folder)
343
344
    assert metadata['title'] == unicode_title, metadata['title']
345
346
# This is a test generator that will test reading and writing to
347
# various RAW formats. Each sample file has a different date which
348
# is the only information which needs to be added to run the tests
349
# for that file type.
350
# https://nose.readthedocs.io/en/latest/writing_tests.html#test-generators
351
def test_various_types():
352
    types = Photo.extensions
353
    #extensions = ('arw', 'cr2', 'dng', 'gif', 'jpeg', 'jpg', 'nef', 'rw2')
354
    dates = {
355
        'arw': (2007, 4, 8, 17, 41, 18, 6, 98, 0),
356
        'cr2': (2005, 10, 29, 16, 14, 44, 5, 302, 0),
357
        'dng': (2009, 10, 20, 9, 10, 46, 1, 293, 0),
358
        'heic': (2019, 5, 26, 10, 33, 20, 6, 146, 0),
359
        'nef': (2008, 10, 24, 9, 12, 56, 4, 298, 0),
360
        'rw2': (2014, 11, 19, 23, 7, 44, 2, 323, 0)
361
    }
362
363
    for type in types:
364
        if type in dates:
365
            yield (_test_photo_type_get, type, dates[type])
366
            yield (_test_photo_type_set, type, dates[type])
367
368
def _test_photo_type_get(type, date):
369
    temporary_folder, folder = helper.create_working_folder()
370
371
    photo_name = 'photo.{}'.format(type)
372
    photo_file = helper.get_file(photo_name)
373
    origin = '{}/{}'.format(folder, photo_name)
374
375
    if not photo_file:
376
        photo_file = helper.download_file(photo_name, folder)
377
        if not photo_file or not os.path.isfile(photo_file):
378
            raise SkipTest('{} file not downlaoded'.format(type))
379
380
        # downloading for each test is costly so we save it in the working directory
381
        file_path_save_as = helper.get_file_path(photo_name)
382
        if os.path.isfile(photo_file):
383
            shutil.copyfile(photo_file, file_path_save_as)
384
385
    shutil.copyfile(photo_file, origin)
386
387
    photo = Photo(origin)
388
    metadata = photo.get_metadata()
389
390
    shutil.rmtree(folder)
391
392
    assert metadata['date_taken'] == helper.time_convert(date), '{} date {}'.format(type, metadata['date_taken'])
393
394
def _test_photo_type_set(type, date):
395
    temporary_folder, folder = helper.create_working_folder()
396
397
    photo_name = 'photo.{}'.format(type)
398
    photo_file = helper.get_file(photo_name)
399
    origin = '{}/{}'.format(folder, photo_name)
400
401
    if not photo_file:
402
        photo_file = helper.download_file(photo_name, folder)
403
        if not photo_file or not os.path.isfile(photo_file):
404
            raise SkipTest('{} file not downlaoded'.format(type))
405
406
    shutil.copyfile(photo_file, origin)
407
408
    photo = Photo(origin)
409
    origin_metadata = photo.get_metadata()
410
411
    status = photo.set_location(11.1111111111, 99.9999999999)
412
413
    assert status == True, status
414
415
    photo_new = Photo(origin)
416
    metadata = photo_new.get_metadata()
417
418
    shutil.rmtree(folder)
419
420
    assert metadata['date_taken'] == helper.time_convert(date), '{} date {}'.format(type, metadata['date_taken'])
421
    assert helper.isclose(metadata['latitude'], 11.1111111111), '{} lat {}'.format(type, metadata['latitude'])
422
    assert helper.isclose(metadata['longitude'], 99.9999999999), '{} lon {}'.format(type, metadata['latitude'])
423