Skip to content

Commit 72a97a4

Browse files
committed
- fixing global functions conflict detection
- fixing invalid chareacter set - conflict detection against self._list instead of kbkey - a bit of refactoring
1 parent e9810d1 commit 72a97a4

File tree

9 files changed

+187
-139
lines changed

9 files changed

+187
-139
lines changed

devel/get_shortcuts_and_classes.py

+97-45
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
import ast
44
import re
55
import json
6+
import argparse
7+
import subprocess
8+
import sys
9+
import threading
10+
11+
# Argument parser for command line options
12+
parser = argparse.ArgumentParser(description="Analyze Python project for classes and keyboard shortcuts.")
13+
parser.add_argument("-v", "--verbose", action="store_true", help="Display all messages")
14+
args = parser.parse_args()
15+
16+
def verbose_print(message):
17+
"""Prints messages only if verbose mode is enabled."""
18+
if args.verbose:
19+
print(message)
620

721
def find_keypress_functions_with_kbkeys(project_path):
822
result = {}
@@ -121,16 +135,16 @@ def find_class_inheritance(classes):
121135
cls["inherits_from"] = None
122136

123137
def display_classes(classes):
124-
print("\nClasses Found in Files:")
138+
verbose_print("\nClasses Found in Files:")
125139
for entry in classes:
126-
print(f"File: {os.path.basename(entry['file'])}, Class: {entry['class_name']}, "
140+
verbose_print(f"File: {os.path.basename(entry['file'])}, Class: {entry['class_name']}, "
127141
f"Start Line: {entry['start_line']}, End Line: {entry['end_line']}, "
128142
f"Uses: {entry['uses']}, Inherits from: {entry['inherits_from']}")
129143

130144
def display_results(results):
131-
print("\n\nFound keypress functions with kbkey references:")
145+
verbose_print("\n\nFound keypress functions with kbkey references:")
132146
for class_name, kbkeys in results.items():
133-
print(f"Class: {class_name}, kbkey References: {kbkeys}")
147+
verbose_print(f"Class: {class_name}, kbkey References: {kbkeys}")
134148

135149
def map_functional_relationships(results, classes):
136150
"""Map functional relationships of classes with keypress shortcuts."""
@@ -180,24 +194,25 @@ def functional_structural_integration(results, classes):
180194
return integration_map
181195

182196
def display_functional_relationships(map_data):
183-
print("\nFunctional Relationships:")
184-
for entry in map_data:
185-
print(f"Class: {entry['class_name']}, Inherits From: {entry['inherits_from']}, "
186-
f"Uses: {entry['uses']}, Keypress Shortcuts: {entry['kbkeys']}")
197+
if args.verbose:
198+
verbose_print("\nFunctional Relationships:")
199+
for entry in map_data:
200+
verbose_print(f"Class: {entry['class_name']}, Inherits From: {entry['inherits_from']}, "
201+
f"Uses: {entry['uses']}, Keypress Shortcuts: {entry['kbkeys']}")
187202

188203
def display_dependencies(map_data):
189-
print("\nDependencies Analysis:")
190-
for entry in map_data:
191-
print(f"Class: {entry['class_name']}, Depends On: {entry['dependencies']}, "
192-
f"Own Keypress Shortcuts: {entry['kbkeys']}")
204+
if args.verbose:
205+
verbose_print("\nDependencies Analysis:")
206+
for entry in map_data:
207+
verbose_print(f"Class: {entry['class_name']}, Depends On: {entry['dependencies']}, "
208+
f"Own Keypress Shortcuts: {entry['kbkeys']}")
193209

194210
def display_integration(integration_map):
195-
print("\nFunctional-Structural Integration:")
196-
for cls, data in integration_map.items():
197-
print(f"Class: {cls}, Keypress Shortcuts: {data['kbkeys']}, "
198-
f"Related Classes: {data['related_classes']}")
199-
200-
211+
if args.verbose:
212+
verbose_print("\nFunctional-Structural Integration:")
213+
for cls, data in integration_map.items():
214+
verbose_print(f"Class: {cls}, Keypress Shortcuts: {data['kbkeys']}, "
215+
f"Related Classes: {data['related_classes']}")
201216

202217
def extend_results_with_related_keys(results, classes):
203218
"""Extend results by appending keys from used and inherited classes."""
@@ -225,16 +240,16 @@ def extend_results_with_related_keys(results, classes):
225240
return extended_results
226241

227242
def display_extended_results(extended_results):
228-
print("\nExtended Results with Related Keys:")
229-
for class_name, keys in extended_results.items():
230-
print(f"Class: {class_name}, Keypress Shortcuts: {keys}")
243+
if args.verbose:
244+
verbose_print("\nExtended Results with Related Keys:")
245+
for class_name, keys in extended_results.items():
246+
verbose_print(f"Class: {class_name}, Keypress Shortcuts: {keys}")
231247

232248
def extract_global_functions_keys(file_path):
233249
"""Extract keys from `_global_functions` in the specified Python file."""
234250
global_functions_keys = []
235251
inside_global_functions = False
236252
inside_local_functions = False
237-
global_functions_keys = []
238253
local_functions_keys = []
239254
file_name = os.path.join(file_path, 'radio.py')
240255

@@ -325,17 +340,49 @@ def precompute_context_map(results):
325340
context_map[key].append(class_name)
326341
return context_map
327342

343+
def ask_and_execute():
344+
print("Do you want to execute './pyradio/keyboard.py'? (y/n, ENTER = 'y'): ", end='', flush=True)
345+
346+
# Variable to store user's answer
347+
user_answer = None
348+
input_event = threading.Event()
349+
350+
def get_user_input():
351+
nonlocal user_answer
352+
user_answer = input().strip().lower()
353+
input_event.set() # Signal that input was received
354+
355+
# Start a thread to get the user input
356+
input_thread = threading.Thread(target=get_user_input)
357+
input_thread.daemon = True
358+
input_thread.start()
359+
360+
# Wait for input or timeout
361+
if input_event.wait(timeout=5): # Wait up to 5 seconds for input
362+
if user_answer == '' or user_answer == 'y': # Treat ENTER or 'y' as confirmation
363+
try:
364+
# Execute the script
365+
subprocess.run(["python", "./pyradio/keyboard.py"], check=True)
366+
except subprocess.CalledProcessError as e:
367+
print(f"Error executing script: {e}")
368+
except FileNotFoundError:
369+
print("File './pyradio/keyboard.py' not found.")
370+
else:
371+
print("You entered 'n'. Exiting...")
372+
else:
373+
print("\nTimeout occurred. Exiting...")
374+
328375
if __name__ == "__main__":
329376
from sys import exit
330377
# Updated project path
331378
starting_dir = os.getcwd()
332-
print(f'{starting_dir = }')
379+
verbose_print(f'{starting_dir = }')
333380
project_path = os.path.join(starting_dir, 'pyradio')
334-
print(f'{project_path = }')
381+
verbose_print(f'{project_path = }')
335382
out_file = os.path.join(project_path, 'keyboard', 'classes.json')
336383
new_out_file = os.path.join(project_path, 'keyboard', 'keys.json')
337-
print(f'{out_file = }')
338-
print(f'{new_out_file = }')
384+
verbose_print(f'{out_file = }')
385+
verbose_print(f'{new_out_file = }')
339386

340387
# Find and display keypress functions with kbkeys
341388
results = find_keypress_functions_with_kbkeys(project_path)
@@ -346,9 +393,9 @@ def precompute_context_map(results):
346393
find_class_usages(classes)
347394
find_class_inheritance(classes)
348395
global_functions_keys, local_functions_keys = extract_global_functions_keys(project_path)
349-
results['PyRadio'] += local_functions_keys
396+
results['PyRadio'].extend(local_functions_keys)
350397
'''
351-
print(results)
398+
verbose_print(results)
352399
for a_class in results:
353400
results[a_class] += global_functions_keys
354401
'''
@@ -378,13 +425,13 @@ def precompute_context_map(results):
378425

379426
# Extract h_extra keys from keyboard.py
380427
h_extra_keys = extract_section_keys(project_path, 'h_extra')
381-
print("\nExtracted h_extra keys:")
428+
verbose_print("\nExtracted h_extra keys:")
382429
for key in sorted(h_extra_keys):
383-
print(f" - {key}")
430+
verbose_print(f" - {key}")
384431

385432
# Remove h_extra keys from results
386433
remove_section_keys_from_results(results, h_extra_keys)
387-
print("\nUpdated results after removing h_extra keys:")
434+
verbose_print("\nUpdated results after removing h_extra keys:")
388435
display_results(results)
389436

390437
# these three keys are added by code, they are not detected
@@ -396,12 +443,8 @@ def precompute_context_map(results):
396443
# info_rename is a uniq key in the info window
397444
results['PyRadio'].pop(results['PyRadio'].index('info_rename'))
398445
results['InfoWindow'] = ['info_rename']
399-
400-
results['GlobalFunctions'] = global_functions_keys + ['t']
401-
results['ExtraKeys'] = list(h_extra_keys)
402-
print("\n\nFinal results after removing h_extra keys:")
403-
display_results(results)
404446

447+
'''
405448
# remove global function keys
406449
for gl_key in global_functions_keys:
407450
for a_key in results:
@@ -411,25 +454,34 @@ def precompute_context_map(results):
411454
break
412455
except ValueError:
413456
pass
414-
457+
# results[a_key].extend(global_functions_keys)
458+
'''
459+
for a_key in results:
460+
results[a_key].extend(global_functions_keys)
461+
results['ExtraKeys'] = list(h_extra_keys)
462+
463+
verbose_print("\n\nFinal results after removing h_extra keys:")
464+
display_results(results)
465+
415466
with open(out_file, 'w', encoding='utf-8') as f:
416467
json.dump(results, f)
417468

418-
419469
precompute_map = precompute_context_map(results)
420470

421471
with open(new_out_file, 'w', encoding='utf-8') as f:
422472
json.dump(precompute_map, f)
423-
# print('\n\n{}'.format(global_functions_keys))
424-
425-
# print('\n\n{}'.format(h_extra_keys))
473+
474+
# verbose_print('\n\n{}'.format(global_functions_keys))
475+
# verbose_print('\n\n{}'.format(h_extra_keys))
426476

427477
print('''
428-
429478
Files created:
430-
classes.json
431-
keys.json
479+
- classes.json
480+
- keys.json
432481
Execute
433-
python keyboard.py
482+
- python keyboard.py
434483
to check for missing shortcuts
435484
''')
485+
486+
ask_and_execute()
487+
sys.exit()

pyradio/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,7 @@ def find_history_by_station_title(self, a_title):
12701270
class PyRadioConfig(PyRadioStations):
12711271
''' PyRadio Config Class '''
12721272

1273-
DO_NOT_PLAY_OPTS = None
1273+
EXTERNAL_PLAYER_OPTS = None
12741274

12751275
''' I will get this when a player is selected
12761276
It will be used when command line parameters are evaluated

0 commit comments

Comments
 (0)