playlist_manager.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import json
  2. import os
  3. import logging
  4. from modules.core.state import state
  5. # Configure logging
  6. logger = logging.getLogger(__name__)
  7. # Global state
  8. PLAYLISTS_FILE = os.path.join(os.getcwd(), "playlists.json")
  9. # Ensure the file exists and contains at least an empty JSON object
  10. if not os.path.isfile(PLAYLISTS_FILE):
  11. logger.info(f"Creating new playlists file at {PLAYLISTS_FILE}")
  12. with open(PLAYLISTS_FILE, "w") as f:
  13. json.dump({}, f, indent=2)
  14. def load_playlists():
  15. """Load the entire playlists dictionary from the JSON file."""
  16. try:
  17. with open(PLAYLISTS_FILE, "r") as f:
  18. content = f.read().strip()
  19. if not content:
  20. logger.warning("Playlists file is empty, returning empty dict")
  21. return {}
  22. playlists = json.loads(content)
  23. logger.debug(f"Loaded {len(playlists)} playlists")
  24. return playlists
  25. except (json.JSONDecodeError, ValueError) as e:
  26. logger.error(f"Playlists file is corrupted, resetting to empty: {e}")
  27. save_playlists({})
  28. return {}
  29. def save_playlists(playlists_dict):
  30. """Save the entire playlists dictionary back to the JSON file."""
  31. logger.debug(f"Saving {len(playlists_dict)} playlists to file")
  32. with open(PLAYLISTS_FILE, "w") as f:
  33. json.dump(playlists_dict, f, indent=2)
  34. def list_all_playlists():
  35. """Returns a list of all playlist names."""
  36. playlists_dict = load_playlists()
  37. playlist_names = list(playlists_dict.keys())
  38. logger.debug(f"Found {len(playlist_names)} playlists")
  39. return playlist_names
  40. def get_playlist(playlist_name):
  41. """Get a specific playlist by name."""
  42. playlists_dict = load_playlists()
  43. if playlist_name not in playlists_dict:
  44. logger.warning(f"Playlist not found: {playlist_name}")
  45. return None
  46. logger.debug(f"Retrieved playlist: {playlist_name}")
  47. return {
  48. "name": playlist_name,
  49. "files": playlists_dict[playlist_name]
  50. }
  51. def create_playlist(playlist_name, files):
  52. """Create or update a playlist."""
  53. playlists_dict = load_playlists()
  54. playlists_dict[playlist_name] = files
  55. save_playlists(playlists_dict)
  56. logger.info(f"Created/updated playlist '{playlist_name}' with {len(files)} files")
  57. # Keep the board's /playlists/<name>.txt mirror in sync (autostart runs it).
  58. from modules.core import board_settings
  59. board_settings.mirror_playlist_async(playlist_name, files)
  60. return True
  61. def modify_playlist(playlist_name, files):
  62. """Modify an existing playlist."""
  63. logger.info(f"Modifying playlist '{playlist_name}' with {len(files)} files")
  64. return create_playlist(playlist_name, files)
  65. def delete_playlist(playlist_name):
  66. """Delete a playlist."""
  67. playlists_dict = load_playlists()
  68. if playlist_name not in playlists_dict:
  69. logger.warning(f"Cannot delete non-existent playlist: {playlist_name}")
  70. return False
  71. del playlists_dict[playlist_name]
  72. save_playlists(playlists_dict)
  73. logger.info(f"Deleted playlist: {playlist_name}")
  74. from modules.core import board_settings
  75. board_settings.unmirror_playlist_async(playlist_name)
  76. return True
  77. def add_to_playlist(playlist_name, pattern):
  78. """Add a pattern to an existing playlist."""
  79. playlists_dict = load_playlists()
  80. if playlist_name not in playlists_dict:
  81. logger.warning(f"Cannot add to non-existent playlist: {playlist_name}")
  82. return False
  83. playlists_dict[playlist_name].append(pattern)
  84. save_playlists(playlists_dict)
  85. logger.info(f"Added pattern '{pattern}' to playlist '{playlist_name}'")
  86. from modules.core import board_settings
  87. board_settings.mirror_playlist_async(playlist_name, playlists_dict[playlist_name])
  88. return True
  89. def rename_playlist(old_name, new_name):
  90. """Rename an existing playlist."""
  91. if not new_name or not new_name.strip():
  92. logger.warning("Cannot rename playlist: new name is empty")
  93. return False, "New name cannot be empty"
  94. new_name = new_name.strip()
  95. playlists_dict = load_playlists()
  96. if old_name not in playlists_dict:
  97. logger.warning(f"Cannot rename non-existent playlist: {old_name}")
  98. return False, "Playlist not found"
  99. if old_name == new_name:
  100. return True, "Name unchanged"
  101. if new_name in playlists_dict:
  102. logger.warning(f"Cannot rename playlist: '{new_name}' already exists")
  103. return False, "A playlist with that name already exists"
  104. # Copy files to new key and delete old key
  105. playlists_dict[new_name] = playlists_dict[old_name]
  106. del playlists_dict[old_name]
  107. save_playlists(playlists_dict)
  108. logger.info(f"Renamed playlist '{old_name}' to '{new_name}'")
  109. from modules.core import board_settings
  110. board_settings.unmirror_playlist_async(old_name)
  111. board_settings.mirror_playlist_async(new_name, playlists_dict[new_name])
  112. return True, f"Playlist renamed to '{new_name}'"