Code Monkey home page Code Monkey logo

photo-cli / photo-cli Goto Github PK

View Code? Open in Web Editor NEW
34.0 4.0 4.0 31.65 MB

A photo organizer for your file system without sticking to any application or vendor. Extract when and where (reverse geocoding) your photos are taken, copy into a new organized folder with various folder & file naming strategies, export into CSV files.

Home Page: https://photocli.com

License: Apache License 2.0

C# 100.00%
photo-organizer photo-gallery cli folder-structure folder-tooling organizer photo photo-album photography photography-gallery

photo-cli's Introduction

A photo organizer for your file system without sticking to any application or vendor

Nuget release .github/workflows/stable.yml Coverage Nuget pre-release .github/workflows/preview.yml GitHub license

Docs Quality Gate Status Reliability Rating Maintainability Rating Security Rating Bugs .github/workflows/CI.yml

photo-cli is CLI tool (works on Linux & macOS & Windows) that extracts when and where (reverse geocode) your photographs are taken, copy into a new organized folder (not modifying source folder) with various folder & file naming strategies or export all data into CSV (can view on Microsoft Excel, Libre/OpenOffice Calc, Apple Numbers, Google Sheets) files. With this exported CSV file you can navigate your photo locations on Google Maps & Earth with your custom label and pin style.

Contents

Features Explained With Examples

There is three main feature that can be explain better with examples.

  1. Copy into a new organized folder example with photo-cli copy command
  2. Archive & index into local SQLite incrementally in a specific folder with photo-cli archive command
  3. Export all extracted information into a CSV Report With photo-cli info Command
  4. Navigate Your Photo Locations on Google Maps & Earth

1. Copy Into a New Organized Folder Example With photo-cli copy Command

Folder & File Hierarchy Before -> After

Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── 2005.08.13_09.47.23-Kenya.jpg
├── 2005.12.14-2008.10.22-Italy album
│   ├── 2005.12.14_14.39.47-Italia-Firenze-Quartiere 1.jpg
│   ├── 2008.10.22_16.28.39-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.29.49-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.38.20-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.43.21-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.44.01-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.46.53-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.52.15-Italia-Arezzo.jpg
│   ├── 2008.10.22_16.55.37-Italia-Arezzo.jpg
│   ├── 2008.10.22_17.00.07-Italia-Arezzo-1.jpg
│   └── 2008.10.22_17.00.07-Italia-Arezzo-2.jpg
├── 2012.06.22_19.52.31-United Kingdom-Ascot-Sunninghill and Ascot.jpg
├── 2015.04.10-2015.04.10-Spain Journey
│   ├── 2015.04.10_20.12.23-España-Madrid-1.jpg
│   └── 2015.04.10_20.12.23-España-Madrid-2.jpg
├── Italy album
│   └── no-address
│       └── IMG_2371.jpg
├── photo-cli-report.csv
└── Spain Journey
    └── no-address-and-no-photo-taken-date
        └── IMG_5397.jpg

6 directories, 18 files

What Happened? / How It Is Processed?

There are lots of transformation options and customization settings, this is just a one of them. This transformation is done by running only the following single command;

Command with explicit argument names & values

photo-cli copy --process-type SubFoldersPreserveFolderHierarchy --naming-style DateTimeWithSecondsAddress --number-style PaddingZeroCharacter --folder-append DayRange --folder-append-location Prefix --reverse-geocode OpenStreetMapFoundation --openstreetmap-properties country city town suburb --output photo-cli-test --no-coordinate InSubFolder --no-taken-date InSubFolder --verify

Same command with shorter alias of all argument names & values

photo-cli copy -f 2 -s 8 -n 2 -a 4 -p 1 -e 2 -r country city town suburb -o photo-cli-test -c 3 -t 3 -v

Console/terminal output (as progress may take time, for each operation completion status shown with progress)

Searching photos: finished. 17 photos found.
Parsing photo exif information: finished.
This OpenStreetMapFoundation provider is using rate limit of 1 seconds between each request
Reverse Geocoding: finished.
Directory grouping: finished.
Processing target folder: finished.
Verified all photo files copied successfully by comparing file hashes from original photo files.
All files SHA1 hashes written into file: sha1.lst. You may verify yourself with `sha1sum --check sha1.lst` tool in Linux/macOS.
Writing csv report: finished.
- 17 photos copied.
- 4 directories created.
- 15 photos has taken date and coordinate.
- 1 photos has taken date but no coordinate.
- 1 photos has no taken date and coordinate.

Step By Step photo-cli copy Process

  1. Gather all photo paths in the source folder within subfolders.
  2. Extract EXIF data of each photograph's taken date and coordinate.
  3. As the file name strategy is selected as DateTimeWithSecondsAddress and it contains the address, by using third-party reverse geocode provider we are building the address with OpenStreetMap by using given administrative levels as city town suburb for each photograph.
  4. As the folder process type is selected as SubFoldersPreserveFolderHierarchy folder and file hierarchy at the new output folder will be the same.
  5. As the folder append type is selected as DayRange and folder append location is Prefix, folder names on output folder will be created with same name prefixed with a earliest and latest photograph taken date. For example: 2005.12.14-2008.10.22-Italy album (original folder name is Italy album)
  6. As the file name strategy is selected as DateTimeWithSecondsAddress each photograph file name would be copied as photo taken date unified with the address which is built from third party reverse geocode provider by photograph's coordinate. For example: 2012.06.22_19.52.31-United Kingdom-Ascot-Sunninghill and Ascot.jpg (original file name is GOPR6742.jpg)
  7. As no photograph taken date action is selected as InSubFolder and no coordinate action is selected as InSubFolder, photographs with no related EXIF data copied into a sub folder by obeying original folder hierarchy. For example: /Italy album/no-address/IMG_2371.jpg and /Spain Journey/no-address-and-no-photo-taken-date/IMG_5397.jpg
  8. As verify is added, it is verifying that all photo files copied successfully by comparing file hashes. By adding this, it guarantees that there won't be any corrupted photos that is caused by disk operation failures.
  9. To verify and see all information in one place, photo-cli-report.csv report will be created on the output file. Can be examined in Markdown table or CSV file.

Contents of photo-cli-report.csv File in Markdown Table (report of copy command)

Click to expand
PhotoPath PhotoNewPath PhotoDateTaken ReverseGeocodeFormatted Latitude Longitude PhotoTakenYear PhotoTakenMonth PhotoTakenDay PhotoTakenHour PhotoTakenMinute PhotoTakenSeconds Address1 Address2 Address3 Address4 Address5 Address6 Address7 Address8
/TestImages/DSC_5727.jpg photo-cli-test/2005.08.13_09.47.23-Kenya.jpg 08/13/2005 09:47:23 Kenya -0.37129999999999996 36.056416666666664 2005 8 13 9 47 23 Kenya
/TestImages/GOPR6742.jpg photo-cli-test/2012.06.22_19.52.31-United Kingdom-Ascot-Sunninghill and Ascot.jpg 06/22/2012 19:52:31 United Kingdom-Ascot-Sunninghill and Ascot 51.424838333333334 -0.6735616666666666 2012 6 22 19 52 31 United Kingdom Ascot Sunninghill and Ascot
/TestImages/Italy album/DSC03467.jpg photo-cli-test/2005.12.14-2008.10.22-Italy album/2005.12.14_14.39.47-Italia-Firenze-Quartiere 1.jpg 12/14/2005 14:39:47 Italia-Firenze-Quartiere 1 43.78559443333333 11.234619433333334 2005 12 14 14 39 47 Italia Firenze Quartiere 1
/TestImages/Italy album/GOPR7497.jpg photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.28.39-Italia-Arezzo.jpg 10/22/2008 16:28:39 Italia-Arezzo 43.46744833333334 11.885126666663888 2008 10 22 16 28 39 Italia Arezzo
/TestImages/Italy album/DJI_01732.jpg photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.29.49-Italia-Arezzo.jpg 10/22/2008 16:29:49 Italia-Arezzo 43.46715666666389 11.885394999997223 2008 10 22 16 29 49 Italia Arezzo
/TestImages/Italy album/GOPR7496.jpg photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.38.20-Italia-Arezzo.jpg 10/22/2008 16:38:20 Italia-Arezzo 43.467081666663894 11.884538333330555 2008 10 22 16 38 20 Italia Arezzo
/TestImages/Italy album/DJI_01733.jpg photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.43.21-Italia-Arezzo.jpg 10/22/2008 16:43:21 Italia-Arezzo 43.468365 11.881634999972222 2008 10 22 16 43 21 Italia Arezzo
/TestImages/Italy album/DSC00001.JPG photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.44.01-Italia-Arezzo.jpg 10/22/2008 16:44:01 Italia-Arezzo 43.46844166666667 11.881515 2008 10 22 16 44 1 Italia Arezzo
/TestImages/Italy album/IMG_0747.JPG photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.46.53-Italia-Arezzo.jpg 10/22/2008 16:46:53 Italia-Arezzo 43.468243333330555 11.880171666638889 2008 10 22 16 46 53 Italia Arezzo
/TestImages/Italy album/DSC_1771.JPG photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.52.15-Italia-Arezzo.jpg 10/22/2008 16:52:15 Italia-Arezzo 43.46725499999722 11.879213333333334 2008 10 22 16 52 15 Italia Arezzo
/TestImages/Italy album/DSC_1769.JPG photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.55.37-Italia-Arezzo.jpg 10/22/2008 16:55:37 Italia-Arezzo 43.46601166663889 11.87911166663889 2008 10 22 16 55 37 Italia Arezzo
/TestImages/Italy album/DSC_1770.JPG photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_17.00.07-Italia-Arezzo-1.jpg 10/22/2008 17:00:07 Italia-Arezzo 43.464455 11.881478333333334 2008 10 22 17 0 7 Italia Arezzo
/TestImages/Italy album/DSC_1770_(same).jpg photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_17.00.07-Italia-Arezzo-2.jpg 10/22/2008 17:00:07 Italia-Arezzo 43.464455 11.881478333333334 2008 10 22 17 0 7 Italia Arezzo
/TestImages/Italy album/IMG_2371.jpg photo-cli-test/Italy album/no-address/IMG_2371.jpg 07/16/2008 11:33:20 2008 7 16 11 33 20
/TestImages/Spain Journey/DSC_1807.jpg photo-cli-test/2015.04.10-2015.04.10-Spain Journey/2015.04.10_20.12.23-España-Madrid-1.jpg 04/10/2015 20:12:23 España-Madrid 40.44697222222222 -3.724752777777778 2015 4 10 20 12 23 España Madrid
/TestImages/Spain Journey/DSC_1808.jpg photo-cli-test/2015.04.10-2015.04.10-Spain Journey/2015.04.10_20.12.23-España-Madrid-2.jpg 04/10/2015 20:12:23 España-Madrid 40.44697222222222 -3.724752777777778 2015 4 10 20 12 23 España Madrid
/TestImages/Spain Journey/IMG_5397.jpg photo-cli-test/Spain Journey/no-address-and-no-photo-taken-date/IMG_5397.jpg

Contents of photo-cli-report.csv File in Raw Text Format (report of copy command)

Click to expand
PhotoPath,PhotoNewPath,PhotoDateTaken,ReverseGeocodeFormatted,Latitude,Longitude,PhotoTakenYear,PhotoTakenMonth,PhotoTakenDay,PhotoTakenHour,PhotoTakenMinute,PhotoTakenSeconds,Address1,Address2,Address3,Address4,Address5,Address6,Address7,Address8
/TestImages/DSC_5727.jpg,photo-cli-test/2005.08.13_09.47.23-Kenya.jpg,08/13/2005 09:47:23,Kenya,-0.37129999999999996,36.056416666666664,2005,8,13,9,47,23,Kenya,,,,,,,
/TestImages/GOPR6742.jpg,photo-cli-test/2012.06.22_19.52.31-United Kingdom-Ascot-Sunninghill and Ascot.jpg,06/22/2012 19:52:31,United Kingdom-Ascot-Sunninghill and Ascot,51.424838333333334,-0.6735616666666666,2012,6,22,19,52,31,United Kingdom,Ascot,Sunninghill and Ascot,,,,,
/TestImages/Italy album/DSC03467.jpg,photo-cli-test/2005.12.14-2008.10.22-Italy album/2005.12.14_14.39.47-Italia-Firenze-Quartiere 1.jpg,12/14/2005 14:39:47,Italia-Firenze-Quartiere 1,43.78559443333333,11.234619433333334,2005,12,14,14,39,47,Italia,Firenze,Quartiere 1,,,,,
/TestImages/Italy album/GOPR7497.jpg,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.28.39-Italia-Arezzo.jpg,10/22/2008 16:28:39,Italia-Arezzo,43.46744833333334,11.885126666663888,2008,10,22,16,28,39,Italia,Arezzo,,,,,,
/TestImages/Italy album/DJI_01732.jpg,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.29.49-Italia-Arezzo.jpg,10/22/2008 16:29:49,Italia-Arezzo,43.46715666666389,11.885394999997223,2008,10,22,16,29,49,Italia,Arezzo,,,,,,
/TestImages/Italy album/GOPR7496.jpg,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.38.20-Italia-Arezzo.jpg,10/22/2008 16:38:20,Italia-Arezzo,43.467081666663894,11.884538333330555,2008,10,22,16,38,20,Italia,Arezzo,,,,,,
/TestImages/Italy album/DJI_01733.jpg,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.43.21-Italia-Arezzo.jpg,10/22/2008 16:43:21,Italia-Arezzo,43.468365,11.881634999972222,2008,10,22,16,43,21,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC00001.JPG,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.44.01-Italia-Arezzo.jpg,10/22/2008 16:44:01,Italia-Arezzo,43.46844166666667,11.881515,2008,10,22,16,44,1,Italia,Arezzo,,,,,,
/TestImages/Italy album/IMG_0747.JPG,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.46.53-Italia-Arezzo.jpg,10/22/2008 16:46:53,Italia-Arezzo,43.468243333330555,11.880171666638889,2008,10,22,16,46,53,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC_1771.JPG,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.52.15-Italia-Arezzo.jpg,10/22/2008 16:52:15,Italia-Arezzo,43.46725499999722,11.879213333333334,2008,10,22,16,52,15,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC_1769.JPG,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_16.55.37-Italia-Arezzo.jpg,10/22/2008 16:55:37,Italia-Arezzo,43.46601166663889,11.87911166663889,2008,10,22,16,55,37,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC_1770.JPG,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_17.00.07-Italia-Arezzo-1.jpg,10/22/2008 17:00:07,Italia-Arezzo,43.464455,11.881478333333334,2008,10,22,17,0,7,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC_1770_(same).jpg,photo-cli-test/2005.12.14-2008.10.22-Italy album/2008.10.22_17.00.07-Italia-Arezzo-2.jpg,10/22/2008 17:00:07,Italia-Arezzo,43.464455,11.881478333333334,2008,10,22,17,0,7,Italia,Arezzo,,,,,,
/TestImages/Italy album/IMG_2371.jpg,photo-cli-test/Italy album/no-address/IMG_2371.jpg,07/16/2008 11:33:20,,,,2008,7,16,11,33,20,,,,,,,,
/TestImages/Spain Journey/DSC_1807.jpg,photo-cli-test/2015.04.10-2015.04.10-Spain Journey/2015.04.10_20.12.23-España-Madrid-1.jpg,04/10/2015 20:12:23,España-Madrid,40.44697222222222,-3.724752777777778,2015,4,10,20,12,23,España,Madrid,,,,,,
/TestImages/Spain Journey/DSC_1808.jpg,photo-cli-test/2015.04.10-2015.04.10-Spain Journey/2015.04.10_20.12.23-España-Madrid-2.jpg,04/10/2015 20:12:23,España-Madrid,40.44697222222222,-3.724752777777778,2015,4,10,20,12,23,España,Madrid,,,,,,
/TestImages/Spain Journey/IMG_5397.jpg,photo-cli-test/Spain Journey/no-address-and-no-photo-taken-date/IMG_5397.jpg,,,,,,,,,,,,,,,,,,

2. Archive & index into local SQLite incrementally in a specific folder with photo-cli archive command

Folder & File Hierarchy Before -> After

Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── 2005
│   ├── 08
│   │   └── 13
│   │       └── 2005.08.13_09.47.23-5842c73cfdc5f347551bb6016e00c71bb1393169.jpg
│   └── 12
│       └── 14
│           └── 2005.12.14_14.39.47-03cb14d5c68beed97cbe73164de9771d537fcd96.jpg
├── 2008
│   ├── 07
│   │   └── 16
│   │       └── 2008.07.16_11.33.20-90d835861e1aa3c829e3ab28a7f01ec3a090f664.jpg
│   └── 10
│       └── 22
│           ├── 2008.10.22_16.28.39-5d66eec547469a1817bda4abe35c801359b2bb55.jpg
│           ├── 2008.10.22_16.29.49-629b0b141634d6c0906e49af448bec8d755ba32c.jpg
│           ├── 2008.10.22_16.38.20-620d23336a12ab54f9f0190fe93960a4dba2df59.jpg
│           ├── 2008.10.22_16.43.21-3b0a3215b4f66d7ff4804dd223f192c21aee71bc.jpg
│           ├── 2008.10.22_16.44.01-d470205a1d331a9d3765b3762b7c954bb8efc6ea.jpg
│           ├── 2008.10.22_16.46.53-f670f2bb6c54898894b06b083185b05086bd4e6e.jpg
│           ├── 2008.10.22_16.52.15-6b89a245809031ecc47789cdeaa332545330fc39.jpg
│           ├── 2008.10.22_16.55.37-dd42edcde2433a7df4a3d67bf61944a20884da89.jpg
│           └── 2008.10.22_17.00.07-a0ab699f5f99fce8ff49163e87c7590c2c9a66eb.jpg
├── 2012
│   └── 06
│       └── 22
│           └── 2012.06.22_19.52.31-bb649a18b3e7bb3df3701587a13f833749091817.jpg
├── 2015
│   └── 04
│       └── 10
│           ├── 2015.04.10_20.12.23-3907fc960f2873f40c8f35643dd444e0468be131.jpg
│           └── 2015.04.10_20.12.23-9f4e6d352ec172e1059571250655e376769080fe.jpg
├── no-photo-taken-date
│   └── cf756397cc3ca81b2650c8801fd64e172504015a.jpg
└── photo-cli.sqlite3

17 directories, 17 files

What Happened? / How It Is Processed?

This archive process is done by running only the following single command;

photo-cli archive --output archive-folder --reverse-geocode OpenStreetMapFoundation --openstreetmap-properties country city town suburb

Same command with shorter alias of all argument names & values

photo-cli archive -o archive-folder -e 2 -r country city town suburb

Console/terminal output (as progress may take time, for each operation completion status shown with progress)

Searching photos: finished. 17 photo(s) found.
warn: PhotoCli.Services.Implementations.ExifParserService[0]
      No coordinate found on `Gps` directory for /Users/ac/dev/src/photo-cli/photo-cli/docs/test-photographs/Spain Journey/IMG_5397.jpg
warn: PhotoCli.Services.Implementations.ExifParserService[0]
      No coordinate found on `Gps` directory for /Users/ac/dev/src/photo-cli/photo-cli/docs/test-photographs/Italy album/IMG_2371.jpg
Parsing photo exif information: finished.
This OpenStreetMapFoundation provider is using rate limit of 1 second(s) between each request
Reverse Geocoding: finished.
Directory grouping: started.
Directory grouping: finished.
warn: PhotoCli.Services.Implementations.DuplicatePhotoRemoveService[0]
      Photo is skipped due to same photo has already been archived. Same photo paths: /Users/ac/dev/src/photo-cli/photo-cli/docs/test-photographs/Italy album/DSC_1770.JPG, /Users/ac/dev/src/photo-cli/photo-cli/docs/test-photographs/Italy album/DSC_1770_(same).jpg
Processing target folder: finished.
Verified all photo files copied successfully by comparing file hashes from original photo files.
- 16 photo(s) existed on the output.
- 1 photo(s) are skipped, they have the same photo.
- 15 photo(s) has taken date and coordinate.
- 1 photo(s) has taken date but no coordinate.
- 1 photo(s) has no taken date and coordinate.

Step By Step photo-cli archive Process

  1. Gather all photo paths in the source folder within subfolders.
  2. Extract EXIF data of each photograph's taken date and coordinate.
  3. As third-party reverse geocode is selected, we are building address with OpenStreetMap by using given administrative levels as city town suburb for each photograph.
  4. On the output folder, photos will be placed on folder hierarchy by it's photo taken date's /[year]/[month]/[day]. For example: /2008/07/16/.
  5. Photo file names will be formatted as yyyy.MM.dd_HH.mm.ss-{sha1-hash-of-file}.{extension}. For example: 2008.07.16_11.33.20-90d835861e1aa3c829e3ab28a7f01ec3a090f664.jpg. Input file name is: IMG_2371.jpg.
  6. Input folder has duplicate photos with different names DSC_1770.JPG, DSC_1770_(same).JPG. We are only archiving one of them by comparing file hashes to output 2008/10/22/2008.10.22_17.00.07-a0ab699f5f99fce8ff49163e87c7590c2c9a66eb.jpg and logs warning on the console with a message Photo is skipped due to same photo has already been archived. Same photo paths: /Users/ac/dev/src/photo-cli/photo-cli/docs/test-photographs/Italy album/DSC_1770.JPG, /Users/ac/dev/src/photo-cli/photo-cli/docs/test-photographs/Italy album/DSC_1770_(same).jpg.
  7. The photo that don't have any photo taken date Spain Journey/IMG_5397.jpg, copied into no-photo-taken-date folder with only a sha1-hash cf756397cc3ca81b2650c8801fd64e172504015a.jpg.
  8. After copying all photos, we are verifying that all photo files copied successfully by comparing file hashes. It guarantees that there won't be any corrupted photos that is caused by disk operation failures.
  9. All photo taken dates, address information is saved on local SQLite database on the output folder's top most folder photo-cli.sqlite3. It's an extra feature for technical persons who has technical knowledge about databases who wants to query for personal purposes.
