Created
January 6, 2020 22:47
-
-
Save nathan-v/03257c1d56fb3879788af30a0475b167 to your computer and use it in GitHub Desktop.
Facebook Photos & Videos Export Date Fixer -- Sets the file dates to the dates from Fb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: utf-8 | |
# | |
# Facebook Photos & Videos Export Date Fixer | |
# Author: Nathan V <[email protected]> | |
# | |
# Copyright 2019 Nathan V | |
# License: MIT; https://opensource.org/licenses/MIT | |
# | |
# Works on Python 3+ | |
# | |
# Placed in the root folder where the export was extracted and run | |
# | |
import fnmatch | |
import json | |
import os | |
import sys | |
import datetime as DT | |
class FBExportFixer: | |
""" The class that does the needful | |
""" | |
def __init__(self): | |
""" Init the needful | |
""" | |
self.log("Initialized") | |
if not os.path.exists("photos_and_videos"): | |
self.log("photos_and_videos not found, exiting") | |
sys.exit(1) | |
@staticmethod | |
def log(message): | |
""" Stupid simple logger; easy to replace later if desired | |
""" | |
print("FBExportFixer: {}".format(message)) | |
def main(self): | |
self.process_vidoes() | |
self.process_albums() | |
self.log("Done.") | |
def process_vidoes(self): | |
""" Process any videos in the backup | |
""" | |
if not os.path.exists("photos_and_videos/your_videos.json"): | |
self.log("Videos JSON file missing. Skipping videos.") | |
return | |
videos_json = open("photos_and_videos/your_videos.json").read() | |
videos = json.loads(videos_json) | |
self.log("{} videos found".format(len(videos["videos"]))) | |
for num, video in enumerate(videos["videos"], start=1): | |
video_date = DT.datetime.utcfromtimestamp(video["creation_timestamp"]) | |
video_id = "{} - {}".format(video["title"], str(num).zfill(3)) | |
print("Video: '{}', Create date {}".format(video_id, video_date)) | |
self.update_file_date(video["uri"], video["creation_timestamp"]) | |
def process_albums(self): | |
""" Process any photos in the backup | |
""" | |
if not os.path.exists("photos_and_videos/album/0.json"): | |
self.log("Photo album file(s) missing. Skipping photos.") | |
return | |
albums = fnmatch.filter(os.listdir("photos_and_videos/album/"), "*.json") | |
self.log("{} albums found".format(len(albums))) | |
for album in albums: | |
path = "photos_and_videos/album/{}".format(album) | |
photos_json = open(path).read() | |
photos = json.loads(photos_json) | |
self.process_album_contents(photos) | |
def process_album_contents(self, photos): | |
""" Given an album do the album needful | |
""" | |
self.log( | |
"Found Album: {} with {} items".format( | |
photos["name"], len(photos["photos"]) | |
) | |
) | |
for num, photo in enumerate(photos["photos"], start=1): | |
photo_date = DT.datetime.utcfromtimestamp(photo["creation_timestamp"]) | |
photo_id = "{} - {}".format(photos["name"], str(num).zfill(3)) | |
print("Photo: '{}', Create date {}".format(photo_id, photo_date)) | |
self.update_file_date(photo["uri"], photo["creation_timestamp"]) | |
def update_file_date(self, file, date): | |
os.utime(file, (date, date)) | |
if __name__ == "__main__": | |
sys.exit(FBExportFixer().main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment