Merge pull request #81 from noonat/click
Switched to click for argument parsing
This commit is contained in:
commit
5babcf3583
|
@ -58,7 +58,7 @@ My guess is you've got quite a few photos scattered around. The first thing I'll
|
||||||
Fire up your terminal and run this command which *__copies__* your photos into something a bit more structured.
|
Fire up your terminal and run this command which *__copies__* your photos into something a bit more structured.
|
||||||
|
|
||||||
```
|
```
|
||||||
./elodie.py import --source="/where/my/photos/are" --destination="/where/i/want/my/photos/to/go"
|
./elodie.py import --destination="/where/i/want/my/photos/to/go" /where/my/photos/are
|
||||||
```
|
```
|
||||||
|
|
||||||
I'm pretty fast but depending on how many photos you have you might want to grab a snack. When you run this command I'll `print` out my work as I go along. If you're bored you can open `/where/i/want/my/photos/to/go` in *Finder* and watch as I effortlessly copy your photos there.
|
I'm pretty fast but depending on how many photos you have you might want to grab a snack. When you run this command I'll `print` out my work as I go along. If you're bored you can open `/where/i/want/my/photos/to/go` in *Finder* and watch as I effortlessly copy your photos there.
|
||||||
|
@ -93,7 +93,7 @@ Not too bad, eh? Wait a second, what's *Unknown Location*? If I'm not able to fi
|
||||||
If you notice some photos were incorrectly organized you should definitely let me know. In the example above I put two photos into an *Unknown Location* folder because I didn't find GPS information in their EXIF. To fix this I'll help you add GPS information into the photos' EXIF and then I'll reorganize them.
|
If you notice some photos were incorrectly organized you should definitely let me know. In the example above I put two photos into an *Unknown Location* folder because I didn't find GPS information in their EXIF. To fix this I'll help you add GPS information into the photos' EXIF and then I'll reorganize them.
|
||||||
|
|
||||||
#### Tell me where your photos were taken
|
#### Tell me where your photos were taken
|
||||||
Run the command below if you want to tell me the photos were taken in Las Vegas. You don't have to type all that in though. It's easier to just type `./update.py --location="Las Vegas, NV" ` and select and drag the files from *OS X Finder* into the terminal.
|
Run the command below if you want to tell me the photos were taken in Las Vegas. You don't have to type all that in though. It's easier to just type `./elodie.py update --location="Las Vegas, NV" ` and select and drag the files from *OS X Finder* into the terminal.
|
||||||
|
|
||||||
```
|
```
|
||||||
./elodie.py update --location="Las Vegas, NV" /where/i/want/my/photos/to/go/2015-09-Sep/Unknown\ Location/2015-09-27_01-41-38-_dsc8705.dng /where/i/want/my/photos/to/go/2015-09-Sep/Unknown\ Location/2015-09-27_01-41-38-_dsc8705.nef
|
./elodie.py update --location="Las Vegas, NV" /where/i/want/my/photos/to/go/2015-09-Sep/Unknown\ Location/2015-09-27_01-41-38-_dsc8705.dng /where/i/want/my/photos/to/go/2015-09-Sep/Unknown\ Location/2015-09-27_01-41-38-_dsc8705.nef
|
||||||
|
@ -142,10 +142,10 @@ If you'd like to let me know of a specific photo or group of photos to add to yo
|
||||||
|
|
||||||
```
|
```
|
||||||
# I can import a single file into your library.
|
# I can import a single file into your library.
|
||||||
/full/path/to/import.py --type=photo --file="/full/path/to/file.jpg" --destination="/where/i/want/my/photo/to/go"
|
./elodie.py import --destination="/where/i/want/my/photo/to/go" /full/path/to/file.jpg
|
||||||
|
|
||||||
# I can also import all the photos from a directory into your library.
|
# I can also import all the photos from a directory into your library.
|
||||||
/full/path/to/import.py --type=photo --source="/where/my/photos/are" --destination="/where/i/want/my/photo/to/go"
|
./elodie.py import --destination="/where/i/want/my/photo/to/go" /where/my/photos/are
|
||||||
```
|
```
|
||||||
|
|
||||||
## Why not use a database?
|
## Why not use a database?
|
||||||
|
|
101
elodie.py
101
elodie.py
|
@ -3,9 +3,9 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from docopt import docopt
|
|
||||||
|
import click
|
||||||
from send2trash import send2trash
|
from send2trash import send2trash
|
||||||
|
|
||||||
# Verify that external dependencies are present first, so the user gets a
|
# Verify that external dependencies are present first, so the user gets a
|
||||||
|
@ -24,16 +24,6 @@ from elodie.filesystem import FileSystem
|
||||||
from elodie.localstorage import Db
|
from elodie.localstorage import Db
|
||||||
|
|
||||||
|
|
||||||
def usage():
|
|
||||||
"""Return usage message
|
|
||||||
"""
|
|
||||||
return """
|
|
||||||
Usage: elodie.py import --destination=<d> [--source=<s>] [--file=<f>] [--album-from-folder] [--trash] [INPUT ...]
|
|
||||||
elodie.py update [--time=<t>] [--location=<l>] [--album=<a>] [--title=<t>] INPUT ...
|
|
||||||
|
|
||||||
-h --help show this
|
|
||||||
"""
|
|
||||||
|
|
||||||
DB = Db()
|
DB = Db()
|
||||||
FILESYSTEM = FileSystem()
|
FILESYSTEM = FileSystem()
|
||||||
|
|
||||||
|
@ -69,17 +59,29 @@ def import_file(_file, destination, album_from_folder, trash):
|
||||||
send2trash(_file)
|
send2trash(_file)
|
||||||
|
|
||||||
|
|
||||||
def _import(params):
|
@click.command('import')
|
||||||
"""Import files.
|
@click.option('--destination', type=click.Path(file_okay=False),
|
||||||
|
required=True, help='Copy imported files into this directory.')
|
||||||
|
@click.option('--source', type=click.Path(file_okay=False),
|
||||||
|
help='Import files from this directory, if specified.')
|
||||||
|
@click.option('--file', type=click.Path(dir_okay=False),
|
||||||
|
help='Import this file, if specified.')
|
||||||
|
@click.option('--album-from-folder', default=False, is_flag=True,
|
||||||
|
help="Use images' folders as their album names.")
|
||||||
|
@click.option('--trash', default=False, is_flag=True,
|
||||||
|
help='After copying files, move the old files to the trash.')
|
||||||
|
@click.argument('paths', nargs=-1, type=click.Path())
|
||||||
|
def _import(destination, source, file, album_from_folder, trash, paths):
|
||||||
|
"""Import files or directories.
|
||||||
"""
|
"""
|
||||||
destination = os.path.expanduser(params['--destination'])
|
destination = os.path.expanduser(destination)
|
||||||
|
|
||||||
files = set()
|
files = set()
|
||||||
paths = set(params['INPUT'])
|
paths = set(paths)
|
||||||
if params['--source']:
|
if source:
|
||||||
paths.add(params['--source'])
|
paths.add(source)
|
||||||
if params['--file']:
|
if file:
|
||||||
paths.add(params['--file'])
|
paths.add(file)
|
||||||
for path in paths:
|
for path in paths:
|
||||||
path = os.path.expanduser(path)
|
path = os.path.expanduser(path)
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
|
@ -88,8 +90,8 @@ def _import(params):
|
||||||
files.add(path)
|
files.add(path)
|
||||||
|
|
||||||
for current_file in files:
|
for current_file in files:
|
||||||
import_file(current_file, destination, params['--album-from-folder'],
|
import_file(current_file, destination, album_from_folder,
|
||||||
params['--trash'])
|
trash)
|
||||||
|
|
||||||
|
|
||||||
def update_location(media, file_path, location_name):
|
def update_location(media, file_path, location_name):
|
||||||
|
@ -128,10 +130,20 @@ def update_time(media, file_path, time_string):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _update(params):
|
@click.command('update')
|
||||||
|
@click.option('--album', help='Update the image album.')
|
||||||
|
@click.option('--location', help=('Update the image location. Location '
|
||||||
|
'should be the name of a place, like "Las '
|
||||||
|
'Vegas, NV".'))
|
||||||
|
@click.option('--time', help=('Update the image time. Time should be in '
|
||||||
|
'YYYY-mm-dd hh:ii:ss or YYYY-mm-dd format.'))
|
||||||
|
@click.option('--title', help='Update the image title.')
|
||||||
|
@click.argument('files', nargs=-1, type=click.Path(dir_okay=False),
|
||||||
|
required=True)
|
||||||
|
def _update(album, location, time, title, files):
|
||||||
"""Update files.
|
"""Update files.
|
||||||
"""
|
"""
|
||||||
for file_path in params['INPUT']:
|
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
|
||||||
|
@ -148,12 +160,14 @@ def _update(params):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
updated = False
|
updated = False
|
||||||
if params['--location']:
|
if location:
|
||||||
updated = update_location(media, file_path, params['--location'])
|
update_location(media, file_path, location)
|
||||||
if params['--time']:
|
updated = True
|
||||||
updated = update_time(media, file_path, params['--time'])
|
if time:
|
||||||
if params['--album']:
|
update_time(media, file_path, time)
|
||||||
media.set_album(params['--album'])
|
updated = True
|
||||||
|
if album:
|
||||||
|
media.set_album(album)
|
||||||
updated = True
|
updated = True
|
||||||
|
|
||||||
# Updating a title can be problematic when doing it 2+ times on a file.
|
# Updating a title can be problematic when doing it 2+ times on a file.
|
||||||
|
@ -165,10 +179,10 @@ def _update(params):
|
||||||
# Since FileSystem.get_file_name() relies on base_name it will properly
|
# Since FileSystem.get_file_name() relies on base_name it will properly
|
||||||
# rename the file by updating the title instead of appending it.
|
# rename the file by updating the title instead of appending it.
|
||||||
remove_old_title_from_name = False
|
remove_old_title_from_name = False
|
||||||
if params['--title']:
|
if title:
|
||||||
# We call get_metadata() to cache it before making any changes
|
# We call get_metadata() to cache it before making any changes
|
||||||
metadata = media.get_metadata()
|
metadata = media.get_metadata()
|
||||||
title_update_status = media.set_title(params['--title'])
|
title_update_status = media.set_title(title)
|
||||||
original_title = metadata['title']
|
original_title = metadata['title']
|
||||||
if title_update_status and original_title:
|
if title_update_status and original_title:
|
||||||
# @TODO: We should move this to a shared method since
|
# @TODO: We should move this to a shared method since
|
||||||
|
@ -179,7 +193,8 @@ def _update(params):
|
||||||
updated = True
|
updated = True
|
||||||
|
|
||||||
if updated:
|
if updated:
|
||||||
updated_media = Media.get_class_by_file(file_path, [Audio, Photo, Video])
|
updated_media = Media.get_class_by_file(file_path,
|
||||||
|
[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.
|
||||||
if remove_old_title_from_name and len(original_title) > 0:
|
if remove_old_title_from_name and len(original_title) > 0:
|
||||||
|
@ -200,18 +215,14 @@ def _update(params):
|
||||||
os.path.dirname(os.path.dirname(file_path)))
|
os.path.dirname(os.path.dirname(file_path)))
|
||||||
|
|
||||||
|
|
||||||
def main(argv=None):
|
@click.group()
|
||||||
"""Main function call elodie subcommand on files.
|
def main():
|
||||||
"""
|
pass
|
||||||
if argv is None:
|
|
||||||
argv = sys.argv
|
|
||||||
params = docopt(usage())
|
main.add_command(_import)
|
||||||
if params['import']:
|
main.add_command(_update)
|
||||||
_import(params)
|
|
||||||
elif params['update']:
|
|
||||||
_update(params)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
main()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
docopt>=0.6.2,<1.0
|
click>=6.2,<7.0
|
||||||
LatLon>=1.0.2,<2.0
|
LatLon>=1.0.2,<2.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
|
||||||
|
|
Loading…
Reference in New Issue