Merge pull request #2072 from FoamyGuy/winamp_auto_playlist

auto playlist generation for pyportal winamp project
This commit is contained in:
Anne Barela 2022-02-26 19:12:19 -05:00 committed by GitHub
commit 40e6157eb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,6 +4,7 @@
""" """
PyPortal winamp displayio widget classes. PyPortal winamp displayio widget classes.
""" """
import os
import time import time
import json import json
import board import board
@ -28,7 +29,7 @@ class WinampApplication(displayio.Group):
STATE_PLAYING = 0 STATE_PLAYING = 0
STATE_PAUSED = 1 STATE_PAUSED = 1
# pylint: disable=too-many-statements # pylint: disable=too-many-statements,too-many-branches
def __init__( def __init__(
self, self,
playlist_file="playlist.json", playlist_file="playlist.json",
@ -45,10 +46,29 @@ class WinampApplication(displayio.Group):
self.CONFIG_DATA = json.loads(f.read()) self.CONFIG_DATA = json.loads(f.read())
f.close() f.close()
if self.PLAYLIST_FILE:
try:
# read the playlist data into variable # read the playlist data into variable
f = open(self.PLAYLIST_FILE, "r") f = open(self.PLAYLIST_FILE, "r")
self.PLAYLIST = json.loads(f.read()) self.PLAYLIST = json.loads(f.read())
f.close() f.close()
except OSError:
# file not found
self.auto_find_tracks()
except ValueError:
# json parse error
self.auto_find_tracks()
else:
# playlist file argument was None
self.auto_find_tracks()
if self.PLAYLIST:
try:
if len(self.PLAYLIST["playlist"]["files"]) == 0:
# valid playlist json data, but no tracks
self.auto_find_tracks()
except KeyError:
self.auto_find_tracks()
# initialize clock display # initialize clock display
self.clock_display = ClockDisplay(text_color=self.CONFIG_DATA["time_color"]) self.clock_display = ClockDisplay(text_color=self.CONFIG_DATA["time_color"])
@ -148,6 +168,80 @@ class WinampApplication(displayio.Group):
self._seconds_elapsed = 0 self._seconds_elapsed = 0
self._last_increment_time = 0 self._last_increment_time = 0
def auto_find_tracks(self):
"""
Initialize the song_list by searching for all MP3's within
two layers of directories on the SDCard.
e.g. It will find all of:
/sd/Amazing Song.mp3
/sd/[artist_name]/Amazing Song.mp3
/sd/[artist_name]/[album_name]/Amazing Song.mp3
but won't find:
/sd/my_music/[artist_name]/[album_name]/Amazing Song.mp3
:return: None
"""
# list that holds all files in the root of SDCard
_root_sd_all_files = os.listdir("/sd/")
# list that will hold all directories in the root of the SDCard.
_root_sd_dirs = []
# list that will hold all subdirectories inside of root level directories
_second_level_dirs = []
# list that will hold all MP3 file songs that we find
_song_list = []
# loop over all files found on SDCard
for _file in _root_sd_all_files:
try:
# Check if the current file is a directory
os.listdir("/sd/{}".format(_file))
# add it to a list to look at later
_root_sd_dirs.append(_file)
except OSError:
# current file was not a directory, nothing to do.
pass
# if current file is an MP3 file
if _file.endswith(".mp3"):
# we found an MP3 file, add it to the list that will become our playlist
_song_list.append("/sd/{}".format(_file))
# loop over root level directories
for _dir in _root_sd_dirs:
# loop over all files inside of root level directory
for _file in os.listdir("/sd/{}".format(_dir)):
# check if current file is a directory
try:
# if it is a directory, loop over all files inside of it
for _inner_file in os.listdir("/sd/{}/{}".format(_dir, _file)):
# check if inner file is an MP3
if _inner_file.endswith(".mp3"):
# we found an MP3 file, add it to the list that will become our playlist
_song_list.append(
"/sd/{}/{}/{}".format(_dir, _file, _inner_file)
)
except OSError:
# current file is not a directory
pass
# if the current file is an MP3 file
if _file.endswith(".mp3"):
# we found an MP3 file, add it to the list that will become our playlist
_song_list.append("/sd/{}/{}".format(_dir, _file))
# format the songs we found into the PLAYLIST data structure
self.PLAYLIST = {"playlist": {"files": _song_list}}
# print message to user letting them know we auto-generated the playlist
print("Auto Generated Playlist from MP3's found on SDCard:")
print(json.dumps(self.PLAYLIST))
def update(self): def update(self):
""" """
Must be called each iteration from the main loop. Must be called each iteration from the main loop.
@ -359,7 +453,7 @@ class PlaylistDisplay(displayio.Group):
def from_files_list(self, files_list): def from_files_list(self, files_list):
""" """
Initialize the song_list from a list of filenames. Initialize the song_list from a list of filenames.
Directories and mp3 file extension will be removed. Directories and MP3 file extension will be removed.
:param files_list: list of strings containing filenames :param files_list: list of strings containing filenames
:return: None :return: None