Package: elodie
Hello, I'm Elodie~~Your Personal EXIF-based Photo, Video and Audio Assistant~~I made an app from this open source project.Download Elodie, the EXIF-based photo organizer app.Quickstart guideGetting started takes just a few minutes.Install ExifToolElodie relies on the greatExifTool library by Phil Harvey. You'll need to install it for your platform.Some features for video files will only work with newer versions of ExifTool and have been tested on version 10.20 or higher. Support for HEIC files requires version 11.50 or higher. Check your version by typingexiftool -verand see themanual installation instructions for ExifToolif needed.# OSX (uses homebrew, http://brew.sh/)
brew install exiftool

# Debian / Ubuntu
apt-get install libimage-exiftool-perl

# Fedora / Redhat
dnf install perl-Image-ExifTool

# Windows users can install the binary
# http://www.sno.phy.queensu.ca/~phil/exiftool/install.htmlClone the Elodie repositoryYou can clone Elodie from GitHub. You'll needgitinstalled (instructions).git clone https://github.com/jmathai/elodie.git
cd elodie
pip install -r requirements.txtGive Elodie a test driveNow that you've got the minimum dependencies installed you can start using Elodie. You'll need a photo, video or audio file and a folder you'd like Elodie to organize them into.# Run these commands from the root of the repository you just cloned.
./elodie.py import --debug --destination="/where/i/want/my/photos/to/go" /where/my/photo/is.jpgYou'll notice that the photo was organized into anUnknown Locationfolder. That's because you haven't set up your MapQuest API (instructions).Now you're ready to learn more about Elodie.Slowstart guideRead a 3 part blog post on why I was createdand howI can be used with Google Photos.I work tirelessly to make sure your photos are always sorted and organized so you can focus on more important things. By photos I mean JPEG, DNG, NEF and common video and audio files.You don't love me yet but you will.I only do 3 things.Firstly I organize your existing collection of photos into a customizable folder structure.Second I help make it easy for all the photos you haven't taken yet to flow into the exact location they belong.Third but not least I promise to do all this without a yucky propietary database that some friends of mine use.NOTE: make sure you've installed everything I need before running the commands below.Instructionsat the top of this page.Let's organize your existing photosMy guess is you've got quite a few photos scattered around. The first thing I'll help you do is to get those photos organized. It doesn't matter if you have hundreds, thousands or tens of thousands of photos; the more the merrier.Fire up your terminal and run this command whichcopiesyour photos into something a bit more structured../elodie.py import --destination="/where/i/want/my/photos/to/go" /where/my/photos/areI'm pretty fast but depending on how many photos you have you might want to grab a snack. When you run this command I'llprintout my work as I go along. If you're bored you can open/where/i/want/my/photos/to/goinFinderand watch as I effortlessly copy your photos there.You'll notice that your photos are now organized by date and location. Some photos do not have proper dates or location information in them. I do my best and in the worst case scenario I'll use the earlier of the files access or modified time. Ideally your photos have dates and location in the EXIF so my work is more accurate.Don't fret if your photos don't have much EXIF information. I'll show you how you can fix them up later on but let's walk before we run.Back to your photos. When I'm done you should see something like this. Notice that I've renamed your files by adding the date and time they were taken. This helps keep them in chronological order when using most viewing applications. You'll thank me later.├── 2015-06-Jun
│   ├── California
│   │   ├── 2015-06-29_16-34-14-img_3900.jpg
│   │   └── 2015-06-29_17-07-06-img_3901.jpg
│   └── Paris
│       └── 2015-06-30_02-40-43-img_3903.jpg
├── 2015-07-Jul
│   ├── Mountain View
│   │   ├── 2015-07-19_17-16-37-img_9426.jpg
│   │   └── 2015-07-24_19-06-33-img_9432.jpg
└── 2015-09-Sep
│   ├── Unknown Location
    │   ├── 2015-09-27_01-41-38-_dsc8705.dng
    │   └── 2015-09-27_01-41-38-_dsc8705.nefNot too bad, eh? Wait a second, what'sUnknown Location? If I'm not able to figure out where a photo was taken I'll place it into a folder namedUnknown Location. This typically happens when photos do not have GPS information in their EXIF. You shouldn't see this for photos taken on a smartphone but it's often the case with digital cameras and SLRs. I can help you add GPS information to those photos and get them organized better. Let me show you how.Usage InstructionsYou can view these instructions on the command line by typing./elodie.py import --help,./elodie.py update --helpor./elodie.py generate-db --help.Import photosUsage: elodie.py import [OPTIONS] [PATHS]...

  Import files or directories by reading their EXIF and organizing them
  accordingly.

Options:
  --destination DIRECTORY  Copy imported files into this directory.
                           [required]
  --source DIRECTORY       Import files from this directory, if specified.
  --file PATH              Import this file, if specified.
  --album-from-folder      Use images' folders as their album names.
  --trash                  After copying files, move the old files to the
                           trash.
  --allow-duplicates       Import the file even if it's already been imported.
  --debug                  Override the value in constants.py with True.
  --exclude-regex TEXT     Regular expression for directories or files to
                           exclude.
  --help                   Show this message and exit.Update photosUsage: elodie.py update [OPTIONS] FILES...

  Update a file's EXIF. Automatically modifies the file's location and file
  name accordingly.

