# # Copyright (C) 2009 Anton Khirnov # # Nephilim is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Nephilim is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Nephilim. If not, see . # from PyQt5 import QtWidgets, QtCore import os import shutil from ..plugin import Plugin class Filebrowser(Plugin): # public, const info = 'A file browser that allows adding files not in collection.' # public, read-only o = None def _load(self): self.o = wgFilebrowser(self) def _unload(self): self.o = None def _get_dock_widget(self): return self._create_dock(self.o) class wgFilebrowser(QtWidgets.QWidget): view = None model = None path = None plugin = None logger = None class FileView(QtWidgets.QListView): "context menu" menu = None plugin = None logger = None def __init__(self, model, plugin): QtWidgets.QListView.__init__(self) self.plugin = plugin self.logger = plugin.logger self.setModel(model) self.setRootIndex(self.model().index(os.path.expanduser('~'))) self.setSelectionMode(QtWidgets.QTreeWidget.ExtendedSelection) self.menu = QtWidgets.QMenu('file') self.menu.addAction('&Make file(s) readable for MPD.', self.selection_make_readable) self.menu.addAction('***EXPERIMENTAL DON\'T USE*** &Copy to collection.', self.selection_copy_to_collection) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_context_menu) def show_context_menu(self, pos): if not self.indexAt(pos).isValid(): return self.menu.popup(self.mapToGlobal(pos)) def selection_make_readable(self): for index in self.selectedIndexes(): filepath = self.model().filePath(index) if os.path.isdir(filepath): perm = 0o755 else: perm = 0o644 self.logger.info('Changind permissions of %s to %d.'%(filepath, perm)) try: os.chmod(filepath, perm) except OSError as e: self.logger.error('Can\'t change permissions: %s.'%e) def selection_copy_to_collection(self): target_paths = [] for index in self.selectedIndexes(): filepath = self.model().filePath(index) self.logger.info('Copying %s to collection.'%filepath) path_base = os.path.basename(filepath) try: if os.path.isdir(filepath): shutil.copytree(filepath, '%s/%s'%(self.plugin.settings.value('MPD/music_dir'), path_base)) else: shutil.copy(filepath, self.plugin.settings.value('MPD/music_dir')) target_paths.append(path_base) except (OSError, IOError) as e: self.logger.error('Error copying to collection: %s.'%e) self.plugin.mpclient.update_db(target_paths) def __init__(self, plugin): QtWidgets.QWidget.__init__(self) self.plugin = plugin self.logger = plugin.logger self.model = QtWidgets.QDirModel() self.model.setFilter(QtCore.QDir.AllDirs|QtCore.QDir.AllEntries) self.model.setSorting(QtCore.QDir.DirsFirst) self.view = self.FileView(self.model, self.plugin) self.view.activated.connect(self.item_activated) self.path = QtWidgets.QLineEdit(self.model.filePath(self.view.rootIndex())) self.path.returnPressed.connect(self.path_changed) self.setLayout(QtWidgets.QVBoxLayout()) self.layout().setSpacing(0) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self.path) self.layout().addWidget(self.view) def item_activated(self, index): if self.model.hasChildren(index): self.view.setRootIndex(index) self.path.setText(self.model.filePath(index)) else: if not 'file://' in self.plugin.mpclient.urlhandlers: self.logger.error('file:// handler not available. Connect via unix domain sockets.') return paths = [] for index in self.view.selectedIndexes(): paths.append('file://%s'%self.model.filePath(index)) self.logger.info('Adding %d song to playlist.'%len(paths)) self.plugin.mpclient.add(paths) def path_changed(self): if os.path.isdir(self.path.text()): self.view.setRootIndex(self.model.index(self.path.text()))