From 829172177c76aae8a9e4f38f11f4a35a80a3923a Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Fri, 19 Jul 2024 19:59:18 +0100 Subject: [PATCH] Implement external browser --- app/config.py | 6 +++- app/infotabs.py | 44 ++++++--------------------- app/musicmuster.py | 72 ++++++++++++++++++++++++++++++++++++-------- app/playlistmodel.py | 11 +++++-- 4 files changed, 83 insertions(+), 50 deletions(-) diff --git a/app/config.py b/app/config.py index 430f4c7..6e175a1 100644 --- a/app/config.py +++ b/app/config.py @@ -37,10 +37,11 @@ class Config(object): DEBUG_MODULES: List[Optional[str]] = [] DEFAULT_COLUMN_WIDTH = 200 DISPLAY_SQL = False - EPOCH = dt.datetime(1970, 1, 1) ENGINE_OPTIONS = dict(pool_pre_ping=True) + EPOCH = dt.datetime(1970, 1, 1) ERRORS_FROM = ["noreply@midnighthax.com"] ERRORS_TO = ["kae@midnighthax.com"] + EXTERNAL_BROWSER_PATH = "/usr/bin/vivaldi" FADE_CURVE_BACKGROUND = "lightyellow" FADE_CURVE_FOREGROUND = "blue" FADE_CURVE_MS_BEFORE_FADE = 5000 @@ -90,10 +91,12 @@ class Config(object): ROOT = os.environ.get("ROOT") or "/home/kae/music" ROWS_FROM_ZERO = True SCROLL_TOP_MARGIN = 3 + SONGFACTS_ON_NEXT = False START_GAP_WARNING_THRESHOLD = 300 TEXT_NO_TRACK_NO_NOTE = "[Section header]" TOD_TIME_FORMAT = "%H:%M:%S" TRACK_TIME_FORMAT = "%H:%M:%S" + USE_INTERNAL_BROWSER = False VLC_MAIN_PLAYER_NAME = "MusicMuster Main Player" VLC_PREVIEW_PLAYER_NAME = "MusicMuster Preview Player" VLC_VOLUME_DEFAULT = 75 @@ -101,6 +104,7 @@ class Config(object): WARNING_MS_BEFORE_FADE = 5500 WARNING_MS_BEFORE_SILENCE = 5500 WEB_ZOOM_FACTOR = 1.2 + WIKIPEDIA_ON_NEXT = False # These rely on earlier definitions IMPORT_DESTINATION = os.path.join(ROOT, "Singles") diff --git a/app/infotabs.py b/app/infotabs.py index 2901620..2542ea1 100644 --- a/app/infotabs.py +++ b/app/infotabs.py @@ -1,7 +1,5 @@ # Standard library imports -import urllib.parse import datetime as dt -from slugify import slugify # type: ignore from typing import Dict, Optional # PyQt imports @@ -13,8 +11,6 @@ from PyQt6.QtWidgets import QTabWidget, QWidget # App imports from config import Config -from classes import MusicMusterSignals -from log import log class InfoTabs(QTabWidget): @@ -25,37 +21,17 @@ class InfoTabs(QTabWidget): def __init__(self, parent: Optional[QWidget] = None) -> None: super().__init__(parent) - self.signals = MusicMusterSignals() - self.signals.search_songfacts_signal.connect(self.open_in_songfacts) - self.signals.search_wikipedia_signal.connect(self.open_in_wikipedia) - # re-use the oldest one later) - self.last_update: Dict[QWebEngineView, dt.datetime] = {} - self.tabtitles: Dict[int, str] = {} + if Config.USE_INTERNAL_BROWSER: + # re-use the oldest one later) + self.last_update: Dict[QWebEngineView, dt.datetime] = {} + self.tabtitles: Dict[int, str] = {} - # Create one tab which (for some reason) creates flickering if - # done later - widget = QWebEngineView() - widget.setZoomFactor(Config.WEB_ZOOM_FACTOR) - self.last_update[widget] = dt.datetime.now() - _ = self.addTab(widget, "") - - def open_in_songfacts(self, title: str) -> None: - """Search Songfacts for title""" - - slug = slugify(title, replacements=([["'", ""]])) - log.info(f"Songfacts Infotab for {title=}") - url = f"https://www.songfacts.com/search/songs/{slug}" - - self.open_tab(url, title) - - def open_in_wikipedia(self, title: str) -> None: - """Search Wikipedia for title""" - - str = urllib.parse.quote_plus(title) - log.info(f"Wikipedia Infotab for {title=}") - url = f"https://www.wikipedia.org/w/index.php?search={str}" - - self.open_tab(url, title) + # Create one tab which (for some reason) creates flickering if + # done later + widget = QWebEngineView() + widget.setZoomFactor(Config.WEB_ZOOM_FACTOR) + self.last_update[widget] = dt.datetime.now() + _ = self.addTab(widget, "") def open_tab(self, url: str, title: str) -> None: """ diff --git a/app/musicmuster.py b/app/musicmuster.py index 698a648..9504168 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -7,8 +7,11 @@ import argparse import datetime as dt import os import shutil +from slugify import slugify # type: ignore import subprocess import sys +import urllib.parse +import webbrowser # PyQt imports from PyQt6.QtCore import ( @@ -238,7 +241,9 @@ class PreviewManager: with db.Session() as session: track = session.get(Tracks, self.track_id) if not track: - raise ValueError(f"PreviewManager: unable to retreive track {self.track_id=}") + raise ValueError( + f"PreviewManager: unable to retreive track {self.track_id=}" + ) self.intro = track.intro self.path = track.path @@ -258,7 +263,9 @@ class PreviewManager: class Window(QMainWindow, Ui_MainWindow): - def __init__(self, parent: Optional[QWidget] = None, *args: list, **kwargs: dict) -> None: + def __init__( + self, parent: Optional[QWidget] = None, *args: list, **kwargs: dict + ) -> None: super().__init__(parent) self.setupUi(self) @@ -299,6 +306,13 @@ class Window(QMainWindow, Ui_MainWindow): self.connect_signals_slots() self.catch_return_key = False + if not Config.USE_INTERNAL_BROWSER: + webbrowser.register( + "browser", + None, + webbrowser.BackgroundBrowser(Config.EXTERNAL_BROWSER_PATH), + ) + # Set up shortcut key for instant logging from keyboard self.action_quicklog = QShortcut(QKeySequence("Ctrl+L"), self) self.action_quicklog.activated.connect(self.quicklog) @@ -504,6 +518,9 @@ class Window(QMainWindow, Ui_MainWindow): self.timer100.timeout.connect(self.tick_100ms) self.timer1000.timeout.connect(self.tick_1000ms) + self.signals.search_songfacts_signal.connect(self.open_songfacts_browser) + self.signals.search_wikipedia_signal.connect(self.open_wikipedia_browser) + def create_playlist( self, session: Session, playlist_name: Optional[str] = None ) -> Optional[Playlists]: @@ -1028,6 +1045,30 @@ class Window(QMainWindow, Ui_MainWindow): self.tabPlaylist.setCurrentIndex(idx) + def open_songfacts_browser(self, title: str) -> None: + """Search Songfacts for title""" + + slug = slugify(title, replacements=([["'", ""]])) + log.info(f"Songfacts browser tab for {title=}") + url = f"https://www.songfacts.com/search/songs/{slug}" + + if Config.USE_INTERNAL_BROWSER: + self.tabInfolist.open_tab(url, title) + else: + webbrowser.get('browser').open_new_tab(url) + + def open_wikipedia_browser(self, title: str) -> None: + """Search Wikipedia for title""" + + str = urllib.parse.quote_plus(title) + log.info(f"Wikipedia browser tab for {title=}") + url = f"https://www.wikipedia.org/w/index.php?search={str}" + + if Config.USE_INTERNAL_BROWSER: + self.tabInfolist.open_tab(url, title) + else: + webbrowser.get('browser').open_new_tab(url) + def paste_rows(self) -> None: """ Paste earlier cut rows. @@ -1189,9 +1230,9 @@ class Window(QMainWindow, Ui_MainWindow): # Otherwise get track_id to next track to play if track_sequence.next: if track_sequence.next.path: - track_info = TrackInfo(track_sequence.next.track_id, - track_sequence.next.row_number - ) + track_info = TrackInfo( + track_sequence.next.track_id, track_sequence.next.row_number + ) else: return self.preview_manager.set_track_info(track_info) @@ -1456,13 +1497,18 @@ class Window(QMainWindow, Ui_MainWindow): y = Settings.get_setting(session, "mainwindow_y").f_int or 100 width = Settings.get_setting(session, "mainwindow_width").f_int or 100 height = Settings.get_setting(session, "mainwindow_height").f_int or 100 - splitter_top = Settings.get_setting(session, "splitter_top").f_int or 100 - splitter_bottom = ( - Settings.get_setting(session, "splitter_bottom").f_int or 100 - ) - self.setGeometry(x, y, width, height) - self.splitter.setSizes([splitter_top, splitter_bottom]) + + if Config.USE_INTERNAL_BROWSER: + splitter_top = ( + Settings.get_setting(session, "splitter_top").f_int or 100 + ) + splitter_bottom = ( + Settings.get_setting(session, "splitter_bottom").f_int or 100 + ) + self.splitter.setSizes([splitter_top, splitter_bottom]) + else: + self.tabInfolist.hide() def set_selected_track_next(self) -> None: """ @@ -1615,7 +1661,9 @@ class Window(QMainWindow, Ui_MainWindow): if self.btnPreview.isChecked(): if self.preview_manager.is_playing(): self.btnPreview.setChecked(True) - minutes, seconds = divmod(self.preview_manager.get_playtime() / 1000, 60) + minutes, seconds = divmod( + self.preview_manager.get_playtime() / 1000, 60 + ) self.label_intro_timer.setText(f"{int(minutes)}:{seconds:04.1f}") # if self.preview_track_manager.time_remaining_intro() <= 50: # self.label_intro_timer.setStyleSheet( diff --git a/app/playlistmodel.py b/app/playlistmodel.py index f0817b7..56befb8 100644 --- a/app/playlistmodel.py +++ b/app/playlistmodel.py @@ -1259,9 +1259,14 @@ class PlaylistModel(QAbstractTableModel): log.error(f"Error creating MainTrackManager({prd=}): ({str(e)})") return False - self.signals.search_wikipedia_signal.emit( - self.playlist_rows[row_number].title - ) + if Config.WIKIPEDIA_ON_NEXT: + self.signals.search_wikipedia_signal.emit( + self.playlist_rows[row_number].title + ) + if Config.SONGFACTS_ON_NEXT: + self.signals.search_songfacts_signal.emit( + self.playlist_rows[row_number].title + ) if old_next_row: self.invalidate_row(old_next_row) self.invalidate_row(row_number)