#!/usr/bin/env python3 """Fix broken cover URLs by prepending the Audiobookshelf server URL""" import asyncio import sqlite3 from app.database import async_session from app.models import Book, User from sqlalchemy import select, update async def fix_cover_urls(): """Update all book cover URLs to be full URLs""" async with async_session() as db: # Get all users result = await db.execute(select(User)) users = result.scalars().all() if not users: print("No users found") return # For each user, get their ABS URL # Since books are shared, we'll use the first admin user's URL admin_user = next((u for u in users if u.is_admin), users[0]) abs_url = admin_user.abs_url.rstrip('/') print(f"Using Audiobookshelf URL: {abs_url}") # Get all books with relative cover URLs result = await db.execute( select(Book).where( Book.cover_url.isnot(None), Book.cover_url != '' ) ) books = result.scalars().all() fixed_count = 0 for book in books: if book.cover_url and not book.cover_url.startswith('http'): # This is a relative URL, fix it old_url = book.cover_url book.cover_url = f"{abs_url}{old_url}" print(f"Fixed: {book.title[:50]}") print(f" Old: {old_url}") print(f" New: {book.cover_url}") print() fixed_count += 1 await db.commit() print(f"\nFixed {fixed_count} cover URLs") if __name__ == "__main__": print("Fixing book cover URLs...") print("-" * 60) asyncio.run(fix_cover_urls())