Skip to content

Instantly share code, notes, and snippets.

@metriics
Last active January 27, 2023 21:55
Show Gist options
  • Select an option

  • Save metriics/285131aa867d350049a8a31e691ebf9c to your computer and use it in GitHub Desktop.

Select an option

Save metriics/285131aa867d350049a8a31e691ebf9c to your computer and use it in GitHub Desktop.
A (hopefully) portable Python3 script to copy Sony ARW raw files that have been rated from one directory to another, sorted by image date
import errno
import os
import shutil
directory = None
destDir = None
while not directory:
target = input("Directory to look in: ")
if os.path.exists(target):
directory = target
else:
print("{} does not exist.\n".format(target))
while not destDir:
target = input("Directory to copy to: ")
if os.path.exists(target):
destDir = target
else:
print("{} does not exist.\n".format(target))
# https://stackoverflow.com/a/14115286
def createDir(destination, date):
currentDir = os.path.join(
destination,
date)
try:
os.makedirs(currentDir)
return currentDir
except OSError as e:
if e.errno != errno.EEXIST:
raise # This was not a "directory exist" error..
else:
return currentDir # Dir exists, just add to it
print("\n{} -> {}".format(directory, destDir))
print("Copying rated images...\n")
copied = dict()
numCopied = 0
ratingsTotal = [ 0, 0, 0, 0, 0 ]
for pic in os.listdir(directory):
full = os.path.join(directory, pic)
if os.path.splitext(pic)[1].upper() == ".ARW":
if os.path.isfile(full):
with open(full, 'rb') as imageFile: # Read XMP from file bytes https://stackoverflow.com/a/8120117
fb = imageFile.read()
# Find image timestamp, extract date and create export folder if it doesn't exist
date_start = fb.find(b'\x49\x49\x5E\x00\x02\x01') + 6 # hex that seems to consistently appear before one of the timestamps in an ARW
date_str = fb[date_start:date_start+10].decode("utf-8").replace(':', '-')
dest = createDir(destDir, date_str)
# Find image rating
xmp_rating_start = fb.find(b'<xmp:Rating>')
xmp_rating_end = fb.find(b'</xmp:Rating>')
xmp_rating = int(fb[xmp_rating_start + 12:xmp_rating_end].decode("utf-8"))
if xmp_rating >= 1:
shutil.copy2(full, dest) # copy2 preservesd timestamps
copied[pic] = xmp_rating
numCopied += 1
ratingsTotal[xmp_rating - 1] += 1
if numCopied == 0:
print("No rated pictures found.\n")
else:
print("Copied {} image(s) to {}".format(numCopied, destDir))
print("Stats:")
for rating in range(0, 5):
if ratingsTotal[rating] > 0:
print("{stars:>5}: {num} image(s)".format(stars="*"*(rating+1), num=ratingsTotal[rating]))
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment