#!/usr/bin/env python3 """ Bulk-Cleanup von 'ÖAMTC'/'OEAMTC'/'Christophorus N' in user-sichtbaren Files. Strategie: 1) ' (ÖAMTC)' / ' (OEAMTC)' Suffix wird gestripped (z.B. 'C8 Nenzing (ÖAMTC)' -> 'C8 Nenzing') 2) 'ÖAMTC Christophorus N' / 'OEAMTC Christophorus N' -> ' ' 3) 'Christophorus N' / 'Christophorus ' -> ' ' 4) Klammer-Annotation '(ÖAMTC)' / '(OEAMTC)' allein -> '' 5) Restliches alleinstehendes 'ÖAMTC' / 'OEAMTC' -> 'Notarzt-Heli' (Legende) Schreibt .bak-pre-christo-bulk fuer jede beruehrte Datei. """ import json, re, os, sys REPO = 'C:/xampp/htdocs/geograsim/App' CS_FILE = REPO + '/sims/heli/data/heli-callsigns.json' cs = json.load(open(CS_FILE, encoding='utf-8')) mapping = cs['mapping'] zah2hel = {k: v for k, v in cs['_zahl_zu_helikey'].items() if not k.startswith('_')} # Fallback Stationsdaten fuer Helis die NICHT im Pool sind (C15 Ybbsitz, C17 Vomp) EXTRA = { '13': ('Wiener Neustadt', 'OE-XAU'), # Polizei nominally '15': ('Ybbsitz', 'OE-XSA'), '17': ('Vomp', 'OE-XAB'), } def normalize(s): return s.lower().replace('ä','ae').replace('ö','oe').replace('ü','ue').replace('ß','ss') def by_digit(n): h = 'c' + str(n) if h in mapping: return f"{mapping[h]['station']} {mapping[h]['callsign']}" if str(n) in EXTRA: st, cs_ = EXTRA[str(n)] return f"{st} {cs_}" return f"C{n}" # generischer Fallback def by_word(w): w_n = normalize(w) if w_n in zah2hel: h = zah2hel[w_n] if h in mapping: return f"{mapping[h]['station']} {mapping[h]['callsign']}" return None def clean(text): n = 0 # Step 1: ' (ÖAMTC)' / ' (OEAMTC)' suffix def repl1(m): nonlocal n; n += 1; return '' text = re.sub(r' \((?:ÖAMTC|OEAMTC)\)', repl1, text) # Step 2: 'ÖAMTC Christophorus N' / 'OEAMTC Christophorus N' def repl2(m): nonlocal n r = by_digit(m.group(1)) if r: n += 1; return r return m.group(0) text = re.sub(r'(?:ÖAMTC|OEAMTC)\s+Christophorus\s+(\d+)', repl2, text) # Step 3a: 'Christophorus N' (digit) def repl3a(m): nonlocal n r = by_digit(m.group(1)) if r: n += 1; return r return m.group(0) text = re.sub(r'Christophorus\s+(\d+)', repl3a, text) # Step 3b: 'Christophorus ' def repl3b(m): nonlocal n r = by_word(m.group(1)) if r: n += 1; return r return m.group(0) text = re.sub(r'Christophorus\s+([A-Za-zÄÖÜäöüß]+)', repl3b, text) # Step 4: '(ÖAMTC)' allein (ohne fuehrendes Space) def repl4(m): nonlocal n; n += 1; return '' text = re.sub(r'\((?:ÖAMTC|OEAMTC)\)', repl4, text) # Step 5: 'ÖAMTC Christophorus' OHNE Zahl/Wort (vor ' raus) def repl5a(m): nonlocal n; n += 1; return 'Notarzt-Heli' text = re.sub(r'(?:ÖAMTC|OEAMTC)\s+Christophorus(?=\W|$)', repl5a, text) # Step 5b: einsamer 'Christophorus' (Restposten) def repl5b(m): nonlocal n; n += 1; return 'Notarzt-Heli' text = re.sub(r'\bChristophorus\b', repl5b, text) # Step 6: alleinstehendes 'ÖAMTC' (Legende, Label) -> 'Notarzt-Heli' def repl6(m): nonlocal n; n += 1; return 'Notarzt-Heli' text = re.sub(r'\b(?:ÖAMTC|OEAMTC)\b', repl6, text) # Zwei aufeinanderfolgende Spaces vermeiden text = re.sub(r' +', ' ', text) return text, n TARGETS = [ '/sims/heli/waypoints.js', '/sims/heli/start.html', '/sims/heli/landing.html', '/sims/heli/audio-matrix.html', '/sims/heli/audio-overview.html', '/heli.html', '/pages/heli-uebersicht.php', '/sims/heli/scripts/mission-start-lines.json', '/sims/heli/scripts/mission-geo-lines.json', '/sims/heli/scripts/tower-lines.json', '/sims/heli/scripts/tower-geo-lines.json', '/sims/heli/scripts/tower-sea-lines.json', '/sims/heli/scripts/tower-start-lines.json', '/sims/heli/scripts/tower-heliintro-lines.json', '/sims/heli/scripts/wp-geo-lines.json', '/sims/heli/routes.html', '/sims/heli/game.html', ] total = 0 for f in TARGETS: path = REPO + f if not os.path.exists(path): print(f' SKIP {f}') continue txt = open(path, encoding='utf-8').read() bak = path + '.bak-pre-christo-bulk' if not os.path.exists(bak): with open(bak, 'w', encoding='utf-8') as g: g.write(txt) new, n = clean(txt) if n > 0: with open(path, 'w', encoding='utf-8') as g: g.write(new) print(f' OK {f}: {n} Ersetzungen') total += n else: print(f' -- {f}: nichts zu tun') print(f'\nGesamt: {total} Ersetzungen ueber {len(TARGETS)} Dateien')