Skip to content

Instantly share code, notes, and snippets.

@nathan-v
Created January 6, 2020 22:47
Show Gist options
  • Save nathan-v/03257c1d56fb3879788af30a0475b167 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env python
# coding: utf-8
#
# Facebook Photos & Videos Export Date Fixer
# Author: Nathan V <Nathan.V@gmail.com>
#
# 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