Update v1.2

This commit is contained in:
afkarxyz
2025-01-09 23:16:16 +07:00
committed by GitHub
parent 77bbc70c9b
commit 61c53655ff
+67 -22
View File
@@ -6,8 +6,8 @@ from pathlib import Path
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout, QLabel, QLineEdit, QPushButton,
QProgressBar, QFileDialog, QCheckBox, QRadioButton, QProgressBar, QFileDialog, QCheckBox, QRadioButton,
QGroupBox) QGroupBox, QComboBox)
from PyQt6.QtCore import QThread, pyqtSignal, Qt, QSettings, QTimer from PyQt6.QtCore import QThread, pyqtSignal, Qt, QSettings, QSize
from PyQt6.QtGui import QIcon, QPixmap, QCursor from PyQt6.QtGui import QIcon, QPixmap, QCursor
from GetMetadata import get_metadata from GetMetadata import get_metadata
from LucidaDownloader import TrackDownloader from LucidaDownloader import TrackDownloader
@@ -29,11 +29,11 @@ class MetadataFetcher(QThread):
finished = pyqtSignal(dict) finished = pyqtSignal(dict)
error = pyqtSignal(str) error = pyqtSignal(str)
def __init__(self, url, headless=True, use_fallback=False): def __init__(self, url, headless=True, service="tidal"):
super().__init__() super().__init__()
self.url = url self.url = url
self.headless_mode = headless self.headless_mode = headless
self.use_fallback = use_fallback self.service = service
self.max_retries = 3 self.max_retries = 3
def extract_track_id(self, url): def extract_track_id(self, url):
@@ -47,8 +47,7 @@ class MetadataFetcher(QThread):
for attempt in range(self.max_retries): for attempt in range(self.max_retries):
try: try:
platform = "amazon" if self.use_fallback else "tidal" lucida_url = f"https://lucida.to/?url=https%3A%2F%2Fopen.spotify.com%2Ftrack%2F{track_id}&country=auto&to={self.service}"
lucida_url = f"https://lucida.to/?url=https%3A%2F%2Fopen.spotify.com%2Ftrack%2F{track_id}&country=auto&to={platform}"
browser = await zd.start(headless=self.headless_mode) browser = await zd.start(headless=self.headless_mode)
try: try:
page = await browser.get(lucida_url) page = await browser.get(lucida_url)
@@ -106,11 +105,10 @@ class DownloaderWorker(QThread):
def progress_callback(self, downloaded_size, total_size): def progress_callback(self, downloaded_size, total_size):
current_time = time.time() current_time = time.time()
if current_time - self.last_update_time >= 0.5: # Update every 0.5 seconds if current_time - self.last_update_time >= 0.5:
progress = int((downloaded_size / total_size) * 100) if total_size > 0 else 0 progress = int((downloaded_size / total_size) * 100) if total_size > 0 else 0
self.progress.emit(progress) self.progress.emit(progress)
# Calculate speed
time_diff = current_time - self.last_update_time time_diff = current_time - self.last_update_time
if time_diff > 0: if time_diff > 0:
speed = (downloaded_size - self.last_downloaded_size) / time_diff speed = (downloaded_size - self.last_downloaded_size) / time_diff
@@ -132,6 +130,38 @@ class DownloaderWorker(QThread):
except Exception as e: except Exception as e:
self.error.emit(f"Error: {str(e)}") self.error.emit(f"Error: {str(e)}")
class ServiceComboBox(QComboBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setIconSize(QSize(16, 16))
self.setup_items()
def setup_items(self):
current_dir = os.path.dirname(os.path.abspath(__file__))
icons_dir = os.path.join(current_dir, 'icons')
if not os.path.exists(icons_dir):
os.makedirs(icons_dir)
services = [
{'id': 'tidal', 'name': 'Tidal', 'icon': 'tidal.png'},
{'id': 'amazon', 'name': 'Amazon Music', 'icon': 'amazon.png'},
{'id': 'qobuz', 'name': 'Qobuz', 'icon': 'qobuz.png'}
]
for service in services:
icon_path = os.path.join(icons_dir, service['icon'])
if not os.path.exists(icon_path):
self.create_placeholder_icon(icon_path)
icon = QIcon(icon_path)
self.addItem(icon, service['name'], service['id'])
def create_placeholder_icon(self, path):
pixmap = QPixmap(16, 16)
pixmap.fill(Qt.GlobalColor.transparent)
pixmap.save(path)
class SpotifyFlacGUI(QMainWindow): class SpotifyFlacGUI(QMainWindow):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@@ -157,11 +187,17 @@ class SpotifyFlacGUI(QMainWindow):
def load_settings(self): def load_settings(self):
headless = self.settings.value('headless', True, type=bool) headless = self.settings.value('headless', True, type=bool)
fallback = self.settings.value('fallback', False, type=bool) service = self.settings.value('service', 'tidal')
format_type = self.settings.value('format', 'title_artist') format_type = self.settings.value('format', 'title_artist')
output_dir = self.settings.value('output_dir', self.default_music_dir) output_dir = self.settings.value('output_dir', self.default_music_dir)
self.headless_checkbox.setChecked(headless) self.headless_checkbox.setChecked(headless)
self.fallback_checkbox.setChecked(fallback)
for i in range(self.service_combo.count()):
if self.service_combo.itemData(i) == service:
self.service_combo.setCurrentIndex(i)
break
self.format_title_artist.setChecked(format_type == 'title_artist') self.format_title_artist.setChecked(format_type == 'title_artist')
self.format_artist_title.setChecked(format_type == 'artist_title') self.format_artist_title.setChecked(format_type == 'artist_title')
self.dir_input.setText(output_dir) self.dir_input.setText(output_dir)
@@ -169,8 +205,8 @@ class SpotifyFlacGUI(QMainWindow):
def setup_settings_persistence(self): def setup_settings_persistence(self):
self.headless_checkbox.stateChanged.connect( self.headless_checkbox.stateChanged.connect(
lambda x: self.settings.setValue('headless', bool(x))) lambda x: self.settings.setValue('headless', bool(x)))
self.fallback_checkbox.stateChanged.connect( self.service_combo.currentIndexChanged.connect(
lambda x: self.settings.setValue('fallback', bool(x))) lambda i: self.settings.setValue('service', self.service_combo.itemData(i)))
self.format_title_artist.toggled.connect( self.format_title_artist.toggled.connect(
lambda x: self.settings.setValue('format', 'title_artist' if x else 'artist_title')) lambda x: self.settings.setValue('format', 'title_artist' if x else 'artist_title'))
self.dir_input.textChanged.connect( self.dir_input.textChanged.connect(
@@ -218,29 +254,38 @@ class SpotifyFlacGUI(QMainWindow):
settings_group = QGroupBox("Settings") settings_group = QGroupBox("Settings")
settings_layout = QHBoxLayout(settings_group) settings_layout = QHBoxLayout(settings_group)
settings_layout.setContentsMargins(10, 0, 10, 10) settings_layout.setContentsMargins(10, 0, 10, 10)
settings_layout.setSpacing(20) settings_layout.setSpacing(15)
settings_container = QWidget() settings_container = QWidget()
settings_container_layout = QHBoxLayout(settings_container) settings_container_layout = QHBoxLayout(settings_container)
settings_container_layout.setContentsMargins(0, 0, 0, 0) settings_container_layout.setContentsMargins(0, 0, 0, 0)
settings_container_layout.setSpacing(20) settings_container_layout.setSpacing(15)
self.headless_checkbox = QCheckBox("Headless") self.headless_checkbox = QCheckBox("Headless")
self.headless_checkbox.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.headless_checkbox.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
self.headless_checkbox.setChecked(True) self.headless_checkbox.setChecked(True)
settings_container_layout.addWidget(self.headless_checkbox) settings_container_layout.addWidget(self.headless_checkbox)
self.fallback_checkbox = QCheckBox("Fallback") service_widget = QWidget()
self.fallback_checkbox.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) service_layout = QHBoxLayout(service_widget)
self.fallback_checkbox.setChecked(False) service_layout.setContentsMargins(0, 0, 0, 0)
settings_container_layout.addWidget(self.fallback_checkbox) service_layout.setSpacing(10)
service_label = QLabel("Service:")
self.service_combo = ServiceComboBox()
self.service_combo.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
service_layout.addWidget(service_label)
service_layout.addWidget(self.service_combo)
settings_container_layout.addWidget(service_widget)
format_widget = QWidget() format_widget = QWidget()
format_layout = QHBoxLayout(format_widget) format_layout = QHBoxLayout(format_widget)
format_layout.setContentsMargins(0, 0, 0, 0) format_layout.setContentsMargins(0, 0, 0, 0)
format_layout.setSpacing(15) format_layout.setSpacing(10)
format_label = QLabel("Filename Format:") format_label = QLabel("Filename:")
self.format_title_artist = QRadioButton("Title - Artist") self.format_title_artist = QRadioButton("Title - Artist")
self.format_artist_title = QRadioButton("Artist - Title") self.format_artist_title = QRadioButton("Artist - Title")
self.format_title_artist.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) self.format_title_artist.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
@@ -361,8 +406,8 @@ class SpotifyFlacGUI(QMainWindow):
self.fetch_button.setEnabled(False) self.fetch_button.setEnabled(False)
self.status_label.setText("Fetching track information...") self.status_label.setText("Fetching track information...")
headless = self.headless_checkbox.isChecked() headless = self.headless_checkbox.isChecked()
use_fallback = self.fallback_checkbox.isChecked() service = self.service_combo.currentData()
self.fetcher = MetadataFetcher(url, headless=headless, use_fallback=use_fallback) self.fetcher = MetadataFetcher(url, headless=headless, service=service)
self.fetcher.finished.connect(self.handle_track_info) self.fetcher.finished.connect(self.handle_track_info)
self.fetcher.error.connect(self.handle_fetch_error) self.fetcher.error.connect(self.handle_fetch_error)
self.fetcher.start() self.fetcher.start()