dotfiles/.local/share/rhythmbox/plugins/fileorganizer/fileorganizer.py

232 lines
8.8 KiB
Python

#!/usr/bin/env python3
""" Fileorganizer
----------------Authors----------------
Lachlan de Waard <lachlan.00@gmail.com>
Wolter Hellmund <wolterh6@gmail.com>
----------------Licence----------------
Creative Commons - Attribution Share Alike v3.0
"""
import configparser
import os
import shutil
import gi
gi.require_version('Peas', '1.0')
gi.require_version('PeasGtk', '1.0')
gi.require_version('Notify', '0.7')
gi.require_version('RB', '3.0')
from gi.repository import GObject, Peas, PeasGtk, Gtk, Notify, Gio
from gi.repository import RB
import fileops
import tools
from configurator import FileorganizerConf
PLUGIN_PATH = 'plugins/fileorganizer/'
CONFIGFILE = 'fo.conf'
CONFIGTEMPLATE = 'fo.conf.template'
UIFILE = 'config.ui'
C = "conf"
class Fileorganizer(GObject.Object, Peas.Activatable, PeasGtk.Configurable):
""" Main class that loads fileorganizer into Rhythmbox """
__gtype_name = 'fileorganizer'
object = GObject.property(type=GObject.Object)
_menu_names = ['browser-popup',
'playlist-popup']
def __init__(self, *args, **kwargs):
GObject.Object.__init__(self)
super(Fileorganizer, self).__init__(*args, **kwargs)
self.configurator = FileorganizerConf()
self.conf = configparser.RawConfigParser()
self.configfile = RB.find_user_data_file(PLUGIN_PATH + CONFIGFILE)
self.ui_file = RB.find_user_data_file(PLUGIN_PATH + UIFILE)
self.shell = None
self.rbdb = None
self.action_group = None
self.action = None
self.source = None
self.plugin_info = "fileorganizer"
# Rhythmbox standard Activate method
def do_activate(self):
""" Activate the plugin """
print("activating Fileorganizer")
shell = self.object
self.shell = shell
self.rbdb = shell.props.db
self._check_configfile()
self.menu_build(shell)
# Rhythmbox standard Deactivate method
def do_deactivate(self):
""" Deactivate the plugin """
print("deactivating Fileorganizer")
app = Gio.Application.get_default()
for menu_name in Fileorganizer._menu_names:
app.remove_plugin_menu_item(menu_name, 'selection-' + 'organize')
self.action_group = None
self.action = None
# self.source.delete_thyself()
self.source = None
# FUNCTIONS
# check if configfile is present, if not copy from template folder
def _check_configfile(self):
""" Copy the default config template or load existing config file """
if not os.path.isfile(self.configfile):
template = RB.find_user_data_file(PLUGIN_PATH + CONFIGTEMPLATE)
folder = os.path.split(self.configfile)[0]
if not os.path.exists(folder):
os.makedirs(folder)
shutil.copyfile(template, self.configfile)
# Build menu option
def menu_build(self, shell):
""" Add 'Organize Selection' to the Rhythmbox righ-click menu """
app = Gio.Application.get_default()
# create action
action = Gio.SimpleAction(name="organize-selection")
action.connect("activate", self.organize_selection)
app.add_action(action)
# create menu item
item = Gio.MenuItem()
item.set_label("Organize Selection")
item.set_detailed_action("app.organize-selection")
# add plugin menu item
# app.add_plugin_menu_item('browser-popup', "Organize Selection", item)
for menu_name in Fileorganizer._menu_names:
app.add_plugin_menu_item(menu_name, "Organize Selection", item)
app.add_action(action)
# Create the Configure window in the rhythmbox plugins menu
def do_create_configure_widget(self):
""" Load the glade UI for the config window """
build = Gtk.Builder()
build.add_from_file(self.ui_file)
self._check_configfile()
self.conf.read(self.configfile)
window = build.get_object("fileorganizer")
build.get_object("log_path").set_text(self.conf.get(C, "log_path"))
if self.conf.get(C, "log_enabled") == "True":
build.get_object("logbutton").set_active(True)
if self.conf.get(C, "cleanup_enabled") == "True":
build.get_object("cleanupbutton").set_active(True)
if self.conf.get(C, "cleanup_empty_folders") == "True":
build.get_object("removebutton").set_active(True)
if self.conf.get(C, "preview_mode") == "True":
build.get_object("previewbutton").set_active(True)
if self.conf.get(C, "strip_ntfs") == "True":
build.get_object("ntfsbutton").set_active(True)
build.get_object("logbutton").connect('clicked', lambda x: self.save_config(build))
build.get_object("log_path").connect('changed', lambda x: self.save_config(build))
build.get_object("cleanupbutton").connect('clicked', lambda x: self.save_config(build))
build.get_object("removebutton").connect('clicked', lambda x: self.save_config(build))
build.get_object("previewbutton").connect('clicked', lambda x: self.save_config(build))
build.get_object("ntfsbutton").connect('clicked', lambda x: self.save_config(build))
return window
def save_config(self, builder):
""" Save changes to the plugin config """
if builder.get_object("logbutton").get_active():
self.conf.set(C, "log_enabled", "True")
else:
self.conf.set(C, "log_enabled", "False")
if builder.get_object("cleanupbutton").get_active():
self.conf.set(C, "cleanup_enabled", "True")
else:
self.conf.set(C, "cleanup_enabled", "False")
if builder.get_object("removebutton").get_active():
self.conf.set(C, "cleanup_empty_folders", "True")
else:
self.conf.set(C, "cleanup_empty_folders", "False")
if builder.get_object("previewbutton").get_active():
self.conf.set(C, "preview_mode", "True")
else:
self.conf.set(C, "preview_mode", "False")
if builder.get_object("ntfsbutton").get_active():
self.conf.set(C, "strip_ntfs", "True")
else:
self.conf.set(C, "strip_ntfs", "False")
self.conf.set(C, "log_path",
builder.get_object("log_path").get_text())
datafile = open(self.configfile, "w")
self.conf.write(datafile)
datafile.close()
# Organize selection
def organize_selection(self, action, shell):
""" get your current selection and run process_selection """
page = self.shell.props.selected_page
if not hasattr(page, "get_entry_view"):
return
selected = page.get_entry_view()
selection = selected.get_selected_entries()
self.process_selection(selection)
# Process selection: Run in Preview Mode or Normal Mode
def process_selection(self, filelist):
""" using your selection, run the preview or process from fileops """
self.conf.read(self.configfile)
strip_ntfs = self.conf.get(C, "strip_ntfs") == "True"
# Run in Preview Modelogops
if self.conf.get(C, "preview_mode") == "True":
if filelist:
prelist = os.getenv('HOME') + '/.fileorganizer-preview.log'
datafile = open(prelist, "w")
datafile.close()
damlist = os.getenv('HOME') + '/.fileorganizer-damaged.log'
datafile = open(damlist, "w")
datafile.close()
for item in filelist:
item = fileops.MusicFile(self, item, strip_ntfs=strip_ntfs)
item.preview()
Notify.init('Fileorganizer')
title = 'Fileorganizer'
note = 'Preview Has Completed'
notification = Notify.Notification.new(title, note, None)
Notify.Notification.show(notification)
# Show Results of preview
tools.results(prelist, damlist)
else:
# Run Normally
self.organize(filelist, strip_ntfs)
Notify.init('Fileorganizer')
title = 'Fileorganizer'
note = 'Your selection is organised'
notification = Notify.Notification.new(title, note, None)
Notify.Notification.show(notification)
return
# Organize array of files
def organize(self, filelist, strip_ntfs=False):
""" get fileops to move media files to the correct location """
if filelist:
for item in filelist:
item = fileops.MusicFile(self, item, strip_ntfs=strip_ntfs)
item.relocate()
return
class PythonSource(RB.Source):
""" Register with rhythmbox """
def __init__(self):
RB.Source.__init__(self)
GObject.type_register_dynamic(PythonSource)