Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 76e02d77e8 | |||
| 75cc4543ad | |||
| 0b468c4b60 | |||
| 87a6a778f7 | |||
| ef893ab9f4 |
+33
-2
@@ -8,6 +8,7 @@ import re
|
|||||||
import asyncio
|
import asyncio
|
||||||
from packaging import version
|
from packaging import version
|
||||||
import qdarktheme
|
import qdarktheme
|
||||||
|
from mutagen.flac import FLAC
|
||||||
|
|
||||||
from PyQt6.QtWidgets import (
|
from PyQt6.QtWidgets import (
|
||||||
QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit,
|
QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit,
|
||||||
@@ -101,6 +102,15 @@ class DownloadWorker(QThread):
|
|||||||
self.successful_tracks = []
|
self.successful_tracks = []
|
||||||
self.skipped_tracks = []
|
self.skipped_tracks = []
|
||||||
|
|
||||||
|
def get_flac_isrc(self, filepath):
|
||||||
|
try:
|
||||||
|
audio = FLAC(filepath)
|
||||||
|
if 'isrc' in audio:
|
||||||
|
return audio['isrc'][0]
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
def get_formatted_filename(self, track):
|
def get_formatted_filename(self, track):
|
||||||
if self.filename_format == "artist_title":
|
if self.filename_format == "artist_title":
|
||||||
filename = f"{track.artists} - {track.title}.flac"
|
filename = f"{track.artists} - {track.title}.flac"
|
||||||
@@ -155,6 +165,27 @@ class DownloadWorker(QThread):
|
|||||||
else:
|
else:
|
||||||
track_outpath = self.outpath
|
track_outpath = self.outpath
|
||||||
|
|
||||||
|
spotify_isrc = track.isrc
|
||||||
|
if spotify_isrc:
|
||||||
|
is_already_downloaded = False
|
||||||
|
try:
|
||||||
|
for filename in os.listdir(track_outpath):
|
||||||
|
if filename.lower().endswith('.flac'):
|
||||||
|
filepath = os.path.join(track_outpath, filename)
|
||||||
|
local_isrc = self.get_flac_isrc(filepath)
|
||||||
|
if local_isrc and local_isrc == spotify_isrc:
|
||||||
|
self.progress.emit(f"Skipped: Track with matching ISRC '{spotify_isrc}' already exists ('{filename}').", 0)
|
||||||
|
self.progress.emit(f"Skipped: {track.title} - {track.artists}",
|
||||||
|
int((i + 1) / total_tracks * 100))
|
||||||
|
self.skipped_tracks.append(track)
|
||||||
|
is_already_downloaded = True
|
||||||
|
break
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if is_already_downloaded:
|
||||||
|
continue
|
||||||
|
|
||||||
if (self.is_album or self.is_playlist) and self.use_track_numbers:
|
if (self.is_album or self.is_playlist) and self.use_track_numbers:
|
||||||
new_filename = f"{track.track_number:02d} - {self.get_formatted_filename(track)}"
|
new_filename = f"{track.track_number:02d} - {self.get_formatted_filename(track)}"
|
||||||
else:
|
else:
|
||||||
@@ -164,7 +195,7 @@ class DownloadWorker(QThread):
|
|||||||
new_filepath = os.path.join(track_outpath, new_filename)
|
new_filepath = os.path.join(track_outpath, new_filename)
|
||||||
|
|
||||||
if os.path.exists(new_filepath) and os.path.getsize(new_filepath) > 0:
|
if os.path.exists(new_filepath) and os.path.getsize(new_filepath) > 0:
|
||||||
self.progress.emit(f"File already exists: {new_filename}. Skipping download.", 0)
|
self.progress.emit(f"File already exists by name: {new_filename}. Skipping download.", 0)
|
||||||
self.progress.emit(f"Skipped: {track.title} - {track.artists}",
|
self.progress.emit(f"Skipped: {track.title} - {track.artists}",
|
||||||
int((i + 1) / total_tracks * 100))
|
int((i + 1) / total_tracks * 100))
|
||||||
self.skipped_tracks.append(track)
|
self.skipped_tracks.append(track)
|
||||||
@@ -476,7 +507,7 @@ class ServiceComboBox(QComboBox):
|
|||||||
class SpotiFLACGUI(QWidget):
|
class SpotiFLACGUI(QWidget):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.current_version = "4.9"
|
self.current_version = "5.0"
|
||||||
self.tracks = []
|
self.tracks = []
|
||||||
self.all_tracks = []
|
self.all_tracks = []
|
||||||
self.successful_downloads = []
|
self.successful_downloads = []
|
||||||
|
|||||||
@@ -31,15 +31,7 @@ def summarise(caps):
|
|||||||
|
|
||||||
return True, f"Saved to: {output_file}"
|
return True, f"Saved to: {output_file}"
|
||||||
|
|
||||||
|
|
||||||
def grab_live(progress_callback=None):
|
def grab_live(progress_callback=None):
|
||||||
"""
|
|
||||||
Grab secrets from Spotify web player
|
|
||||||
Args:
|
|
||||||
progress_callback: Optional callback function to report progress
|
|
||||||
Returns:
|
|
||||||
list: Captured secrets
|
|
||||||
"""
|
|
||||||
def emit_progress(msg):
|
def emit_progress(msg):
|
||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(msg)
|
progress_callback(msg)
|
||||||
@@ -87,20 +79,12 @@ def grab_live(progress_callback=None):
|
|||||||
page.quit()
|
page.quit()
|
||||||
|
|
||||||
def scrape_and_save(progress_callback=None):
|
def scrape_and_save(progress_callback=None):
|
||||||
"""
|
|
||||||
Main function to scrape secrets and save to file
|
|
||||||
Args:
|
|
||||||
progress_callback: Optional callback function to report progress
|
|
||||||
Returns:
|
|
||||||
tuple: (success: bool, message: str)
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
caps = grab_live(progress_callback)
|
caps = grab_live(progress_callback)
|
||||||
return summarise(caps)
|
return summarise(caps)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return False, f"Error: {str(e)}"
|
return False, f"Error: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
success, message = scrape_and_save()
|
success, message = scrape_and_save()
|
||||||
print(message)
|
print(message)
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"version": "4.8"
|
"version": "4.9"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user