twist.py 2.23 KB
import requests
import base64
from hashlib import md5
from Crypto.Cipher import AES


# If changed, check javascript for "x-access-token"
ACCESS_TOKEN = "1rj2vRtegS8Y60B3w3qNZm5T2Q0TN2NR"
# If changed, check javascript for "name: "floating-player""
SOURCE_KEY = 'k8B$B@0L8D$tDYHGmRg98sQ7!%GOEGOX27T'


def get_anime_list():
    resp = requests.get("https://twist.moe/api/anime",
                        headers={"x-access-token": ACCESS_TOKEN})

    anime_list = {}
    for anime in resp.json():
        slug = anime["slug"]["slug"]
        anime_list[slug] = {"id": anime["id"],
                            "title": anime["title"],
                            "alt_title": anime["alt_title"],
                            "created_at": anime["created_at"]}

    return anime_list


def get_anime(slug):
    resp = requests.get("https://twist.moe/api/anime/{}".format(slug),
                        headers={"x-access-token": ACCESS_TOKEN})

    return resp.json()


def get_anime_sources(slug, raw=False):
    url = "https://twist.moe/api/anime/{}/sources".format(slug)
    resp = requests.get(url,
                        headers={"x-access-token": ACCESS_TOKEN})
    respj = resp.json()

    # Let's hope that they're sorted lol
    sources = [decode_source_url(entry["source"], raw) for entry in respj]
    return sources


def derive_key_and_iv(password, salt, key_length, iv_length):
    d = d_i = b''
    while len(d) < key_length + iv_length:
        d_i = md5(d_i + str.encode(password) + salt).digest()
        d += d_i
    return d[:key_length], d[key_length:key_length + iv_length]


def decode_source_url(encrypted_url, raw=False):
    ciphertext = base64.b64decode(encrypted_url)
    salt = ciphertext[8:16]
    KEY, IV = derive_key_and_iv(SOURCE_KEY, salt, 32, 16)
    aes = AES.new(KEY, AES.MODE_CBC, IV)
    dec = aes.decrypt(ciphertext[16:])

    if raw:
        return dec.decode()

    # this is the hackiest shit ever I ever wrote in my whole fucking life
    # Without this it gets appended with \r \x03 \x01 etc etc
    # xd
    decsplit = dec.decode().split('.')

    decsplit = decsplit[-2] + "." + decsplit[-1][0:3]

    # Drop anything before /, fixing issues with some anime
    url = "https://twist.moe" + decsplit[decsplit.index("/"):]
    return url