64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
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) |