import json import re import sqlite3 import argparse from pathlib import Path def load_genre(conn, unique=False): """ Return all genres from the books table. Args: conn: sqlite3 connection unique: if True, return unique genres only Returns: list[str] """ genres = [] for (genres_json,) in conn.execute("SELECT genres FROM books"): if not genres_json: continue try: genres.extend(json.loads(genres_json)) except Exception: pass if unique: return sorted(set(genres)) return genres def main(): parser = argparse.ArgumentParser() parser.add_argument( "database", type=Path, help="SQL Database Path", ) args = parser.parse_args() database = args.database.resolve() if not database.is_file(): parser.error(f"Database is not a file: {database}") db = sqlite3.connect(database) cur = db.cursor() list_genres = load_genre(cur,True) for genre in list_genres: print(genre) for book_id, genres_json in cur.execute("SELECT id, genres FROM books"): if not genres_json: continue genres = json.loads(genres_json) new_genres = [] for genre in genres: genre = re.sub(r'(?i)^audio\s*books?$', '', genre) genre = re.sub(r'(?i)^audiobooks?$', '', genre) genre = re.sub(r'(?i)^hörb(uch|ücher)$', '', genre) genre = re.sub(r'(?i)^hörspiele?$', '', genre) genre = re.sub(r'(?i)^spoken\s*word$', '', genre) genre = re.sub(r'(?i)^speech$', '', genre) genre = re.sub(r'(?i)^(sci[- ]?fi|sf)$', 'Science Fiction', genre) genre = re.sub(r'(?i)^nonfiction$', 'NonFiction', genre) genre = genre.strip() if genre: new_genres.append(genre) new_genres = sorted(set(new_genres)) cur.execute( "UPDATE books SET genres=? WHERE id=?", (json.dumps(new_genres), book_id), ) db.commit() if __name__ == "__main__": main()