From 11eaa803f52fc7379a1ea8dcadde2d8582e830a5 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Mon, 12 Sep 2022 18:20:24 +0100 Subject: [PATCH] Remove odd file --- ¡ | 1192 ------------------------------------------------------------- 1 file changed, 1192 deletions(-) delete mode 100644 ¡ diff --git a/¡ b/¡ deleted file mode 100644 index 81916a7..0000000 --- a/¡ +++ /dev/null @@ -1,1192 +0,0 @@ -#!/usr/bin/env python - -from log import log -# import argparse -# import psutil -import sys -# import threading -# import urllib.parse -# import webbrowser -# -# -# from datetime import datetime, timedelta -# from typing import Callable, Dict, List, Optional, Tuple -# -# from PyQt5.QtCore import QDate, QEvent, QProcess, Qt, QTime, QTimer, QUrl -from PyQt5.QtCore import Qt -from PyQt5.QtGui import QColor -# from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView -from PyQt5.QtWidgets import ( - QApplication, - QDialog, - # QFileDialog, - # QInputDialog, - QLabel, - # QLineEdit, - QListWidgetItem, - QMainWindow, - # QMessageBox, -) -# -from dbconfig import engine, Session -# import helpers -# import music -# -# from config import Config -from models import ( - Base, - # Playdates, - PlaylistRows, - Playlists, - Settings, - Tracks -) -from playlists import PlaylistTab -from sqlalchemy.orm.exc import DetachedInstanceError -# from ui.dlg_search_database_ui import Ui_Dialog -from ui.dlg_SelectPlaylist_ui import Ui_dlgSelectPlaylist -# from ui.downloadcsv_ui import Ui_DateSelect -from config import Config -from ui.main_window_ui import Ui_MainWindow -# from utilities import create_track_from_file, update_db -# -# -# log = logging.getLogger(Config.LOG_NAME) -class TrackData: - def __init__(self, track): - self.id = track.id - self.title = track.title - self.artist = track.artist - self.duration = track.duration - self.start_gap = track.start_gap - self.fade_at = track.fade_at - self.silence_at = track.silence_at - self.path = track.path - self.mtime = track.mtime - - -# class InfoTab(QWebView): -# """Subclass QWebView to show info about tracks""" -# -# def __init__(self, parent=None) -> None: -# super().__init__(parent) -# self.title = None - -class Window(QMainWindow, Ui_MainWindow): - def __init__(self, parent=None) -> None: - super().__init__(parent) - self.setupUi(self) - -# self.timer: QTimer = QTimer() -# self.even_tick: bool = True -# self.playing: bool = False -# self.disable_play_next_controls() -# -# self.music: music.Music = music.Music() - self.current_track: Optional[TrackData] = None - self.current_track_playlist_tab: Optional[PlaylistTab] = None - self.info_tabs: Optional[Dict[str, QWebView]] = {} - self.next_track: Optional[TrackData] = None - self.next_track_playlist_tab: Optional[PlaylistTab] = None - self.previous_track: Optional[TrackData] = None - self.previous_track_position: Optional[int] = None - -# self.set_main_window_size() - self.lblSumPlaytime = QLabel("") - self.statusbar.addPermanentWidget(self.lblSumPlaytime) -# self.txtSearch = QLineEdit() -# self.statusbar.addWidget(self.txtSearch) -# self.txtSearch.setHidden(True) -# self.hide_played_tracks = False -# - self.splitter.setStretchSizes[200,200] - self.visible_playlist_tab: Callable[[], PlaylistTab] = \ - self.tabPlaylist.currentWidget -# - self._load_last_playlists() -# self.enable_play_next_controls() -# self.check_audacity() -# self.timer.start(Config.TIMER_MS) - self.connect_signals_slots() -# -# def set_main_window_size(self) -> None: -# """Set size of window from database""" -# -# with Session() as session: -# record = Settings.get_int_settings(session, "mainwindow_x") -# x = record.f_int or 1 -# record = Settings.get_int_settings(session, "mainwindow_y") -# y = record.f_int or 1 -# record = Settings.get_int_settings(session, "mainwindow_width") -# width = record.f_int or 1599 -# record = Settings.get_int_settings(session, "mainwindow_height") -# height = record.f_int or 981 -# self.setGeometry(x, y, width, height) -# return -# -# @staticmethod -# def print_current_database(): -# with Session() as session: -# db = session.bind.engine.url.database -# print(f"{db=}") -# -# @staticmethod -# def check_audacity() -> None: -# """Offer to run Audacity if not running""" -# -# if not Config.CHECK_AUDACITY_AT_STARTUP: -# return -# -# if "audacity" in [i.name() for i in psutil.process_iter()]: -# return -# -# if helpers.ask_yes_no("Audacity not running", "Start Audacity?"): -# QProcess.startDetached(Config.AUDACITY_COMMAND, []) - - def clear_selection(self) -> None: - """ Clear selected row""" - - if self.visible_playlist_tab(): - self.visible_playlist_tab().clear_selection() -# -# def closeEvent(self, event: QEvent) -> None: -# """Don't allow window to close when a track is playing""" -# -# if self.music.playing(): -# log.debug("closeEvent() ignored as music is playing") -# event.ignore() -# helpers.show_warning( -# "Track playing", -# "Can't close application while track is playing") -# else: -# log.debug("closeEvent() accepted") -# -# with Session() as session: -# record = Settings.get_int_settings( -# session, "mainwindow_height") -# if record.f_int != self.height(): -# record.update(session, {'f_int': self.height()}) -# -# record = Settings.get_int_settings(session, "mainwindow_width") -# if record.f_int != self.width(): -# record.update(session, {'f_int': self.width()}) -# -# record = Settings.get_int_settings(session, "mainwindow_x") -# if record.f_int != self.x(): -# record.update(session, {'f_int': self.x()}) -# -# record = Settings.get_int_settings(session, "mainwindow_y") -# if record.f_int != self.y(): -# record.update(session, {'f_int': self.y()}) -# -# # Find a playlist tab (as opposed to an info tab) and -# # save column widths -# if self.current_track_playlist_tab: -# self.current_track_playlist_tab.close() -# elif self.next_track_playlist_tab: -# self.next_track_playlist_tab.close() -# -# event.accept() - - def connect_signals_slots(self) -> None: -# self.actionAdd_note.triggered.connect(self.create_note) - self.action_Clear_selection.triggered.connect(self.clear_selection) -# self.actionClosePlaylist.triggered.connect(self.close_playlist_tab) -# self.actionDownload_CSV_of_played_tracks.triggered.connect( -# self.download_played_tracks) -# self.actionEnable_controls.triggered.connect( -# self.enable_play_next_controls) -# self.actionExport_playlist.triggered.connect(self.export_playlist_tab) -# self.actionImport.triggered.connect(self.import_track) -# self.actionFade.triggered.connect(self.fade) -# self.actionMoveSelected.triggered.connect(self.move_selected) -# self.actionNewPlaylist.triggered.connect(self.create_playlist) -# self.actionOpenPlaylist.triggered.connect(self.open_playlist) -# self.actionPlay_next.triggered.connect(self.play_next) -# self.actionSearch.triggered.connect(self.search_playlist) -# self.actionSearch_database.triggered.connect(self.search_database) -# self.actionSelect_next_track.triggered.connect(self.select_next_row) -# self.actionSelect_played_tracks.triggered.connect(self.select_played) -# self.actionSelect_previous_track.triggered.connect( -# self.select_previous_row) -# self.actionSelect_unplayed_tracks.triggered.connect( -# self.select_unplayed) -# self.actionSetNext.triggered.connect( -# lambda: self.tabPlaylist.currentWidget().set_selected_as_next()) -# self.actionSkip_next.triggered.connect(self.play_next) -# self.actionStop.triggered.connect(self.stop) -# # self.btnAddNote.clicked.connect(self.create_note) -# # self.btnDatabase.clicked.connect(self.search_database) -# self.btnDrop3db.clicked.connect(self.drop3db) -# self.btnHidePlayed.clicked.connect(self.hide_played) -# self.btnFade.clicked.connect(self.fade) -# # self.btnPlay.clicked.connect(self.play_next) -# # self.btnSetNext.clicked.connect( -# # lambda: self.tabPlaylist.currentWidget().set_selected_as_next()) -# # self.btnSongInfo.clicked.connect(self.song_info_search) -# self.btnStop.clicked.connect(self.stop) -# self.tabPlaylist.tabCloseRequested.connect(self.close_tab) -# self.txtSearch.returnPressed.connect(self.search_playlist_return) -# self.txtSearch.textChanged.connect(self.search_playlist_update) -# -# self.timer.timeout.connect(self.tick) -# -# def create_playlist(self) -> None: -# """Create new playlist""" -# -# dlg = QInputDialog(self) -# dlg.setInputMode(QInputDialog.TextInput) -# dlg.setLabelText("Playlist name:") -# dlg.resize(500, 100) -# ok = dlg.exec() -# if ok: -# with Session() as session: -# playlist = Playlists(session, dlg.textValue()) -# self.create_playlist_tab(session, playlist) -# -# def close_playlist_tab(self) -> None: -# """Close active playlist tab""" -# -# self.close_tab(self.tabPlaylist.currentIndex()) -# -# def close_tab(self, index: int) -> None: -# """ -# Close tab unless it holds the curren or next track -# """ -# -# if hasattr(self.tabPlaylist.widget(index), 'playlist_id'): -# if self.tabPlaylist.widget(index) == ( -# self.current_track_playlist_tab): -# self.statusbar.showMessage( -# "Can't close current track playlist", 5000) -# return -# if self.tabPlaylist.widget(index) == self.next_track_playlist_tab: -# self.statusbar.showMessage( -# "Can't close next track playlist", 5000) -# return -# # It's OK to close this playlist so remove from open playlist list -# self.tabPlaylist.widget(index).close() -# -# # Close regardless of tab type -# self.tabPlaylist.removeTab(index) -# -# def create_note(self) -> None: -# """Call playlist to create note""" -# -# try: -# self.visible_playlist_tab().create_note() -# except AttributeError: -# # Just return if there's no visible playlist tab -# return - - def create_playlist_tab(self, session: Session, - playlist: Playlists) -> None: - """ - Take the passed playlist database object, create a playlist tab and - add tab to display. - """ - - playlist_tab: PlaylistTab = PlaylistTab( - musicmuster=self, session=session, playlist_id=playlist.id) - idx: int = self.tabPlaylist.addTab(playlist_tab, playlist.name) - self.tabPlaylist.setCurrentIndex(idx) -# -# def disable_play_next_controls(self) -> None: -# """ -# Disable "play next" keyboard controls -# """ -# -# log.debug("disable_play_next_controls()") -# self.actionPlay_next.setEnabled(False) -# self.statusbar.showMessage("Play controls: Disabled", 0) -# -# def download_played_tracks(self) -> None: -# """Download a CSV of played tracks""" -# -# dlg = DownloadCSV(self) -# if dlg.exec(): -# start_dt = dlg.ui.dateTimeEdit.dateTime().toPyDateTime() -# # Get output filename -# pathspec: Tuple[str, str] = QFileDialog.getSaveFileName( -# self, 'Save CSV of tracks played', -# directory="/tmp/playlist.csv", -# filter="CSV files (*.csv)" -# ) -# if not pathspec: -# return -# -# path: str = pathspec[0] -# if not path.endswith(".csv"): -# path += ".csv" -# -# with open(path, "w") as f: -# with Session() as session: -# for playdate in Playdates.played_after(session, start_dt): -# f.write( -# f"{playdate.track.artist},{playdate.track.title}\n" -# ) -# -# def drop3db(self) -> None: -# """Drop music level by 3db if button checked""" -# -# if self.btnDrop3db.isChecked(): -# self.music.set_volume(Config.VOLUME_VLC_DROP3db, set_default=False) -# else: -# self.music.set_volume(Config.VOLUME_VLC_DEFAULT, set_default=False) -# -# def enable_play_next_controls(self) -> None: -# """ -# Enable "play next" keyboard controls -# """ -# -# log.debug("enable_play_next_controls()") -# self.actionPlay_next.setEnabled(True) -# self.statusbar.showMessage("Play controls: Enabled", 0) -# -# def end_of_track_actions(self) -> None: -# """ -# Clean up after track played -# -# Actions required: -# - Set flag to say we're not playing a track -# - Reset current track -# - Tell playlist_tab track has finished -# - Reset current playlist_tab -# - Reset clocks -# - Update headers -# - Enable controls -# """ -# -# # Set flag to say we're not playing a track so that tick() -# # doesn't see player=None and kick off end-of-track actions -# self.playing = False -# -# # Reset current track -# if self.current_track: -# self.previous_track = self.current_track -# self.current_track = None -# -# # Tell playlist_tab track has finished and -# # reset current playlist_tab -# if self.current_track_playlist_tab: -# self.current_track_playlist_tab.play_stopped() -# self.current_track_playlist_tab = None -# -# # Reset clocks -# self.frame_fade.setStyleSheet("") -# self.frame_silent.setStyleSheet("") -# self.label_elapsed_timer.setText("00:00") -# self.label_end_timer.setText("00:00") -# self.label_fade_length.setText("0:00") -# self.label_fade_timer.setText("00:00") -# self.label_silent_timer.setText("00:00") -# self.label_track_length.setText("0:00") -# self.label_start_time.setText("00:00:00") -# self.label_end_time.setText("00:00:00") -# -# # Update headers -# self.update_headers() -# -# # Enable controls -# self.enable_play_next_controls() -# -# def export_playlist_tab(self) -> None: -# """Export the current playlist to an m3u file""" -# -# if not self.visible_playlist_tab(): -# return -# -# with Session() as session: -# playlist = Playlists.get_by_id( -# session, self.visible_playlist_tab().playlist_id) -# # Get output filename -# pathspec: Tuple[str, str] = QFileDialog.getSaveFileName( -# self, 'Save Playlist', -# directory=f"{playlist.name}.m3u", -# filter="M3U files (*.m3u);;All files (*.*)" -# ) -# if not pathspec: -# return -# -# path: str = pathspec[0] -# if not path.endswith(".m3u"): -# path += ".m3u" -# -# with open(path, "w") as f: -# # Required directive on first line -# f.write("#EXTM3U\n") -# for _, track in playlist.tracks.items(): -# f.write( -# "#EXTINF:" -# f"{int(track.duration / 1000)}," -# f"{track.title} - " -# f"{track.artist}" -# "\n" -# f"{track.path}" -# "\n" -# ) -# -# def fade(self) -> None: -# """Fade currently playing track""" -# -# log.debug("musicmuster:fade()", True) -# -# self.stop_playing(fade=True) -# -# def hide_played(self): -# """Toggle hide played tracks""" -# -# if self.hide_played_tracks: -# self.hide_played_tracks = False -# self.btnHidePlayed.setText("Hide played") -# else: -# self.hide_played_tracks = True -# self.btnHidePlayed.setText("Show played") -# if self.current_track_playlist_tab: -# with Session() as session: -# self.current_track_playlist_tab.update_display(session) -# -# def import_track(self) -> None: -# """Import track file""" -# -# dlg = QFileDialog() -# dlg.setFileMode(QFileDialog.ExistingFiles) -# dlg.setViewMode(QFileDialog.Detail) -# dlg.setDirectory(Config.IMPORT_DESTINATION) -# dlg.setNameFilter("Music files (*.flac *.mp3)") -# -# if dlg.exec_(): -# with Session() as session: -# txt: str = "" -# new_tracks = [] -# for fname in dlg.selectedFiles(): -# tags = helpers.get_tags(fname) -# new_tracks.append((fname, tags)) -# title = tags['title'] -# artist = tags['artist'] -# possible_matches = Tracks.search_titles(session, title) -# if possible_matches: -# txt += 'Similar to new track ' -# txt += f'"{title}" by "{artist} ({fname})":\n\n' -# for track in possible_matches: -# txt += f' "{track.title}" by {track.artist}' -# txt += f' ({track.path})\n' -# txt += "\n" -# # Check whether to proceed if there were potential matches -# if txt: -# txt += "Proceed with import?" -# result = QMessageBox.question(self, -# "Possible duplicates", -# txt, -# QMessageBox.Ok, -# QMessageBox.Cancel -# ) -# if result == QMessageBox.Cancel: -# return -# -# # Import in separate thread -# thread = threading.Thread(target=self._import_tracks, -# args=(new_tracks,)) -# thread.start() -# -# def _import_tracks(self, tracks: list): -# """ -# Import passed files. Don't use parent session as that may be invalid -# by the time we need it. -# """ -# -# with Session() as session: -# for (fname, tags) in tracks: -# track = create_track_from_file(session, fname, tags=tags) -# # Add to playlist on screen -# # If we don't specify "repaint=False", playlist will -# # also be saved to database -# self.visible_playlist_tab().insert_track(session, track) - - def _load_last_playlists(self) -> None: - """Load the playlists that were open when the last session closed""" - - with Session() as session: - for playlist in Playlists.get_open(session): - self.create_playlist_tab(session, playlist) - playlist.mark_open(session) - - def move_selected(self) -> None: - """ - Move selected rows to another playlist - - Actions required: - - identify destination playlist - - update playlist for the rows in the database - - remove them from the display - - update destination playlist display if loaded - """ - - # Identify destination playlist - with Session() as session: - visible_tab = self.visible_playlist_tab() - source_playlist = visible_tab.playlist_id - playlists = [] - for playlist in Playlists.get_all(session): - if playlist.id == source_playlist: - continue - else: - playlists.append(playlist) - - # Get destination playlist id - dlg = SelectPlaylistDialog(self, playlists=playlists, - session=session) - dlg.exec() - if not dlg.playlist: - return - destination_playlist = dlg.playlist - - # Update playlist for the rows in the database - plr_ids = visible_tab.get_selected_playlistrow_ids() - PlaylistRows.move_to_playlist( - session, plr_ids, destination_playlist.id - ) - - # Remove moved rows from display - visible_tab.remove_selected_rows() - - # Update destination playlist_tab if visible (if not visible, it - # will be re-populated when it is opened) - destination_visible_playlist_tab = None - for tab in range(self.tabPlaylist.count()): - # Non-playlist tabs won't have a 'playlist_id' attribute - if not hasattr(self.tabPlaylist.widget(tab), 'playlist_id'): - continue - if self.tabPlaylist.widget(tab).playlist_id == dlg.playlist.id: - destination_visible_playlist_tab = ( - self.tabPlaylist.widget(tab)) - break - if destination_visible_playlist_tab: - destination_visible_playlist_tab.populate( - session, dlg.playlist.id) - - def open_info_tabs(self) -> None: - """ - Ensure we have info tabs for next and current track titles - """ - - title_list: List[str] = [] - - if self.previous_track: - title_list.append(self.previous_track.title) - if self.current_track: - title_list.append(self.current_track.title) - if self.next_track: - title_list.append(self.next_track.title) - - for title in title_list: - if title in self.info_tabs.keys(): - # We already have a tab for this track - continue - if len(self.info_tabs) >= Config.MAX_log.info_TABS: - # Find an unneeded info tab - try: - old_title = list( - set(self.info_tabs.keys()) - set(title_list) - )[0] - except IndexError: - log.debug( - f"ensure_info_tabs({title_list}): unable to add " - f"{title=}" - ) - return - # Assign redundant widget a new title - widget = self.info_tabs[title] = self.info_tabs[old_title] - idx = self.tabPlaylist.indexOf(widget) - self.tabPlaylist.setTabText( - idx, title[:Config.log.info_TAB_TITLE_LENGTH]) - del self.info_tabs[old_title] - else: - # Create a new tab for this title - widget = self.info_tabs[title] = QWebView() - widget.setZoomFactor(Config.WEB_ZOOM_FACTOR) - self.tabPlaylist.addTab( - widget, title[:Config.log.info_TAB_TITLE_LENGTH]) - txt = urllib.parse.quote_plus(title) - url = Config.log.info_TAB_URL % txt - widget.setUrl(QUrl(url)) -# -# def play_next(self) -> None: -# """ -# Play next track. -# -# Actions required: -# - If there is no next track set, return. -# - If there's currently a track playing, fade it. -# - Move next track to current track. -# - Update record of current track playlist_tab -# - If current track on different playlist_tab to last, reset -# last track playlist_tab colour -# - Set current track playlist_tab colour -# - Restore volume if -3dB active -# - Play (new) current track. -# - Tell database to record it as played -# - Tell playlist track is now playing -# - Disable play next controls -# - Update headers -# - Update clocks -# """ -# -# log.debug( -# "musicmuster.play_next(), " -# f"next_track={self.next_track.title if self.next_track else None} " -# "current_track=" -# f"{self.current_track.title if self.current_track else None}", -# True -# ) -# -# # If there is no next track set, return. -# if not self.next_track: -# log.debug("musicmuster.play_next(): no next track selected", True) -# return -# -# with Session() as session: -# # If there's currently a track playing, fade it. -# self.stop_playing(fade=True) -# -# # Move next track to current track. -# self.current_track = self.next_track -# self.next_track = None -# -# # If current track on different playlist_tab to last, reset -# # last track playlist_tab colour -# # Set current track playlist_tab colour -# if self.current_track_playlist_tab != self.next_track_playlist_tab: -# self.set_tab_colour(self.current_track_playlist_tab, -# QColor(Config.COLOUR_NORMAL_TAB)) -# -# # Update record of current track playlist_tab -# self.current_track_playlist_tab = self.next_track_playlist_tab -# self.next_track_playlist_tab = None -# -# # Set current track playlist_tab colour -# self.set_tab_colour(self.current_track_playlist_tab, -# QColor(Config.COLOUR_CURRENT_TAB)) -# -# # Restore volume if -3dB active -# if self.btnDrop3db.isChecked(): -# self.btnDrop3db.setChecked(False) -# -# # Play (new) current track -# start_at = datetime.now() -# self.music.play(self.current_track.path) -# -# # Tell database to record it as played -# Playdates(session, self.current_track.id) -# -# # Set last_played date -# Tracks.update_lastplayed(session, self.current_track.id) -# -# # Tell playlist track is now playing -# self.current_track_playlist_tab.play_started(session) -# -# # Disable play next controls -# self.disable_play_next_controls() -# -# # Update headers -# self.update_headers() -# -# # Update clocks -# self.label_track_length.setText( -# helpers.ms_to_mmss(self.current_track.duration) -# ) -# fade_at = self.current_track.fade_at -# silence_at = self.current_track.silence_at -# length = self.current_track.duration -# self.label_fade_length.setText( -# helpers.ms_to_mmss(silence_at - fade_at)) -# self.label_start_time.setText( -# start_at.strftime(Config.TRACK_TIME_FORMAT)) -# end_at = start_at + timedelta( -# milliseconds=self.current_track.duration) -# self.label_end_time.setText( -# end_at.strftime(Config.TRACK_TIME_FORMAT)) -# -# def search_database(self) -> None: -# """Show dialog box to select and cue track from database""" -# -# with Session() as session: -# dlg = DbDialog(self, session) -# dlg.exec() -# -# def search_playlist(self): -# """Show text box to search playlist""" -# -# self.disable_play_next_controls() -# self.txtSearch.setHidden(False) -# self.txtSearch.setFocus() -# -# def search_playlist_return(self): -# """Close off search box when return pressed""" -# -# self.txtSearch.setText("") -# self.txtSearch.setHidden(True) -# self.enable_play_next_controls() -# self.visible_playlist_tab().set_filter("") -# -# def search_playlist_update(self): -# """Update search when search string changes""" -# -# self.visible_playlist_tab().set_filter(self.txtSearch.text()) -# -# def open_playlist(self): -# with Session() as session: -# playlists = Playlists.get_closed(session) -# dlg = SelectPlaylistDialog(self, playlists=playlists, -# session=session) -# dlg.exec() -# playlist = dlg.playlist -# if playlist: -# playlist.mark_open(session) -# self.create_playlist_tab(session, playlist) -# -# def select_next_row(self) -> None: -# """Select next or first row in playlist""" -# -# self.visible_playlist_tab().select_next_row() -# -# def select_played(self) -> None: -# """Select all played tracks in playlist""" -# -# self.visible_playlist_tab().select_played_tracks() -# -# def select_previous_row(self) -> None: -# """Select previous or first row in playlist""" -# -# self.visible_playlist_tab().select_previous_row() -# -# def select_unplayed(self) -> None: -# """Select all unplayed tracks in playlist""" -# -# self.visible_playlist_tab().select_unplayed_tracks() - - def set_tab_colour(self, widget: PlaylistTab, colour: QColor) -> None: - """ - 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) -> None: -# """ -# Open browser tab for Wikipedia, searching for -# the first that exists of: -# - selected track -# - next track -# - current track -# """ -# -# title: Optional[str] = self.visible_playlist_tab().get_selected_title() -# if not title: -# if self.next_track: -# title = self.next_track.title -# if not title: -# if self.current_track: -# title = self.current_track.title -# if title: -# txt = urllib.parse.quote_plus(title) -# url = Config.log.info_TAB_URL % txt -# webbrowser.open(url, new=2) -# -# def stop(self) -> None: -# """Stop playing immediately""" -# -# log.debug("musicmuster.stop()") -# -# self.stop_playing(fade=False) -# -# def stop_playing(self, fade=True) -> None: -# """ -# Stop playing current track -# -# Actions required: -# - Return if not playing -# - Stop/fade track -# - Reset playlist_tab colour -# - Run end-of-track actions -# """ -# -# log.debug(f"musicmuster.stop_playing({fade=})", True) -# -# # Return if not playing -# if not self.playing: -# log.debug("musicmuster.stop_playing(): not playing", True) -# return -# -# # Stop/fade track -# self.previous_track_position = self.music.get_position() -# if fade: -# log.debug("musicmuster.stop_playing(): fading music", True) -# self.music.fade() -# else: -# log.debug("musicmuster.stop_playing(): stopping music", True) -# self.music.stop() -# -# # Reset playlist_tab colour -# 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)) -# -# # Run end-of-track actions -# self.end_of_track_actions() - - def this_is_the_next_track(self, playlist_tab: PlaylistTab, - track: Tracks, session) -> None: - """ - This is notification from a playlist tab that it holds the next - track to be played. - - Actions required: - - Clear next track if on other tab - - Reset tab colour if on other tab - - Note next playlist tab - - Set next playlist_tab tab colour - - Note next track - - Update headers - - Populate ‘info’ tabs - - """ - - # Clear next track if on another tab - if self.next_track_playlist_tab != playlist_tab: - # We need to reset the ex-next-track playlist - if self.next_track_playlist_tab: - self.next_track_playlist_tab.clear_next(session) - - # Reset tab colour if on other 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)) - - # Note next playlist tab - self.next_track_playlist_tab = playlist_tab - - # Set next playlist_tab tab colour if it isn't the - # currently-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_NEXT_TAB)) - - # Note next track - self.next_track = TrackData(track) - - # Update headers - self.update_headers() - - # Populate 'info' tabs - self.open_info_tabs() -# -# def tick(self) -> None: -# """ -# Carry out clock tick actions. -# -# The Time of Day clock is updated every tick (500ms). -# -# All other timers are updated every second. As the timers have a -# one-second resolution, updating every 500ms can result in some -# timers updating and then, 500ms later, other timers updating. That -# looks odd. -# -# Actions required: -# - Update TOD clock -# - If track is playing, update track clocks time and colours -# - Else: run stop_track -# """ -# -# # Update TOD clock -# self.lblTOD.setText(datetime.now().strftime(Config.TOD_TIME_FORMAT)) -# -# self.even_tick = not self.even_tick -# if not self.even_tick: -# return -# -# # If track is playing, update track clocks time and colours -# if self.music.player and self.music.playing(): -# self.playing = True -# playtime: int = self.music.get_playtime() -# time_to_fade: int = (self.current_track.fade_at - playtime) -# time_to_silence: int = ( -# self.current_track.silence_at - playtime) -# time_to_end: int = (self.current_track.duration - playtime) -# -# # Elapsed time -# if time_to_end < 500: -# self.label_elapsed_timer.setText( -# helpers.ms_to_mmss(playtime) -# ) -# else: -# self.label_elapsed_timer.setText( -# helpers.ms_to_mmss(playtime) -# ) -# -# # Time to fade -# self.label_fade_timer.setText(helpers.ms_to_mmss(time_to_fade)) -# -# # If silent in the next 5 seconds, put warning colour on -# # time to silence box and enable play controls -# if time_to_silence <= 5500: -# self.frame_silent.setStyleSheet( -# f"background: {Config.COLOUR_ENDING_TIMER}" -# ) -# self.enable_play_next_controls() -# # Set warning colour on time to silence box when fade starts -# elif time_to_fade <= 500: -# self.frame_silent.setStyleSheet( -# f"background: {Config.COLOUR_WARNING_TIMER}" -# ) -# # Five seconds before fade starts, set warning colour on -# # time to silence box and enable play controls -# elif time_to_fade <= 5500: -# self.frame_fade.setStyleSheet( -# f"background: {Config.COLOUR_WARNING_TIMER}" -# ) -# self.enable_play_next_controls() -# else: -# self.frame_silent.setStyleSheet("") -# self.frame_fade.setStyleSheet("") -# -# self.label_silent_timer.setText( -# helpers.ms_to_mmss(time_to_silence) -# ) -# -# # Time to end -# self.label_end_timer.setText(helpers.ms_to_mmss(time_to_end)) -# -# else: -# if self.playing: -# self.stop_playing() - - def update_headers(self) -> None: - """ - Update last / current / next track headers - """ - - try: - self.hdrPreviousTrack.setText( - f"{self.previous_track.title} - {self.previous_track.artist}" - ) - except (AttributeError, DetachedInstanceError): - self.hdrPreviousTrack.setText("") - - try: - self.hdrCurrentTrack.setText( - f"{self.current_track.title} - {self.current_track.artist}" - ) - except (AttributeError, DetachedInstanceError): - self.hdrCurrentTrack.setText("") - - try: - self.hdrNextTrack.setText( - f"{self.next_track.title} - {self.next_track.artist}" - ) - except (AttributeError, DetachedInstanceError): - self.hdrNextTrack.setText("") -# -# -# class DbDialog(QDialog): -# """Select track from database""" -# -# def __init__(self, parent, session): # review -# super().__init__(parent) -# self.session = session -# self.ui = Ui_Dialog() -# self.ui.setupUi(self) -# self.ui.btnAdd.clicked.connect(self.add_selected) -# self.ui.btnAddClose.clicked.connect(self.add_selected_and_close) -# self.ui.btnClose.clicked.connect(self.close) -# self.ui.matchList.itemDoubleClicked.connect(self.double_click) -# self.ui.matchList.itemSelectionChanged.connect(self.selection_changed) -# self.ui.radioTitle.toggled.connect(self.title_artist_toggle) -# self.ui.searchString.textEdited.connect(self.chars_typed) -# -# record = Settings.get_int_settings(self.session, "dbdialog_width") -# width = record.f_int or 800 -# record = Settings.get_int_settings(self.session, "dbdialog_height") -# height = record.f_int or 600 -# self.resize(width, height) -# -# def __del__(self): # review -# record = Settings.get_int_settings(self.session, "dbdialog_height") -# if record.f_int != self.height(): -# record.update(self.session, {'f_int': self.height()}) -# -# record = Settings.get_int_settings(self.session, "dbdialog_width") -# if record.f_int != self.width(): -# record.update(self.session, {'f_int': self.width()}) -# -# def add_selected(self): # review -# if not self.ui.matchList.selectedItems(): -# return -# -# item = self.ui.matchList.currentItem() -# track = item.data(Qt.UserRole) -# self.add_track(track) -# -# def add_selected_and_close(self): # review -# self.add_selected() -# self.close() -# -# def title_artist_toggle(self): # review -# """ -# Handle switching between searching for artists and searching for -# titles -# """ -# -# # Logic is handled already in chars_typed(), so just call that. -# self.chars_typed(self.ui.searchString.text()) -# -# def chars_typed(self, s): # review -# if len(s) > 0: -# if self.ui.radioTitle.isChecked(): -# matches = Tracks.search_titles(self.session, s) -# else: -# matches = Tracks.search_artists(self.session, s) -# self.ui.matchList.clear() -# if matches: -# for track in matches: -# t = QListWidgetItem() -# t.setText( -# f"{track.title} - {track.artist} " -# f"[{helpers.ms_to_mmss(track.duration)}] " -# f"({helpers.get_relative_date(track.lastplayed)})" -# ) -# t.setData(Qt.UserRole, track) -# self.ui.matchList.addItem(t) -# -# def double_click(self, entry): # review -# track = entry.data(Qt.UserRole) -# self.add_track(track) -# # Select search text to make it easier for next search -# self.select_searchtext() -# -# def add_track(self, track): # review -# # Add to playlist on screen -# self.parent().visible_playlist_tab().insert_track( -# self.session, track) -# # Commit session to get correct row numbers if more tracks added -# self.session.commit() -# # Select search text to make it easier for next search -# self.select_searchtext() -# -# def select_searchtext(self): # review -# self.ui.searchString.selectAll() -# self.ui.searchString.setFocus() -# -# def selection_changed(self): # review -# if not self.ui.matchList.selectedItems(): -# return -# -# item = self.ui.matchList.currentItem() -# track = item.data(Qt.UserRole) -# self.ui.dbPath.setText(track.path) -# -# -# class DownloadCSV(QDialog): -# def __init__(self, parent=None): -# super().__init__(parent) -# -# self.ui = Ui_DateSelect() -# self.ui.setupUi(self) -# self.ui.dateTimeEdit.setDate(QDate.currentDate()) -# self.ui.dateTimeEdit.setTime(QTime(19, 59, 0)) -# self.ui.buttonBox.accepted.connect(self.accept) -# self.ui.buttonBox.rejected.connect(self.reject) - - -class SelectPlaylistDialog(QDialog): - def __init__(self, parent=None, playlists=None, session=None): - super().__init__(parent) - - if playlists is None: - return - self.ui = Ui_dlgSelectPlaylist() - self.ui.setupUi(self) - self.ui.lstPlaylists.itemDoubleClicked.connect(self.list_doubleclick) - self.ui.buttonBox.accepted.connect(self.open) - self.ui.buttonBox.rejected.connect(self.close) - self.session = session - self.playlist = None - self.plid = None - - record = Settings.get_int_settings( - self.session, "select_playlist_dialog_width") - width = record.f_int or 800 - record = Settings.get_int_settings( - self.session, "select_playlist_dialog_height") - height = record.f_int or 600 - self.resize(width, height) - - for playlist in playlists: - p = QListWidgetItem() - p.setText(playlist.name) - p.setData(Qt.UserRole, playlist) - self.ui.lstPlaylists.addItem(p) - - def __del__(self): # review - record = Settings.get_int_settings( - self.session, "select_playlist_dialog_height") - if record.f_int != self.height(): - record.update(self.session, {'f_int': self.height()}) - - record = Settings.get_int_settings( - self.session, "select_playlist_dialog_width") - if record.f_int != self.width(): - record.update(self.session, {'f_int': self.width()}) - - def list_doubleclick(self, entry): # review - self.playlist = entry.data(Qt.UserRole) - self.accept() - - def open(self): # review - if self.ui.lstPlaylists.selectedItems(): - item = self.ui.lstPlaylists.currentItem() - self.playlist = item.data(Qt.UserRole) - self.accept() - - -if __name__ == "__main__": - # p = argparse.ArgumentParser() - # # Only allow at most one option to be specified - # group = p.add_mutually_exclusive_group() - # group.add_argument('-u', '--update', - # action="store_true", dest="update", - # default=False, help="Update database") - # # group.add_argument('-f', '--full-update', - # # action="store_true", dest="full_update", - # # default=False, help="Update database") - # # group.add_argument('-i', '--import', dest="fname", help="Input file") - # args = p.parse_args() - # - # # Run as required - # if args.update: - # log.debug("Updating database") - # with Session() as session: - # update_db(session) - # # elif args.full_update: - # # log.debug("Full update of database") - # # with Session() as session: - # # full_update_db(session) - # else: - # # Normal run - try: - Base.metadata.create_all(engine) - app = QApplication(sys.argv) - win = Window() - win.show() - sys.exit(app.exec()) - except Exception: - msg = "Unhandled Exception caught by musicmuster.main()" - log.exception(msg, exc_info=True, stack_info=True)