Skip to content

Commit

Permalink
Added support for CR3 and Apple DNG files (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
brian978 authored Jan 21, 2023
1 parent 6370c7e commit 6aeb53b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,6 @@ dmypy.json
# IDE
.idea
.vscode

# Local files
resources
10 changes: 10 additions & 0 deletions fs/ftype.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ class FileType(enum.Enum):
TYPE_JPEG = 'jpg'
TYPE_PNG = 'png'
TYPE_MP4 = 'png'
TYPE_CR3 = 'cr3'
TYPE_DNG = 'dng'

@classmethod
def list(cls):
return list(map(lambda c: c.value, cls))

@staticmethod
def detect_type(filename):
Expand All @@ -22,5 +28,9 @@ def detect_type(filename):
return FileType.TYPE_PNG
elif fn.find('.mp4') > 0:
return FileType.TYPE_MP4
elif fn.find('.cr3') > 0:
return FileType.TYPE_CR3
elif fn.find('.dng') > 0:
return FileType.TYPE_DNG

raise ValueError('Filename has an unsupported format!')
15 changes: 13 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@
import shutil

from fs.common import Directory
from fs.ftype import FileType
from media.metadata import MetaFactory

path = input('Target path: ')
# path = os.path.abspath('./resources')

print(f'Lookup directory: {path}')

dir_obj = Directory(path)

for file in dir_obj.fetch(['jpg', 'jpeg', 'heic', 'mov', 'png']):
print(f'Processing file {file.name}')
for file in dir_obj.fetch(FileType.list()):
print(f'-------- Processing file {file.name}')
print(f'#')

try:
file_meta = MetaFactory.factory(file)

date = file_meta.get_create_timestamp()
if date is not None:
print(f'Tagging file {file.basename} with date {date}')

file.create_timestamp = date
file.save()
else:
Expand All @@ -37,3 +44,7 @@
except ValueError as msg:
print(f'{file.name}: {msg}')
continue
finally:
print(f'#')
print(f'-------------- End processing for file {file.basename}----------------------')
print('')
41 changes: 41 additions & 0 deletions media/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ def factory(file: File) -> AbstractMeta:
return PngMeta(file.name)
elif file.type == FileType.TYPE_HEIC:
return HeicMeta(file.name)
elif file.type == FileType.TYPE_CR3:
return Cr3Meta(file.name)
elif file.type == FileType.TYPE_DNG:
return DngMeta(file.name)


class MovMeta(AbstractMeta):
Expand Down Expand Up @@ -171,3 +175,40 @@ def get_create_timestamp(self) -> Optional[datetime]:
break

return create_timestamp


class Cr3Meta(AbstractMeta):
def get_create_timestamp(self) -> Optional[datetime]:
create_timestamp = None

with open(self._filename, 'rb') as fh:
# Seek to byte
fh.seek(524, 0)

try:
timestamp = fh.read(20).decode('utf8').replace('\x00', '')
create_timestamp = datetime.strptime(timestamp, "%Y:%m:%d %H:%M:%S")
# print(f'Found timestamp: {create_timestamp}')
except ValueError as e:
print(f'Invalid position for timestamp in file {self._filename}')
print(f'Error message: {str(e)}')

return create_timestamp


class DngMeta(AbstractMeta):
def get_create_timestamp(self) -> Optional[datetime]:
create_timestamp = None

with open(self._filename, 'rb') as fh:
# Seek to byte
fh.seek(448, 0)

try:
timestamp = fh.read(20).decode('utf8').replace('\x00', '')
create_timestamp = datetime.strptime(timestamp, "%Y:%m:%d %H:%M:%S")
except ValueError as e:
print(f'Invalid position for timestamp in file {self._filename}')
print(f'Error message: {str(e)}')

return create_timestamp

0 comments on commit 6aeb53b

Please sign in to comment.