search and replace
This commit is contained in:
parent
a804643d74
commit
ddfa0f920b
78
analytics.py
78
analytics.py
@ -5,6 +5,7 @@ import geoip2.database
|
|||||||
from auth import require_secret
|
from auth import require_secret
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
from typing import Optional, List, Tuple
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import auth
|
import auth
|
||||||
@ -701,9 +702,76 @@ def export_to_excel():
|
|||||||
# Close the cursor and database connection
|
# Close the cursor and database connection
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
|
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).
|
||||||
|
"""
|
||||||
|
|
||||||
|
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__":
|
if __name__ == "__main__":
|
||||||
print("Running as a standalone script.")
|
# Example usage: dry run first
|
||||||
export_to_excel()
|
search_and_replace_rel_path(
|
||||||
print("Exported search_db to search_db.xlsx")
|
search="2025-06-13 Freitag 16 Uhr",
|
||||||
|
replacement="2025-06-13 Eröffnungsgottesdienst Freitag 16 Uhr",
|
||||||
|
dry_run=True
|
||||||
|
)
|
||||||
Loading…
x
Reference in New Issue
Block a user