Implement external browser

This commit is contained in:
Keith Edmunds 2024-07-19 19:59:18 +01:00
parent 30d8b0d5c8
commit 829172177c
4 changed files with 83 additions and 50 deletions

View File

@ -37,10 +37,11 @@ class Config(object):
DEBUG_MODULES: List[Optional[str]] = [] DEBUG_MODULES: List[Optional[str]] = []
DEFAULT_COLUMN_WIDTH = 200 DEFAULT_COLUMN_WIDTH = 200
DISPLAY_SQL = False DISPLAY_SQL = False
EPOCH = dt.datetime(1970, 1, 1)
ENGINE_OPTIONS = dict(pool_pre_ping=True) ENGINE_OPTIONS = dict(pool_pre_ping=True)
EPOCH = dt.datetime(1970, 1, 1)
ERRORS_FROM = ["noreply@midnighthax.com"] ERRORS_FROM = ["noreply@midnighthax.com"]
ERRORS_TO = ["kae@midnighthax.com"] ERRORS_TO = ["kae@midnighthax.com"]
EXTERNAL_BROWSER_PATH = "/usr/bin/vivaldi"
FADE_CURVE_BACKGROUND = "lightyellow" FADE_CURVE_BACKGROUND = "lightyellow"
FADE_CURVE_FOREGROUND = "blue" FADE_CURVE_FOREGROUND = "blue"
FADE_CURVE_MS_BEFORE_FADE = 5000 FADE_CURVE_MS_BEFORE_FADE = 5000
@ -90,10 +91,12 @@ class Config(object):
ROOT = os.environ.get("ROOT") or "/home/kae/music" ROOT = os.environ.get("ROOT") or "/home/kae/music"
ROWS_FROM_ZERO = True ROWS_FROM_ZERO = True
SCROLL_TOP_MARGIN = 3 SCROLL_TOP_MARGIN = 3
SONGFACTS_ON_NEXT = False
START_GAP_WARNING_THRESHOLD = 300 START_GAP_WARNING_THRESHOLD = 300
TEXT_NO_TRACK_NO_NOTE = "[Section header]" TEXT_NO_TRACK_NO_NOTE = "[Section header]"
TOD_TIME_FORMAT = "%H:%M:%S" TOD_TIME_FORMAT = "%H:%M:%S"
TRACK_TIME_FORMAT = "%H:%M:%S" TRACK_TIME_FORMAT = "%H:%M:%S"
USE_INTERNAL_BROWSER = False
VLC_MAIN_PLAYER_NAME = "MusicMuster Main Player" VLC_MAIN_PLAYER_NAME = "MusicMuster Main Player"
VLC_PREVIEW_PLAYER_NAME = "MusicMuster Preview Player" VLC_PREVIEW_PLAYER_NAME = "MusicMuster Preview Player"
VLC_VOLUME_DEFAULT = 75 VLC_VOLUME_DEFAULT = 75
@ -101,6 +104,7 @@ class Config(object):
WARNING_MS_BEFORE_FADE = 5500 WARNING_MS_BEFORE_FADE = 5500
WARNING_MS_BEFORE_SILENCE = 5500 WARNING_MS_BEFORE_SILENCE = 5500
WEB_ZOOM_FACTOR = 1.2 WEB_ZOOM_FACTOR = 1.2
WIKIPEDIA_ON_NEXT = False
# These rely on earlier definitions # These rely on earlier definitions
IMPORT_DESTINATION = os.path.join(ROOT, "Singles") IMPORT_DESTINATION = os.path.join(ROOT, "Singles")

View File

@ -1,7 +1,5 @@
# Standard library imports # Standard library imports
import urllib.parse
import datetime as dt import datetime as dt
from slugify import slugify # type: ignore
from typing import Dict, Optional from typing import Dict, Optional
# PyQt imports # PyQt imports
@ -13,8 +11,6 @@ from PyQt6.QtWidgets import QTabWidget, QWidget
# App imports # App imports
from config import Config from config import Config
from classes import MusicMusterSignals
from log import log
class InfoTabs(QTabWidget): class InfoTabs(QTabWidget):
@ -25,37 +21,17 @@ class InfoTabs(QTabWidget):
def __init__(self, parent: Optional[QWidget] = None) -> None: def __init__(self, parent: Optional[QWidget] = None) -> None:
super().__init__(parent) super().__init__(parent)
self.signals = MusicMusterSignals() if Config.USE_INTERNAL_BROWSER:
self.signals.search_songfacts_signal.connect(self.open_in_songfacts) # re-use the oldest one later)
self.signals.search_wikipedia_signal.connect(self.open_in_wikipedia) self.last_update: Dict[QWebEngineView, dt.datetime] = {}
# re-use the oldest one later) self.tabtitles: Dict[int, str] = {}
self.last_update: Dict[QWebEngineView, dt.datetime] = {}
self.tabtitles: Dict[int, str] = {}
# Create one tab which (for some reason) creates flickering if # Create one tab which (for some reason) creates flickering if
# done later # done later
widget = QWebEngineView() widget = QWebEngineView()
widget.setZoomFactor(Config.WEB_ZOOM_FACTOR) widget.setZoomFactor(Config.WEB_ZOOM_FACTOR)
self.last_update[widget] = dt.datetime.now() self.last_update[widget] = dt.datetime.now()
_ = self.addTab(widget, "") _ = 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)
def open_tab(self, url: str, title: str) -> None: def open_tab(self, url: str, title: str) -> None:
""" """

