From 03a30ee09a9c5b1f2dc9029babd7efef4576f24a Mon Sep 17 00:00:00 2001 From: afkarxyz Date: Tue, 22 Jul 2025 14:03:41 +0700 Subject: [PATCH] v4.0 --- SpotiFLAC.py | 108 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/SpotiFLAC.py b/SpotiFLAC.py index 905b76a..c0c1e7c 100644 --- a/SpotiFLAC.py +++ b/SpotiFLAC.py @@ -586,6 +586,7 @@ class SpotiFLACGUI(QWidget): super().__init__() self.current_version = "4.0" self.tracks = [] + self.all_tracks = [] self.reset_state() self.settings = QSettings('SpotiFLAC', 'Settings') @@ -640,6 +641,7 @@ class SpotiFLACGUI(QWidget): def reset_state(self): self.tracks.clear() + self.all_tracks.clear() self.is_album = False self.is_playlist = False self.is_single_track = False @@ -655,11 +657,15 @@ class SpotiFLACGUI(QWidget): self.pause_resume_btn.setText('Pause') self.reset_info_widget() self.hide_track_buttons() + if hasattr(self, 'search_input'): + self.search_input.clear() + if hasattr(self, 'search_widget'): + self.search_widget.hide() def initUI(self): self.setWindowTitle('SpotiFLAC') self.setFixedWidth(650) - self.setFixedHeight(350) + self.setMinimumHeight(350) icon_path = os.path.join(os.path.dirname(__file__), "icon.svg") if os.path.exists(icon_path): @@ -692,6 +698,27 @@ class SpotiFLACGUI(QWidget): spotify_layout.addWidget(self.fetch_btn) self.main_layout.addLayout(spotify_layout) + def filter_tracks(self): + search_text = self.search_input.text().lower().strip() + + if not search_text: + self.tracks = self.all_tracks.copy() + else: + self.tracks = [ + track for track in self.all_tracks + if (search_text in track.title.lower() or + search_text in track.artists.lower() or + search_text in track.album.lower()) + ] + + self.update_track_list_display() + + def update_track_list_display(self): + self.track_list.clear() + for i, track in enumerate(self.tracks, 1): + duration = self.format_duration(track.duration_ms) + self.track_list.addItem(f"{i}. {track.title} - {track.artists} • {duration}") + def browse_output(self): directory = QFileDialog.getExistingDirectory(self, "Select Output Directory") if directory: @@ -760,10 +787,37 @@ class SpotiFLACGUI(QWidget): text_info_layout.addStretch() info_layout.addLayout(text_info_layout, 1) + + self.setup_search_widget() + info_layout.addWidget(self.search_widget) + self.info_widget.setLayout(info_layout) self.info_widget.setFixedHeight(100) self.info_widget.hide() + def setup_search_widget(self): + self.search_widget = QWidget() + search_layout = QVBoxLayout() + search_layout.setContentsMargins(10, 0, 0, 0) + + search_layout.addStretch() + + search_input_layout = QHBoxLayout() + search_input_layout.addStretch() + + self.search_input = QLineEdit() + self.search_input.setPlaceholderText("Search...") + self.search_input.setClearButtonEnabled(True) + self.search_input.textChanged.connect(self.filter_tracks) + self.search_input.setFixedWidth(250) + + + search_input_layout.addWidget(self.search_input) + search_layout.addLayout(search_input_layout) + + self.search_widget.setLayout(search_layout) + self.search_widget.hide() + def setup_track_buttons(self): self.btn_layout = QHBoxLayout() self.download_selected_btn = QPushButton('Download Selected') @@ -1169,7 +1223,7 @@ class SpotiFLACGUI(QWidget): def handle_track_metadata(self, track_data): track_id = track_data["external_urls"].split("/")[-1] - self.tracks = [Track( + track = Track( external_urls=track_data["external_urls"], title=track_data["name"], artists=track_data["artists"], @@ -1178,7 +1232,10 @@ class SpotiFLACGUI(QWidget): duration_ms=track_data.get("duration_ms", 0), id=track_id, isrc=track_data.get("isrc", "") - )] + ) + + self.tracks = [track] + self.all_tracks = [track] self.is_single_track = True self.is_album = self.is_playlist = False self.album_or_playlist_name = f"{self.tracks[0].title} - {self.tracks[0].artists}" @@ -1209,7 +1266,8 @@ class SpotiFLACGUI(QWidget): id=track_id, isrc=track.get("isrc", "") )) - + + self.all_tracks = self.tracks.copy() self.is_album = True self.is_playlist = self.is_single_track = False @@ -1239,7 +1297,8 @@ class SpotiFLACGUI(QWidget): id=track_id, isrc=track.get("isrc", "") )) - + + self.all_tracks = self.tracks.copy() self.is_playlist = True self.is_album = self.is_single_track = False @@ -1256,10 +1315,10 @@ class SpotiFLACGUI(QWidget): self.track_list.setVisible(not self.is_single_track) if not self.is_single_track: - self.track_list.clear() - for i, track in enumerate(self.tracks, 1): - duration = self.format_duration(track.duration_ms) - self.track_list.addItem(f"{i}. {track.title} - {track.artists} • {duration}") + self.search_widget.show() + self.update_track_list_display() + else: + self.search_widget.hide() self.update_info_widget(metadata) @@ -1365,13 +1424,14 @@ class SpotiFLACGUI(QWidget): if not selected_items: self.log_output.append('Warning: Please select tracks to download.') return - self.download_tracks([self.track_list.row(item) for item in selected_items]) + selected_indices = [self.track_list.row(item) for item in selected_items] + self.download_tracks(selected_indices) def download_all(self): if self.is_single_track: self.download_tracks([0]) else: - self.download_tracks(range(self.track_list.count())) + self.download_tracks(range(len(self.tracks))) def download_tracks(self, indices): self.log_output.clear() @@ -1495,20 +1555,22 @@ class SpotiFLACGUI(QWidget): def remove_selected_tracks(self): if not self.is_single_track: - selected_indices = sorted([self.track_list.row(item) for item in self.track_list.selectedItems()], reverse=True) + selected_items = self.track_list.selectedItems() + selected_indices = [self.track_list.row(item) for item in selected_items] - for index in selected_indices: - self.track_list.takeItem(index) - self.tracks.pop(index) + tracks_to_remove = [self.tracks[i] for i in selected_indices] - for i, track in enumerate(self.tracks, 1): - if self.is_playlist: + for track in tracks_to_remove: + if track in self.tracks: + self.tracks.remove(track) + if track in self.all_tracks: + self.all_tracks.remove(track) + + if self.is_playlist: + for i, track in enumerate(self.all_tracks, 1): track.track_number = i - duration = self.format_duration(track.duration_ms) - display_text = f"{i}. {track.title} - {track.artists} • {duration}" - list_item = self.track_list.item(i - 1) - if list_item: - list_item.setText(display_text) + + self.update_track_list_display() def clear_tracks(self): self.reset_state() @@ -1537,4 +1599,4 @@ if __name__ == '__main__': app = QApplication(sys.argv) ex = SpotiFLACGUI() ex.show() - sys.exit(app.exec()) \ No newline at end of file + sys.exit(app.exec())