{"id":21630113,"url":"https://github.com/virtualritz/exifmv","last_synced_at":"2025-04-11T13:51:46.233Z","repository":{"id":43684112,"uuid":"178980941","full_name":"virtualritz/exifmv","owner":"virtualritz","description":"CLI to organize image files into a folder hierarchy based on EXIF data","archived":false,"fork":false,"pushed_at":"2023-09-23T09:56:03.000Z","size":78,"stargazers_count":8,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-05-01T15:37:56.599Z","etag":null,"topics":["dng","exif-metadata","jpeg","jpg","raw-image","rust","tiff"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/virtualritz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"virtualritz","ko_fi":"virtual_ritz"}},"created_at":"2019-04-02T02:12:08.000Z","updated_at":"2024-03-28T19:01:56.000Z","dependencies_parsed_at":"2024-11-25T02:09:51.470Z","dependency_job_id":"5f2dccf3-a07c-463d-a180-d969928ed475","html_url":"https://github.com/virtualritz/exifmv","commit_stats":{"total_commits":45,"total_committers":4,"mean_commits":11.25,"dds":0.2222222222222222,"last_synced_commit":"c403d76de76fce909819d169439b18371cbaa478"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualritz%2Fexifmv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualritz%2Fexifmv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualritz%2Fexifmv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualritz%2Fexifmv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/virtualritz","download_url":"https://codeload.github.com/virtualritz/exifmv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248411966,"owners_count":21099036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dng","exif-metadata","jpeg","jpg","raw-image","rust","tiff"],"created_at":"2024-11-25T02:09:48.579Z","updated_at":"2025-04-11T13:51:46.207Z","avatar_url":"https://github.com/virtualritz.png","language":"Rust","funding_links":["https://github.com/sponsors/virtualritz","https://ko-fi.com/virtual_ritz"],"categories":[],"sub_categories":[],"readme":"\n# `exifmv`\n\n![build](https://github.com/virtualritz/exifmv/workflows/build/badge.svg)\n![Maintenance](https://img.shields.io/badge/maintenance-passively--maintained-yellowgreen.svg)\n\nMoves images into a folder hierarchy based on EXIF tags.\n\nCurrently the hierarchy is hard-wired into the tool as this suits my needs.\nIn the future this should be configured by a human-readable string\nsupporting regular expressions etc.\n\nFor now the built-in string is this:\n\n`{destination}/{year}/{month}/{day}/{filename}.{extension}`\n\nFor example, if you have an image shot on *Aug. 15 2020* named\n`Foo1234.ARW` it will e.g. end up in a folder hierarchy like so:\n\n```\n2020\n├── 08\n│   ├── 15\n│   │   ├── foo1234.arw\n│   │   ├── …\n```\n\n## Safety\n\nWith default settings `exifmv` uses move/rename only for organizing files.\nThe only thing you risk is having files end up somewhere you didn’t intend.\n\nBut – if you specify the `--remove-source` it will *remove the original*.\n\u003e ⚠ **In this case the original is permanently deleted!**\n\nAlternatively you can use the `--trash-source` which will move source files to\nthe user's trash folder from where they can be restored to their original\nlocation on most operating systems.\n\nBefore doing any deletion or moving-to-trash `exifmv` checks that the file\nsize matches. This is not the same as checking the files byte-by-byte. But\ndue to almost all image file formats using some kind of compression matching\nsize is a good enough indicator for files being identical for this\napplication.\n\nAll that being said: I have been using this app since about seven years\nwithout loosing any images. As such I have quite a lot of *empirical*\nevidence that it doesn’t destroy data.\n\nStill – writing some proper tests would likely give everyone else more\nconfidence than my word. Until I find some time to do that: **you have been\nwarned.**\n\n## Usage\n\n```cli\nUSAGE:\n    exifmv [OPTIONS] \u003cSOURCE\u003e [DESTINATION]\n\nARGS:\n    \u003cSOURCE\u003e         Where to search for images\n    \u003cDESTINATION\u003e    Where to move the images (if omitted, images will be moved to current dir)\n                     [default: .]\n\nOPTIONS:\n        --day-wrap \u003cH[H][:M[M]]\u003e    The time at which the date wraps to the next day [default: 0:0]\n        --dry-run                   Do not move any files (forces --verbose)\n    -h, --help                      Print help information\n    -H, --halt-on-errors            Exit if any errors are encountered\n    -l, --make-lowercase            Change filename \u0026 extension to lowercase\n    -L, --dereference               Dereference symbolic links\n    -r, --recurse-subdirs           Recurse subdirectories\n        --remove-source             Delete any SOURCE file existing at DESTINATION and matching in\n                                    size\n        --trash-source              Move any SOURCE file existing at DESTINATION and matching in\n                                    size to the system's trash\n    -v, --verbose                   Babble a lot\n    -V, --version                   Print version information\n```\n\n## History\n\nThis is based on a Python script that did more or less the same thing and\nwhich served me well for 15 years. When I started to learn Rust in 2018 I\ndecided to port the Python code to Rust as CLI app learning experience.\n\nAs such this app may not be the prettiest code you've come accross lately.\nIt may also contain non-idiomatic (aka: non-Rust) ways of doing stuff. If\nyou feel like fixing any of those or add some nice features, I look forward\nto merge your PRs. Beers!\n\nCurrent version: 0.1.2\n\n## License\n\nApache-2.0 OR BSD-3-Clause OR MIT OR Zlib at your discretion.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirtualritz%2Fexifmv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvirtualritz%2Fexifmv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirtualritz%2Fexifmv/lists"}