Skip to content

Instantly share code, notes, and snippets.

@lkraider
Last active November 3, 2023 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lkraider/83856fca740320751194bdf9c60a2ab6 to your computer and use it in GitHub Desktop.
Save lkraider/83856fca740320751194bdf9c60a2ab6 to your computer and use it in GitHub Desktop.
Synchronize the modified timestamps of files between a backup folder and a destination folder.
import os
from datetime import datetime
def sync_timestamps(backup_folder, destination_folder, dry_run=False):
# Loop through the files in the destination folder
for file_name in os.listdir(destination_folder):
destination_file_path = os.path.join(destination_folder, file_name)
destination_modified_time = os.path.getmtime(destination_file_path)
# Check if there is a corresponding file in the backup folder with the same name
backup_file_path = os.path.join(backup_folder, file_name)
if os.path.isfile(backup_file_path):
# Get the modified time attribute of the backup file
backup_modified_time = os.path.getmtime(backup_file_path)
# Skip if dates are the same
if destination_modified_time == backup_modified_time:
continue
# If dry_run is True, only print the proposed changes
print('Set modified time from {} to {} of {}'.format(
datetime.fromtimestamp(destination_modified_time).isoformat(),
datetime.fromtimestamp(backup_modified_time).isoformat(),
destination_file_path))
if dry_run:
continue
# Set the modified time attribute of the destination file to the value obtained in the previous step
os.utime(destination_file_path, (backup_modified_time, backup_modified_time))
def sync_all_timestamps(backup_folder, destination_folder, dry_run=False):
# Loop through all subdirectories in the destination folder
for root, dirs, files in os.walk(destination_folder):
# Calculate the relative path of the current directory
relative_dir = os.path.relpath(root, destination_folder)
# Construct the corresponding directory in the backup folder
corresponding_backup_dir = os.path.join(backup_folder, relative_dir)
# If the corresponding directory exists in the backup folder, sync the timestamps
if os.path.isdir(corresponding_backup_dir):
sync_timestamps(corresponding_backup_dir, root, dry_run)
if __name__ == '__main__':
# Define the paths for the backup and destination folders
backup_folder = "/mnt/z/Downloads/GooglePhotos/ALL_PHOTOS/"
destination_folder = "/mnt/y/GooglePhotos/"
sync_all_timestamps(backup_folder, destination_folder, dry_run=True)
@lkraider
Copy link
Author

lkraider commented Nov 3, 2023

This script provides a way to synchronize the modified timestamps of files between a backup folder and a destination folder. It includes a sync_timestamps function to sync the timestamps of files in a pair of directories, and a sync_all_timestamps function to sync the timestamps of files in all subdirectories of a pair of directories. The script also includes a dry-run mode that prints the proposed changes without actually modifying the files.

It can be used to fix photo files that don't contain date/time metadata (like those exported from Google Photos Takeout) that were edited by a tool like digikam before including the date/time metadata.

The tool assumes the same folder structure from backup was kept on the destination.

Suggestion is to run this to restore the modified time, then on digikam use the "Tools > Adjust Time Date" from "File Last Modified" to then store the timestamp in the metadata.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment