|
4 | 4 | """
|
5 | 5 | PyPortal winamp displayio widget classes.
|
6 | 6 | """
|
| 7 | +import os |
7 | 8 | import time
|
8 | 9 | import json
|
9 | 10 | import board
|
@@ -45,10 +46,29 @@ def __init__(
|
45 | 46 | self.CONFIG_DATA = json.loads(f.read())
|
46 | 47 | f.close()
|
47 | 48 |
|
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() |
52 | 72 |
|
53 | 73 | # initialize clock display
|
54 | 74 | self.clock_display = ClockDisplay(text_color=self.CONFIG_DATA["time_color"])
|
@@ -148,6 +168,80 @@ def __init__(
|
148 | 168 | self._seconds_elapsed = 0
|
149 | 169 | self._last_increment_time = 0
|
150 | 170 |
|
| 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 | + |
151 | 245 | def update(self):
|
152 | 246 | """
|
153 | 247 | Must be called each iteration from the main loop.
|
@@ -359,7 +453,7 @@ def song_list(self, new_song_list):
|
359 | 453 | def from_files_list(self, files_list):
|
360 | 454 | """
|
361 | 455 | 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. |
363 | 457 |
|
364 | 458 | :param files_list: list of strings containing filenames
|
365 | 459 | :return: None
|
|
0 commit comments