Contents of photo-cli.sqlite3 SQLite Database in Markdown Table (output of archive command)
Id Path CreatedAt DateTaken ReverseGeocodeFormatted Latitude Longitude Year Month Day Hour Minute Seconds Address1 Address2 Address3 Address4 Address5 Address6 Address7 Address8 Sha1Hash
1 2012/06/22/2012.06.22_19.52.31-bb649a18b3e7bb3df3701587a13f833749091817.jpg 2023-11-17 00:44:18.942182 2012-06-22 19:52:31 United Kingdom-Ascot-Sunninghill and Ascot 51.424838333333334 -0.6735616666666666 2012 6 22 19 52 31 United Kingdom Ascot Sunninghill and Ascot null null null null null bb649a18b3e7bb3df3701587a13f833749091817
2 2005/08/13/2005.08.13_09.47.23-5842c73cfdc5f347551bb6016e00c71bb1393169.jpg 2023-11-17 00:44:18.942391 2005-08-13 09:47:23 Kenya-Barut ward -0.37129999999999996 36.056416666666664 2005 8 13 9 47 23 Kenya Barut ward null null null null null null 5842c73cfdc5f347551bb6016e00c71bb1393169
3 no-photo-taken-date/cf756397cc3ca81b2650c8801fd64e172504015a.jpg 2023-11-17 00:44:18.942393 null null null null null null null null null null null null null null null null null null cf756397cc3ca81b2650c8801fd64e172504015a
4 2015/04/10/2015.04.10_20.12.23-9f4e6d352ec172e1059571250655e376769080fe.jpg 2023-11-17 00:44:18.942394 2015-04-10 20:12:23 España-Madrid 40.44697222222222 -3.724752777777778 2015 4 10 20 12 23 España Madrid null null null null null null 9f4e6d352ec172e1059571250655e376769080fe
5 2015/04/10/2015.04.10_20.12.23-3907fc960f2873f40c8f35643dd444e0468be131.jpg 2023-11-17 00:44:18.942395 2015-04-10 20:12:23 España-Madrid 40.44697222222222 -3.724752777777778 2015 4 10 20 12 23 España Madrid null null null null null null 3907fc960f2873f40c8f35643dd444e0468be131
6 2008/07/16/2008.07.16_11.33.20-90d835861e1aa3c829e3ab28a7f01ec3a090f664.jpg 2023-11-17 00:44:18.942396 2008-07-16 11:33:20 null null null 2008 7 16 11 33 20 null null null null null null null null 90d835861e1aa3c829e3ab28a7f01ec3a090f664
7 2008/10/22/2008.10.22_16.44.01-d470205a1d331a9d3765b3762b7c954bb8efc6ea.jpg 2023-11-17 00:44:18.942398 2008-10-22 16:44:01 Italia-Arezzo 43.46844166666667 11.881515 2008 10 22 16 44 1 Italia Arezzo null null null null null null d470205a1d331a9d3765b3762b7c954bb8efc6ea
8 2008/10/22/2008.10.22_17.00.07-a0ab699f5f99fce8ff49163e87c7590c2c9a66eb.jpg 2023-11-17 00:44:18.942401 2008-10-22 17:00:07 Italia-Arezzo 43.464455 11.881478333333334 2008 10 22 17 0 7 Italia Arezzo null null null null null null a0ab699f5f99fce8ff49163e87c7590c2c9a66eb
9 2008/10/22/2008.10.22_16.52.15-6b89a245809031ecc47789cdeaa332545330fc39.jpg 2023-11-17 00:44:18.942401 2008-10-22 16:52:15 Italia-Arezzo 43.46725499999722 11.879213333333334 2008 10 22 16 52 15 Italia Arezzo null null null null null null 6b89a245809031ecc47789cdeaa332545330fc39
10 2008/10/22/2008.10.22_16.55.37-dd42edcde2433a7df4a3d67bf61944a20884da89.jpg 2023-11-17 00:44:18.942402 2008-10-22 16:55:37 Italia-Arezzo 43.46601166663889 11.87911166663889 2008 10 22 16 55 37 Italia Arezzo null null null null null null dd42edcde2433a7df4a3d67bf61944a20884da89
11 2008/10/22/2008.10.22_16.43.21-3b0a3215b4f66d7ff4804dd223f192c21aee71bc.jpg 2023-11-17 00:44:18.942403 2008-10-22 16:43:21 Italia-Arezzo 43.468365 11.881634999972222 2008 10 22 16 43 21 Italia Arezzo null null null null null null 3b0a3215b4f66d7ff4804dd223f192c21aee71bc
12 2008/10/22/2008.10.22_16.29.49-629b0b141634d6c0906e49af448bec8d755ba32c.jpg 2023-11-17 00:44:18.942403 2008-10-22 16:29:49 Italia-Arezzo 43.46715666666389 11.885394999997223 2008 10 22 16 29 49 Italia Arezzo null null null null null null 629b0b141634d6c0906e49af448bec8d755ba32c
13 2008/10/22/2008.10.22_16.38.20-620d23336a12ab54f9f0190fe93960a4dba2df59.jpg 2023-11-17 00:44:18.942404 2008-10-22 16:38:20 Italia-Arezzo 43.467081666663894 11.884538333330555 2008 10 22 16 38 20 Italia Arezzo null null null null null null 620d23336a12ab54f9f0190fe93960a4dba2df59
14 2008/10/22/2008.10.22_16.28.39-5d66eec547469a1817bda4abe35c801359b2bb55.jpg 2023-11-17 00:44:18.942405 2008-10-22 16:28:39 Italia-Arezzo 43.46744833333334 11.885126666663888 2008 10 22 16 28 39 Italia Arezzo null null null null null null 5d66eec547469a1817bda4abe35c801359b2bb55
15 2008/10/22/2008.10.22_16.46.53-f670f2bb6c54898894b06b083185b05086bd4e6e.jpg 2023-11-17 00:44:18.942406 2008-10-22 16:46:53 Italia-Arezzo 43.468243333330555 11.880171666638889 2008 10 22 16 46 53 Italia Arezzo null null null null null null f670f2bb6c54898894b06b083185b05086bd4e6e
16 2005/12/14/2005.12.14_14.39.47-03cb14d5c68beed97cbe73164de9771d537fcd96.jpg 2023-11-17 00:44:18.942407 2005-12-14 14:39:47 Italia-Firenze-Quartiere 1 43.78559443333333 11.234619433333334 2005 12 14 14 39 47 Italia Firenze Quartiere 1 null null null null null 03cb14d5c68beed97cbe73164de9771d537fcd96

3. Export all extracted information into a CSV Report With photo-cli info Command

Contents of photo-info.csv File in Markdown Table (output of info command)

Click to expand
PhotoPath PhotoNewPath PhotoDateTaken ReverseGeocodeFormatted Latitude Longitude PhotoTakenYear PhotoTakenMonth PhotoTakenDay PhotoTakenHour PhotoTakenMinute PhotoTakenSeconds Address1 Address2 Address3 Address4 Address5 Address6 Address7 Address8
/TestImages/DSC_5727.jpg 08/13/2005 09:47:23 Kenya -0.37129999999999996 36.056416666666664 2005 8 13 9 47 23 Kenya
/TestImages/GOPR6742.jpg 06/22/2012 19:52:31 United Kingdom-Ascot-Sunninghill and Ascot 51.424838333333334 -0.6735616666666666 2012 6 22 19 52 31 United Kingdom Ascot Sunninghill and Ascot
/TestImages/Italy album/DSC_1770.JPG 10/22/2008 17:00:07 Italia-Arezzo 43.464455 11.881478333333334 2008 10 22 17 0 7 Italia Arezzo
/TestImages/Italy album/DSC_1771.JPG 10/22/2008 16:52:15 Italia-Arezzo 43.46725499999722 11.879213333333334 2008 10 22 16 52 15 Italia Arezzo
/TestImages/Italy album/IMG_0747.JPG 10/22/2008 16:46:53 Italia-Arezzo 43.468243333330555 11.880171666638889 2008 10 22 16 46 53 Italia Arezzo
/TestImages/Italy album/IMG_2371.jpg 07/16/2008 11:33:20 2008 7 16 11 33 20
/TestImages/Italy album/DSC_1770_(same).jpg 10/22/2008 17:00:07 Italia-Arezzo 43.464455 11.881478333333334 2008 10 22 17 0 7 Italia Arezzo
/TestImages/Italy album/DJI_01733.jpg 10/22/2008 16:43:21 Italia-Arezzo 43.468365 11.881634999972222 2008 10 22 16 43 21 Italia Arezzo
/TestImages/Italy album/DSC00001.JPG 10/22/2008 16:44:01 Italia-Arezzo 43.46844166666667 11.881515 2008 10 22 16 44 1 Italia Arezzo
/TestImages/Italy album/DSC_1769.JPG 10/22/2008 16:55:37 Italia-Arezzo 43.46601166663889 11.87911166663889 2008 10 22 16 55 37 Italia Arezzo
/TestImages/Italy album/GOPR7497.jpg 10/22/2008 16:28:39 Italia-Arezzo 43.46744833333334 11.885126666663888 2008 10 22 16 28 39 Italia Arezzo
/TestImages/Italy album/DSC03467.jpg 12/14/2005 14:39:47 Italia-Firenze-Quartiere 1 43.78559443333333 11.234619433333334 2005 12 14 14 39 47 Italia Firenze Quartiere 1
/TestImages/Italy album/GOPR7496.jpg 10/22/2008 16:38:20 Italia-Arezzo 43.467081666663894 11.884538333330555 2008 10 22 16 38 20 Italia Arezzo
/TestImages/Italy album/DJI_01732.jpg 10/22/2008 16:29:49 Italia-Arezzo 43.46715666666389 11.885394999997223 2008 10 22 16 29 49 Italia Arezzo
/TestImages/Spain Journey/DSC_1807.jpg 04/10/2015 20:12:23 España-Madrid 40.44697222222222 -3.724752777777778 2015 4 10 20 12 23 España Madrid
/TestImages/Spain Journey/DSC_1808.jpg 04/10/2015 20:12:23 España-Madrid 40.44697222222222 -3.724752777777778 2015 4 10 20 12 23 España Madrid
/TestImages/Spain Journey/IMG_5397.jpg

Contents of photo-info.csv File in Raw Text Format (report of info command)

Click to expand
PhotoPath,PhotoNewPath,PhotoDateTaken,ReverseGeocodeFormatted,Latitude,Longitude,PhotoTakenYear,PhotoTakenMonth,PhotoTakenDay,PhotoTakenHour,PhotoTakenMinute,PhotoTakenSeconds,Address1,Address2,Address3,Address4,Address5,Address6,Address7,Address8
/TestImages/DSC_5727.jpg,,08/13/2005 09:47:23,Kenya,-0.37129999999999996,36.056416666666664,2005,8,13,9,47,23,Kenya,,,,,,,
/TestImages/GOPR6742.jpg,,06/22/2012 19:52:31,United Kingdom-Ascot-Sunninghill and Ascot,51.424838333333334,-0.6735616666666666,2012,6,22,19,52,31,United Kingdom,Ascot,Sunninghill and Ascot,,,,,
/TestImages/Italy album/DSC_1770.JPG,,10/22/2008 17:00:07,Italia-Arezzo,43.464455,11.881478333333334,2008,10,22,17,0,7,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC_1771.JPG,,10/22/2008 16:52:15,Italia-Arezzo,43.46725499999722,11.879213333333334,2008,10,22,16,52,15,Italia,Arezzo,,,,,,
/TestImages/Italy album/IMG_0747.JPG,,10/22/2008 16:46:53,Italia-Arezzo,43.468243333330555,11.880171666638889,2008,10,22,16,46,53,Italia,Arezzo,,,,,,
/TestImages/Italy album/IMG_2371.jpg,,07/16/2008 11:33:20,,,,2008,7,16,11,33,20,,,,,,,,
/TestImages/Italy album/DSC_1770_(same).jpg,,10/22/2008 17:00:07,Italia-Arezzo,43.464455,11.881478333333334,2008,10,22,17,0,7,Italia,Arezzo,,,,,,
/TestImages/Italy album/DJI_01733.jpg,,10/22/2008 16:43:21,Italia-Arezzo,43.468365,11.881634999972222,2008,10,22,16,43,21,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC00001.JPG,,10/22/2008 16:44:01,Italia-Arezzo,43.46844166666667,11.881515,2008,10,22,16,44,1,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC_1769.JPG,,10/22/2008 16:55:37,Italia-Arezzo,43.46601166663889,11.87911166663889,2008,10,22,16,55,37,Italia,Arezzo,,,,,,
/TestImages/Italy album/GOPR7497.jpg,,10/22/2008 16:28:39,Italia-Arezzo,43.46744833333334,11.885126666663888,2008,10,22,16,28,39,Italia,Arezzo,,,,,,
/TestImages/Italy album/DSC03467.jpg,,12/14/2005 14:39:47,Italia-Firenze-Quartiere 1,43.78559443333333,11.234619433333334,2005,12,14,14,39,47,Italia,Firenze,Quartiere 1,,,,,
/TestImages/Italy album/GOPR7496.jpg,,10/22/2008 16:38:20,Italia-Arezzo,43.467081666663894,11.884538333330555,2008,10,22,16,38,20,Italia,Arezzo,,,,,,
/TestImages/Italy album/DJI_01732.jpg,,10/22/2008 16:29:49,Italia-Arezzo,43.46715666666389,11.885394999997223,2008,10,22,16,29,49,Italia,Arezzo,,,,,,
/TestImages/Spain Journey/DSC_1807.jpg,,04/10/2015 20:12:23,España-Madrid,40.44697222222222,-3.724752777777778,2015,4,10,20,12,23,España,Madrid,,,,,,
/TestImages/Spain Journey/DSC_1808.jpg,,04/10/2015 20:12:23,España-Madrid,40.44697222222222,-3.724752777777778,2015,4,10,20,12,23,España,Madrid,,,,,,
/TestImages/Spain Journey/IMG_5397.jpg,,,,,,,,,,,,,,,,,,,

