updated songs screen

This commit is contained in:
JISAUAY committed 2025-10-22 11:13:12 -05:00
1 parent 1e4616d498
commit 48c9aca87e
3 files changed
+177 -16

No files matched your search

+108 -16
View File
@@ -23,6 +23,7 @@ BITRATE = int(BITRATE) if BITRATE else BITRATE
IMAGE_MODE = config.getboolean('GENERAL', 'GUI')
import SubSonic
import Navidrome
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
@@ -34,7 +35,7 @@ from textual import on, events, work
from textual.binding import Binding
from textual.reactive import reactive
from textual.app import App, ComposeResult, RenderResult
from textual.widgets import Footer, Header, OptionList, DataTable, ProgressBar, Label, Input, Placeholder, Static, Rule, Button
from textual.widgets import Footer, Header, OptionList, DataTable, ProgressBar, Label, Input, Placeholder, Static, Rule, Button, ListView, ListItem
from textual.widget import Widget
from textual.containers import Horizontal, Vertical, Container, Center
from textual.screen import Screen, ModalScreen
@@ -46,9 +47,12 @@ from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
u, p = [s.strip() for s in open('auth', 'r').read().split(',')]
user, passw = [s.strip() for s in open('auth', 'r').read().split(',')]
MUSIC_SERVER_URL = 'https://music.0x01fe.net'
conn = SubSonic.SubpyConn(user, passw, MUSIC_SERVER_URL)
conn = SubSonic.SubpyConn(u, p, "https://music.0x01fe.net")
pygame.mixer.init()
@@ -197,7 +201,7 @@ class ArtistAlbumsGUI(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("* F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
yield Label(classes='artistNameHeader')
yield Rule()
@@ -297,7 +301,7 @@ class Artists(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("* F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
with Vertical(id="artistContainer"):
yield Input(placeholder="Search")
@@ -438,7 +442,7 @@ class ArtistsGUI(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("* F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
yield Input(placeholder="Search", id="artistSearchBar")
with Horizontal():
@@ -565,7 +569,7 @@ class Albums(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("* F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
with Vertical(id="albumContainer"):
yield Input(placeholder="Search", id="albumSearchBar")
@@ -610,7 +614,7 @@ class Playlists(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("* F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
yield DataTable()
yield Footer()
@@ -703,12 +707,24 @@ class PlaylistSongs(Screen):
class SongsScreen(Screen):
BINDINGS = [
("p", "play_song()", "Play Song"),
("q", "queue_song()", "Queue Song"),
("m", "shuffle_mix()", 'Shuffle Play'),
('a', "page_backward()", "Prev. Page"),
('d', "page_forward()", "Next Page")
]
songs: list[SubSonic.Song]
selected_song_id: str | None = None
# 0 = All, 1 = Favourites
mode: int = 0
page: dict[int, int] = {
0: 0,
1: 0
}
def compose(self) -> ComposeResult:
yield Header(icon='')
@@ -716,15 +732,87 @@ class SongsScreen(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("* F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("* F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
with Horizontal(id='songsScreen'):
yield Placeholder(id='songModeSelectorList')
yield Placeholder(id='songDatatable')
yield ListView(
ListItem(Label('All')),
ListItem(Label('Favourites')),
id='songModeSelectorList'
)
yield DataTable(id='songDatatable')
yield Footer()
def on_mount(self) -> None:
app.sub_title = "Songs"
self.update_datatable()
# TODO @0x01fe : find better way to do space
@on(ListView.Selected)
def mode_selected(self, e: ListView.Selected) -> None:
self.mode = e.index
self.update_datatable()
def _get_offset(self) -> int:
return (self.page[self.mode]) * 30
def action_shuffle_mix(self) -> None:
if self.mode == 0:
q = conn.getRandomSongs(size=200)
app.play_song(q.pop(0))
app.song_queue = q
elif self.mode == 1:
q = self.songs.copy()
random.shuffle(q)
app.play_song(q.pop(0))
app.song_queue = q
def action_page_forward(self) -> None:
self.page[self.mode] += 1
self.update_datatable()
def action_page_backward(self) -> None:
if self.page[self.mode] - 1 < 0:
return
self.page[self.mode] -= 1
self.update_datatable()
def update_datatable(self) -> None:
datatable = self.query_one(DataTable)
if self.mode == 0:
self.update_all(datatable)
elif self.mode == 1:
self.update_favorites(datatable)
def update_favorites(self, dt: DataTable) -> None:
self.songs = conn.getStarredSongs()
space = 30
offset = self._get_offset()
dt.clear()
for song in self.songs[offset:offset + space]:
dt.add_row(song.title, song.album, song.artist, song.playCount, song.duration)
def update_all(self, dt: DataTable) -> None:
space = 30
offset = self._get_offset()
self.songs = app.navidrome.getAllSongs(offset + space, offset)
dt.cursor_type = "row"
dt.clear()
dt.add_columns("Title", "Album", "Artist", "Plays", "Duration")
for song in self.songs:
dt.add_row(song.title, song.album, song.artist, song.playCount, song.duration)
class Favourites(Screen):
BINDINGS = [
('p', 'play()', 'Play Song'),
@@ -741,7 +829,7 @@ class Favourites(Screen):
yield Label(Text("F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("* F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("* F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
yield DataTable()
yield Footer()
@@ -970,7 +1058,7 @@ class Player(Screen):
yield Label(Text("* F1 ", style="bold orange").append_text(Text("Player", style="white")), classes="headerb")
yield Label(Text("F2 ", style="bold orange").append_text(Text("Artists", style="white")), classes="headerb")
yield Label(Text("F3 ", style="bold orange").append_text(Text("Albums", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Favourites", style="white")), classes="headerb")
yield Label(Text("F4 ", style="bold orange").append_text(Text("Songs", style="white")), classes="headerb")
yield Label(Text("F5 ", style="bold orange").append_text(Text("Playlists", style="white")), classes="headerb")
with Center(id='playerTrackTitleBox'):
@@ -1064,7 +1152,7 @@ class SubPy(App):
Binding('f1', "switch_mode('main')", 'Overview', show=False),
Binding('f2', "switch_mode('artists')", "Artists", show=False),
Binding('f3', "switch_mode('albums')", "Albums", show=False),
Binding('f4', "switch_mode('favourites')", "Favourites", show=False),
Binding('f4', "switch_mode('songs')", "Songs", show=False),
Binding('f5', "switch_mode('playlists')", "Playlists", show=False)
]
@@ -1072,7 +1160,7 @@ class SubPy(App):
"main" : Player,
"artists" : ArtistsGUI,
"albums" : Albums,
"favourites" : SongsScreen,
"songs" : SongsScreen,
"playlists" : Playlists
}
@@ -1084,6 +1172,8 @@ class SubPy(App):
is_paused: bool = False
place: int = 0
navidrome: Navidrome.NavidromeAPI
music_command_queue: multiprocessing.Queue
check_playing_timer: Timer | None = None
@@ -1095,6 +1185,8 @@ class SubPy(App):
self.check_music_commands = self.set_interval(2/3, self._music_player_loop, pause=False)
self.navidrome = Navidrome.NavidromeAPI(user, passw, MUSIC_SERVER_URL)
@work(exclusive=True)
async def play_song(self, song: SubSonic.Song) -> None:
self.currently_playing = song