playlist_manager.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import json
  2. import os
  3. import threading
  4. import logging
  5. from modules.core import pattern_manager
  6. from modules.core.state import state
  7. # Configure logging
  8. logger = logging.getLogger(__name__)
  9. # Global state
  10. PLAYLISTS_FILE = os.path.join(os.getcwd(), "playlists.json")
  11. # Ensure the file exists and contains at least an empty JSON object
  12. if not os.path.isfile(PLAYLISTS_FILE):
  13. logger.info(f"Creating new playlists file at {PLAYLISTS_FILE}")
  14. with open(PLAYLISTS_FILE, "w") as f:
  15. json.dump({}, f, indent=2)
  16. def load_playlists():
  17. """Load the entire playlists dictionary from the JSON file."""
  18. with open(PLAYLISTS_FILE, "r") as f:
  19. playlists = json.load(f)
  20. logger.debug(f"Loaded {len(playlists)} playlists")
  21. return playlists
  22. def save_playlists(playlists_dict):
  23. """Save the entire playlists dictionary back to the JSON file."""
  24. logger.debug(f"Saving {len(playlists_dict)} playlists to file")
  25. with open(PLAYLISTS_FILE, "w") as f:
  26. json.dump(playlists_dict, f, indent=2)
  27. def list_all_playlists():
  28. """Returns a list of all playlist names."""
  29. playlists_dict = load_playlists()
  30. playlist_names = list(playlists_dict.keys())
  31. logger.debug(f"Found {len(playlist_names)} playlists")
  32. return playlist_names
  33. def get_playlist(playlist_name):
  34. """Get a specific playlist by name."""
  35. playlists_dict = load_playlists()
  36. if playlist_name not in playlists_dict:
  37. logger.warning(f"Playlist not found: {playlist_name}")
  38. return None
  39. logger.debug(f"Retrieved playlist: {playlist_name}")
  40. return {
  41. "name": playlist_name,
  42. "files": playlists_dict[playlist_name]
  43. }
  44. def create_playlist(playlist_name, files):
  45. """Create or update a playlist."""
  46. playlists_dict = load_playlists()
  47. playlists_dict[playlist_name] = files
  48. save_playlists(playlists_dict)
  49. logger.info(f"Created/updated playlist '{playlist_name}' with {len(files)} files")
  50. return True
  51. def modify_playlist(playlist_name, files):
  52. """Modify an existing playlist."""
  53. logger.info(f"Modifying playlist '{playlist_name}' with {len(files)} files")
  54. return create_playlist(playlist_name, files)
  55. def delete_playlist(playlist_name):
  56. """Delete a playlist."""
  57. playlists_dict = load_playlists()
  58. if playlist_name not in playlists_dict:
  59. logger.warning(f"Cannot delete non-existent playlist: {playlist_name}")
  60. return False
  61. del playlists_dict[playlist_name]
  62. save_playlists(playlists_dict)
  63. logger.info(f"Deleted playlist: {playlist_name}")
  64. return True
  65. def add_to_playlist(playlist_name, pattern):
  66. """Add a pattern to an existing playlist."""
  67. playlists_dict = load_playlists()
  68. if playlist_name not in playlists_dict:
  69. logger.warning(f"Cannot add to non-existent playlist: {playlist_name}")
  70. return False
  71. playlists_dict[playlist_name].append(pattern)
  72. save_playlists(playlists_dict)
  73. logger.info(f"Added pattern '{pattern}' to playlist '{playlist_name}'")
  74. return True
  75. def run_playlist(playlist_name, pause_time=0, clear_pattern=None, run_mode="single", shuffle=False):
  76. """Run a playlist with the given options."""
  77. playlists = load_playlists()
  78. if playlist_name not in playlists:
  79. logger.error(f"Cannot run non-existent playlist: {playlist_name}")
  80. return False, "Playlist not found"
  81. file_paths = playlists[playlist_name]
  82. file_paths = [os.path.join(pattern_manager.THETA_RHO_DIR, file) for file in file_paths]
  83. if not file_paths:
  84. logger.warning(f"Cannot run empty playlist: {playlist_name}")
  85. return False, "Playlist is empty"
  86. try:
  87. logger.info(f"Starting playlist '{playlist_name}' with mode={run_mode}, shuffle={shuffle}")
  88. state.current_playlist_name = playlist_name
  89. state.current_playlist = playlist_name
  90. threading.Thread(
  91. target=pattern_manager.run_theta_rho_files,
  92. args=(file_paths,),
  93. kwargs={
  94. 'pause_time': pause_time,
  95. 'clear_pattern': clear_pattern,
  96. 'run_mode': run_mode,
  97. 'shuffle': shuffle,
  98. },
  99. daemon=True
  100. ).start()
  101. return True, f"Playlist '{playlist_name}' is now running."
  102. except Exception as e:
  103. logger.error(f"Failed to run playlist '{playlist_name}': {str(e)}")
  104. return False, str(e)