What Happened? / How It Is Processed?

There is some options and lots of customization settings, this is just a one of them. This information extracted is done by running only the following single command;

Command with explicit argument names & values

photo-cli info --all-folders --output photo-info.csv --reverse-geocode OpenStreetMapFoundation --openstreetmap-properties country city town suburb --no-taken-date Continue --no-coordinate Continue

Same command with shorter alias of all argument names & values

photo-cli info -a -o photo-info.csv -e 2 -r country city town suburb -t Continue -c Continue

Console/terminal output (as progress may take time, for each operation completion status shown as percentage)

Searching photos: finished. 17 photos found.
Parsing photo exif information: finished.
Reverse Geocoding: finished.
Writing csv report: finished.
- 15 photos has taken date and coordinate.
- 1 photos has taken date but no coordinate.
- 1 photos has no taken date and coordinate.

Step By Step photo-cli info Process

  1. As all folders is selected. We are gathering all photo paths in the source folder within subfolders.
  2. Extract EXIF data of each photograph's taken date and coordinate.
  3. As third-party reverse geocode is selected, we are building address with OpenStreetMap by using given administrative levels as city town suburb for each photograph.
  4. As no photograph taken date action is selected as Continue and no coordinate action is selected as Continue, they are listing in report with empty data.

4. Navigate Your Photo Locations on Google Maps & Earth

If you want to discover your photographs interactively in the world, you may do it by importing your CSV output (whether photo-cli copy or photo-cli info command) to Google Maps and Google Earth, you can interactively navigate through your photographs.

Google Maps

Open Google My Maps and after clicking Create a New Map, you can import your CSV file on a layer(you may add many layers).

google-maps

Google Earth Desktop

After installing Google Earth Desktop, on File menu, you can import your CSV file via Import menu item.

google-earth-desktop

Google Earth Web

To navigate your photographs on Google Earth Web, first you should import your CSV on Google Earth Desktop and save it as KMZ or KML. Then you can create a project and add this KML file.

google-earth-web

Installation

Important note: This application is a command line tool which don't have any user interface. To use this application, basic knowledge of how to run and send arguments to CLI applications is a must.

  1. Installing .NET 6 runtime for your platform (Linux, macOS, Windows).

  2. Install or update with these commands both on Linux, macOS, Windows;

Install: To update newer version:
dotnet tool install photo-cli -g dotnet tool update photo-cli -g
  1. Installing the tool globally provides access to the photo-cli command in your terminal.
photo-cli [command]

photo-cli help [command]

Note: You may test commands on test photographs which has coordinates and photograph taken dates in it.

  1. (For macOS and Linux) You should add your .dotnet/tools (path may change for your installation choices) to your PATH environment variable.

For macOS - Z Shell add the following line to your ~/.zshenv file.

export PATH="$PATH:/Users/[your-account-name]/.dotnet/tools"

For Linux Bash add the following line to your ~/.profile file.

export PATH="$PATH:/home/ac/.dotnet/tools"

Sample Usage Screenshots

The following command used in all samples with test photographs

photo-cli copy -i photos -f 2 -s 8 -n 2 -a 4 -p 1 -e 2 -r country city town suburb -o organized-albums -c 3 -t 3

Windows

Executing

windows-execute

File Explorer

Click to expand

windows-file-explorer

Microsoft Excel

Click to expand

windows-excel

Tree Command

Click to expand

windows-tree-command

macOS

Executing

mac-os-execute

Finder
Click to expand

mac-os-finder

Apple Numbers
Click to expand

mac-os-numbers

Tree Command
Click to expand

mac-os-tree-command

Linux

Executing

linux-execute

File Manager
Click to expand

linux-file-manager

Libre Office Calc
Click to expand

linux-calc

Tree Command
Click to expand

mac-os-tree-command

How It's Done?

By extracting Exchangeable image file format stored on each of your photographs.

When

Photograph's taken date used to determine when photograph's date. Most of the camera/cell phones save this data without any setting.

Where

Photograph's coordinate data is sent to selected third-party reverse geocode provider to build a address.

Most of the cameras and cellphones have GPS receiver on them. You need to be sure that on settings something like Save GPS location should be enabled.

Address Building & Reverse Geocoding

If you use only photo taken date and not interested in building address from reverse geocode, you can skip reading this section. But if you want to use address (reverse geocode) in file and/or folder naming, you should read the following sections and must learn the details.

1. Selecting Third-Party Reverse Geocode Provider

To build addresses we need a reserve geocode provider. Currently, there is four reverse geocode provider is supported.

  1. BigDataCloud
  2. Open Street Map Foundation - Nominatim
  3. Google Maps
  4. LocationIq

Comparison of Supported Third-Party Reverse Geocode Providers

Reverse Geocode Provider API Key Required Free Tier Free Count Limit Free Rate Limit (free) Map Data Owner
BigDataCloud Yes Yes - 50.000 req/month Big Data Cloud
Open Street Map Foundation - Nominatim No - - 1req/sec Open Street Map Foundation
GoogleMaps Yes No - - Google
LocationIq Yes Yes 5.000 req/day 1req/sec Open Street Map Foundation

2. Setting API Key

After selecting reverse geocode provider, you need to provide an API key. There are three ways to provide this API key;

  1. Send as an argument every time
  2. Use persist a setting to save it as configuration, so you don't need to submit everytime.
  3. Use environment variable, so you don't need to submit everytime.
Reverse Geocode Provider Settings Key Environment Variable Argument
BigDataCloud BigDataCloudApiKey PHOTO_CLI_BIG_DATA_CLOUD_API_KEY -b or --bigdatacloud-key
Open Street Map Foundation - Nominatim - - -
GoogleMaps GoogleMapsApiKey PHOTO_CLI_GOOGLE_MAPS_API_KEY -k or --googlemaps-key
LocationIq LocationIqApiKey PHOTO_CLI_LOCATIONIQ_API_KEY -q or --locationiq-key

3. Understanding Reverse Geocode Response

Every reverse geocode provider has its data and they also represent it very differently. The information returned from reverse geocode provider is different or may differ in the level of detail. As there is no way to generalize every reverse geocode provider's response into the same address administrative level, users must understand the response returned from their selected reverse geocode provider.

There is two way to understand the reverse geocoding response.

  1. Easy Way To Inspect Reserve Geocode Response
  2. Power User Way To Inspect Reserve Geocode Response

Easy Way To Inspect Reserve Geocode Response

photo-cli has a feature to extract and list the response of each reverse geocode provider. If you are using a reverse geocode provider that needs an API key, first you need to get it from the provider and set API key.

Listing Reverse Geocode Response. Ref: reverse geocode provider command line arguments

