gh-145 Add stats output block at the end of an update or import command.
This commit is contained in:
parent
86313ed8d4
commit
33cc0e17ca
47
elodie.py
47
elodie.py
|
@ -18,18 +18,20 @@ if not verify_dependencies():
|
||||||
from elodie import constants
|
from elodie import constants
|
||||||
from elodie import geolocation
|
from elodie import geolocation
|
||||||
from elodie import log
|
from elodie import log
|
||||||
|
from elodie.filesystem import FileSystem
|
||||||
|
from elodie.localstorage import Db
|
||||||
from elodie.media.base import Base
|
from elodie.media.base import Base
|
||||||
from elodie.media.media import Media
|
from elodie.media.media import Media
|
||||||
from elodie.media.text import Text
|
from elodie.media.text import Text
|
||||||
from elodie.media.audio import Audio
|
from elodie.media.audio import Audio
|
||||||
from elodie.media.photo import Photo
|
from elodie.media.photo import Photo
|
||||||
from elodie.media.video import Video
|
from elodie.media.video import Video
|
||||||
from elodie.filesystem import FileSystem
|
from elodie.result import Result
|
||||||
from elodie.localstorage import Db
|
|
||||||
|
|
||||||
|
|
||||||
DB = Db()
|
DB = Db()
|
||||||
FILESYSTEM = FileSystem()
|
FILESYSTEM = FileSystem()
|
||||||
|
RESULT = Result()
|
||||||
|
|
||||||
|
|
||||||
def import_file(_file, destination, album_from_folder, trash, allow_duplicates):
|
def import_file(_file, destination, album_from_folder, trash, allow_duplicates):
|
||||||
|
@ -42,7 +44,7 @@ def import_file(_file, destination, album_from_folder, trash, allow_duplicates):
|
||||||
return
|
return
|
||||||
# Check if the source, _file, is a child folder within destination
|
# Check if the source, _file, is a child folder within destination
|
||||||
elif destination.startswith(os.path.dirname(_file)):
|
elif destination.startswith(os.path.dirname(_file)):
|
||||||
print('{"source": "%s", "destination": "%s", "error_msg": "Cannot be in destination"}' % (_file, destination))
|
print('{"source": "%s", "destination": "%s", "error_msg": "Source cannot be in destination"}' % (_file, destination))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,8 +100,11 @@ def _import(destination, source, file, album_from_folder, trash, paths, allow_du
|
||||||
files.add(path)
|
files.add(path)
|
||||||
|
|
||||||
for current_file in files:
|
for current_file in files:
|
||||||
import_file(current_file, destination, album_from_folder,
|
dest_path = import_file(current_file, destination, album_from_folder,
|
||||||
trash, allow_duplicates)
|
trash, allow_duplicates)
|
||||||
|
RESULT.append((current_file, dest_path))
|
||||||
|
|
||||||
|
RESULT.write()
|
||||||
|
|
||||||
|
|
||||||
def update_location(media, file_path, location_name):
|
def update_location(media, file_path, location_name):
|
||||||
|
@ -149,27 +154,28 @@ def update_time(media, file_path, time_string):
|
||||||
def _update(album, location, time, title, files):
|
def _update(album, location, time, title, files):
|
||||||
"""Update a file's EXIF. Automatically modifies the file's location and file name accordingly.
|
"""Update a file's EXIF. Automatically modifies the file's location and file name accordingly.
|
||||||
"""
|
"""
|
||||||
for file_path in files:
|
for current_file in files:
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(current_file):
|
||||||
log.warn('Could not find %s' % file_path)
|
if constants.debug:
|
||||||
|
print('Could not find %s' % current_file)
|
||||||
print('{"source":"%s", "error_msg":"Could not find %s"}' % \
|
print('{"source":"%s", "error_msg":"Could not find %s"}' % \
|
||||||
(file_path, file_path))
|
(current_file, current_file))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
file_path = os.path.expanduser(file_path)
|
current_file = os.path.expanduser(current_file)
|
||||||
destination = os.path.expanduser(os.path.dirname(os.path.dirname(
|
destination = os.path.expanduser(os.path.dirname(os.path.dirname(
|
||||||
os.path.dirname(file_path))))
|
os.path.dirname(current_file))))
|
||||||
|
|
||||||
media = Media.get_class_by_file(file_path, [Text, Audio, Photo, Video])
|
media = Media.get_class_by_file(current_file, [Text, Audio, Photo, Video])
|
||||||
if not media:
|
if not media:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
updated = False
|
updated = False
|
||||||
if location:
|
if location:
|
||||||
update_location(media, file_path, location)
|
update_location(media, current_file, location)
|
||||||
updated = True
|
updated = True
|
||||||
if time:
|
if time:
|
||||||
update_time(media, file_path, time)
|
update_time(media, current_file, time)
|
||||||
updated = True
|
updated = True
|
||||||
if album:
|
if album:
|
||||||
media.set_album(album)
|
media.set_album(album)
|
||||||
|
@ -198,7 +204,7 @@ def _update(album, location, time, title, files):
|
||||||
updated = True
|
updated = True
|
||||||
|
|
||||||
if updated:
|
if updated:
|
||||||
updated_media = Media.get_class_by_file(file_path,
|
updated_media = Media.get_class_by_file(current_file,
|
||||||
[Text, Audio, Photo, Video])
|
[Text, Audio, Photo, Video])
|
||||||
# See comments above on why we have to do this when titles
|
# See comments above on why we have to do this when titles
|
||||||
# get updated.
|
# get updated.
|
||||||
|
@ -207,16 +213,21 @@ def _update(album, location, time, title, files):
|
||||||
updated_media.set_metadata_basename(
|
updated_media.set_metadata_basename(
|
||||||
original_base_name.replace('-%s' % original_title, ''))
|
original_base_name.replace('-%s' % original_title, ''))
|
||||||
|
|
||||||
dest_path = FILESYSTEM.process_file(file_path, destination,
|
dest_path = FILESYSTEM.process_file(current_file, destination,
|
||||||
updated_media, move=True, allowDuplicate=True)
|
updated_media, move=True, allowDuplicate=True)
|
||||||
log.info(u'%s -> %s' % (file_path, dest_path))
|
log.info(u'%s -> %s' % (current_file, 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(current_file))
|
||||||
FILESYSTEM.delete_directory_if_empty(
|
FILESYSTEM.delete_directory_if_empty(
|
||||||
os.path.dirname(os.path.dirname(file_path)))
|
os.path.dirname(os.path.dirname(current_file)))
|
||||||
|
RESULT.append((current_file, dest_path))
|
||||||
|
else:
|
||||||
|
RESULT.append((current_file, None))
|
||||||
|
|
||||||
|
RESULT.write()
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
from tabulate import tabulate
|
||||||
|
|
||||||
|
|
||||||
|
class Result(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.records = []
|
||||||
|
self.success = 0
|
||||||
|
self.error = 0
|
||||||
|
self.error_items = []
|
||||||
|
|
||||||
|
def append(self, row):
|
||||||
|
id, status = row
|
||||||
|
|
||||||
|
if status:
|
||||||
|
self.success += 1
|
||||||
|
else:
|
||||||
|
self.error += 1
|
||||||
|
self.error_items.append(id)
|
||||||
|
|
||||||
|
def write(self):
|
||||||
|
if self.error > 0:
|
||||||
|
error_headers = ["File"]
|
||||||
|
error_result = []
|
||||||
|
for id in self.error_items:
|
||||||
|
error_result.append([id])
|
||||||
|
|
||||||
|
print("****** ERROR DETAILS ******")
|
||||||
|
print(tabulate(error_result, headers=error_headers))
|
||||||
|
print("\n")
|
||||||
|
|
||||||
|
headers = ["Metric", "Count"]
|
||||||
|
result = [
|
||||||
|
["Success", self.success],
|
||||||
|
["Error", self.error],
|
||||||
|
]
|
||||||
|
|
||||||
|
print("****** SUMMARY ******")
|
||||||
|
print(tabulate(result, headers=headers))
|
|
@ -7,7 +7,6 @@ import unittest
|
||||||
|
|
||||||
from json import dumps
|
from json import dumps
|
||||||
from mock import patch
|
from mock import patch
|
||||||
from nose.tools import with_setup
|
|
||||||
try:
|
try:
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -19,8 +18,6 @@ from elodie import constants
|
||||||
from elodie import log
|
from elodie import log
|
||||||
|
|
||||||
|
|
||||||
os.environ['TZ'] = 'GMT'
|
|
||||||
|
|
||||||
def call_log_and_assert(func, message, expected):
|
def call_log_and_assert(func, message, expected):
|
||||||
saved_stdout = sys.stdout
|
saved_stdout = sys.stdout
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
# Project imports
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from json import dumps
|
||||||
|
from mock import patch
|
||||||
|
try:
|
||||||
|
from StringIO import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
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.result import Result
|
||||||
|
|
||||||
|
def call_result_and_assert(result, expected):
|
||||||
|
saved_stdout = sys.stdout
|
||||||
|
try:
|
||||||
|
out = StringIO()
|
||||||
|
sys.stdout = out
|
||||||
|
result.write()
|
||||||
|
output = out.getvalue().strip()
|
||||||
|
assert output == expected, expected
|
||||||
|
finally:
|
||||||
|
sys.stdout = saved_stdout
|
||||||
|
|
||||||
|
def test_add_multiple_rows():
|
||||||
|
expected = """****** ERROR DETAILS ******
|
||||||
|
File
|
||||||
|
------
|
||||||
|
id1
|
||||||
|
|
||||||
|
|
||||||
|
****** SUMMARY ******
|
||||||
|
Metric Count
|
||||||
|
-------- -------
|
||||||
|
Success 1
|
||||||
|
Error 1"""
|
||||||
|
result = Result()
|
||||||
|
result.append(('id1', None))
|
||||||
|
result.append(('id2', '/some/path'))
|
||||||
|
call_result_and_assert(result, expected)
|
|
@ -3,3 +3,4 @@ requests==2.11.1
|
||||||
Send2Trash==1.3.0
|
Send2Trash==1.3.0
|
||||||
future==0.16.0
|
future==0.16.0
|
||||||
configparser==3.5.0
|
configparser==3.5.0
|
||||||
|
tabulate==0.7.7
|
||||||
|
|
Loading…
Reference in New Issue