Fbrowser/python-src/Fbrowser.py
stan44 565be4e1e7 Migrate Fbrowser to Rust and Tauri desktop app
- Replace the Python/Docker setup with a Rust workspace and Tauri frontend
- Add core crates for archive, audio, MIDI, plugin, and desktop UI layers
- Refresh the app scaffolding, build config, and documentation
2026-03-30 16:18:26 -05:00

216 lines
9.1 KiB
Python

# Path: Fbrowser.py
# Sample Music Browser & Ogranizer: Main.py
# Importing Libraries
import sys
import os
from ScanOrg import organizer, file_scanner, DirectoryFilterProxyModel, FileFilterProxyModel
from PyQt5.QtGui import QStandardItem , QStandardItemModel
from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QTreeView, QMessageBox, QSlider, QWidget, QFileSystemModel, QSplitter, QHBoxLayout, QFileDialog
from PyQt5.QtMultimedia import QMediaPlaylist, QMediaPlayer, QMediaContent, QAudioFormat, QAudioDeviceInfo, QAudio
from PyQt5.QtCore import QDir, QSortFilterProxyModel, Qt, QUrl #QAbstractItemModel, QAbstractProxyModel, QModelIndex, QItemSelectionModel, QItemSelection, QItemSelectionRange, QItemSelectionModel, QItemSelection, QItemSelectionRange
"""
# Audio Format
audio_format = QAudioFormat()
audio_format.setSampleRate(44100)
audio_format.setChannelCount(2)
audio_format.setSampleSize(16)
audio_format.setCodec('audio/pcm')
audio_format.setByteOrder(QAudioFormat.LittleEndian)
audio_format.setSampleType(QAudioFormat.SignedInt)
# Audio Device Info
device_info = QAudioDeviceInfo.defaultOutputDevice()
if not device_info.isFormatSupported(audio_format):
print('Raw audio format not supported by backend, cannot play audio.')
audio_format = device_info.nearestFormat(audio_format)
"""
# Sample Music Browser Main Class
class SampleMusicBrowser(QWidget):
def __init__(self):
super().__init__()
self.organizer = organizer()
self.file_model = QStandardItemModel()
self.player = QMediaPlayer()
self.playlist = QMediaPlaylist()
self.player.setPlaylist(self.playlist)
self.tree_model = QFileSystemModel()
self.init_ui()
self.folder_contents_view.setEditTriggers(QTreeView.NoEditTriggers)
self.player.error.connect(self.player_error)
self.player.mediaStatusChanged.connect(self.player_media_status_changed)
self.player.setAudioRole(QAudio.MusicRole)
def player_error(self, error):
if error == QMediaPlayer.NoError:
return
print('Error: ' + self.player.errorString())
def player_media_status_changed(self, status):
if status == QMediaPlayer.NoMedia:
return
print('Media Status: ' + str(status))
def init_ui(self):
layout = QHBoxLayout()
label = QLabel('Sample Music Browser')
layout.addWidget(label)
button = QPushButton('Exit')
button.clicked.connect(self.show_exit_popup)
layout.addWidget(button)
self.file_tree = QTreeView()
self.file_tree.setHeaderHidden(True)
self.file_tree.clicked.connect(self.change_directory)
self.folder_contents_view = QTreeView()
self.folder_contents_view.setHeaderHidden(False)
self.folder_contents_view.setRootIsDecorated(False)
self.folder_contents_view.setSortingEnabled(True)
splitter = QSplitter()
splitter.addWidget(self.file_tree)
splitter.addWidget(self.folder_contents_view)
layout.addWidget(splitter)
self.current_dir_label = QLabel()
layout.addWidget(self.current_dir_label)
up_dir_button = QPushButton('Up Directory')
up_dir_button.clicked.connect(self.go_up_directory)
layout.addWidget(up_dir_button)
back_button = QPushButton('Back')
back_button.clicked.connect(self.go_back_directory)
layout.addWidget(back_button)
forward_button = QPushButton('Forward')
forward_button.clicked.connect(self.go_forward_directory)
layout.addWidget(forward_button)
self.setLayout(layout)
self.setWindowTitle('Samples are life!')
path = QFileDialog.getExistingDirectory(self, 'Select Directory')
if path:
self.populate_file_tree(path)
play_button = QPushButton('Play')
play_button.clicked.connect(self.player.play)
layout.addWidget(play_button)
pause_button = QPushButton('Pause')
pause_button.clicked.connect(self.player.pause)
layout.addWidget(pause_button)
stop_button = QPushButton('Stop')
stop_button.clicked.connect(self.player.stop)
layout.addWidget(stop_button)
self.player.stateChanged.connect(self.player_state_changed)
self.player.positionChanged.connect(self.player_position_changed)
self.player.durationChanged.connect(self.player_duration_changed)
self.player.setVolume(50)
volume_slider = QSlider(Qt.Horizontal)
volume_slider.setRange(0, 100)
volume_slider.setValue(50)
volume_slider.valueChanged.connect(self.player.setVolume)
layout.addWidget(volume_slider)
self.playlist.currentIndexChanged.connect(self.playlist_current_index_changed)
self.playlist.currentMediaChanged.connect(self.playlist_current_media_changed)
self.playlist.mediaInserted.connect(self.playlist_media_inserted)
self.playlist.mediaRemoved.connect(self.playlist_media_removed)
self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
self.folder_contents_view.doubleClicked.connect(self.play_file)
def directory_loaded(self, path):
self.file_tree.setRootIndex(self.directory_model.mapFromSource(self.model.index(path)))
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(self.list_model.index(path)))
def populate_file_tree(self, path):
try:
self.tree_model.setRootPath(path)
self.file_tree.setModel(self.tree_model)
self.directory_model = DirectoryFilterProxyModel()
self.directory_model.setSourceModel(self.tree_model)
self.file_tree.setModel(self.directory_model)
self.file_tree.setRootIndex(self.directory_model.mapFromSource(self.tree_model.index(path)))
self.list_model = QFileSystemModel()
self.list_model.setRootPath(path)
self.file_filter_model = FileFilterProxyModel()
self.file_filter_model.setSourceModel(self.list_model)
self.folder_contents_view.setModel(self.file_filter_model)
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(self.list_model.index(path)))
self.current_dir_label.setText(path)
except Exception as e:
print(f"Error Populating File Tree: {e}")
def show_exit_popup(self):
reply = QMessageBox.question(self, 'Exit', 'Are you sure you want to exit?',
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
sys.exit()
def play_file(self, index):
index = self.file_filter_model.mapToSource(index)
file_path = self.list_model.filePath(index)
media = QMediaContent(QUrl.fromLocalFile(file_path))
self.playlist.addMedia(media)
self.player.play()
def player_state_changed(self, state):
if state == QMediaPlayer.StoppedState:
self.playlist.setCurrentIndex(0)
def player_position_changed(self, position):
pass
def player_duration_changed(self, duration):
pass
def playlist_current_index_changed(self, index):
pass
def playlist_current_media_changed(self, media):
pass
def playlist_media_inserted(self, start, end):
pass
def playlist_media_removed(self, start, end):
pass
def change_directory(self, index):
index = self.directory_model.mapToSource(index)
try:
file_path = self.tree_model.filePath(index)
self.list_model.setRootPath(file_path)
self.current_dir_label.setText(file_path)
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(self.list_model.index(file_path)))
except Exception as e:
print(f"Error Changing Dirs.: {e}")
def go_up_directory(self):
index = self.folder_contents_view.rootIndex()
index = self.file_filter_model.mapToSource(index)
index = self.file_model.index(index)
index = index.parent()
index = self.file_filter_model.mapFromSource(index)
self.folder_contents_view.setRootIndex(index)
self.current_dir_label.setText(self.model.filePath(index))
def go_back_directory(self):
index = self.folder_contents_view.rootIndex()
index = self.file_filter_model.mapToSource(index)
index = self.file_model.index(index)
index = index.parent()
index = self.file_filter_model.mapFromSource(index)
self.folder_contents_view.setRootIndex(index)
self.current_dir_label.setText(self.model.filePath(index))
def go_forward_directory(self):
index = self.folder_contents_view.rootIndex()
index = self.file_filter_model.mapToSource(index)
index = self.file_model.index(index)
index = index.parent()
index = self.file_filter_model.mapFromSource(index)
self.folder_contents_view.setRootIndex(index)
self.current_dir_label.setText(self.model.filePath(index))
if __name__ == '__main__':
app = QApplication(sys.argv)
sampleMusicBrowser = SampleMusicBrowser()
sampleMusicBrowser.show()
sys.exit(app.exec_())