commit
90862cb771
3 changed files with 102 additions and 0 deletions
@ -0,0 +1,12 @@ |
||||
[[source]] |
||||
name = "pypi" |
||||
url = "https://pypi.org/simple" |
||||
verify_ssl = true |
||||
|
||||
[dev-packages] |
||||
|
||||
[packages] |
||||
exifread = "*" |
||||
|
||||
[requires] |
||||
python_version = "3.7" |
@ -0,0 +1,29 @@ |
||||
{ |
||||
"_meta": { |
||||
"hash": { |
||||
"sha256": "d334e0b74eb9f528b448a30bb08927d71137c1737fe11cd575cee482d0a56f54" |
||||
}, |
||||
"pipfile-spec": 6, |
||||
"requires": { |
||||
"python_version": "3.7" |
||||
}, |
||||
"sources": [ |
||||
{ |
||||
"name": "pypi", |
||||
"url": "https://pypi.org/simple", |
||||
"verify_ssl": true |
||||
} |
||||
] |
||||
}, |
||||
"default": { |
||||
"exifread": { |
||||
"hashes": [ |
||||
"sha256:4aa9d227db5c4cd65d87520076140a6f84e33363e08e649b87c7afec6bab60ab", |
||||
"sha256:79e244f2eb466709029e8806fe5e2cdd557870c3db5f68954db0ef548d9320ad" |
||||
], |
||||
"index": "pypi", |
||||
"version": "==2.1.2" |
||||
} |
||||
}, |
||||
"develop": {} |
||||
} |
@ -0,0 +1,61 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
import argparse |
||||
import glob |
||||
import os |
||||
import shutil |
||||
|
||||
import exifread |
||||
|
||||
HOME = os.getenv("HOME") |
||||
NEXTCLOUD_DIR = os.path.join(HOME, "Nextcloud") |
||||
PHOTOS_DIR = os.path.join(NEXTCLOUD_DIR, "Photos") |
||||
UNSORTED_DIR = os.path.join(PHOTOS_DIR, "Unsorted") |
||||
print("Photos dir: {}".format(PHOTOS_DIR)) |
||||
|
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument("--src", required=True) |
||||
parser.add_argument("--dst", default=PHOTOS_DIR, required=False) |
||||
parser.add_argument("--debug", action="store_true") |
||||
parser.add_argument("--dry-run", action="store_true") |
||||
args = parser.parse_args() |
||||
|
||||
def debug(s): |
||||
if args.debug: |
||||
print(s) |
||||
|
||||
def move(src, dst): |
||||
if not args.dry_run: |
||||
shutil.move(src, dst) |
||||
|
||||
def mkdir(path): |
||||
if not args.dry_run: |
||||
os.makedirs(path, exist_ok=True) |
||||
|
||||
def get_date(path): |
||||
with open(path, 'rb') as f: |
||||
tags = exifread.process_file(f, stop_tag="EXIF DateTimeOriginal") |
||||
|
||||
y, m, d = tags["EXIF DateTimeOriginal"].values.split(" ")[0].split(":") |
||||
return (y, m, d) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
g = glob.glob(args.src) |
||||
for a in g: |
||||
try: |
||||
y, m, _ = get_date(a) |
||||
ymdir = os.path.join(PHOTOS_DIR, y, m) |
||||
mkdir(ymdir) |
||||
debug("{} -> {}".format(a, ymdir)) |
||||
move(a, ymdir) |
||||
except KeyError: |
||||
# Could not parse date |
||||
mkdir(UNSORTED_DIR) |
||||
print("{} -> {}".format(a, UNSORTED_DIR)) |
||||
move(a, UNSORTED_DIR) |
||||
except IsADirectoryError: |
||||
# leave directories, happens if you didn't give the |
||||
# correct full path |
||||
print("Skipping directory: {}".format(a)) |
||||
continue |
Loading…
Reference in new issue