Browse Source

Added post.

dev
Franco Masotti 8 months ago
parent
commit
6018e8a114
Signed by: frnmst
GPG Key ID: 24116ED85666780A
  1. 115
      _posts/2021-12-19-sorting-files-after-recovery-with-photorec.md

115
_posts/2021-12-19-sorting-files-after-recovery-with-photorec.md

@ -0,0 +1,115 @@
---
title: Sorting files after recovery with Photorec
tags: [photorec, exif, exiftool, rsync, sort]
updated: 2021-12-19 22:21:50
description: Batch sorting files by date after a recovery with Photorec.
---
Here is a trivial, non efficient Python script that you can run after
a [Photorec](https://www.cgsecurity.org/wiki/PhotoRec) recovery.
This will use [EXIF](https://en.wikipedia.org/wiki/Exif)
and other file metadata to move the files in a `${YEAR}/${MONTH}/${DAY}` fashion.
To keep things simple all timezone handling is ignored.
You just need to install:
- [fpyutils](https://blog.franco.net.eu.org/software/#fpyutils)
- [Rsync](https://rsync.samba.org/)
- [Exiftool](https://exiftool.org/)
```python
#!/usr/bin/env python3
#
# Copyright (C) 2021 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import datetime
import pathlib
import json
import subprocess
import fpyutils
if __name__ == '__main__':
def main():
# Edit these variables.
SRC = '/home/myuser/recovery'
DST = '/home/myuser/sorted'
EXIFTOOL = '/usr/bin/exiftool'
RSYNC = '/usr/bin/rsync'
GLOB = '**/recup_dir.*/*'
for f in pathlib.Path(SRC).glob(GLOB):
if f.is_file():
cmd = [
EXIFTOOL,
'-j',
'-d',
'%Y-%m-%d %H:%M:%S',
str(f),
]
s = subprocess.run(cmd, capture_output = True)
js = s.stdout.decode('UTF-8')
struct = json.loads(js)[0]
# For simplicity all timestamps are assumed to be UTC naive.
# This is inherently wrong but it is a good approximation.
if 'CreateDate' in struct:
timestamp = struct['CreateDate']
elif 'DateTimeOriginal' in struct:
timestamp = struct['DateTimeOriginal']
elif 'TrackCreateDate' in struct:
timestamp = struct['TrackCreateDate']
elif 'ModifyDate' in struct:
timestamp = struct['ModifyDate']
elif 'TrackModifyDate' in struct:
timestamp = struct['TrackModifyDate']
elif 'FileInodeChangeDate' in struct:
timestamp = struct['FileInodeChangeDate']
elif 'FileModifyDate' in struct:
timestamp = struct['FileModifyDate']
elif 'FileAccessDate' in struct:
timestamp = struct['FileAccessDate']
else:
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# Try various formats before going fallback to current datetime.
try:
timestamp_struct = datetime.datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S')
except ValueError:
try:
timestamp_struct = datetime.datetime.strptime(timestamp, '%Y:%m:%d %H:%M:%S')
except ValueError:
timestamp_struct = datetime.datetime.now()
year = str(timestamp_struct.year).zfill(4)
month = str(timestamp_struct.month).zfill(2)
day = str(timestamp_struct.day).zfill(2)
dst_dir = pathlib.Path(DST,year,month,day)
dst_dir.mkdir(exist_ok=True, parents=True)
# Copy and then REMOVE.
cmd = (
RSYNC
+ ' -avAX --progress --remove-source-files '
+ str(f)
+ ' '
+ str(dst_dir)
)
fpyutils.shell.execute_command_live_output(cmd)
main()
```
Loading…
Cancel
Save