Explorer
/tmp/modify_aa045_p2.py
← Zurück ↓ Download
from pathlib import Path

# Central persistence normalization.
p = Path('/opt/struktur/social-media-radar/aa045_enrich.py')
s = p.read_text()
s = s.replace('from datetime import datetime, timezone\n', 'from datetime import datetime, timezone\n\nfrom published_at_normalizer import normalize_published_at\n')
s = s.replace('    now = datetime.now(timezone.utc).isoformat()\n    conn.execute("""', '    now = datetime.now(timezone.utc).isoformat()\n    observed_at = data.get("observed_at", "") or now\n    conn.execute("""', 1)
s = s.replace('        data.get("observed_at", "") or now,\n        data.get("published_at", "") or "",\n', '        observed_at,\n        normalize_published_at(data.get("published_at"), observed_at),\n', 1)
p.write_text(s)

# YouTube: preserve raw source wording until central normalizer, and use actual observed_at.
p = Path('/opt/struktur/social-media-radar/intake/multi_intake.py')
s = p.read_text()
s = s.replace('    expires = (datetime.now(timezone.utc) + timedelta(hours=_DECAY_H)).isoformat()\n', '    observed_at = datetime.now(timezone.utc).isoformat()\n    expires = (datetime.now(timezone.utc) + timedelta(hours=_DECAY_H)).isoformat()\n', 1)
s = s.replace('        "published_at": (pub_iso if "T" in pub_iso else _parse_relative_time_german(pub_iso)),\n', '        "observed_at":       observed_at,\n        "published_at":      (pub_iso or None),\n', 1)
p.write_text(s)

# Robust SQLite datetime semantics and explicit deep-link highlight loading.
p = Path('/opt/struktur/social-media-agent/app.py')
s = p.read_text()
s = s.replace('def get_radar_signals(limit=12, days=3, sort="relevance",\n                      status_filter=None, competition_only=False, pinned_only=False):', 'def get_radar_signals(limit=12, days=3, sort="relevance",\n                      status_filter=None, competition_only=False, pinned_only=False,\n                      highlight_id=None):', 1)
s = s.replace('        sql = (\n', '        if highlight_id:\n            date_clause = "AND signal_id = ?"\n            date_params = [highlight_id]\n            st_clause = ""\n            st_params = []\n            comp_clause = ""\n        else:\n            date_clause = "AND datetime(published_at) IS NOT NULL AND datetime(published_at) >= datetime(?)"\n            date_params = [cutoff]\n\n        sql = (\n', 1)
s = s.replace('            " AND (published_at GLOB \'[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T%\' AND published_at >= ?)"\n', '            " " + date_clause\n', 1)
s = s.replace('        params = [cutoff] + st_params + [limit]\n', '        params = date_params + st_params + [limit]\n', 1)
s = s.replace('    tab           = request.args.get("tab", "radar")\n\n    signals     = get_radar_signals(limit=20, days=days, sort=sort,\n                                    status_filter=status_filter)\n', '    tab           = request.args.get("tab", "radar")\n    highlight     = request.args.get("highlight", "").strip()\n\n    signals     = get_radar_signals(limit=20, days=days, sort=sort,\n                                    status_filter=status_filter,\n                                    highlight_id=highlight or None)\n', 1)
s = s.replace('                           tab=tab,\n                           version=cockpit_version)', '                           tab=tab,\n                           highlight=highlight,\n                           version=cockpit_version)', 1)
p.write_text(s)

# Rendered Cockpit deep-link: select the highlighted signal in the right detail panel.
p = Path('/opt/struktur/social-media-agent/templates/cockpit.html')
s = p.read_text()
s = s.replace('window._S = {};\n', 'window._S = {};\nconst HIGHLIGHT = {{(highlight or "")|tojson}};\n', 1)
marker = "function closePanel() {\n"
# Insert auto-selection immediately before panel functions so sel is defined by execution time.
needle = "// ═══ Panel ═══════════════════════════════════════════════════════════════\nlet _cur = null;\n"
replacement = "// ═══ Panel ═══════════════════════════════════════════════════════════════\nlet _cur = null;\n"
s = s.replace(needle, replacement, 1)
# Append after sel() definition, before panel builder.
needle = "}\n\n// ═══ Panel Builder ════════════════════════════════════════════════════════\n"
replacement = "}\n\nif (HIGHLIGHT && window._S[HIGHLIGHT]) {\n  window.addEventListener('DOMContentLoaded', function() { sel(HIGHLIGHT); });\n}\n\n// ═══ Panel Builder ════════════════════════════════════════════════════════\n"
s = s.replace(needle, replacement, 1)
p.write_text(s)