Files
DAO3/ao3.py

64 lines
1.9 KiB
Python
Raw Permalink Normal View History

2026-09-04 18:15:22 +01:00
import os
import re
import sys
import argparse
from pathlib import Path
import AO3
from dotenv import load_dotenv
load_dotenv()
def sanitize_filename(name: str) -> str:
"""Remove characters that are invalid in filenames."""
return re.sub(r'[\\/*?:"<>|]', "", name).strip()
def get_session() -> AO3.Session | None:
username = os.getenv("AO3_USERNAME")
password = os.getenv("AO3_PASSWORD")
if not username or not password:
print("No AO3_USERNAME/AO3_PASSWORD found in .env — proceeding without login.")
return None
try:
session = AO3.Session(username, password)
print(f"Logged in as {username}")
return session
except Exception as e:
print(f"Login failed: {e}")
return None
def download_work(workid: int, filetype: str = "EPUB", output_dir: str = ".", session=None):
work = AO3.Work(workid, session=session)
print(f"Title: {work.title}")
print(f"Author(s): {', '.join(a.username for a in work.authors)}")
print(f"Summary:\n{work.summary}\n")
out_path = Path(output_dir)
out_path.mkdir(parents=True, exist_ok=True)
filename = out_path / f"{sanitize_filename(work.title)}.{filetype.lower()}"
with open(filename, "wb") as file:
file.write(work.download(filetype))
print(f"Downloaded: {filename}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Download an AO3 work.")
parser.add_argument("workid", type=int, nargs="?", help="AO3 work ID")
parser.add_argument("-t", "--type", default="EPUB", help="File type (EPUB, PDF, MOBI, HTML, AZW3)")
parser.add_argument("-o", "--output", default=os.getenv("AO3_OUTPUT_DIR", "."), help="Output directory")
args = parser.parse_args()
workid = args.workid or int(input("Enter AO3 work ID: "))
session = get_session()
print(session)
download_work(workid, filetype=args.type, output_dir=args.output, session=session)