Skip to content

auto playlist generation for pyportal winamp project #2072

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 27, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 100 additions & 6 deletions PyPortal_Winamp_Player/winamp_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""
PyPortal winamp displayio widget classes.
"""
import os
import time
import json
import board
Expand All @@ -28,7 +29,7 @@ class WinampApplication(displayio.Group):

STATE_PLAYING = 0
STATE_PAUSED = 1
# pylint: disable=too-many-statements
# pylint: disable=too-many-statements,too-many-branches
def __init__(
self,
playlist_file="playlist.json",
Expand All @@ -45,10 +46,29 @@ def __init__(
self.CONFIG_DATA = json.loads(f.read())
f.close()

# read the playlist data into variable
f = open(self.PLAYLIST_FILE, "r")
self.PLAYLIST = json.loads(f.read())
f.close()
if self.PLAYLIST_FILE:
try:
# read the playlist data into variable
f = open(self.PLAYLIST_FILE, "r")
self.PLAYLIST = json.loads(f.read())
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
self.clock_display = ClockDisplay(text_color=self.CONFIG_DATA["time_color"])
Expand Down Expand Up @@ -148,6 +168,80 @@ def __init__(
self._seconds_elapsed = 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):
"""
Must be called each iteration from the main loop.
Expand Down Expand Up @@ -359,7 +453,7 @@ def song_list(self, new_song_list):
def from_files_list(self, files_list):
"""
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
:return: None
Expand Down