Options:
  --album TEXT     Update the image album.
  --location TEXT  Update the image location. Location should be the name of a
                   place, like "Las Vegas, NV".
  --time TEXT      Update the image time. Time should be in YYYY-mm-dd
                   hh:ii:ss or YYYY-mm-dd format.
  --title TEXT     Update the image title.
  --help           Show this message and exit.(Re)Generate checksum databaseUsage: elodie.py generate-db [OPTIONS]

  Regenerate the hash.json database which contains all of the sha256
  signatures of media files. The hash.json file is located at ~/.elodie/.

Options:
  --source DIRECTORY  Source of your photo library.  [required]
  --help              Show this message and exit.Verify library against bit rot / data rotUsage: elodie.py verifyExcluding folders and files from being importedIf you have specific folders or files which you would like to prevent from being imported you can provide regular expressions which will be used to match and skip files from being imported.You can specify an exclusion at run time by using the--exclude-regexargument of theimportcommand. You can pass multiple--exclude-regexarguments and all folder/file paths which match will be (silently) skipped.If there are certain file or folder paths youneverwant to import then you can also add an[Exclusions]section to yourconfig.inifile. Similar to the command line argument you can provide multiple exclusions. Here is an example.[Exclusions]
synology_folders=@eaDir
thumbnails=.thumbnailsCreate your own folder structureOK, so what if you don't like the folders being named2015-07-Jul/Mountain View? No problem!You can add a custom folder structure by editing yourconfig.inifile (which should be placed under~/.elodie/config.ini). If you'd like to use a different folder for your configuration file then set an environment variable namedELODIE_APPLICATION_DIRECTORYwith the fully qualified directory path.Custom folder examplesSometimes examples are easier to understand than explainations so I'll start there. If you'd like to understand my magic I explain it in more detail below these examples. You customize your folder structure in theDirectorysection of yourconfig.ini. For details of the supported formats seestrftime.org[Directory]
location=%city, %state
year=%Y
full_path=%year/%location
# -> 2015/Sunnyvale, California

location=%city, %state
month=%B
year=%Y
full_path=%year/%month/%location
# -> 2015/December/Sunnyvale, California

location=%city, %state
month=%m
year=%Y
full_path=%year-%month/%location
# -> 2015-12/Sunnyvale, California

date=%Y
location=%city, %state
custom=%date %album
full_path=%location/%custom
# -> Sunnyvale, California/2015 Birthday PartyUsing fallback foldersThere are times when the EXIF needed to correctly name a folder doesn't exist on a photo. I came up with fallback folders to help you deal with situations such as this. Here's how it works.You can specify a series of folder names by separating them with a|. That's a pipe, not an L. Let's look at an example.[Directory]
month=%m
year=%Y
location=%city
full_path=%month/%year/%album|%location|%"Beats me"What this asks me to do is to name the last folder the same as the album I find in EXIF. If I don't find an album in EXIF then I should use the location. If there's no GPS in the EXIf then I should name the last folderBeats me.How folder customization worksYou can construct your folder structure using a combination of the location, dates and camera make/model. Under theDirectorysection of yourconfig.inifile you can define placeholder names and assign each a value. For example,date=%Y-%mwould create a date placeholder with a value of YYYY-MM which would be filled in with the date from the EXIF on the photo.The placeholders can be used to define the folder structure you'd like to create. The default structure would look like2015-07-Jul/Mountain View.I have some date placeholders you can customize. You can use any ofthe standard Python time directivesto customize the date format to your liking.%daythe day the photo was taken.%monththe month the photo was taken.%yearthe year the photo was taken.I have camera make and model placeholders which can be used to include the camera make and model into the folder path.%camera_makethe make of the camera which took the photo.%camera_modelthe model of the camera which took the photo.I also have a few built-in location placeholders you can use. Use this to construct the%locationyou use infull_path.%citythe name of the city the photo was taken. Requires geolocation data in EXIF.%statethe name of the state the photo was taken. Requires geolocation data in EXIF.%countrythe name of the country the photo was taken. Requires geolocation data in EXIF.In addition to my built-in and date placeholders you can combine them into a single folder name using my complex placeholders.%locationcan be used to combine multiple values of%city,%stateand%country. For example,location=%city, %statewould result in folder names likeSunnyvale, California.%datecan be used to combine multiple values fromthe standard Python time directives. For example,date=%Y-%mwould result in folder names like2015-12.%customcan be used to combine multiple values from anything else. Think of it as a catch-all when%locationand%datedon't meet your needs.How file customization worksYou can configure how Elodie names your files using placeholders. This works similarly to how folder customization works. The default naming format is what's referred to elsewhere in this document and has many thought through benefits. Using the default will gives you files named like2015-09-27_01-41-38-_dsc8705.jpg.Minimizes the likelihood of naming conflicts.Encodes important EXIF information into the file name.Optimizes for sort order when listing in most file and photo viewers.If you'd like to specify your own naming convention it's recommended you include something that's mostly unique like the time including seconds. You'll need to include a[File]section in yourconfig.inifile with a name attribute. If a placeholder doesn't have a value then it plus any preceding characters which are not alphabetic are removed.By default the resulting filename is all lowercased. To change this behavior to uppercasing add capitalization=upper.[File]
date=%Y-%m-%b-%H-%M-%S
name=%date-%original_name-%title.jpg
# -> 2012-05-mar-12-59-30-dsc_1234-my-title.jpg

