diff --git a/.gitignore b/.gitignore index 68bc17f..10189be 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,10 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +# User config +vATISLoadUserConfig.json + +# LLM stuff +.claude/ +CLAUDE.md diff --git a/vATISLoad.ipynb b/vATISLoad.ipynb index 24aa2b6..ae67ba9 100644 --- a/vATISLoad.ipynb +++ b/vATISLoad.ipynb @@ -273,7 +273,49 @@ " replacements[a] = config['replacements'][a]\n", "\n", " return replacements\n", - " \n", + "\n", + "def get_user_config():\n", + " config = {}\n", + " config_path = os.path.join(os.path.dirname(sys.argv[0]), 'vATISLoadUserConfig.json')\n", + " try:\n", + " with open(config_path, 'r') as f:\n", + " config = json.load(f)\n", + " except Exception as ignored:\n", + " pass\n", + " return config\n", + "\n", + "def apply_user_modifications(airport, conditions, notams, user_config):\n", + " if airport not in user_config:\n", + " return conditions, notams\n", + "\n", + " cfg = user_config[airport]\n", + "\n", + " # Apply conditions modifications\n", + " if 'conditions' in cfg:\n", + " for text in cfg['conditions'].get('remove', []):\n", + " conditions = conditions.replace(text, '')\n", + " append_text = cfg['conditions'].get('append', '')\n", + " if append_text:\n", + " if conditions and not conditions.endswith(' '):\n", + " conditions += ' '\n", + " conditions += append_text\n", + "\n", + " # Apply notams modifications\n", + " if 'notams' in cfg:\n", + " for text in cfg['notams'].get('remove', []):\n", + " notams = notams.replace(text, '')\n", + " append_text = cfg['notams'].get('append', '')\n", + " if append_text:\n", + " if notams and not notams.endswith(' '):\n", + " notams += ' '\n", + " notams += append_text\n", + "\n", + " # Clean up extra spaces\n", + " conditions = re.sub(r'\\s+', ' ', conditions).strip()\n", + " notams = re.sub(r'\\s+', ' ', notams).strip()\n", + "\n", + " return conditions, notams\n", + "\n", "async def get_contractions(station):\n", " try:\n", " async with websockets.connect('ws://127.0.0.1:49082/', close_timeout=0.01) as websocket:\n", @@ -409,6 +451,7 @@ " stations = await get_datis_stations(initial=initial)\n", " replacements = get_atis_replacements(stations)\n", " atis_data = get_datis_data()\n", + " user_config = get_user_config()\n", "\n", " atis_statuses = await get_atis_statuses()\n", "\n", @@ -429,6 +472,8 @@ " \n", " v = {'id': i, 'preset': 'D-ATIS', 'syncAtisLetter': True}\n", " v['airportConditionsFreeText'], v['notamsFreeText'] = await get_datis(s, atis_data, rep)\n", + " v['airportConditionsFreeText'], v['notamsFreeText'] = apply_user_modifications(\n", + " s[0:4], v['airportConditionsFreeText'], v['notamsFreeText'], user_config)\n", "\n", " if connected_only and v['airportConditionsFreeText'] == 'D-ATIS NOT AVBL.':\n", " continue\n", diff --git a/vATISLoad.pyw b/vATISLoad.pyw index cec4558..7af478d 100644 --- a/vATISLoad.pyw +++ b/vATISLoad.pyw @@ -256,7 +256,49 @@ def get_atis_replacements(stations): replacements[a] = config['replacements'][a] return replacements - + +def get_user_config(): + config = {} + config_path = os.path.join(os.path.dirname(sys.argv[0]), 'vATISLoadUserConfig.json') + try: + with open(config_path, 'r') as f: + config = json.load(f) + except Exception as ignored: + pass + return config + +def apply_user_modifications(airport, conditions, notams, user_config): + if airport not in user_config: + return conditions, notams + + cfg = user_config[airport] + + # Apply conditions modifications + if 'conditions' in cfg: + for text in cfg['conditions'].get('remove', []): + conditions = conditions.replace(text, '') + append_text = cfg['conditions'].get('append', '') + if append_text: + if conditions and not conditions.endswith(' '): + conditions += ' ' + conditions += append_text + + # Apply notams modifications + if 'notams' in cfg: + for text in cfg['notams'].get('remove', []): + notams = notams.replace(text, '') + append_text = cfg['notams'].get('append', '') + if append_text: + if notams and not notams.endswith(' '): + notams += ' ' + notams += append_text + + # Clean up extra spaces + conditions = re.sub(r'\s+', ' ', conditions).strip() + notams = re.sub(r'\s+', ' ', notams).strip() + + return conditions, notams + async def get_contractions(station): try: async with websockets.connect('ws://127.0.0.1:49082/', close_timeout=0.01) as websocket: @@ -392,6 +434,7 @@ async def configure_atises(connected_only=False, initial=False, temp_rep={}): stations = await get_datis_stations(initial=initial) replacements = get_atis_replacements(stations) atis_data = get_datis_data() + user_config = get_user_config() atis_statuses = await get_atis_statuses() @@ -412,6 +455,8 @@ async def configure_atises(connected_only=False, initial=False, temp_rep={}): v = {'id': i, 'preset': 'D-ATIS', 'syncAtisLetter': True} v['airportConditionsFreeText'], v['notamsFreeText'] = await get_datis(s, atis_data, rep) + v['airportConditionsFreeText'], v['notamsFreeText'] = apply_user_modifications( + s[0:4], v['airportConditionsFreeText'], v['notamsFreeText'], user_config) if connected_only and v['airportConditionsFreeText'] == 'D-ATIS NOT AVBL.': continue @@ -483,19 +528,19 @@ async def connect_atises(airport_override=None): def kill_open_instances(): prev_instances = {} + skip_pids = {os.getpid(), os.getppid()} for q in psutil.process_iter(): + if q.pid in skip_pids: + continue if 'python' in q.name(): for parameter in q.cmdline(): if 'vATISLoad' in parameter and parameter.endswith('.pyw'): q_create_time = q.create_time() q_create_datetime = datetime.fromtimestamp(q_create_time) prev_instances[q.pid] = {'process': q, 'start': q_create_datetime} - - prev_instances = dict(sorted(prev_instances.items(), key=lambda item: item[1]['start'])) - - for i in range(0, len(prev_instances) - 1): - k = list(prev_instances.keys())[i] + + for k in prev_instances: prev_instances[k]['process'].terminate() def open_vATIS():