diff --git a/.project b/.project
new file mode 100644
index 0000000..c031460
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ media-scripts
+
+
+
+
+
+ org.python.pydev.PyDevBuilder
+
+
+
+
+
+ org.python.pydev.pythonNature
+
+
diff --git a/.pydevproject b/.pydevproject
new file mode 100644
index 0000000..13cd160
--- /dev/null
+++ b/.pydevproject
@@ -0,0 +1,8 @@
+
+
+
+/${PROJECT_DIR_NAME}
+
+python interpreter
+Default
+
diff --git a/correct_finepix.py b/correct_finepix.py
new file mode 100644
index 0000000..2331d48
--- /dev/null
+++ b/correct_finepix.py
@@ -0,0 +1,37 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+
+SRC = r'E:\RawByDateArchive'
+
+for raw in Path(SRC).glob("**/*.jpg"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ exif_dict = piexif.load(str(raw))
+ try:
+ model = exif_dict["0th"][piexif.ImageIFD.Model].decode("ascii")
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ except:
+ continue
+ if model != 'FinePix REAL 3D W3':
+ continue
+ rawdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ destdir = raw.parent
+ stem = f"ab-{day}-{ts}"
+ destfn = destdir / f"{stem}{raw.suffix}"
+ if destfn.exists():
+ print(f'skipped {destfn}, already exists')
+ continue
+ print(fn, "->", destfn)
+ raw.rename(destfn)
diff --git a/cp_exif.py b/cp_exif.py
new file mode 100644
index 0000000..2fffb83
--- /dev/null
+++ b/cp_exif.py
@@ -0,0 +1,26 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+import re
+
+SRC = r'E:\RawByUser\Andreas\Fuji Finepix 3D W3\Adjusted'
+DEST = r'E:\RawByUser\Andreas\Fuji Finepix 3D W3\2D'
+
+src = Path(SRC)
+for raw in src.glob("*.mpo"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ destfn = Path(DEST) / f"{raw.stem}.jpg"
+ if not destfn.exists():
+ print(f'skipped {destfn}, missing')
+ continue
+ print(f"{fn}", "->", destfn)
+ piexif.transplant(str(raw), str(destfn))
diff --git a/del_empty_folders.py b/del_empty_folders.py
new file mode 100644
index 0000000..9386c59
--- /dev/null
+++ b/del_empty_folders.py
@@ -0,0 +1,33 @@
+#!python3
+
+# set mtime for DV files from filename
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+import os
+
+src = Path(r'E:\MediaArchive\Andreas\MaxQByDate')
+dry_run = True
+
+for year in src.iterdir():
+ if not year.is_dir():
+ continue
+ for day in year.iterdir():
+ if not day.is_dir():
+ continue
+ files = list(day.iterdir())
+ file_count = len(files)
+ if file_count > 0:
+ continue
+ if not re.match("\d{8}", day.name):
+ continue
+ print(f"{file_count:3} files in {day.name}")
+ if not dry_run:
+ day.rmdir()
\ No newline at end of file
diff --git a/dv.kds b/dv.kds
new file mode 100644
index 0000000..f0d5e37
--- /dev/null
+++ b/dv.kds
@@ -0,0 +1,7 @@
+S'(?P\\S*)\\s?(?P.*)'
+p1
+.S'20030215'
+p2
+.I0
+.S''
+.
\ No newline at end of file
diff --git a/dv_avi.kds b/dv_avi.kds
new file mode 100644
index 0000000..3089233
--- /dev/null
+++ b/dv_avi.kds
@@ -0,0 +1,7 @@
+S'ab-(?P\\d{8})-(?P[\\s\\w]+)-(?P\\d{6})-(?P[\\w\\s]+).avi'
+p1
+.S'ab-20030215-Familienskifahren Saas Fee-121807-Sony TRV_25E.avi'
+p2
+.I0
+.S''
+.
\ No newline at end of file
diff --git a/exif_dump.py b/exif_dump.py
new file mode 100644
index 0000000..cbc8e46
--- /dev/null
+++ b/exif_dump.py
@@ -0,0 +1,27 @@
+#!python3
+
+import sys
+from pathlib import Path
+import datetime as dt
+import piexif
+
+
+def dump(fn):
+ exif_dict = piexif.load(fn)
+ for ifd_name in exif_dict:
+ print("\n{0} IFD:".format(ifd_name))
+ for key in exif_dict[ifd_name]:
+ try:
+ tag = piexif.TAGS[ifd_name][key]['name']
+ try:
+ print(key, tag, exif_dict[ifd_name][key][:40])
+ except:
+ print(key, tag, exif_dict[ifd_name][key])
+ except:
+ pass
+ print(exif_dict["0th"][piexif.ImageIFD.DateTime])
+ print(exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal])
+
+
+if __name__ == "__main__":
+ dump(sys.argv[1])
\ No newline at end of file
diff --git a/m4v.kds b/m4v.kds
new file mode 100644
index 0000000..d635764
--- /dev/null
+++ b/m4v.kds
@@ -0,0 +1,7 @@
+S'(?P[^-]*)-(?P\\S*)-(?P[^-]*)(-\\S+)?.m4v'
+p1
+.S'Ab-20160506-111908-Sony A5100-1.m4v'
+p2
+.I0
+.S''
+.
\ No newline at end of file
diff --git a/merge_photos.py b/merge_photos.py
new file mode 100644
index 0000000..7c8a311
--- /dev/null
+++ b/merge_photos.py
@@ -0,0 +1,44 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+src = Path(r'E:\MediaArchive\Andreas\MaxQByDate\2005\Uncategorized')
+dest = Path(r'E:\MediaArchive\Andreas\MaxQByDate')
+dry_run = False
+
+for suffix in ("jpg",):
+ for pic in src.rglob(f"*.{suffix}"):
+ try:
+ exif_dict = piexif.load(str(pic))
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ picdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ except:
+ print(f'exif failed {pic.name}, using file date')
+ mtime = pic.stat().st_mtime
+ picdt = dt.datetime.fromtimestamp(mtime)
+ # create new dir with exif date and original title
+ title = pic.parts[-2]
+ mo = re.match("\d{8}",title)
+ if mo is None:
+ pic_dir = dest / str(picdt.year) / f"{picdt:%Y%m%d} {title}"
+ else:
+ pic_dir = dest / str(picdt.year) / f"{title}"
+ if not pic_dir.exists():
+ if not dry_run:
+ print(f"creating {pic_dir}")
+ pic_dir.mkdir(parents=True)
+ pic_n = pic_dir / f"ab-{picdt:%Y%m%d}-{picdt:%H%M%S}{pic.suffix}"
+ n = 1
+ while pic_n.exists():
+ pic_n = pic_dir / f"ab-{picdt:%Y%m%d}-{picdt:%H%M%S}-{n:02}{pic.suffix}"
+ n += 1
+ print(pic.name, "->", pic_n)
+ if not dry_run:
+ pic.rename(pic_n)
diff --git a/mover.py b/mover.py
new file mode 100644
index 0000000..2bce811
--- /dev/null
+++ b/mover.py
@@ -0,0 +1,50 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+
+SRC = r'E:\MediaByTarget\Plex\Home Videos'
+DEST = r'E:\Users\Andreas\RawByDate'
+author = 'ab'
+dry_run = False
+
+def constant_factory(value):
+ return lambda: value
+
+dateidx = defaultdict(constant_factory(0))
+
+for suffix in ("jpg", "gif", "png", "mp4", "avi", "mov"):
+ for raw in Path(SRC).rglob(f"*.{suffix}"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ try:
+ exif_dict = piexif.load(str(raw))
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ rawdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ except:
+ print(f'exif failed {fn}, using file date')
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ destdir = Path(DEST, f"{year}",f"{day}")
+ if not destdir.exists() and not dry_run:
+ print(f'creating {destdir}')
+ destdir.mkdir(parents=True)
+ destfn = destdir / f"{author}-{day}-{ts}{raw.suffix}"
+ if destfn.exists():
+ index = dateidx[day] + 1
+ dateidx[day] = index
+ destfn = destdir / f"{author}-{day}-{index:04}{raw.suffix}"
+ print(fn, "->", destfn)
+ if not dry_run:
+ raw.rename(destfn)
diff --git a/mv_arw.py b/mv_arw.py
new file mode 100644
index 0000000..20c0183
--- /dev/null
+++ b/mv_arw.py
@@ -0,0 +1,41 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+src = Path(r'E:\MediaArchive\Andreas\RawByDate')
+dest = Path(r'E:\MediaArchive\Andreas\RawByCamera\Sony a5100')
+dry_run = False
+
+for mrw in src.rglob("*.arw"):
+ mo = re.match("ab-(?P\S*-\S*).arw", mrw.name)
+ if mo is None:
+ print(f"skipped {mrw.name}, no match")
+ continue
+ md = mo.groupdict()
+ try:
+ mrwdt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ except:
+ print(f"skipped {mrw.name}, unknown format")
+ continue
+ # move avi to raw Sony
+ mrw_dir = dest / str(mrwdt.year) / f"{mrwdt:%Y%m%d}"
+ mrw_n = mrw_dir / mrw.name
+ if not mrw_dir.exists():
+ if not dry_run:
+ print(f"creating {mrw_dir}")
+ mrw_dir.mkdir(parents=True)
+ print(mrw.name, "->", mrw_n)
+ if not mrw_n.exists():
+ if not dry_run:
+ mrw.rename(mrw_n)
+ else:
+ print(f"skipped {mrw.name}, {mrw_n}, already exists")
+
\ No newline at end of file
diff --git a/mv_dng.py b/mv_dng.py
new file mode 100644
index 0000000..b5c4cab
--- /dev/null
+++ b/mv_dng.py
@@ -0,0 +1,45 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+src = Path(r'E:\MediaArchive\Andreas\MaxQByDate')
+dest1 = Path(r"E:\MediaArchive\Andreas\RawByCamera\Minolta Dynax 5")
+dest2 = Path(r'E:\MediaArchive\Andreas\RawByCamera\Sony a5100')
+dry_run = False
+
+for mrw in src.rglob("*.dng"):
+ mo = re.match("ab-(?P\S*-\S*).dng", mrw.name)
+ if mo is None:
+ print(f"skipped {mrw.name}, no match")
+ continue
+ md = mo.groupdict()
+ try:
+ mrwdt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ except:
+ print(f"skipped {mrw.name}, unknown format")
+ continue
+ # move avi to raw Sony
+ if mrwdt.year > 2010:
+ mrw_dir = dest2 / str(mrwdt.year) / f"{mrwdt:%Y%m%d}"
+ else:
+ mrw_dir = dest1 / str(mrwdt.year) / f"{mrwdt:%Y%m%d}"
+ mrw_n = mrw_dir / mrw.name
+ if not mrw_dir.exists():
+ if not dry_run:
+ print(f"creating {mrw_dir}")
+ mrw_dir.mkdir(parents=True)
+ print(mrw.name, "->", mrw_n)
+ if not mrw_n.exists():
+ if not dry_run:
+ mrw.rename(mrw_n)
+ else:
+ print(f"skipped {mrw.name}, {mrw_n}, already exists")
+
\ No newline at end of file
diff --git a/mv_dv_avi.py b/mv_dv_avi.py
new file mode 100644
index 0000000..5a709e8
--- /dev/null
+++ b/mv_dv_avi.py
@@ -0,0 +1,38 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+import re
+
+SRC = r'E:\RawByUser\Andreas\Sony TRV-25E\DV'
+DEST = r'E:\VideoByDateArchive'
+
+src = Path(SRC)
+for raw in src.glob("*.avi"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ mo = re.match("(?P\S*\s\S*)(\s(?P.*))?.avi", fn)
+ md = mo.groupdict()
+ rawdt = dt.datetime.strptime(md['dt'],"%Y-%m-%d %H.%M.%S")
+ title = md['title']
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ destdir = Path(DEST, f"{year}",f"{day}")
+ if not destdir.exists():
+ print(f'creating {destdir}')
+ destdir.mkdir(parents=True)
+ stem = f"ab-{day}-{ts}-{title}-Sony TRV_25E"
+ destfn = destdir / f"{stem}{raw.suffix}"
+ if destfn.exists():
+ print(f'skipped {destfn}, already exists')
+ continue
+ print(f"{fn}", "->", destfn)
+ raw.rename(destfn)
diff --git a/mv_hd_mp4.py b/mv_hd_mp4.py
new file mode 100644
index 0000000..6371fc4
--- /dev/null
+++ b/mv_hd_mp4.py
@@ -0,0 +1,45 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+src = Path(r'E:\MediaByTarget\Plex\Home Videos')
+dest = Path(r'E:\MediaArchive\Andreas\RawByDate')
+author = 'ab'
+dry_run = False
+
+# def constant_factory(value):
+# return lambda: value
+# fileidx = defaultdict(constant_factory(0))
+
+fileidx = defaultdict(int)
+
+for mp4 in src.rglob("*-HD.mp4"):
+ mo = re.match("(?P\S*-\S*)-HD.mp4", mp4.name)
+ if mo is None:
+ print(f"skipped {mp4.name}, no match")
+ continue
+ md = mo.groupdict()
+ mp4dt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ # move avi to raw Sony
+ mp4_fn = f"ab-{md['dt']}-Panasonic HDC_SD99.mp4"
+ mp4_dir = dest / str(mp4dt.year) / f"{mp4dt:%Y%m%d}"
+ mp4_n = mp4_dir / mp4_fn
+ if not mp4_dir.exists():
+ print(f"creating {mp4_dir}")
+ if not dry_run:
+ mp4_dir.mkdir(parents=True)
+ print(mp4.name, "->", mp4_n)
+ if not mp4_n.exists():
+ if not dry_run:
+ mp4.rename(mp4_n)
+ else:
+ print(f"skipped {mp4.name}, {mp4_n}, already exists")
+
\ No newline at end of file
diff --git a/mv_lumia.py b/mv_lumia.py
new file mode 100644
index 0000000..68e6ec3
--- /dev/null
+++ b/mv_lumia.py
@@ -0,0 +1,42 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+
+# SRC = r'E:\RawByUser\Andreas\Microsoft Lumia 640'
+# SRC = r'E:\RawByUser\Andreas\Samsung DV-150'
+SRC = r'E:\RawByUser\Andreas\Sony K800i'
+DEST = r'E:\VideoByDateArchive'
+
+src = Path(SRC)
+for raw in src.glob("*.3GP"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ try:
+ # rawdt = dt.datetime.strptime(fn,"ab-%Y%m%d-%H%M%S-Samsung DV-150.MP4")
+ rawdt = dt.datetime.strptime(fn,"ab-%Y%m%d-%H%M%S-Sony K800i.3GP")
+ except:
+ print(f'exif failed {fn}, using file date')
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ destdir = Path(DEST, f"{year}",f"{day}")
+ if not destdir.exists():
+ print(f'creating {destdir}')
+ destdir.mkdir(parents=True)
+ # stem = f"kb-{day}-{ts}"
+ destfn = destdir / f"{fn}"
+ if destfn.exists():
+ print(f'skipped {destfn}, already exists')
+ continue
+ print(f"{fn}", "->", destfn)
+ raw.rename(destfn)
diff --git a/mv_mrw.py b/mv_mrw.py
new file mode 100644
index 0000000..33fdd84
--- /dev/null
+++ b/mv_mrw.py
@@ -0,0 +1,37 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+src = Path(r'E:\MediaArchive\Andreas\RawByDate')
+dest = Path(r'E:\MediaArchive\Andreas\RawByCamera\Minolta Dynax 5')
+dry_run = False
+
+for mrw in src.rglob("*.mrw"):
+ mo = re.match("ab-(?P\S*-\S*).mrw", mrw.name)
+ if mo is None:
+ print(f"skipped {mrw.name}, no match")
+ continue
+ md = mo.groupdict()
+ mrwdt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ # move avi to raw Sony
+ mrw_dir = dest / str(mrwdt.year) / f"{mrwdt:%Y%m%d}"
+ mrw_n = mrw_dir / mrw.name
+ if not mrw_dir.exists():
+ print(f"creating {mrw_dir}")
+ if not dry_run:
+ mrw_dir.mkdir(parents=True)
+ print(mrw.name, "->", mrw_n)
+ if not mrw_n.exists():
+ if not dry_run:
+ mrw.rename(mrw_n)
+ else:
+ print(f"skipped {mrw.name}, {mrw_n}, already exists")
+
\ No newline at end of file
diff --git a/mv_samsung.py b/mv_samsung.py
new file mode 100644
index 0000000..05ae8b5
--- /dev/null
+++ b/mv_samsung.py
@@ -0,0 +1,41 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+
+SRC = r'E:\RawByUser\Andreas\Samsung DV-150'
+DEST = r'E:\RawByDateArchive'
+
+src = Path(SRC)
+for raw in src.glob("**/*.JPG"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ try:
+ exif_dict = piexif.load(str(raw))
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ rawdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ except:
+ print(f'skipped {fn}, using file date')
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ destdir = Path(DEST, f"{year}",f"{day}")
+ if not destdir.exists():
+ print(f'creating {destdir}')
+ destdir.mkdir()
+ stem = f"ab-{day}-{ts}"
+ destfn = destdir / f"{stem}{raw.suffix}"
+ if destfn.exists():
+ print(f'skipped {destfn}, already exists')
+ continue
+ print(f"{fn}", "->", destfn)
+ raw.rename(destfn)
diff --git a/mv_sd_mp4.py b/mv_sd_mp4.py
new file mode 100644
index 0000000..565030a
--- /dev/null
+++ b/mv_sd_mp4.py
@@ -0,0 +1,45 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+src = Path(r'E:\MediaByTarget\Plex\Home Videos')
+dest = Path(r'E:\MediaArchive\Andreas\RawByDate')
+author = 'ab'
+dry_run = False
+
+# def constant_factory(value):
+# return lambda: value
+# fileidx = defaultdict(constant_factory(0))
+
+fileidx = defaultdict(int)
+
+for mp4 in src.rglob("*-SD.mp4"):
+ mo = re.match("(?P\S*-\S*)-SD.mp4", mp4.name)
+ if mo is None:
+ print(f"skipped {mp4.name}, no match")
+ continue
+ md = mo.groupdict()
+ mp4dt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ # move avi to raw Sony
+ mp4_fn = f"ab-{md['dt']}-Panasonic SDR_S7.mp4"
+ mp4_dir = dest / str(mp4dt.year) / f"{mp4dt:%Y%m%d}"
+ mp4_n = mp4_dir / mp4_fn
+ if not mp4_dir.exists():
+ # print(f"creating {mp4_dir}")
+ if not dry_run:
+ mp4_dir.mkdir(parents=True)
+ print(mp4.name, "->", mp4_n)
+ if not mp4_n.exists():
+ if not dry_run:
+ mp4.rename(mp4_n)
+ else:
+ print(f"skipped {mp4.name}, {mp4_n}, already exists")
+
\ No newline at end of file
diff --git a/ren_dv_avi.py b/ren_dv_avi.py
new file mode 100644
index 0000000..86c5da3
--- /dev/null
+++ b/ren_dv_avi.py
@@ -0,0 +1,34 @@
+#!python3
+
+# replace avi originals by mp4
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+import os
+
+src = Path(r'E:\MediaArchive\Andreas\RawByCamera\Sony TRV-25E')
+DRY_RUN = False
+
+def rename(old, new):
+ print(old.name, "->", new.name)
+ if not DRY_RUN:
+ if not new.exists():
+ old.rename(new)
+ else:
+ print(f"skipped {old.name}, {new.name}, already exists")
+
+for raw in src.glob("*.avi"):
+ mo = re.match("ab-(?P\d{8})-(?P[&\s\w]+)-(?P\d{6})-(?P[\w\s]+).avi", raw.name)
+ if mo is None:
+ # print(f"skipped {raw.name}, no match")
+ continue
+ md = mo.groupdict()
+ fn = f"ab-{md['dat']}-{md['tim']}-{md['title']}-{md['camera']}{raw.suffix}"
+ rename(raw, raw.parent / fn)
diff --git a/ren_finepix.py b/ren_finepix.py
new file mode 100644
index 0000000..11cf9a4
--- /dev/null
+++ b/ren_finepix.py
@@ -0,0 +1,43 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+import re
+
+SRC = r'E:\RawByUser\Andreas\Fuji Finepix 3D W3\Adjusted'
+# DEST = r'E:\VideoByDateArchive'
+
+src = Path(SRC)
+for raw in src.glob("*.mpo"):
+ fn = raw.name
+ if not raw.is_file():
+ print(f"skipped {fn}")
+ continue
+ try:
+ exif_dict = piexif.load(str(raw))
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ rawdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ except:
+ # print(f'skipped {fn}, using file date')
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ stem = f"ab-{day}-{ts}"
+ destdir = raw.parent
+ # destdir = Path(DEST, f"{year}",f"{day}")
+ # if not destdir.exists():
+ # print(f'creating {destdir}')
+ # destdir.mkdir(parents=True)
+ destfn = destdir / f"{stem}{raw.suffix}"
+ # if destfn.exists():
+ # print(f'skipped {destfn}, already exists')
+ # continue
+ print(f"{fn}", "->", destfn)
+ raw.rename(destfn)
diff --git a/ren_title.py b/ren_title.py
new file mode 100644
index 0000000..e13256e
--- /dev/null
+++ b/ren_title.py
@@ -0,0 +1,81 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+SRC = r'E:\MediaArchive\Andreas\RawByDate\2004'
+# camera = "Minolta"
+author = 'ab'
+dry_run = False
+
+# def constant_factory(value):
+# return lambda: value
+# fileidx = defaultdict(constant_factory(0))
+
+fileidx = defaultdict(int)
+
+for daydir in Path(SRC).iterdir():
+ mo = re.match("(?P\S*)\s(?P.*)", daydir.name)
+ md = mo.groupdict()
+ title = md['title']
+ for raw in daydir.rglob(f"*.jpg"):
+ # check whether exif works
+ try:
+ exif_dict = piexif.load(str(raw))
+ model = exif_dict["0th"][piexif.ImageIFD.Model].decode("ascii")
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ rawdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ except:
+ model = None
+ print(f'exif failed {raw.name}, using file date')
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ # digitized negative photo?
+ if model == 'Canon EOS 5D':
+ rawdt = dt.datetime.strptime(md['dt'],"%Y%m%d")
+ use_ts = False
+ else:
+ use_ts = True
+ if model == 'FinePix S602 ZOOM':
+ author = "nn"
+ else:
+ author = "ab"
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ if use_ts:
+ destfn = raw.parent / f"{author}-{day}-{title}-{ts}{raw.suffix}"
+ else:
+ index = fileidx[day] + 1
+ fileidx[day] = index
+ destfn = raw.parent / f"{author}-{day}-{title}-{index:04}{raw.suffix}"
+ # destfn = raw.parent / f"{author}-{day}-{title}-{index:04}-{camera}{raw.suffix}"
+ print(raw.name, "->", destfn.name)
+ if not dry_run:
+ if not destfn.exists():
+ raw.rename(destfn)
+ else:
+ print(f"skipped {raw.name}, {destfn.name}, already exists")
+ camera = "Sony TRV_25E"
+ for raw in daydir.rglob(f"*.avi"):
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ index = fileidx[day] + 1
+ fileidx[day] = index
+ destfn = raw.parent / f"{author}-{day}-{title}-{ts}-{camera}{raw.suffix}"
+ print(raw.name, "->", destfn.name)
+ if not dry_run:
+ if not destfn.exists():
+ raw.rename(destfn)
+ else:
+ print(f"skipped {raw.name}, {destfn.name}, already exists")
diff --git a/ren_triage.py b/ren_triage.py
new file mode 100644
index 0000000..85c9cf4
--- /dev/null
+++ b/ren_triage.py
@@ -0,0 +1,121 @@
+#!python3
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+
+SRC = r'E:\RawTriage'
+DRY_RUN = False
+
+# def constant_factory(value):
+# return lambda: value
+# fileidx = defaultdict(constant_factory(0))
+
+fileidx = defaultdict(int)
+
+CAMERAS = ("GoPro Hero3+", "Ricoh Theta V", "Ricoh Theta S", "Sony a5100", "Sony a65", "Sony TRV-25E")
+
+
+def recurse(dir, md, camera=None):
+ for fp in dir.iterdir():
+ if fp.is_dir():
+ if fp.name in CAMERAS:
+ recurse(fp, md, camera=fp.name)
+ elif camera:
+ recurse(fp, md, camera=camera)
+ else:
+ recurse(fp, md)
+ continue
+ if not fp.is_file():
+ print(f"{fp} neither dir nor file, skipping")
+ continue
+ # defaults
+ use_ts = True
+ use_camera = True
+ author = "ab"
+ mtime = fp.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ if fp.suffix.lower() == ".jpg":
+ try:
+ exif_dict = piexif.load(str(fp))
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ rawdt = dt.datetime.strptime(idto, "%Y:%m:%d %H:%M:%S")
+ except:
+ print(f"no exif in {fp.name}, skipping")
+ continue
+ try:
+ model = exif_dict["0th"][piexif.ImageIFD.Model].decode("ascii")
+ except:
+ model = None
+ pass
+ use_camera = False
+ if model == 'Canon EOS 5D':
+ print(f"{fp.name} scanned photo, use directory date")
+ rawdt = dt.datetime.strptime(md['dt'], "%Y%m%d")
+ use_ts = False
+ if model in ('FinePix S602 ZOOM', 'Canon EOS 6D', 'NIKON D5100'):
+ author = "nn"
+ if model == 'PULP 4G':
+ author = "jb"
+ if model == 'ASUS_Z00ED':
+ author = "sb"
+ elif fp.suffix.upper() == ".ARW":
+ use_camera = False
+ elif fp.suffix.upper() == ".MRW":
+ use_camera = False
+ elif fp.suffix.upper() == ".MP4":
+ pass
+ elif fp.suffix.upper() == ".MTS":
+ pass
+ elif fp.suffix.upper() == ".AVI":
+ pass
+ else:
+ continue
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ stem = f"{author}-{day}"
+ if use_ts:
+ stem += f"-{ts}"
+ else:
+ index = fileidx[day] + 1
+ fileidx[day] = index
+ stem += f"-{index:04}"
+ if use_camera:
+ stem += f"-{camera}"
+ rename(fp, fp.parent / f"{stem}{fp.suffix}")
+ # rename derivative files
+ i = len(fp.stem)
+ dvs = dir.rglob(f"{fp.stem}*.*")
+ for dv in dvs:
+ if dv.name == fp.name:
+ continue
+ # print(fp.name, stem, dv.name)
+ rename(dv, dv.parent / f"{stem}{dv.name[i:]}")
+
+
+def rename(old, new):
+ print(old.name, "->", new.name)
+ if not DRY_RUN:
+ if not new.exists():
+ old.rename(new)
+ else:
+ print(f"skipped {old.name}, {new.name}, already exists")
+
+
+for daydir in Path(SRC).iterdir():
+ if not daydir.is_dir():
+ continue
+ if daydir.name != "Aquaris U Plus":
+ continue
+ print(f"[{daydir.name}] -------------------------------------------------")
+ mo = re.match("(?P\S*)\s?(?P.*)", daydir.name)
+ md = mo.groupdict()
+ title = md['title']
+ recurse(daydir, md, camera="Aquaris U Plus")
diff --git a/rep_dv_avi_by_mp4.py b/rep_dv_avi_by_mp4.py
new file mode 100644
index 0000000..4e93926
--- /dev/null
+++ b/rep_dv_avi_by_mp4.py
@@ -0,0 +1,48 @@
+#!python3
+
+# replace avi originals by mp4
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+import os
+
+plex = Path(r'E:\MediaByTarget\Plex\Home Videos')
+rbd = Path(r"E:\MediaArchive\Andreas\RawByDate")
+sony = Path(r"E:\MediaArchive\Andreas\RawByCamera\Sony TRV-25E")
+author = 'ab'
+dry_run = False
+
+for mp4 in plex.rglob("*-DV.mp4"):
+ mtime = mp4.stat().st_mtime
+ mp4dt = dt.datetime.fromtimestamp(mtime)
+ aviglob = f"ab-{mp4dt:%Y%m%d}*{mp4dt:%H%M%S}*Sony TRV_25E.avi"
+ avis = list(rbd.rglob(aviglob))
+ if len(avis) != 1:
+ print(f"found {len(avis)} for {aviglob}")
+ continue
+ avi = avis[0]
+ # print(f"match {mp4.name} for {avi.name}")
+ # move avi to raw Sony
+ print(avi.name, "->", str(sony))
+ avi_n = sony / avi.name
+ if not avi_n.exists():
+ if not dry_run:
+ avi.rename(avi_n)
+ else:
+ print(f"skipped {avi.name}, {avi_n}, already exists")
+ # move mp4 to hires
+ mp4_fn = f"ab-{mp4dt:%Y%m%d}-{mp4dt:%H%M%S}-Sony TRV_25E.mp4"
+ mp4_n = avi.parent / mp4_fn
+ print(mp4.name, "->", mp4_n.name)
+ if not mp4_n.exists():
+ if not dry_run:
+ mp4.rename(mp4_n)
+ else:
+ print(f"skipped {mp4.name}, {mp4_n}, already exists")
diff --git a/rmorgdups.py b/rmorgdups.py
new file mode 100644
index 0000000..588d88e
--- /dev/null
+++ b/rmorgdups.py
@@ -0,0 +1,56 @@
+#!python3
+
+# remove Minolta original duplicates
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+
+SRC = r'E:\RawByDateArchive'
+DEST = r'E:\RawByDateArchive'
+MINOLTA = "Minolta Dynax 5"
+
+rbda = Path(SRC)
+for yeardir in rbda.iterdir():
+ if not yeardir.is_dir():
+ continue
+ for daydir in yeardir.iterdir():
+ minoltadir = Path(daydir,MINOLTA)
+ if not minoltadir.exists():
+ continue
+ for raw in minoltadir.iterdir():
+ fn = raw.name
+ if not raw.is_file():
+ print(f'skipped {fn}')
+ continue
+ try:
+ exif_dict = piexif.load(str(raw))
+ idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii")
+ rawdt = dt.datetime.strptime(idto,"%Y:%m:%d %H:%M:%S")
+ except:
+ # print(f'skipped {fn}, using file date')
+ mtime = raw.stat().st_mtime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ year = rawdt.year
+ day = f"{rawdt:%Y%m%d}"
+ ts = f"{rawdt:%H%M%S}"
+ destdir = Path(DEST, f"{year}",f"{day}")
+ if not destdir.exists():
+ print(f'creating {destdir}')
+ destdir.mkdir()
+ stem = f"ab-{day}-{ts}"
+ destfn = destdir / f"{stem}{raw.suffix}"
+ print(f"{fn}", "->", destfn)
+ # check dng or mrw dup in daydir
+ dups = daydir.glob(f"{stem}.*")
+ for d in dups:
+ print(f"removing {d}")
+ d.unlink()
+ if destfn.exists():
+ print(f'skipped {destfn}, already exists')
+ continue
+ raw.rename(destfn)
diff --git a/set_dv_mtime.py b/set_dv_mtime.py
new file mode 100644
index 0000000..0a7e0e5
--- /dev/null
+++ b/set_dv_mtime.py
@@ -0,0 +1,30 @@
+#!python3
+
+# set mtime for DV files from filename
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+import os
+
+src = Path(r'E:\MediaByTarget\Plex\Home Videos')
+author = 'ab'
+dry_run = False
+
+for raw in src.rglob("*-DV.mp4"):
+ mo = re.match("(?P\S*-\S*)-DV.mp4", raw.name)
+ if mo is None:
+ print(f"skipped {raw.name}, no match")
+ continue
+ md = mo.groupdict()
+ rawdt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ mtime = rawdt.timestamp()
+ atime = raw.stat().st_atime
+ print(f"setting {raw.name} to {rawdt}")
+ os.utime(raw, (atime, mtime))
diff --git a/set_hdc_mtime.py b/set_hdc_mtime.py
new file mode 100644
index 0000000..037343b
--- /dev/null
+++ b/set_hdc_mtime.py
@@ -0,0 +1,49 @@
+#!python3
+
+# set mtime for handbrake mp4 files from filename
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+import os
+
+DRY_RUN = False
+
+def rename(old, new):
+ print(old.name, "->", new.name)
+ if not DRY_RUN:
+ if not new.exists():
+ old.rename(new)
+ else:
+ print(f"skipped {old.name}, {new.name}, already exists")
+
+src = Path(r'D:\Videos')
+tim = Path(r'E:\MediaArchive\Andreas\RawByCamera\Panasonic HDC-SD99\20150412-20161209 Card\PRIVATE\AVCHD\BDMV\STREAM')
+
+for raw in src.glob("*.m4v"):
+ mo = re.match("(?P\d+)-\d+.m4v", raw.name)
+ if mo is None:
+ print(f"skipped {raw.name}, no match")
+ continue
+ md = mo.groupdict()
+ mtsn = f"{md['seq']}.MTS"
+ mts_ = list(tim.glob(mtsn))
+ if len(mts_) != 1:
+ print(f"skipped {mtsn}, no match")
+ continue
+ mts=mts_[0]
+ stat = mts.stat()
+ mtime = stat.st_mtime
+ atime = stat.st_atime
+ rawdt = dt.datetime.fromtimestamp(mtime)
+ print(f"{raw.name} -> {rawdt}")
+ if not DRY_RUN:
+ os.utime(raw, (atime, mtime))
+ fn = f"ab-{rawdt:%Y%m%d-%H%M%S}-Panasonic HDC_SD99{raw.suffix}"
+ rename(raw, raw.parent / fn)
diff --git a/set_m4v_mtime.py b/set_m4v_mtime.py
new file mode 100644
index 0000000..61d8e2b
--- /dev/null
+++ b/set_m4v_mtime.py
@@ -0,0 +1,41 @@
+#!python3
+
+# set mtime for handbrake mp4 files from filename
+
+# https://github.com/hMatoba/Piexif
+# http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention
+# destination: // /ab---.jpg
+
+from pathlib import Path
+import datetime as dt
+import piexif
+from collections import defaultdict
+import re
+import os
+
+DRY_RUN = False
+
+def rename(old, new):
+ print(old.name, "->", new.name)
+ if not DRY_RUN:
+ if not new.exists():
+ old.rename(new)
+ else:
+ print(f"skipped {old.name}, {new.name}, already exists")
+
+src = Path(r'D:\Videos')
+
+for raw in src.glob("*.m4v"):
+ mo = re.match("(?P[^-]*)-(?P\S*)-(?P[^-]*)(-\S+)?.m4v", raw.name)
+ if mo is None:
+ print(f"skipped {raw.name}, no match")
+ continue
+ md = mo.groupdict()
+ rawdt = dt.datetime.strptime(md['dt'],"%Y%m%d-%H%M%S")
+ mtime = rawdt.timestamp()
+ atime = raw.stat().st_atime
+ print(f"setting {raw.name} to {rawdt}")
+ if not DRY_RUN:
+ os.utime(raw, (atime, mtime))
+ fn = f"{md['author'].lower()}-{md['dt']}-{md['model']}{raw.suffix}"
+ rename(raw, raw.parent / fn)