date=%Y-%m-%b-%H-%M-%S
name=%date-%original_name-%album.jpg
capitalization=upper
# -> 2012-05-MAR-12-59-30-DSC_1234-MY-ALBUM.JPGReorganize by changing location and datesIf you notice some photos were incorrectly organized you should definitely let me know. In the example above I put two photos into anUnknown Locationfolder 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 takenRun 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 fromOS X Finderinto 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.nefYou should see this after running that command.└── 2015-09-Sep
│   ├── Las Vegas
    │   ├── 2015-09-27_01-41-38-_dsc8705.dng
    │   └── 2015-09-27_01-41-38-_dsc8705.nefTell me when you took your photosRun the command below if I got the date wrong when organizing your photos. Similarly to the above command you can drag files fromFinderinto your terminal../elodie.py update --time="2015-04-15" /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.nefThat will change the date folder like so.└── 2015-04-Apr
│   ├── Las Vegas
    │   ├── 2015-09-27_01-41-38-_dsc8705.dng
    │   └── 2015-09-27_01-41-38-_dsc8705.nefYou can, of course, ask me to change the location and time. I'll happily update the photos and move them around accordingly../elodie.py update --location="Las Vegas, NV" --time="2015-04-15" /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.nefWhat about photos I take in the future?Organizing your existing photos is great. But I'd be lying if I said I was the only one who could help you with that. Unlike other programs I put the same effort into keeping your library organized into the future as I have in getting it organized in the first place.Letting me know when you've got more photos to organizeIn order to sort new photos that I haven't already organized I need someone to tell me about them. There's no single way to do this. You could use inotify, cron, Automator or my favorite app - Hazel; it doesn't matter.If you'd like to let me know of a specific photo or group of photos to add to your library you would run one of the following commands. Use fully qualified paths for everything since you won't be running this manually.# I can import a single file into your library.
./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.
./elodie.py import --destination="/where/i/want/my/photo/to/go" /where/my/photos/areWhy not use a database?Look, it's not that I think databases are evil. One of my friends is a database. It's just that I've been doing this for a long time and I've always used a database for it. In the end they're more trouble than they're worth. I should have listened to my mother when she told me to not date a database.It's a lot more work to organize photos without a database. No wonder everyone else uses them. But your happiness is my happiness. If a little elbow grease on my part makes you happy then I'm glad to do it.A bit on how I do all this without a databaseEvery photo is essentially a database. So it's more accurate to say I use the thousands of tiny databases you already have and use them to organize your photos.I'm simple. I put a photo into its proper location. I can update a photo to have the right date or location. The latter triggers the first; creating a nice tidy loop of organizational goodness.I don't do anything else so don't bother asking.EXIF and XMP tagsWhen I organize photos I look at the embedded metadata. Here are the details of how I determine what information to use in order of precedence.DimensionFieldsNotesDate Taken (photo)EXIF:DateTimeOriginal, EXIF:CreateDate, EXIF:ModifyDate, file created, file modifiedDate Taken (video, audio)QuickTime:CreationDate, QuickTime:CreationDate-und-US, QuickTime:MediaCreateDate, file created, file modifiedLocation (photo)EXIF:GPSLatitude/EXIF:GPSLatitudeRef, EXIF:GPSLongitude/EXIF:GPSLongitudeRefLocation (video, audio)XMP:GPSLatitude, Composite:GPSLatitude, XMP:GPSLongitude, Composite:GPSLongitudeComposite tags are read-onlyTitle (photo)XMP:TitleTitle (video, audio)XMP:DisplayNameAlbumXMP-xmpDM:Album, XMP:AlbumXMP:Album is user defined inconfigs/ExifTool_configfor backwards compatabilityCamera Make (photo, video)EXIF:Make, QuickTime:MakeCamera Model (photo, video)EXIF:Model, QuickTime:ModelUsing OpenStreetMap data from MapQuestI use MapQuest to help me organize your photos by location. You'll need to sign up for afree developer accountand get an API key. They give you 15,000 calls per month so I can't do any more than that unless you shell out some big bucks to them. Once I hit my limit the best I'll be able to do isUnknown Locationuntil the following month.Once you sign up you'll have to get an API key and copy it into a file named~/.elodie/config.ini. I've included aconfig.ini-samplefile which you can copy toconfig.ini.mkdir ~/.elodie
cp config.ini-sample ~/.elodie/config.ini
# now you're ready to add your MapQuest keyIf you're an english speaker then you will probably want to addprefer_english_names=Trueto the[MapQuest]section else you'll have cities named using the local language.Questions, comments or concerns?The best ways to provide feedback is by opening aGitHub issueor emailing me atjaisen@jmathai.com.