Fbrowser/Fbrowser.py
2024-06-29 01:01:51 -05:00

273 lines
12 KiB
Python
Executable File

# Path: Fbrowser.py
# Sample Music Browser & Ogranizer: Main.py
# Importing Libraries
import sys
import os
from ScanOrg import organizer, file_scanner, DirectoryFilterProxyModel, FileFilterProxyModel
from stanzip import Extractor as extractor
from stanzip import Compressor as compressor
from stanzip import zipfile, py7zr, rarfile
from PyQt5.QtGui import QStandardItem , QStandardItemModel, QContextMenuEvent
from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QMenu, 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
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as MPLCanvas
from matplotlib.figure import Figure
# Sample Music Browser Main Class
class SampleMusicBrowser(QWidget):
def __init__(self):
super().__init__()
self.organizer = organizer()
self.extractor = extractor()
self.file_model = QStandardItemModel()
self.player = QMediaPlayer()
self.playlist = QMediaPlaylist()
self.player.setPlaylist(self.playlist)
self.tree_model = QFileSystemModel()
self.init_ui()
#self.midi_player = MidPlay()
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)
self.layout = QHBoxLayout()
self.canvas = MPLCanvas()
self.layout.addWidget(self.canvas)
self.setLayout(self.layout)
# Player Error Debugging
def player_error(self, error):
try:
if error == QMediaPlayer.NoError:
return
print(f"An error occurred: Code:{error} {self.player.errorString()}")
except Exception as e:
print(f"Error: {e}")
# Media Status Changed Debugging
def player_media_status_changed(self, status):
if status == QMediaPlayer.NoMedia:
return
print('Media Status: ' + str(status))
def on_extract_button_clicked(self):
extraction_directory = QFileDialog.getExistingDirectory(self, "Select Extraction Directory")
if extraction_directory:
index = self.folder_contents_view.currentIndex()
if index.isValid():
self.extractor.zipviewer(index, self.file_filter_model, self.list_model, extraction_directory)
def show_context_menu(self, position):
menu = QMenu(self)
extract_action = menu.addAction('Extract')
extract_action.triggered.connect(self.on_extract_button_clicked) # Connect to the extraction function
menu.exec(self.folder_contents_view.mapToGlobal(position))
def init_ui(self):
layout = QVBoxLayout()
label = QLabel('Sample Music Browser')
buttons_layout = QHBoxLayout()
layout.addWidget(label)
#self.midi_player = MidPlay()
self.file_tree = QTreeView()
self.file_tree.setHeaderHidden(True)
self.file_tree.clicked.connect(self.change_directory)
play_button = QPushButton('Play')
play_button.clicked.connect(self.player.play)
#play_button.clicked.connect(self.midi_player.play_midi)
buttons_layout.addWidget(play_button)
stop_button = QPushButton('Stop')
stop_button.clicked.connect(self.player.stop)
# stop_button.clicked.connect(self.midi_player.stop)
buttons_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)
layout.addLayout(buttons_layout)
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)
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)
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)
self.folder_contents_view.setContextMenuPolicy(Qt.CustomContextMenu)
self.folder_contents_view.customContextMenuRequested.connect(self.show_context_menu)
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 closeEvent(self, event):
reply = QMessageBox.question(self, 'Exit', 'Are you sure you want to exit?',
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def play_file(self, index):
try:
index = self.file_filter_model.mapToSource(index)
file_path = self.list_model.filePath(index)
if file_path.endswith(('.zip', '.rar', '.7z')):
with zipfile.ZipFile(file_path, 'r') as zip_ref:
for filename in zip_ref.namelist():
if filename.lower().endswith(('mp3', 'wav', 'ogg', 'flac',
'm4a', 'wma', 'aac', 'aiff', 'alac',
'mid', 'midi', 'mp4', 'm4a')):
audo_file = zip_ref.extract(filename)
media = QMediaContent(QUrl.fromLocalFile(audo_file))
self.playlist.clear()
self.playlist.addMedia(media)
self.player.play()
break
if os.path.exists(audo_file):
os.remove(audo_file)
elif file_path.endswith(('.mid', '.midi')):
#self.midi_player = MidPlay()
#fig = self.midi_player.play_midi(file_path)
self.canvas.draw()
else:
media = QMediaContent(QUrl.fromLocalFile(file_path))
self.playlist.clear()
self.playlist.addMedia(media)
self.player.play()
except Exception as e:
print(f"Error Playing File: {e}")
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)
parent_index = index.parent()
if parent_index.isValid(): # Check if the parent index is valid
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(parent_index))
self.current_dir_label.setText(self.list_model.filePath(parent_index))
def go_forward_directory(self):
index = self.folder_contents_view.rootIndex()
index = self.file_filter_model.mapToSource(index)
parent_index = index.parent()
if parent_index.isValid():
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(parent_index))
self.current_dir_label.setText(self.list_model.filePath(parent_index))
if __name__ == '__main__':
# player = MidPlay()
# file_path = list(player.select_file()) # Get the selected file path
# viewer = MidViewer()
# viewer.read_midi(file_path)
# viewer.view_midi()
#viewer.show()
# viewer.save('test.png')
# viewer.clear()
# viewer.close()
# print(viewer.get_midi_info(file_path)) # Use the file path
# print(viewer.get_piano_roll(file_path)) # Use the file path
# print(viewer.get_tempo(file_path)) # Use the file path
# print(viewer.get_notes(file_path)) # Use the file path
app = QApplication(sys.argv)
sampleMusicBrowser = SampleMusicBrowser()
sampleMusicBrowser.show()
sys.exit(app.exec_())