Skip to content

Instantly share code, notes, and snippets.

@dustinrouillard
Created October 29, 2020 01:57
Show Gist options
  • Save dustinrouillard/fdf12606d300856eaa586b47766de2b2 to your computer and use it in GitHub Desktop.
Save dustinrouillard/fdf12606d300856eaa586b47766de2b2 to your computer and use it in GitHub Desktop.
Download Snapchat Memories from a JSON file (Comes from the Snapchat data dump)
import json
import os
import mimetypes
import requests
import datetime as dt
from multiprocessing.pool import ThreadPool as Pool
with open('memories.json', 'r') as memories_file:
memories_data=memories_file.read()
memories = json.loads(memories_data)
if os.path.isdir("memories") == False:
print("Missing memories directory")
exit()
skipped = 0
processed = 0
def run_memory(memory):
global skipped
global processed
date_string = memory['Date'].split(' ')
date_string.pop()
date = dt.datetime.strptime(' '.join(date_string), '%Y-%m-%d %H:%M:%S')
id = memory['Download Link'].split('&mid=')[1].split('&')[0]
file_type = 'mp4' if memory['Media Type'] == "VIDEO" else "jpg"
location = "memories/{}/{}".format(date.year, "{}-{}-{}_{}.{}".format(date.month, date.day, date.year, id, file_type))
if os.path.isfile(location) == True:
skipped = skipped + 1
print("Skipping {}, already exist".format(id))
else:
print("{}/{} : Retrieving download link for {} - {}".format(len(memories['Saved Media']) - (skipped + processed), len(memories['Saved Media']), memory["Media Type"], id))
download_url = requests.post(memory['Download Link']).text
# make sure the directory exists
if os.path.isdir("memories/{}".format(date.year)) == False:
os.mkdir("memories/{}".format(date.year))
split_url = download_url.split('?')[0]
url = split_url[0:int(48/2)] + '...' + split_url[int(len(split_url)-48/2):len(split_url)]
print("Downloading {} to {}".format(url, location))
file_contents = requests.get(download_url)
open(location, 'wb').write(file_contents.content)
processed = processed + 1
if __name__=="__main__":
pool=Pool(20)
print("Starting to download {} memories".format(len(memories)))
for memory in memories['Saved Media']:
pool.apply_async(run_memory, (memory,))
#run_memory(memory)
pool.close()
pool.join()
@khalilbasem
Copy link

khalilbasem commented Nov 4, 2021

Thank you very much for supplying this code! Absolute timesaver. A slight addition if anyone is interested in having the correct Image creation date (if you want to view them in something like google photo by the correct date they were taken). add the following:

import time
from win32_setctime import setctime
import piexif

to the import section of your file

and modify lines 48 - 50 to be

        file_contents = requests.get(download_url)
        open(location, 'wb').write(file_contents.content)

        d = dt.date(date.year,date.month,date.day)
        unixtime = time.mktime(d.timetuple())
        setctime(location, unixtime)

        exif_dict = piexif.load(location)
        new_date = dt.datetime(date.year,date.month,date.day, 0, 0, 0).strftime("%Y:%m:%d %H:%M:%S")
        exif_dict['0th'][piexif.ImageIFD.DateTime] = new_date
        exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = new_date
        exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = new_date
        exif_bytes = piexif.dump(exif_dict)
        piexif.insert(exif_bytes, location)

        processed = processed + 1

Thank you again op for sharing this

@lutfufn
Copy link

lutfufn commented Aug 21, 2022

is there also way to edit the exif date in a way that we can also see the time the medias were taken?

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