Compare commits
8 Commits
e4fe4b576e
...
2fbf829eed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fbf829eed | ||
|
|
32fb44439d | ||
|
|
8b641cd728 | ||
|
|
d5d4361ec5 | ||
|
|
c69aefef92 | ||
|
|
baf0c180bd | ||
|
|
b46830f010 | ||
|
|
0a4730e5a7 |
@ -6,12 +6,15 @@ class Config(object):
|
||||
AUDIO_SEGMENT_CHUNK_SIZE = 10
|
||||
COLOUR_CURRENT_HEADER = "#d4edda"
|
||||
COLOUR_CURRENT_PLAYLIST = "#28a745"
|
||||
COLOUR_CURRENT_TAB = "#248f24"
|
||||
COLOUR_ODD_PLAYLIST = "#f2f2f2"
|
||||
COLOUR_ENDING_TIMER = "#dc3545"
|
||||
COLOUR_EVEN_PLAYLIST = "#d9d9d9"
|
||||
COLOUR_LONG_START = "#dc3545"
|
||||
COLOUR_NORMAL_TAB = "#000000"
|
||||
COLOUR_NEXT_HEADER = "#fff3cd"
|
||||
COLOUR_NEXT_PLAYLIST = "#ffc107"
|
||||
COLOUR_NEXT_TAB = "#b38600"
|
||||
COLOUR_NOTES_PLAYLIST = "#b8daff"
|
||||
COLOUR_PREVIOUS_HEADER = "#f8d7da"
|
||||
COLOUR_UNREADABLE = "#dc3545"
|
||||
|
||||
@ -338,6 +338,7 @@ class PlaylistTracks(Base):
|
||||
f"PlaylistTracks.playlist_id == {from_playlist_id}, "
|
||||
f"PlaylistTracks.row == {row}"
|
||||
)
|
||||
return
|
||||
record.playlist_id = to_playlist_id
|
||||
record.row = new_row
|
||||
session.commit()
|
||||
|
||||
@ -11,7 +11,7 @@ from datetime import datetime, timedelta
|
||||
from log import DEBUG, EXCEPTION
|
||||
|
||||
from PyQt5.QtCore import Qt, QTimer, QUrl
|
||||
from PyQt5.QtGui import QFontMetrics, QPainter
|
||||
from PyQt5.QtGui import QColor, QFontMetrics, QPainter
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
|
||||
from PyQt5.QtWidgets import (
|
||||
QApplication,
|
||||
@ -265,7 +265,8 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
self.playing = False
|
||||
|
||||
# Clean up metadata
|
||||
self.previous_track = self.current_track
|
||||
if self.current_track:
|
||||
self.previous_track = self.current_track
|
||||
if self.current_track_playlist_tab:
|
||||
self.current_track_playlist_tab.play_stopped()
|
||||
self.current_track_playlist_tab.clear_current()
|
||||
@ -480,6 +481,8 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
# Play next track
|
||||
self.current_track = self.next_track
|
||||
self.current_track_playlist_tab = self.next_track_playlist_tab
|
||||
self.set_tab_colour(self.current_track_playlist_tab,
|
||||
QColor(Config.COLOUR_CURRENT_TAB))
|
||||
self.next_track = None
|
||||
self.next_track_playlist_tab = None
|
||||
DEBUG(
|
||||
@ -501,6 +504,12 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
else:
|
||||
self.next_track = self.next_track_playlist_tab = None
|
||||
|
||||
if self.next_track_playlist_tab and (
|
||||
self.current_track_playlist_tab !=
|
||||
self.next_track_playlist_tab):
|
||||
self.set_tab_colour(self.next_track_playlist_tab,
|
||||
QColor(Config.COLOUR_NEXT_TAB))
|
||||
|
||||
# Tell database to record it as played
|
||||
self.current_track.update_lastplayed()
|
||||
Playdates.add_playdate(session, self.current_track)
|
||||
@ -554,12 +563,32 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
if not next_track_id:
|
||||
next_track_id = (
|
||||
self.visible_playlist_tab().set_selected_as_next())
|
||||
if next_track_id:
|
||||
if self.next_track_playlist_tab != self.visible_playlist_tab():
|
||||
if self.next_track_playlist_tab:
|
||||
self.next_track_playlist_tab.clear_next()
|
||||
self.next_track_playlist_tab = self.visible_playlist_tab()
|
||||
self.next_track = Tracks.get_track(session, next_track_id)
|
||||
if not next_track_id:
|
||||
return
|
||||
|
||||
# The next track has been selected on the currently-visible
|
||||
# playlist. However, there may already be a 'next track'
|
||||
# selected on another playlist that the user is overriding,
|
||||
# in which case we need to reset that playlist.
|
||||
if self.next_track_playlist_tab != self.visible_playlist_tab():
|
||||
# We need to reset the ex-next-track playlist
|
||||
if self.next_track_playlist_tab:
|
||||
self.next_track_playlist_tab.clear_next()
|
||||
# Reset tab colour if it NOT the current playing tab
|
||||
if (self.next_track_playlist_tab !=
|
||||
self.current_track_playlist_tab):
|
||||
self.set_tab_colour(self.next_track_playlist_tab,
|
||||
QColor(Config.COLOUR_NORMAL_TAB))
|
||||
self.next_track_playlist_tab = self.visible_playlist_tab()
|
||||
# self.next_track_playlist_tab is now set to correct
|
||||
# playlist
|
||||
if (self.next_track_playlist_tab !=
|
||||
self.current_track_playlist_tab):
|
||||
self.set_tab_colour(self.next_track_playlist_tab,
|
||||
QColor(Config.COLOUR_NEXT_TAB))
|
||||
|
||||
self.next_track = Tracks.get_track(session, next_track_id)
|
||||
|
||||
self.update_headers()
|
||||
|
||||
def select_unplayed(self):
|
||||
@ -567,6 +596,14 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
self.visible_playlist_tab().select_unplayed_tracks()
|
||||
|
||||
def set_tab_colour(self, widget, colour):
|
||||
"""
|
||||
Find the tab containing the widget and set the text colour
|
||||
"""
|
||||
|
||||
idx = self.tabPlaylist.indexOf(widget)
|
||||
self.tabPlaylist.tabBar().setTabTextColor(idx, colour)
|
||||
|
||||
def song_info_search(self):
|
||||
"""
|
||||
Open browser tabs for Wikipedia, searching for
|
||||
@ -601,6 +638,13 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
|
||||
DEBUG(f"musicmuster.stop_playing({fade=})", True)
|
||||
|
||||
if self.current_track_playlist_tab == self.next_track_playlist_tab:
|
||||
self.set_tab_colour(self.current_track_playlist_tab,
|
||||
QColor(Config.COLOUR_NEXT_TAB))
|
||||
else:
|
||||
self.set_tab_colour(self.current_track_playlist_tab,
|
||||
QColor(Config.COLOUR_NORMAL_TAB))
|
||||
|
||||
if not self.music.playing():
|
||||
DEBUG("musicmuster.stop_playing(): not playing", True)
|
||||
self.end_of_track_actions()
|
||||
@ -632,7 +676,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
if not self.playing():
|
||||
return
|
||||
|
||||
self.music.set_position(self.get_current_silence_at() - 1000)
|
||||
self.music.set_position(self.current_track.silence_at - 1000)
|
||||
|
||||
def test_skip_to_fade(self):
|
||||
"Skip current track to 1 second before fade"
|
||||
@ -640,7 +684,7 @@ class Window(QMainWindow, Ui_MainWindow):
|
||||
if not self.music.playing():
|
||||
return
|
||||
|
||||
self.music.set_position(self.get_current_fade_at() - 1000)
|
||||
self.music.set_position(self.current_track.fade_at - 1000)
|
||||
|
||||
def tick(self):
|
||||
"""
|
||||
|
||||
@ -382,6 +382,9 @@ class PlaylistTab(QTableWidget):
|
||||
for row in sorted(rows, reverse=True):
|
||||
self.removeRow(row)
|
||||
|
||||
with Session() as session:
|
||||
self._save_playlist(session)
|
||||
|
||||
self._repaint()
|
||||
|
||||
def play_started(self):
|
||||
@ -420,6 +423,9 @@ class PlaylistTab(QTableWidget):
|
||||
# on its specified row, only that it will be above
|
||||
# larger-numbered row items, and below lower-numbered ones.
|
||||
|
||||
# That means we need to re-save ourself once loaded to ensure
|
||||
# database is correct.
|
||||
|
||||
# First, save our id for the future
|
||||
self.id = playlist_db.id
|
||||
self.name = playlist_db.name
|
||||
@ -446,6 +452,7 @@ class PlaylistTab(QTableWidget):
|
||||
scroll_to = self.item(0, self.COL_INDEX)
|
||||
self.scrollToItem(scroll_to, QAbstractItemView.PositionAtTop)
|
||||
|
||||
self._save_playlist(session)
|
||||
self._repaint()
|
||||
|
||||
def repaint(self):
|
||||
@ -965,13 +972,17 @@ class PlaylistTab(QTableWidget):
|
||||
return None
|
||||
|
||||
track_id = self._get_row_id(row)
|
||||
if track_id:
|
||||
if self._track_path_is_readable(track_id):
|
||||
self._meta_set_next(row)
|
||||
self.master_process.set_next_track(track_id)
|
||||
else:
|
||||
self._meta_set_unreadable(row)
|
||||
track_id = None
|
||||
if not track_id:
|
||||
return None
|
||||
|
||||
if self._track_path_is_readable(track_id):
|
||||
self._meta_set_next(row)
|
||||
self.master_process.set_next_track(track_id)
|
||||
else:
|
||||
self._meta_set_unreadable(row)
|
||||
track_id = None
|
||||
self._repaint()
|
||||
|
||||
return track_id
|
||||
|
||||
def _repaint(self, clear_selection=True):
|
||||
@ -1195,9 +1206,6 @@ class PlaylistTab(QTableWidget):
|
||||
If multiple rows are selected, display sum of durations in status bar.
|
||||
"""
|
||||
|
||||
# Clear label
|
||||
self.master_process.lblSumPlaytime.setText("")
|
||||
|
||||
rows = set([item.row() for item in self.selectedItems()])
|
||||
notes = self._meta_get_notes()
|
||||
ms = 0
|
||||
@ -1210,6 +1218,8 @@ class PlaylistTab(QTableWidget):
|
||||
if ms > 0:
|
||||
self.master_process.lblSumPlaytime.setText(
|
||||
f"Selected duration: {helpers.ms_to_mmss(ms)}")
|
||||
else:
|
||||
self.master_process.lblSumPlaytime.setText("")
|
||||
|
||||
def _set_column_widths(self):
|
||||
# Column widths from settings
|
||||
|
||||
@ -72,6 +72,9 @@ def create_track_from_file(session, path, verbose=False):
|
||||
t = get_music_info(path)
|
||||
track.title = t['title']
|
||||
track.artist = t['artist']
|
||||
if verbose:
|
||||
INFO(f" Title: \"{track.title}\"")
|
||||
INFO(f" Artist: \"{track.artist}\"")
|
||||
track.duration = int(round(
|
||||
t['duration'], Config.MILLISECOND_SIGFIGS) * 1000)
|
||||
|
||||
|
||||
@ -836,7 +836,7 @@ border: 1px solid rgb(85, 87, 83);</string>
|
||||
<string>Skip to &next</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Return</string>
|
||||
<string>Ctrl+Alt+Return</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSearch_database">
|
||||
|
||||
@ -514,7 +514,7 @@ class Ui_MainWindow(object):
|
||||
self.actionPlay_next.setText(_translate("MainWindow", "&Play next"))
|
||||
self.actionPlay_next.setShortcut(_translate("MainWindow", "Return"))
|
||||
self.actionSkip_next.setText(_translate("MainWindow", "Skip to &next"))
|
||||
self.actionSkip_next.setShortcut(_translate("MainWindow", "Ctrl+Return"))
|
||||
self.actionSkip_next.setShortcut(_translate("MainWindow", "Ctrl+Alt+Return"))
|
||||
self.actionSearch_database.setText(_translate("MainWindow", "Search &database"))
|
||||
self.actionSearch_database.setShortcut(_translate("MainWindow", "Ctrl+D"))
|
||||
self.actionAdd_file.setText(_translate("MainWindow", "Add &file"))
|
||||
|
||||
24
musicmuster.desktop
Normal file
24
musicmuster.desktop
Normal file
@ -0,0 +1,24 @@
|
||||
[Desktop Entry]
|
||||
|
||||
Type=Application
|
||||
|
||||
# The version of the desktop entry specification to which this file complies
|
||||
Version=1.0
|
||||
|
||||
# The name of the application
|
||||
Name=MusicMuster
|
||||
|
||||
# A comment which can/will be used as a tooltip
|
||||
Comment=Music play for internet radio
|
||||
|
||||
# The path to the folder in which the executable is run
|
||||
Path=/usr/local/bin
|
||||
|
||||
# The executable of the application, possibly with arguments.
|
||||
Exec=musicmuster
|
||||
|
||||
# Describes whether this application needs to be run in a terminal or not
|
||||
Terminal=false
|
||||
|
||||
# Describes the categories in which this entry should be shown
|
||||
Categories=AudioVideo;Audio;
|
||||
Loading…
Reference in New Issue
Block a user