View File

@ -7,8 +7,11 @@ import argparse
import datetime as dt import datetime as dt
import os import os
import shutil import shutil
from slugify import slugify # type: ignore
import subprocess import subprocess
import sys import sys
import urllib.parse
import webbrowser
# PyQt imports # PyQt imports
from PyQt6.QtCore import ( from PyQt6.QtCore import (
@ -238,7 +241,9 @@ class PreviewManager:
with db.Session() as session: with db.Session() as session:
track = session.get(Tracks, self.track_id) track = session.get(Tracks, self.track_id)
if not track: 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.intro = track.intro
self.path = track.path self.path = track.path
@ -258,7 +263,9 @@ class PreviewManager:
class Window(QMainWindow, Ui_MainWindow): 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) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
@ -299,6 +306,13 @@ class Window(QMainWindow, Ui_MainWindow):
self.connect_signals_slots() self.connect_signals_slots()
self.catch_return_key = False 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 # Set up shortcut key for instant logging from keyboard
self.action_quicklog = QShortcut(QKeySequence("Ctrl+L"), self) self.action_quicklog = QShortcut(QKeySequence("Ctrl+L"), self)
self.action_quicklog.activated.connect(self.quicklog) self.action_quicklog.activated.connect(self.quicklog)
@ -504,6 +518,9 @@ class Window(QMainWindow, Ui_MainWindow):
self.timer100.timeout.connect(self.tick_100ms) self.timer100.timeout.connect(self.tick_100ms)
self.timer1000.timeout.connect(self.tick_1000ms) 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( def create_playlist(
self, session: Session, playlist_name: Optional[str] = None self, session: Session, playlist_name: Optional[str] = None
) -> Optional[Playlists]: ) -> Optional[Playlists]:
@ -1028,6 +1045,30 @@ class Window(QMainWindow, Ui_MainWindow):
self.tabPlaylist.setCurrentIndex(idx) 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: def paste_rows(self) -> None:
""" """
Paste earlier cut rows. Paste earlier cut rows.
@ -1189,9 +1230,9 @@ class Window(QMainWindow, Ui_MainWindow):
# Otherwise get track_id to next track to play # Otherwise get track_id to next track to play
if track_sequence.next: if track_sequence.next:
if track_sequence.next.path: if track_sequence.next.path:
track_info = TrackInfo(track_sequence.next.track_id, track_info = TrackInfo(
track_sequence.next.row_number track_sequence.next.track_id, track_sequence.next.row_number
) )
else: else:
return return
self.preview_manager.set_track_info(track_info) 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 y = Settings.get_setting(session, "mainwindow_y").f_int or 100
width = Settings.get_setting(session, "mainwindow_width").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 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.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: def set_selected_track_next(self) -> None:
""" """
@ -1615,7 +1661,9 @@ class Window(QMainWindow, Ui_MainWindow):
if self.btnPreview.isChecked(): if self.btnPreview.isChecked():
if self.preview_manager.is_playing(): if self.preview_manager.is_playing():
self.btnPreview.setChecked(True) 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}") self.label_intro_timer.setText(f"{int(minutes)}:{seconds:04.1f}")
# if self.preview_track_manager.time_remaining_intro() <= 50: # if self.preview_track_manager.time_remaining_intro() <= 50:
# self.label_intro_timer.setStyleSheet( # self.label_intro_timer.setStyleSheet(

View File

@ -1259,9 +1259,14 @@ class PlaylistModel(QAbstractTableModel):
log.error(f"Error creating MainTrackManager({prd=}): ({str(e)})") log.error(f"Error creating MainTrackManager({prd=}): ({str(e)})")
return False return False
self.signals.search_wikipedia_signal.emit( if Config.WIKIPEDIA_ON_NEXT:
self.playlist_rows[row_number].title 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: if old_next_row:
self.invalidate_row(old_next_row) self.invalidate_row(old_next_row)
self.invalidate_row(row_number) self.invalidate_row(row_number)