photo-cli address --input [input-file.jpg] --reverse-geocode [selected-reverse-geocode-provider]`

For example, a photo was taken on Anıtkabir(place), Çankaya(town), Ankara(city), Turkey(country) with coordinate as 39.925054 and longitude as 32.8347552 (Coordinate in Google Maps) responses should be like the following.

Big Data Cloud
photo-cli address -i DSC_7082.jpg -e 1
AdminLevel2: Turkey
AdminLevel3: Central Anatolia Region
AdminLevel4: Ankara Province
AdminLevel6: Çankaya
AdminLevel8: Mebusevleri Mahallesi
Open Street Map - Nominatim
photo-cli address -i DSC_7082.jpg -e 2
CountryCode: tr
Country: Türkiye
Region: İç Anadolu Bölgesi
Province: Ankara
City: Ankara
Town: Çankaya
Postcode: 06430
Suburb: Yücetepe Mahallesi
Road: İlk Sokak
Military: Anıtkabir
Google Maps
photo-cli address -i DSC_7082.jpg -e 3
plus_code: WRGM+2W
administrative_area_level_2: Çankaya
administrative_area_level_1: Ankara
country: Turkey
route: Anıtkabir
administrative_area_level_4: Mebusevleri
postal_code: 06570
street_number: 108
Map Quest
photo-cli address -i DSC_7082.jpg -e 4
CountryCode: tr
Country: Türkiye
City: Ankara
Postcode: 06580
Suburb: Mebusevleri Mahallesi
Location Iq
photo-cli address -i DSC_7082.jpg -e 5
CountryCode: tr
Country: Turkey
Region: Central Anatolia Region
Province: Ankara
City: Ankara
Town: Çankaya
Postcode: 06570
Suburb: Yücetepe Mahallesi
Road: Ata Sokak
Barracks: Anıtkabir

Power User Way To Inspect Reserve Geocode Response

You should inspect the reverse geocode provider's response with the locations you occasionally take photographs. After getting the response, you can send the properties as an argument of your choice of the administrative level you want to build an address for each photograph.

Using HTTP Files

To trigger HTTP files you may use Visual Studio Code with the extension REST Client or any IntelliJ IDE's.

You may replace {{ApiKey}} in the address with your API key or you can use the IntelliJ environment variable file.

Reverse Geocode Provider HTTP File
BigDataCloud big-data-cloud.http
Open Street Map Foundation - Nominatim open-street-map.http
GoogleMaps google-maps.http
LocationIq location-iq.http
Using Postman

You may import photo-cli | Reverse Geocode collection into Postman.

You should prepare the following environment variables on Postman.

Reverse Geocode Provider Postman Environment Variable
BigDataCloud BigDataCloud-ApiKey
Open Street Map Foundation - Nominatim -
GoogleMaps GoogleMaps-ApiKey
LocationIq LocationIq-ApiKey
Sample Responses

Sample responses in JSON format are listed below from each reverse geocode for the coordinate with latitude as 39.925054 and longitude as 32.8347552 (Coordinate in Google Maps).

Reverse Geocode Provider Sample Response
BigDataCloud big-data-cloud.json
Open Street Map Foundation - Nominatim open-street-map.json
GoogleMaps google-maps.json
LocationIq location-iq.json

4. Building Your Own Address With Selected Properties

Every reverse geocode provider has its address building parameters. With address command you can inspect any photograph's reverse geocode response. These different levels of selected address properties will be used in exported into CSV file for info command or used as file and/or folder names depending on your naming strategies for copy command.

Reverse Geocode Provider Address Building Parameters
BigDataCloud BigDataCloud Properties
Open Street Map Foundation - Nominatim OpenStreet Properties
GoogleMaps GoogleMaps Properties
LocationIq OpenStreet Properties

Big Data Cloud Parameters

Getting a sample reverse geocoding response with all properties listed.

photo-cli address -i DSC_7082.jpg -e 1
AdminLevel2: Turkey
AdminLevel3: Central Anatolia Region
AdminLevel4: Ankara Province
AdminLevel6: Çankaya
AdminLevel8: Mebusevleri Mahallesi

If we want to build an address like with levels only contains Turkey, Ankara Province, and Çankaya, we should use levels 2,4,6. To verify our address is building correctly, you may use type parameter as SelectedProperties and bigdatacloud-levels arguments separated with space like the following example.

photo-cli address --input DSC_7082.jpg --reverse-geocode BigDataCloud --type SelectedProperties --bigdatacloud-levels 2 4 6
Turkey
Ankara Province
Çankaya

Open Street Map Parameters

Getting a sample reverse geocoding response with all properties listed.

photo-cli address -i DSC_7082.jpg -e 2
CountryCode: tr
Country: Türkiye
Region: İç Anadolu Bölgesi
Province: Ankara
City: Ankara
Town: Çankaya
Postcode: 06430
Suburb: Yücetepe Mahallesi
Road: İlk Sokak
Military: Anıtkabir

If we want to build an address like with levels only contains tr, 06430, and Yücetepe Mahallesi, we should use properties CountryCode, Postcode, Suburb. To verify our address is building correctly, you may use type as SelectedProperties and openstreetmap-properties arguments separated with space like the following example.

photo-cli address --input DSC_7082.jpg --reverse-geocode OpenStreetMapFoundation --type SelectedProperties --openstreetmap-properties CountryCode Postcode Suburb
tr
06430
Yücetepe Mahallesi

Google Maps Properties

Getting a sample reverse geocoding response with all properties listed.

photo-cli address -i DSC_7082.jpg -e GoogleMaps
plus_code: WRGM+2W
administrative_area_level_2: Çankaya
administrative_area_level_1: Ankara
country: Turkey
route: Anıtkabir
administrative_area_level_4: Mebusevleri
postal_code: 06570
street_number: 108

If we want to build an address like with levels only contains Mebusevleri, 108, and Anıtkabir, we should use properties administrative_area_level_4, street_number, route. To verify our address is building correctly, you may use type as SelectedProperties and googlemaps-types arguments separated with space like the following example.

photo-cli address --input DSC_7082.jpg --reverse-geocode GoogleMaps --type SelectedProperties --googlemaps-types administrative_area_level_4 street_number route
Mebusevleri
108
Anıtkabir

5. Merging Selected Address Level Properties Into Single Address

After selecting our properties specialized by our selected third-party reverse geocode provider, we can use our address in file and folder names. To merge address levels, - character is used as default.

Example merged address may used in file/folder names: Turkey-Ankara-Çankaya-Mebusevleri-Anıtkabir

You may change default separator (-) via settings command with a setting key AddressSeparator

6. Caching Reverse Geocode Responses

Since the responses in close coordinate's requests in pretty close results, we implemented a caching mechanism for optimization. This is done by rounding the fractional digits of coordinates from the end. We are currently only use 4 fraction digits.

For example the original coordinate for 39.92501234567890, 32.83471234567890 will interpreted as 39.9250, 32.8347 internally before sending the request.

If you need more precise results in your reverse geocode responses, you can increase this value on settings with a key of CoordinatePrecision.

Usages

We can't cover all possible options, because there are so many option combination. Some important copy command examples with comparing of original photos directory structure and output directory of photo-cli listed below.

Names as Sequential Numbering in Same Folder Hierarchy

Preserve same folder hierarchy, copy photos with sequential number ordering by photo taken date.

photo-cli copy --process-type SubFoldersPreserveFolderHierarchy --naming-style Numeric --number-style PaddingZeroCharacter --input photos --output organized-albums
Click to expand
Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── 1.jpg
├── 2.jpg
├── Italy album
│   ├── 01.jpg
│   ├── 02.jpg
│   ├── 03.jpg
│   ├── 04.jpg
│   ├── 05.jpg
│   ├── 06.jpg
│   ├── 07.jpg
│   ├── 08.jpg
│   ├── 09.jpg
│   ├── 10.jpg
│   ├── 11.jpg
│   └── 12.jpg
├── photo-cli-report.csv
└── Spain Journey
    ├── 1.jpg
    ├── 2.jpg
    └── 3.jpg

2 directories, 18 files

Group Into Taken Year/Month/Day Folders, Name as Date & Time

Groups photos by photo taken year, month, day than copy on [year]/[month]/[day] directory with a file name as photo taken date.

photo-cli copy --process-type FlattenAllSubFolders --group-by YearMonthDay --naming-style DateTimeWithSeconds --number-style OnlySequentialNumbers --input photos --output organized-albums
Click to expand
Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── 2005
│   ├── 08
│   │   └── 13
│   │       └── 2005.08.13_09.47.23.jpg
│   └── 12
│       └── 14
│           └── 2005.12.14_14.39.47.jpg
├── 2008
│   ├── 07
│   │   └── 16
│   │       └── 2008.07.16_11.33.20.jpg
│   └── 10
│       └── 22
│           ├── 2008.10.22_16.28.39.jpg
│           ├── 2008.10.22_16.29.49.jpg
│           ├── 2008.10.22_16.38.20.jpg
│           ├── 2008.10.22_16.43.21.jpg
│           ├── 2008.10.22_16.44.01.jpg
│           ├── 2008.10.22_16.46.53.jpg
│           ├── 2008.10.22_16.52.15.jpg
│           ├── 2008.10.22_16.55.37.jpg
│           ├── 2008.10.22_17.00.07-1.jpg
│           └── 2008.10.22_17.00.07-2.jpg
├── 2012
│   └── 06
│       └── 22
│           └── 2012.06.22_19.52.31.jpg
├── 2015
│   └── 04
│       └── 10
│           ├── 2015.04.10_20.12.23-1.jpg
│           └── 2015.04.10_20.12.23-2.jpg
├── IMG_5397.jpg
└── photo-cli-report.csv

16 directories, 18 files

Folders Prefixed With Date Range, Names as Address & Date

Adding day range as a prefix to existing folder names and photos copied with a file name as address and day.

photo-cli copy --process-type SubFoldersPreserveFolderHierarchy --folder-append DayRange --folder-append-location Prefix --naming-style AddressDay --reverse-geocode OpenStreetMapFoundation --openstreetmap-properties country city town suburb  --number-style AllNamesAreSameLength --input photos --output organized-albums
Click to expand
Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── 2005.12.14-2008.10.22-Italy album
│   ├── IMG_2371.jpg
│   ├── Italia-Arezzo-2008.10.22-10.jpg
│   ├── Italia-Arezzo-2008.10.22-11.jpg
│   ├── Italia-Arezzo-2008.10.22-12.jpg
│   ├── Italia-Arezzo-2008.10.22-13.jpg
│   ├── Italia-Arezzo-2008.10.22-14.jpg
│   ├── Italia-Arezzo-2008.10.22-15.jpg
│   ├── Italia-Arezzo-2008.10.22-16.jpg
│   ├── Italia-Arezzo-2008.10.22-17.jpg
│   ├── Italia-Arezzo-2008.10.22-18.jpg
│   ├── Italia-Arezzo-2008.10.22-19.jpg
│   └── Italia-Firenze-Quartiere 1-2005.12.14.jpg
├── 2015.04.10-2015.04.10-Spain Journey
│   ├── España-Madrid-2015.04.10-1.jpg
│   ├── España-Madrid-2015.04.10-2.jpg
│   └── IMG_5397.jpg
├── Kenya-2005.08.13.jpg
├── photo-cli-report.csv
└── United Kingdom-Ascot-Sunninghill and Ascot-2012.06.22.jpg

2 directories, 18 files

Naming With Address, Date in Same Folder Hierarchy

Preserve same folder hierarchy, copy photos with a file name as photo taken date, time and address. Possible file name will have number suffix. Photos that don't have any coordinate or photo taken date will be copied in a relative subfolder.

photo-cli copy --process-type SubFoldersPreserveFolderHierarchy --naming-style AddressDateTimeWithSeconds  --reverse-geocode OpenStreetMapFoundation --openstreetmap-properties country city town suburb --number-style AllNamesAreSameLength --no-taken-date InSubFolder --no-coordinate InSubFolder --input photos --output organized-albums
Click to expand
Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── Italy album
│   ├── Italia-Arezzo-2008.10.22_16.28.39.jpg
│   ├── Italia-Arezzo-2008.10.22_16.29.49.jpg
│   ├── Italia-Arezzo-2008.10.22_16.38.20.jpg
│   ├── Italia-Arezzo-2008.10.22_16.43.21.jpg
│   ├── Italia-Arezzo-2008.10.22_16.44.01.jpg
│   ├── Italia-Arezzo-2008.10.22_16.46.53.jpg
│   ├── Italia-Arezzo-2008.10.22_16.52.15.jpg
│   ├── Italia-Arezzo-2008.10.22_16.55.37.jpg
│   ├── Italia-Arezzo-2008.10.22_17.00.07-1.jpg
│   ├── Italia-Arezzo-2008.10.22_17.00.07-2.jpg
│   ├── Italia-Firenze-Quartiere 1-2005.12.14_14.39.47.jpg
│   └── no-address
│       └── IMG_2371.jpg
├── Kenya-2005.08.13_09.47.23.jpg
├── photo-cli-report.csv
├── Spain Journey
│   ├── España-Madrid-2015.04.10_20.12.23-1.jpg
│   ├── España-Madrid-2015.04.10_20.12.23-2.jpg
│   └── no-address-and-no-photo-taken-date
│       └── IMG_5397.jpg
└── United Kingdom-Ascot-Sunninghill and Ascot-2012.06.22_19.52.31.jpg

4 directories, 18 files

Grouped Into Country/City/Town Folders, Names as Taken Date and Address

Groups photos by address hierarchy than copy on [country]/[city]/[town] directory with a file name as photo taken date. Photos that don't have any coordinate will be copied in a relative subfolder.

photo-cli copy --process-type FlattenAllSubFolders --group-by AddressHierarchy --naming-style DayAddress --reverse-geocode OpenStreetMapFoundation --openstreetmap-properties country city town suburb --number-style OnlySequentialNumbers --no-taken-date AppendToEndOrderByFileName --no-coordinate InSubFolder --input photos --output organized-albums
Click to expand
Original Folder Hierarchy After photo-cli
├── DSC_5727.jpg
├── GOPR6742.jpg
├── Italy album
│   ├── DJI_01732.jpg
│   ├── DJI_01733.jpg
│   ├── DSC00001.JPG
│   ├── DSC03467.jpg
│   ├── DSC_1769.JPG
│   ├── DSC_1770.JPG
│   ├── DSC_1770_(same).jpg
│   ├── DSC_1771.JPG
│   ├── GOPR7496.jpg
│   ├── GOPR7497.jpg
│   ├── IMG_0747.JPG
│   └── IMG_2371.jpg
└── Spain Journey
    ├── DSC_1807.jpg
    ├── DSC_1808.jpg
    └── IMG_5397.jpg

2 directories, 17 files

├── España
│   └── Madrid
│       ├── 2015.04.10-España-Madrid-1.jpg
│       └── 2015.04.10-España-Madrid-2.jpg
├── Italia
│   ├── Arezzo
│   │   ├── 2008.10.22-Italia-Arezzo-10.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-1.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-2.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-3.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-4.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-5.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-6.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-7.jpg
│   │   ├── 2008.10.22-Italia-Arezzo-8.jpg
│   │   └── 2008.10.22-Italia-Arezzo-9.jpg
│   └── Firenze
│       └── Quartiere 1
│           └── 2005.12.14-Italia-Firenze-Quartiere 1.jpg
├── Kenya
│   └── 2005.08.13-Kenya.jpg
├── no-address
│   ├── IMG_2371.jpg
│   └── IMG_5397.jpg
├── photo-cli-report.csv
└── United Kingdom
    └── Ascot
        └── Sunninghill and Ascot
            └── 2012.06.22-United Kingdom-Ascot-Sunninghill and Ascot.jpg

11 directories, 18 files

Commands / Verbs

Subcommand description
info Creates a report (CSV file) listing all photo taken date and address (reverse geocode).
copy Copies photos into new folder hierarchy with given arguments using photograph's taken date and coordinate address (reverse geocode).
archive Archives photos into specific folder and indexing photo taken date, address (reverse geocode) information into SQLite database.
address Get address (reverse geocode) of single photo.
settings Lists, saves and get settings.

Info

Creates a report (CSV file) listing all photo taken date and address (reverse geocode).

photo-cli help info
  -o, --output                      (MUST) File system path to write report file.

  -i, --input                       (Default current executing folder) File system path to read & copy photos from. ( there will be no modification on input path )

  -a, --all-folders                 (Optional) Read & list all photos in all sub folders (no extra parameter needed)

  -t, --no-taken-date               (Optional) Action to do when a photo with a no taken date. ( Continue: 0, PreventProcess: 1 )

  -c, --no-coordinate               (Optional) Action to do when a photo with a no coordinate. ( Continue: 0, PreventProcess: 1 )

  -e, --reverse-geocode             (Optional) Third-party provider to resolve photo taken address by photo's coordinates. ( Disabled: 0 [default], BigDataCloud: 1, OpenStreetMapFoundation: 2, GoogleMaps: 3, LocationIq: 5 )

  -b, --bigdatacloud-key            (Optional) API key needed to use BigDataCloud. https://www.bigdatacloud.com/geocoding-apis/reverse-geocode-to-city-api/ (Instead of using this option, environment name: PHOTO_CLI_BIG_DATA_CLOUD_API_KEY can be used. )

  -u, --bigdatacloud-levels         (Optional) Admin levels separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from BigDataCloud. )

  -m, --googlemaps-types            (Optional) GoogleMaps address types separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from GoogleMaps. )

  -k, --googlemaps-key              (Optional) API key needed to use GoogleMaps. https://developers.google.com/maps/documentation/geocoding/overview/ (Instead of using this option, environment name: PHOTO_CLI_GOOGLE_MAPS_API_KEY can be used. )

  -r, --openstreetmap-properties    (Optional) OpenStreetMap properties separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from OpenStreetMap provider. )

  -q, --locationiq-key              (Optional) API key needed to use LocationIq. https://locationiq.com/docs/ (Instead of using this option, environment name: PHOTO_CLI_LOCATIONIQ_API_KEY can be used. )

  -h, --has-paid-license            (Optional) Bypass rate limit if you have paid license. ( For LocationIq )

  -l, --language                    (Optional) Language/culture value to get localized address result for BigDataCloud ( https://www.bigdatacloud.com/supported-languages/ ) and GoogleMaps (https://developers.google.com/maps/faq#languagesupport ).

  --help                            Display this help screen.

  --version                         Display version information.

NOTES:
- Instead of option names (for ex: DateTimeWithMinutes), you may use options values too. (for ex: 3)
- You can use relative folder paths. If you use the input folder as the working directory, you don't need to use the input argument.

EXAMPLE USAGES:
- Photos located on all subfolders will be processed and their photograph's taken date and address information will be saved on CSV file using BigDataCloud reverse geocode provider.

Example with long argument names;
photo-cli info --all-folders --reverse-geocode OpenStreetMapFoundation --input [input-folder] --output [output-file].csv --openstreetmap-properties country city town suburb

Example with short argument names;
photo-cli info -a -e OpenStreetMapFoundation -i [input-folder] -o [output-file].csv -r country city town suburb

- Using Google Maps reverse geocode provider (need api key) with an option to prevent processing if there is no coordinate or no photo taken date found on any photo.

Example with long argument names;
photo-cli info --no-coordinate PreventProcess --reverse-geocode GoogleMaps --input [input-folder] --googlemaps-key google-api-key --googlemaps-types administrative_area_level_1 administrative_area_level_2 --output [output-file].csv --no-taken-date PreventProcess

Example with short argument names;
photo-cli info -c PreventProcess -e GoogleMaps -i [input-folder] -k google-api-key -m administrative_area_level_1 administrative_area_level_2 -o [output-file].csv -t PreventProcess

Copy

Copies photos into new folder hierarchy with given arguments using photograph's taken date and coordinate address (reverse geocode).

photo-cli help copy
  -o, --output                      (MUST) File system path to create new organized folder. A new folder hierarchy will be created on that location with new file names. (will create folder if not exists)

  -s, --naming-style                (MUST) Naming strategy of newly copied file name. ( Numeric: 1, Day: 2, DateTimeWithMinutes: 3, DateTimeWithSeconds: 4, Address: 5, DayAddress: 6, DateTimeWithMinutesAddress: 7, DateTimeWithSecondsAddress: 8, AddressDay: 9,
                                    AddressDateTimeWithMinutes: 10, AddressDateTimeWithSeconds: 11 )

  -f, --process-type                (MUST) Reading photos strategy from input folder. ( Single: 1, SubFoldersPreserveFolderHierarchy: 2, FlattenAllSubFolders: 3 )

  -n, --number-style                (MUST) Number naming strategy when using `NamingStyle` as `Numeric` or using to numbering the possible same names. ( AllNamesAreSameLength: 1, PaddingZeroCharacter: 2, OnlySequentialNumbers: 3 )

  -t, --no-taken-date               (MUST) Action to do when a photo with a no taken date. ( Continue: 0, PreventProcess: 1, DontCopyToOutput: 2, InSubFolder: 3, AppendToEndOrderByFileName: 4, InsertToBeginningOrderByFileName: 5 )

  -c, --no-coordinate               (MUST) Action to do when a photo with a no coordinate. ( Continue: 0, PreventProcess: 1, DontCopyToOutput: 2, InSubFolder: 3 )

  -i, --input                       (Default current executing folder) File system path to read & copy photos from. ( there will be no modification on input path )

  -d, --dry-run                     (Optional) Simulate the same process without writing to the output folder. (no extra parameter needed)

  -g, --group-by                    (Optional) Strategy to group photos into folders. [Can't use with `FolderProcessType` is `SubFoldersPreserveFolderHierarchy`] ( YearMonthDay: 1, YearMonth: 2, Year: 3, Address: 4 )

  -a, --folder-append               (Optional) Appending name strategy to folder names cloned from source folder hierarchy. [Can be with `FolderProcessType` is `SubFoldersPreserveFolderHierarchy`] ( FirstYearMonthDay: 1, FirstYearMonth: 2, FirstYear: 3, DayRange: 4,
                                    MatchingMinimumAddress: 5 )

  -p, --folder-append-location      (Optional) Append location for `FolderAppendType`. [Can be use with `FolderProcessType` is `SubFoldersPreserveFolderHierarchy`] ( Prefix: 1, Suffix: 2 )

  -v, --verify                      (Optional) Verify that all photo files copied successfully by comparing file hashes. (no extra parameter needed)

  -e, --reverse-geocode             (Optional) Third-party provider to resolve photo taken address by photo's coordinates. ( Disabled: 0 [default], BigDataCloud: 1, OpenStreetMapFoundation: 2, GoogleMaps: 3, LocationIq: 5 )

  -b, --bigdatacloud-key            (Optional) API key needed to use BigDataCloud. https://www.bigdatacloud.com/geocoding-apis/reverse-geocode-to-city-api/ (Instead of using this option, environment name: PHOTO_CLI_BIG_DATA_CLOUD_API_KEY can be used. )

  -u, --bigdatacloud-levels         (Optional) Admin levels separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from BigDataCloud. )

  -m, --googlemaps-types            (Optional) GoogleMaps address types separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from GoogleMaps. )

  -k, --googlemaps-key              (Optional) API key needed to use GoogleMaps. https://developers.google.com/maps/documentation/geocoding/overview/ (Instead of using this option, environment name: PHOTO_CLI_GOOGLE_MAPS_API_KEY can be used. )

  -r, --openstreetmap-properties    (Optional) OpenStreetMap properties separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from OpenStreetMap provider. )

  -q, --locationiq-key              (Optional) API key needed to use LocationIq. https://locationiq.com/docs/ (Instead of using this option, environment name: PHOTO_CLI_LOCATIONIQ_API_KEY can be used. )

  -h, --has-paid-license            (Optional) Bypass rate limit if you have paid license. ( For LocationIq. )

  -l, --language                    (Optional) Language/culture value to get localized address result for BigDataCloud ( https://www.bigdatacloud.com/supported-languages/ ) and GoogleMaps (https://developers.google.com/maps/faq#languagesupport ).

  --help                            Display this help screen.

  --version                         Display version information.

NOTES:
- Instead of option names (for ex: DateTimeWithMinutes), you may use options values too. (for ex: 3)
- You can use relative folder paths. If you use the input folder as the working directory, you don't need to use the input argument.

EXAMPLE USAGES:
- By preserving existing folder hierarchy, photos copied with a file name as photo taken date and time. Photos taken on same date and time, will have a number suffix. Photos that don't have any coordinate or photo taken date will be copied in a relative sub folder.

Example with long argument names;
photo-cli copy --no-coordinate InSubFolder --process-type SubFoldersPreserveFolderHierarchy --input [input-folder] --number-style PaddingZeroCharacter --output [output-folder] --naming-style DateTimeWithMinutes --no-taken-date InSubFolder

Example with short argument names;
photo-cli copy -c InSubFolder -f SubFoldersPreserveFolderHierarchy -i [input-folder] -n PaddingZeroCharacter -o [output-folder] -s DateTimeWithMinutes -t InSubFolder

- Preserving folder hierarchy, photos copied with a sequential file name. Photos that don't have any coordinate or photo taken date won't be copied to output.

Example with long argument names;
photo-cli copy --no-coordinate DontCopyToOutput --process-type SubFoldersPreserveFolderHierarchy --input [input-folder] --number-style AllNamesAreSameLength --output [output-folder] --naming-style Numeric --no-taken-date DontCopyToOutput

Example with short argument names;
photo-cli copy -c DontCopyToOutput -f SubFoldersPreserveFolderHierarchy -i [input-folder] -n AllNamesAreSameLength -o [output-folder] -s Numeric -t DontCopyToOutput

- Grouping all photos in folders with a name photo taken year and month. Photos will be copied with a file name date, time, and address received from OpenStreetMap reverse geocode provider.

Example with long argument names;
photo-cli copy --reverse-geocode OpenStreetMapFoundation --process-type FlattenAllSubFolders --group-by YearMonth --input [input-folder] --number-style OnlySequentialNumbers --output [output-folder] --openstreetmap-properties country city town suburb --naming-style DateTimeWithSecondsAddress --no-taken-date AppendToEndOrderByFileName

Example with short argument names;
photo-cli copy -e OpenStreetMapFoundation -f FlattenAllSubFolders -g YearMonth -i [input-folder] -n OnlySequentialNumbers -o [output-folder] -r country city town suburb -s DateTimeWithSecondsAddress -t AppendToEndOrderByFileName

- Process single folder and copy photos with file names as their address which will get from BigDataCloud

Example with long argument names;
photo-cli copy --no-coordinate PreventProcess --reverse-geocode BigDataCloud --process-type Single --input [input-folder] --number-style AllNamesAreSameLength --output [output-folder] --naming-style Address --no-taken-date DontCopyToOutput --bigdatacloud-levels 2 4 6 8

Example with short argument names;
photo-cli copy -c PreventProcess -e BigDataCloud -f Single -i [input-folder] -n AllNamesAreSameLength -o [output-folder] -s Address -t DontCopyToOutput -u 2 4 6 8

- Adding year month day as a prefix to existing folder names and photos copied with a file name as day and address. The address will be built from Google Maps (need API key).

Example with long argument names;
photo-cli copy --folder-append FirstYearMonthDay --no-coordinate PreventProcess --reverse-geocode GoogleMaps --process-type SubFoldersPreserveFolderHierarchy --input [input-folder] --googlemaps-key google-api-key --googlemaps-types administrative_area_level_1 administrative_area_level_2 administrative_area_level_3 --number-style AllNamesAreSameLength --output [output-folder] --folder-append-location Prefix --naming-style DayAddress --no-taken-date PreventProcess

Example with short argument names;
photo-cli copy -a FirstYearMonthDay -c PreventProcess -e GoogleMaps -f SubFoldersPreserveFolderHierarchy -i [input-folder] -k google-api-key -m administrative_area_level_1 administrative_area_level_2 administrative_area_level_3 -n AllNamesAreSameLength -o [output-folder] -p Prefix -s DayAddress -t PreventProcess

Archive

Archives photos into specific folder and indexing photo taken date, address (reverse geocode) information into SQLite database.

photo-cli help archive
  -o, --output                      (MUST) File system path to create new organized folder. A new folder hierarchy will be created on that location with new file names. (will create folder if not exist)

  -i, --input                       (Default current executing folder) File system path to read & copy photos from. ( there will be no modification on the input path )

  -d, --dry-run                     (Optional) Simulate the same process without writing to the output folder. (no extra parameter needed)

  -x, --invalid-format              (Optional) Action to do when a photo format is invalid. ( Continue: 0 [default], PreventProcess: 1 )

  -t, --no-taken-date               (Optional) Action to do when a photo with a no taken date. ( Continue: 0 [default], PreventProcess: 1 )

  -c, --no-coordinate               (Optional) Action to do when a photo with a no coordinate. ( Continue: 0 [default], PreventProcess: 1 )

  -e, --reverse-geocode             (Optional) Third-party provider to resolve photo taken address by photo's coordinates. ( Disabled: 0 [default], BigDataCloud: 1, OpenStreetMapFoundation: 2, GoogleMaps:
                                    3, LocationIq: 5 )

  -b, --bigdatacloud-key            (Optional) API key needed to use BigDataCloud. https://www.bigdatacloud.com/geocoding-apis/reverse-geocode-to-city-api/ (Instead of using this option, environment name:
                                    PHOTO_CLI_BIG_DATA_CLOUD_API_KEY can be used or `BigDataCloudApiKey` key can be set via settings command. )

  -u, --bigdatacloud-levels         (Optional) Admin levels separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see the full response returned
                                    from BigDataCloud. )

  -m, --googlemaps-types            (Optional) GoogleMaps address types separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see the full
                                    response returned from GoogleMaps. )

  -k, --googlemaps-key              (Optional) API key needed to use GoogleMaps. https://developers.google.com/maps/documentation/geocoding/overview/ (Instead of using this option, environment name:
                                    PHOTO_CLI_GOOGLE_MAPS_API_KEY can be used or `GoogleMapsApiKey` key can be set via settings command. )

  -r, --openstreetmap-properties    (Optional) OpenStreetMap properties separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see the full
                                    response returned from OpenStreetMap provider. )

  -q, --locationiq-key              (Optional) API key needed to use LocationIq. https://locationiq.com/docs/ (Instead of using this option, environment name: PHOTO_CLI_LOCATIONIQ_API_KEY can be used or
                                    `LocationIqApiKey` key can be set via settings command. )

  -h, --has-paid-license            (Optional) Bypass the free rate limit if you have paid license. ( For LocationIq. )

  -l, --language                    (Optional) Language/culture value to get localized address result for BigDataCloud ( https://www.bigdatacloud.com/supported-languages/ ) and GoogleMaps
                                    (https://developers.google.com/maps/faq#languagesupport ).

  --help                            Display this help screen.

  --version                         Display version information.

NOTES:
- Instead of option names (for ex: DateTimeWithMinutes), you may use options values too. (for ex: 3)
- You can use relative folder paths. If you use the input folder as the working directory, you don't need to use the input argument.

EXAMPLE USAGES:
- Archive all photos in current folder (and it's subfolders recursively) into output folder by [year]/[month]/[day] hierarchy with a file name photo taken date with seconds prefixed by file hash. Saves all photo taken information into local SQLite database.

Example with long argument names;
photo-cli archive --output [output-folder]

Example with short argument names;
photo-cli archive -o [output-folder]

- Archive all photos in input folder (and it's subfolders recursively), fetches all photo's reverse geocode information, copies into output folder by [year]/[month]/[day] hierarchy with a file name photo taken date with seconds prefixed by file hash. Saves all photo taken information and it's address (reverse geocode) into local SQLite database.

Example with long argument names;
photo-cli archive --no-coordinate PreventProcess --reverse-geocode OpenStreetMapFoundation --input [input-folder] --output [output-folder] --openstreetmap-properties country city town suburb --no-taken-date PreventProcess --invalid-format PreventProcess

Example with short argument names;
photo-cli archive -c PreventProcess -e OpenStreetMapFoundation -i [input-folder] -o [output-folder] -r country city town suburb -t PreventProcess -x PreventProcess

Address

Get address (reverse geocode) of single photo.

photo-cli help address
  -i, --input                       (Default current executing folder) File system path to read & copy photos from. ( there will be no modification on the input path )

  -e, --reverse-geocode             (Optional) Third-party provider to resolve photo taken address by photo's coordinates. ( Disabled: 0 [default], BigDataCloud: 1, OpenStreetMapFoundation: 2, GoogleMaps: 3, LocationIq: 5 )

  -t, --type                        (MUST) Response list detail level. ( AllAvailableProperties: 0, SelectedProperties: 1, FullResponse: 2 )

  -b, --bigdatacloud-key            (Optional) API key needed to use BigDataCloud. https://www.bigdatacloud.com/geocoding-apis/reverse-geocode-to-city-api/ (Instead of using this option, environment name: PHOTO_CLI_BIG_DATA_CLOUD_API_KEY can be used. )

  -u, --bigdatacloud-levels         (Optional) Admin levels separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from BigDataCloud. )

  -m, --googlemaps-types            (Optional) GoogleMaps address types separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from GoogleMaps. )

  -k, --googlemaps-key              (Optional) API key needed to use GoogleMaps. https://developers.google.com/maps/documentation/geocoding/overview/ (Instead of using this option, environment name: PHOTO_CLI_GOOGLE_MAPS_API_KEY can be used. )

  -r, --openstreetmap-properties    (Optional) OpenStreetMap properties separated with space. ( To see which level correspond to which address level, you may use `photo-cli address` to see full response returned from OpenStreetMap provider. )

  -q, --locationiq-key              (Optional) API key needed to use LocationIq. https://locationiq.com/docs/ (Instead of using this option, environment name: PHOTO_CLI_LOCATIONIQ_API_KEY can be used. )

  -h, --has-paid-license            (Optional) Bypass rate limit if you have paid license. ( For LocationIq. )

  -l, --language                    (Optional) Language/culture value to get localized address result for BigDataCloud ( https://www.bigdatacloud.com/supported-languages/ ) and GoogleMaps (https://developers.google.com/maps/faq#languagesupport ).

  --help                            Display this help screen.

  --version                         Display version information.

NOTES:
- Instead of option names (for ex: DateTimeWithMinutes), you may use options values too. (for ex: 3)
- You can use relative folder paths. If you use the input folder as the working directory, you don't need to use the input argument.

EXAMPLE USAGES:
- All properties

Example with long argument names;
photo-cli address --reverse-geocode OpenStreetMapFoundation --input [photo-path].jpg

Example with short argument names;
photo-cli address -e OpenStreetMapFoundation -i [photo-path].jpg

- Selected properties

Example with long argument names;
photo-cli address --reverse-geocode OpenStreetMapFoundation --input [photo-path].jpg --openstreetmap-properties country city town suburb --type SelectedProperties

Example with short argument names;
photo-cli address -e OpenStreetMapFoundation -i [photo-path].jpg -r country city town suburb -t SelectedProperties

- Show full response

Example with long argument names;
photo-cli address --reverse-geocode OpenStreetMapFoundation --input [photo-path].jpg --type FullResponse

Example with short argument names;
photo-cli address -e OpenStreetMapFoundation -i [photo-path].jpg -t FullResponse

Settings

List, save and get settings.

photo-cli help settings
  -k, --key      (Optional) Setting property name to change.

  -v, --value    (Optional) Setting value to set.

  -r, --reset    (Optional) Reset all settings value to default ones. (no extra parameter needed)

  --help         Display this help screen.

  --version      Display version information.

NOTES:
- Instead of option names (for ex: DateTimeWithMinutes), you may use options values too. (for ex: 3)
- You can use relative folder paths. If you use input folder as working directory, you don't need to use input argument.

EXAMPLE USAGES:
- List all settings

Example with long argument names;
photo-cli settings

Example with short argument names;
photo-cli settings

- Get a setting

Example with long argument names;
photo-cli settings --key YearFormat

Example with short argument names;
photo-cli settings -k YearFormat

- Save a setting

Example with long argument names;
photo-cli settings --key YearFormat --value yyyy

Example with short argument names;
photo-cli settings -k YearFormat -v yyyy

- Reset all settings

Example with long argument names;
photo-cli settings --reset

Example with short argument names;
photo-cli settings -r

Command Line Options / Arguments

Input Path ( -i, --input )

Optional use for copy, archive, info verb. Must be used on address verb. File system path to read & copy photos from. If not given, the current executing folder will be used. There will be no modification on input path.

Output Path ( -o, --output )

Must be used on copy, archive, info verbs. File system path to write output. For copy, new folder hierarchy created on that location with new file names. It will create folder if not exists. For info, report csv file path to write.

Folder Process Type ( -f, --process-type )

Must be used on copy verb. You must select folder process behavior to whether use original folder hierarchy or flatten into single folder/grouped folder by Group By Folder.

Option Name
Single 1
SubFoldersPreserveFolderHierarchy 2
FlattenAllSubFolders 3

Naming Style ( -s, --naming-style )

Must be used on copy verb. While copying to a new organized folder, you must select one of these file naming strategies for a newly copied photo file name.

Option Value
Numeric 1
Day 2
DateTimeWithMinutes 3
DateTimeWithSeconds 4
Address 5
DayAddress 6
DateTimeWithMinutesAddress 7
DateTimeWithSecondsAddress 8
AddressDay 9
AddressDateTimeWithMinutes 10
AddressDateTimeWithSeconds 11

Folder Append Type ( -a, --folder-append )

Optional use for copy verb. While copying to a new organized folder (you should select Folder Process Type as SubFoldersPreserveFolderHierarchy ), you may select one of these file folder naming strategies. Must used with Folder Append Location Type

Option Value
FirstYearMonthDay 1
FirstYearMonth 2
FirstYear 3
DayRange 4
MatchingMinimumAddress 5

Folder Append Location Type ( -p, --folder-append-location )

Optional use for copy verb. While copying to a new organized folder (you should select Folder Process Type as SubFoldersPreserveFolderHierarchy ), you may select one of these file folder naming strategies. Must used with Folder Append Location

Option Value
Prefix 1
Suffix 2

Group By Folder ( -g, --group-by )

Optional use for copy verb. If you want to group photos by EXIF data, you may select one of these strategies.

Option Value
YearMonthDay 1
YearMonth 2
Year 3
Address 4

Number Naming Text Style ( -n, --number-style )

Must be used on copy verb. Number naming strategy when using Naming Style as Numeric or using to numbering the possible same names.

Option Value
AllNamesAreSameLength 1
PaddingZeroCharacter 2
OnlySequentialNumbers 3

Verify ( -v, --verify)

Optional use for copy verb. Verify that all photo files copied successfully by comparing file hashes. (no extra parameter needed)

Is Dry Run ( -d, --dry-run )

Optional use for copy, archive verb. Simulate the same process without writing to output folder. No extra parameter needed.

Reverse Geocode Provider ( -e, --reverse-geocode )

Optional use for copy, archive, info verb. Must be used on address verb. Third-party provider to resolve photo taken address by photo's coordinates.

Option Value
BigDataCloud 1
OpenStreetMapFoundation 2
GoogleMaps 3
LocationIq 5

Big Data Cloud API Key ( -b, --bigdatacloud-key )

Sets Big Data Cloud reverse geocode API key. Alternatively, you may use the environment variable PHOTO_CLI_BIG_DATA_CLOUD_API_KEY.

Google Maps API Key ( -k, --googlemaps-key )

Sets Google Maps reverse geocode API key. Alternatively, you may use the environment variable PHOTO_CLI_GOOGLE_MAPS_API_KEY.

Location Iq API Key ( -q, --locationiq-key )

Sets Location Iq reverse geocode API key. Alternatively, you may use the environment variable PHOTO_CLI_LOCATIONIQ_API_KEY.

BigDataCloud Admin Levels ( -u, --bigdatacloud-levels )

Must be used when BigDataCloud is selected as reverse geocode provider. Big Data Cloud admin levels are separated with space. ( To see which level correspond to which address level, you may use photo-cli address to see the full response returned from BigDataCloud. )

OpenStreetMapProperties ( -r, --openstreetmap-properties )

Must be used when any of OpenStreetMapFoundation, LocationIq is selected as reverse geocode provider. OpenStreetMap properties separated with space. ( To see which level correspond to which address level, you may use photo-cli address to see the full response returned from OpenStreetMap provider. )

Google Maps Address Types ( -m, --googlemaps-types )

Must be used when GoogleMaps selected as reverse geocode provider. Google Maps address types separated with space. ( To see which level correspond to which address level, you may use photo-cli address to see full the response returned from GoogleMaps. )

Has Paid License ( -h, --has-paid-license )

Bypass the free rate limit if you have paid license. (For LocationIq reverse geocode providers)

No Photograph Taken Date Action [for copy command ] ( -t, --no-taken-date )

Optional use for copy verb. Action to do when a photograph with a no taken date. Default is Continue.

Option Value
Continue (default) 0 (default)
PreventProcess 1
DontCopyToOutput 2
InSubFolder 3
AppendToEndOrderByFileName 4
InsertToBeginningOrderByFileName 5

No Coordinate Action [for copy command ] ( -c, --no-coordinate )

Optional use for copy verb. Action to do when a photo with a no coordinate.

Option Value
Continue 0
PreventProcess 1
DontCopyToOutput 2
InSubFolder 3

All Folders ( -a, --all-folders )

Optional use for info verb. Read & list all photos in all subfolders.

No Photograph Taken Date Action [for info command ] ( -t, --no-taken-date )

Optional use for info verb. Action to do when a photograph with a no taken date. Default is Continue.

Option Value
Continue (default) 0 (default)
PreventProcess 1

No Coordinate Action [for info command ] ( -c, --no-coordinate )

Optional use for info verb. Action to do when a photo with a no coordinate.

Option Value
Continue 0
PreventProcess 1

No Photograph Taken Date Action [for archive command ] ( -t, --no-taken-date )

Optional use for archive verb. Action to do when a photograph with a no taken date. Default is Continue.

Option Value
Continue (default) 0 (default)
PreventProcess 1

No Coordinate Action [for archive command ] ( -c, --no-coordinate )

Optional use for archive verb. Action to do when a photo with a no coordinate.

Option Value
Continue 0
PreventProcess 1

Settings

User can customize & set these options via settings command.

  • All date & time formats. Reference values: MSDN Date Time Format Strings
  • File & folder naming separators
  • Report file names
  • No Photo Taken Date Action folder name.
  • No Address Action folder name.
  • Third-party reverse geocode API keys.
  • Change maximum concurrent connection limit to connect third-party reverse geocode provider.

Listing All Settings

photo-cli settings
AddressSeparator=-
ArchivePhotoTakenDateHashSeparator=-
BigDataCloudApiKey=
ConnectionLimit=4
CoordinatePrecision=4
CsvReportFileName=photo-cli-report.csv
DateFormatWithDay=yyyy.MM.dd
DateFormatWithMonth=yyyy.MM
DateTimeFormatWithMinutes=yyyy.MM.dd_HH.mm
DateTimeFormatWithSeconds=yyyy.MM.dd_HH.mm.ss
DayFormat=dd
DayRangeSeparator=-
DryRunCsvReportFileName=photo-cli-dry-run.csv
FolderAppendSeparator=-
GoogleMapsApiKey=
LocationIqApiKey=
LogLevel=Warning
MonthFormat=MM
NoAddressAndPhotoTakenDateFolderName=no-address-and-no-photo-taken-date
NoAddressFolderName=no-address
NoPhotoTakenDateFolderName=no-photo-taken-date
PhotoFormatInvalidFolderName=invalid-photo-format
SameNameNumberSeparator=-
YearFormat=yyyy

Getting a Single Value

photo-cli settings --key YearFormat
YearFormat=yyyy

Setting a Single Value

photo-cli settings --key YearFormat --value y
No output when successful.

Resetting All Values To Defaults

photo-cli settings --reset
No output when successful

Exit Codes

Process exit codes listed below;

Option Value
Success 0
ParseArgsFailed 1
AppSettingsInvalidFile 2
ApiKeyStoreValidationFailed 10
AddressOptionsValidationFailed 11
InfoOptionsValidationFailed 12
CopyOptionsValidationFailed 13
SettingsOptionsValidationFailed 14
ArchiveOptionsValidationFailed 15
InputFolderNotExists 20
NoPhotoFoundOnDirectory 21
OutputFolderIsNotEmpty 22
OutputPathIsExists 23
OutputPathDontHaveWriteFilePermission 24
OutputPathDontHaveCreateDirectoryPermission 25
InputFileNotExists 26
PhotosWithNoDatePreventedProcess 30
PhotosWithNoCoordinatePreventedProcess 31
PhotosWithNoCoordinateAndNoDatePreventedProcess 32
PropertyNotFound 40
InvalidSettingsValue 41

Roadmap

See the roadmap.

Contributing

See the contributing.

Code of Conduct

See the code of conduct.

Changelog - Release History

See the changelog.

Attribution

Many thanks to these open source libraries. This work can not be done without these beautiful libraries and their contributors.

Also thanks exif-samples for sample images, to make project test various EXIF data variations.

License

Everything inside this repository is Apache 2.0 licensed.

Uninstallation

dotnet tool uninstall -g photo-cli

Credits

This tool is currently developed by Alp Coker and is open for contributors.

photo-cli's People

Contributors

alpcoker avatar recepcil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

photo-cli's Issues

Process Companion Files For Photos

Nowadays some devices are also putting companion files related to photo. We need to also copy & archive this photos as our flows.

For my use case, I am using iPhone and I am using the the feature of live photos. I wanted to keep the *.mov files along to *.heic files.

There is also *. aae files which is used by Apple Photos app to keep track of changes you make to your photos.

UI - Web Application to Create & Transmit Commands

Command line arguments are too much and it may be hard to type.

I am creating a POC to spin up a file server with the following command photo-cli ui. This will serve as a web application. Also, this command will open the browser with http://localhost:7000.

This web application will only help to create these CLI commands and only transmit these commands to the tool.

OpenStreetMap - Nominatim Reverse Geocode URL No Longer Works

Problem

Following URL format for OpenStreetMap - Nominatim was working previously

https://nominatim.openstreetmap.org/reverse/?format=json&lat=39.925054&lon=32.8347552&language=en

Solution

It's currently giving 404 not found response. Removing the extra / in the URL that is located before ? should fix the problem.

https://nominatim.openstreetmap.org/reverse?format=json&lat=39.925054&lon=32.8347552&language=en

Support HEIC Photos?

Is it possible to use your photo-cli tool for HEIC format photos from an Apple device? I've tried like below but I got the following output. Thanks in advance.

Command:
photo-cli copy -o ordered-photos -s DateTimeWithMinutes -f FlattenAllSubFolders -n PaddingZeroCharacter

Output:
Searching photos: finished. 0 photos found.
No photo found on folder: /Users/cilrecep/photos
Process failed with a error code 21 (NoPhotoFoundOnDirectory)

Archive - Indexing Into Same Specific Folder

Purpose

Archive verb is a new verb that facilitates users to archive their photos into same specific folder with a recommended way of naming with indexing capabilities on SQLite.

Motivation

People tend to use a single folder for their archive. For archiving into single folder, people need to execute copy verb on an empty output folder and move this folder contents into their archive folder. This is a manual work and this may lead to an inconsistent naming on folder/file naming. Even worse on possible file name conflict, this would cause file overwriting ends with a photo lost.

Requirements

  • Users can and usually use the same output folder and files should never have conflicting names if they are different photos.
  • Photos should be created in an easily accessible folder structure.
  • Indexing all photo information in a local SQLite database would be more flexible and will open the door to more features in the future.

Existing Copy Verb Limitation & Design

Copy verb requires a empty or not existing output path to be able to create output folders and files without conflicting and overwriting. It is a design choice and don't wanted to make it complicated choices on conflicting folder/file names. The copy verb will continue behave like that.

Error in Configuring Non-String Setting Values

When attempting to set a non-string setting value using the photo-cli settings command, an error occurs during conversion.

Command:
photo-cli settings --key ConnectionLimit --value 3

Output:
System.ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Int32'.

I'm willing to contribute towards resolving this issue.

Reverse geocode provider MapQuest not working

MapQuest is terminated its Nominatim (OpenStreetMap) product. Should be removed from the tool.

I had reached out to their support and their response was

The following services have reached their end of life:
The open geocode, directions, guidance, mapping, elevation, and Nominatim APIs
The Directions API Path from Route and Find LinkID functions
The Static Map v5 "@2x" parameter
The unofficial/beta Geocode API v2
All Traffic API v1 and Directions API v1 will reach the end of their lives and all requests should be updated to v2
Static Map v4
All native mobile SDKs (mapping and navigation)
The MapQuest JavaScript v7, Leaflet plugins v1, and Flash SDKs that were sunset in 2016-2018 will stop displaying map tiles

Verifying File Hash

After completing the copy Process, verify all photos are copied successfully by comparing each photograph's file hash.

Getting address without giving reverse geocoding specific properties

When using address verb to inspect reverse geocoding responses we have three choices

AllAvailableProperties = 0,
SelectedProperties = 1,
FullResponse = 2,

src - AddressListType

For SelectedProperties we need Vendor specific properties but for AllAvailableProperties and FullResponse not.

For example, following command shouldn't give validation error;

photo-cli address -i DSC_5727.jpg -e GoogleMaps -t FullResponse

output

Must use GoogleMapsAddressTypes when using GoogleMaps with ( --googlemaps-types or -m )

Crash when cannot determine file format

Hi,

I just try your program on my 15k+ photos
Got an error when trying to organize my collection with : photo-cli copy --process-type FlattenAllSubFolders --group-by YearMonthDay --naming-style DateTimeWithSeconds --number-style OnlySequentialNumbers --input Phones --output organized

Parsing photo exif information: 5% - (738/15087)
Unhandled exception. MetadataExtractor.ImageProcessingException: File format could not be determined
   at MetadataExtractor.ImageMetadataReader.ReadMetadata(Stream stream)
   at PhotoCli.Services.Implementations.ExifParserService.Parse(String filePath, Boolean parseDateTime, Boolean parseCoordinate) in /home/runner/work/photo-cli/photo-cli/src/Services/Implementations/ExifParserService.cs:line 46
   at PhotoCli.Services.Implementations.ExifDataAppenderService.ExifDataByPath(IEnumerable`1 photoPaths, Boolean& allPhotosHasPhotoTaken, Boolean& allPhotosHasCoordinate) in /home/runner/work/photo-cli/photo-cli/src/Services/Implementations/ExifDataAppenderService.cs:line 25
   at PhotoCli.Runners.CopyRunner.Execute() in /home/runner/work/photo-cli/photo-cli/src/Runners/CopyRunner.cs:line 65
   at PhotoCli.Program.MainWithServiceProvider(IServiceProvider serviceProvider) in /home/runner/work/photo-cli/photo-cli/src/Program.cs:line 140
   at PhotoCli.Program.<Main>(String[] args)
Aborted

Due to Some Responses From BigDataCloud on Address Verb Throws Error

BigDataCloud responses might contain multiple admin level. This situation Is throwing the following error.

Command

photo-cli address --type AllAvailableProperties --reverse-geocode BigDataCloud -i photo.jpg

Error Output

Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: AdminLevel4
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at PhotoCli.Services.Implementations.ReverseGeocodes.BigDataCloudReverseGeocodeService.AllAvailableReverseGeocodes(Coordinate coordinate, String language) in /home/runner/work/photo-cli/photo-cli/src/Services/Implementations/ReverseGeocodes/BigDataCloudReverseGeocodeService.cs:line 63
   at PhotoCli.Runners.AddressRunner.Execute() in /home/runner/work/photo-cli/photo-cli/src/Runners/AddressRunner.cs:line 35
   at PhotoCli.Program.MainWithServiceProvider(IServiceProvider serviceProvider) in /home/runner/work/photo-cli/photo-cli/src/Program.cs:line 140
   at PhotoCli.Program.<Main>(String[] args)
[1]    10291 abort      photo-cli address -i  -e 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.