diff --git a/analytics.py b/analytics.py index cbccb40..622bd0f 100644 --- a/analytics.py +++ b/analytics.py @@ -5,6 +5,7 @@ import geoip2.database from auth import require_secret from collections import defaultdict import pandas as pd +from typing import Optional, List, Tuple import json import os import auth @@ -701,9 +702,76 @@ def export_to_excel(): # Close the cursor and database connection cursor.close() -if __name__ == "__main__": - print("Running as a standalone script.") - export_to_excel() - print("Exported search_db to search_db.xlsx") +def search_and_replace_rel_path( + search: str, + replacement: str, + dry_run: bool = True, + limit_preview: int = 10 +) -> Optional[List[Tuple[str, str]]]: + """ + Find all rel_path values containing `search`. + In dry_run mode: + - show up to `limit_preview` example renames + - show total count + - prompt you to apply them (yes/no) + If you answer yes (or if dry_run=False), performs the UPDATE. + + Returns the list of (old_path, new_path) that were applied (or would be applied). + """ - \ No newline at end of file + cursor = log_db.cursor() + like_pattern = f'%{search}%' + + # 1) Fetch matching rows + cursor.execute( + "SELECT id, rel_path FROM file_access_log WHERE rel_path LIKE ?;", + (like_pattern,) + ) + rows = cursor.fetchall() # List of (id, old_path) + total = len(rows) + + if total == 0: + print("No matching rel_path entries found.") + return [] + + # Build all renames + renames = [(old, old.replace(search, replacement)) for (_id, old) in rows] + + # In dry_run: preview + if dry_run: + print(f"\nShowing up to {limit_preview} of {total} pending renames:\n") + for old, new in renames[:limit_preview]: + print(f" {old!r} → {new!r}") + if total > limit_preview: + print(f" ...and {total - limit_preview} more\n") + print(f"Total: {total} renaming action(s) would be applied.\n") + + ans = input("Apply these changes? (yes/no): ").strip().lower() + if ans in ('y', 'yes'): + # Switch to actual update + return search_and_replace_rel_path(search, replacement, dry_run=False) + else: + print("Aborted; no changes made.") + return renames + + # If not dry_run, apply the UPDATE once + cursor.execute( + """ + UPDATE file_access_log + SET rel_path = replace(rel_path, ?, ?) + WHERE rel_path LIKE ?; + """, + (search, replacement, like_pattern) + ) + log_db.commit() + updated = cursor.rowcount + print(f"Done: {updated} row(s) updated.") + return renames + +if __name__ == "__main__": + # Example usage: dry run first + search_and_replace_rel_path( + search="2025-06-13 Freitag 16 Uhr", + replacement="2025-06-13 Eröffnungsgottesdienst Freitag 16 Uhr", + dry_run=True + ) \ No newline at end of file