Chris Pomeroy
2026-01-17 ee9deff6fecf1354ea3e529dda3b7b850a81050f
getMissingFromAudible.py
@@ -5,6 +5,7 @@
import audible
import json
import time
import os
from audible.aescipher import decrypt_voucher_from_licenserequest
from audible.activation_bytes import (
    extract_activation_bytes,
@@ -22,6 +23,22 @@
_metadata = {}
def get_auth_files():
    '''
    Gets the auth files for audible and activation bytes
    Returns:
        audible auth, activation bytes
    '''
    with open('./audible_auth_', 'r') as f:
        auth_data = json.load(f)
    audible_auth = audible.Authenticator.from_dict(auth_data)
    act_bytes = fetch_activation_sign_auth(auth=audible_auth)
    act_bytes = extract_activation_bytes(act_bytes)
    return audible_auth, act_bytes
def get_args():
    '''
    Parses the args for runtime
@@ -130,6 +147,9 @@
    Ret:
        str: The url to download the file from
    '''
    # print(licenserequest)
    if 'Denied' in licenserequest{'content_license']['status'}:
        raise Exception("License request was denied. For ")
    return licenserequest['content_license']['content_metadata'][
        'content_url']['offline_url']
@@ -147,7 +167,7 @@
        f.write(dl.content)
def download_books(asin: str) -> None:
def download_book(asin: str) -> None:
    '''
    Download the book and hand it off to the converter
@@ -156,7 +176,10 @@
        asin (str):  The amazon number of the book being downloaded
    '''
    lr = get_license_request(asin)
    print(ab)
    # see if we already downloaded the file
    if os.path.exists(f"/tmp/{asin}.aax"):
        print(f"{asin} already downloaded, skipping download.")
    else:
    get_content(asin, get_content_url(lr))
    decrypted_voucher = decrypt_voucher_from_licenserequest(_audible_auth, lr)
    key_iv = {
@@ -167,13 +190,9 @@
    aaxConvert.convert_aax(f"/tmp/{asin}.aax", _actbytes, key_iv)
def main():
    args = get_args()
    asin_manual = args.asin
def list_missing_books():
    audible_books = get_audible_books()
    if asin_manual is not None:
        download_books(asin_manual)
    else:
    missing_books = []
        library_ids = get_library_ids()
        for id in library_ids:
            bookshelf_books = get_bookshelf_books(id)
@@ -181,8 +200,22 @@
                if book['content_type'] == 'Product':
                    search = search_local_books(book, bookshelf_books)
                    if search:
                        print(f"{book['title']}, {book['asin']}")
                        download_books(book['asin'])
                    missing_books.append(f"{book['title']}: {book['asin']}")
    return missing_books
def main():
    args = get_args()
    asin_manual = args.asin
    if asin_manual is not None:
        download_book(asin_manual)
    else:
        missing_books = list_missing_books()
        print(missing_books)
        answer = input("Would you like to download the missing books? (y/n)\n")
        if answer.lower() == 'y':
            for book in missing_books:
                download_book(book.split(": ")[1])
                        time.sleep(20)