2024-03-27 01:24:24 +00:00
|
|
|
#!/usr/bin/env python3
|
2024-03-25 21:09:44 +00:00
|
|
|
import json
|
|
|
|
import zlib
|
|
|
|
import sys
|
|
|
|
import pathlib
|
|
|
|
import time
|
|
|
|
import urllib.request
|
|
|
|
import shutil
|
|
|
|
|
|
|
|
# PNG, APNG, Lottie, GIF
|
|
|
|
STICKER_EXTENSIONS = ["", "png", "png", "json", "gif"]
|
|
|
|
|
|
|
|
|
|
|
|
def download_file(url, path):
|
|
|
|
if path.exists():
|
|
|
|
print("Already downloaded, skipping...")
|
|
|
|
return
|
|
|
|
out_file = open(path, "wb")
|
|
|
|
req = urllib.request.urlopen(
|
|
|
|
urllib.request.Request(url, headers={"User-Agent": "curl/8.6.0"})
|
|
|
|
)
|
|
|
|
shutil.copyfileobj(req, out_file)
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
|
|
|
|
2024-03-27 18:25:41 +00:00
|
|
|
def get_guilds(filename):
|
|
|
|
if filename.endswith(".json"):
|
|
|
|
# TODO: specify if it's compressed or not better
|
|
|
|
jsondata = open(filename, "r").read()
|
|
|
|
else:
|
|
|
|
bindata = open(filename, "rb").read()
|
|
|
|
decompress = zlib.decompressobj()
|
|
|
|
jsondata = decompress.decompress(bindata).decode("utf-8")
|
|
|
|
|
2024-03-25 22:24:56 +00:00
|
|
|
decoder = json.JSONDecoder()
|
2024-03-27 18:25:41 +00:00
|
|
|
guilds = []
|
|
|
|
while (offset := jsondata.find("{")) != -1:
|
|
|
|
obj, end = decoder.raw_decode(jsondata[offset:])
|
|
|
|
jsondata = jsondata[end + offset :]
|
|
|
|
|
|
|
|
typ = obj.get("t", "")
|
|
|
|
if typ == "READY":
|
|
|
|
guilds.extend(obj["d"]["guilds"])
|
|
|
|
elif typ == "GUILD_CREATE":
|
|
|
|
guilds.append(obj["d"])
|
|
|
|
|
|
|
|
return guilds
|
|
|
|
|
|
|
|
|
|
|
|
def safe_name(s):
|
|
|
|
# if you're on windows do something else here, i don't care
|
|
|
|
return s.replace("/", " ")
|
2024-03-25 21:09:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
def main(*args):
|
2024-03-27 18:25:41 +00:00
|
|
|
guilds = get_guilds(args[1])
|
2024-03-25 21:09:44 +00:00
|
|
|
|
2024-03-27 18:25:41 +00:00
|
|
|
base_dir = pathlib.Path("out") / "discord"
|
2024-03-25 21:09:44 +00:00
|
|
|
|
2024-03-27 18:25:41 +00:00
|
|
|
for guild in guilds:
|
2024-03-25 21:09:44 +00:00
|
|
|
name = guild["properties"]["name"]
|
|
|
|
print(f"Processing guild '{name}'")
|
|
|
|
|
2024-03-27 18:25:41 +00:00
|
|
|
sticker_objs = guild["stickers"]
|
|
|
|
emoji_objs = guild["emojis"]
|
|
|
|
|
|
|
|
dir_name = safe_name(name)
|
|
|
|
sticker_dir = base_dir / "stickers" / dir_name
|
|
|
|
emoji_dir = base_dir / "emoji" / dir_name
|
2024-03-25 21:09:44 +00:00
|
|
|
|
2024-03-27 18:25:41 +00:00
|
|
|
if len(sticker_objs) > 0:
|
|
|
|
sticker_dir.mkdir(exist_ok=True, parents=True)
|
|
|
|
if len(emoji_objs) > 0:
|
|
|
|
emoji_dir.mkdir(exist_ok=True, parents=True)
|
|
|
|
|
|
|
|
for sticker in sticker_objs:
|
2024-03-25 21:09:44 +00:00
|
|
|
print(f"Found sticker '{sticker['name']}'")
|
|
|
|
extension = STICKER_EXTENSIONS[sticker["format_type"]]
|
2024-03-27 18:25:41 +00:00
|
|
|
if extension == "json":
|
|
|
|
# Lottie is weird for some reason
|
|
|
|
url = f"https://discord.com/stickers/{sticker['id']}.json"
|
|
|
|
else:
|
|
|
|
url = f"https://media.discordapp.net/stickers/{sticker['id']}.{extension}?size=4096"
|
2024-03-25 21:09:44 +00:00
|
|
|
# Set passthrough=false for APNGs if you don't want animated
|
2024-03-27 18:25:41 +00:00
|
|
|
|
|
|
|
filename = sticker_dir / f"{safe_name(sticker['name'])}.{extension}"
|
2024-03-25 21:09:44 +00:00
|
|
|
print(f"Downloading {url} to {filename}")
|
|
|
|
download_file(url, filename)
|
|
|
|
|
2024-03-27 18:25:41 +00:00
|
|
|
for emoji in emoji_objs:
|
2024-03-25 21:09:44 +00:00
|
|
|
print(f"Found emoji '{emoji['name']}'")
|
|
|
|
extension = "gif" if emoji["animated"] else "png"
|
|
|
|
url = f"https://cdn.discordapp.com/emojis/{emoji['id']}.{extension}"
|
2024-03-27 18:25:41 +00:00
|
|
|
filename = emoji_dir / f"{safe_name(emoji['name'])}.{extension}"
|
2024-03-25 21:09:44 +00:00
|
|
|
print(f"Downloading {url} to {filename}")
|
|
|
|
download_file(url, filename)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main(*sys.argv)
|