Skip to content

Commit 40e6157

Browse files
authored
Merge pull request #2072 from FoamyGuy/winamp_auto_playlist
auto playlist generation for pyportal winamp project
2 parents 68f169d + a56d71b commit 40e6157

File tree

1 file changed

+100
-6
lines changed

1 file changed

+100
-6
lines changed

PyPortal_Winamp_Player/winamp_helpers.py

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""
55
PyPortal winamp displayio widget classes.
66
"""
7+
import os
78
import time
89
import json
910
import board
@@ -28,7 +29,7 @@ class WinampApplication(displayio.Group):
2829

2930
STATE_PLAYING = 0
3031
STATE_PAUSED = 1
31-
# pylint: disable=too-many-statements
32+
# pylint: disable=too-many-statements,too-many-branches
3233
def __init__(
3334
self,
3435
playlist_file="playlist.json",
@@ -45,10 +46,29 @@ def __init__(
4546
self.CONFIG_DATA = json.loads(f.read())
4647
f.close()
4748

48-
# read the playlist data into variable
49-
f = open(self.PLAYLIST_FILE, "r")
50-
self.PLAYLIST = json.loads(f.read())
51-
f.close()
49+
if self.PLAYLIST_FILE:
50+
try:
51+
# read the playlist data into variable
52+
f = open(self.PLAYLIST_FILE, "r")
53+
self.PLAYLIST = json.loads(f.read())
54+
f.close()
55+
except OSError:
56+
# file not found
57+
self.auto_find_tracks()
58+
except ValueError:
59+
# json parse error
60+
self.auto_find_tracks()
61+
else:
62+
# playlist file argument was None
63+
self.auto_find_tracks()
64+
65+
if self.PLAYLIST:
66+
try:
67+
if len(self.PLAYLIST["playlist"]["files"]) == 0:
68+
# valid playlist json data, but no tracks
69+
self.auto_find_tracks()
70+
except KeyError:
71+
self.auto_find_tracks()
5272

5373
# initialize clock display
5474
self.clock_display = ClockDisplay(text_color=self.CONFIG_DATA["time_color"])
@@ -148,6 +168,80 @@ def __init__(
148168
self._seconds_elapsed = 0
149169
self._last_increment_time = 0
150170

171+
def auto_find_tracks(self):
172+
"""
173+
Initialize the song_list by searching for all MP3's within
174+
two layers of directories on the SDCard.
175+
176+
e.g. It will find all of:
177+
/sd/Amazing Song.mp3
178+
/sd/[artist_name]/Amazing Song.mp3
179+
/sd/[artist_name]/[album_name]/Amazing Song.mp3
180+
181+
but won't find:
182+
/sd/my_music/[artist_name]/[album_name]/Amazing Song.mp3
183+
184+
:return: None
185+
"""
186+
# list that holds all files in the root of SDCard
187+
_root_sd_all_files = os.listdir("/sd/")
188+
189+
# list that will hold all directories in the root of the SDCard.
190+
_root_sd_dirs = []
191+
192+
# list that will hold all subdirectories inside of root level directories
193+
_second_level_dirs = []
194+
195+
# list that will hold all MP3 file songs that we find
196+
_song_list = []
197+
198+
# loop over all files found on SDCard
199+
for _file in _root_sd_all_files:
200+
try:
201+
# Check if the current file is a directory
202+
os.listdir("/sd/{}".format(_file))
203+
204+
# add it to a list to look at later
205+
_root_sd_dirs.append(_file)
206+
except OSError:
207+
# current file was not a directory, nothing to do.
208+
pass
209+
210+
# if current file is an MP3 file
211+
if _file.endswith(".mp3"):
212+
# we found an MP3 file, add it to the list that will become our playlist
213+
_song_list.append("/sd/{}".format(_file))
214+
215+
# loop over root level directories
216+
for _dir in _root_sd_dirs:
217+
# loop over all files inside of root level directory
218+
for _file in os.listdir("/sd/{}".format(_dir)):
219+
220+
# check if current file is a directory
221+
try:
222+
# if it is a directory, loop over all files inside of it
223+
for _inner_file in os.listdir("/sd/{}/{}".format(_dir, _file)):
224+
# check if inner file is an MP3
225+
if _inner_file.endswith(".mp3"):
226+
# we found an MP3 file, add it to the list that will become our playlist
227+
_song_list.append(
228+
"/sd/{}/{}/{}".format(_dir, _file, _inner_file)
229+
)
230+
except OSError:
231+
# current file is not a directory
232+
pass
233+
# if the current file is an MP3 file
234+
if _file.endswith(".mp3"):
235+
# we found an MP3 file, add it to the list that will become our playlist
236+
_song_list.append("/sd/{}/{}".format(_dir, _file))
237+
238+
# format the songs we found into the PLAYLIST data structure
239+
self.PLAYLIST = {"playlist": {"files": _song_list}}
240+
241+
# print message to user letting them know we auto-generated the playlist
242+
print("Auto Generated Playlist from MP3's found on SDCard:")
243+
print(json.dumps(self.PLAYLIST))
244+
151245
def update(self):
152246
"""
153247
Must be called each iteration from the main loop.
@@ -359,7 +453,7 @@ def song_list(self, new_song_list):
359453
def from_files_list(self, files_list):
360454
"""
361455
Initialize the song_list from a list of filenames.
362-
Directories and mp3 file extension will be removed.
456+
Directories and MP3 file extension will be removed.
363457
364458
:param files_list: list of strings containing filenames
365459
:return: None

0 commit comments

Comments
 (0)