diff --git a/deluge/plugins/extractor/extractor/__init__.py b/deluge/plugins/extractor/extractor/__init__.py new file mode 100644 index 000000000..feee33cce --- /dev/null +++ b/deluge/plugins/extractor/extractor/__init__.py @@ -0,0 +1,47 @@ +# +# __init__.py +# +# Copyright (C) 2009 Andrew Resch +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# +# Deluge is free software. +# +# You may 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. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# + +from deluge.plugins.init import PluginInitBase + +class CorePlugin(PluginInitBase): + def __init__(self, plugin_name): + from core import Core as _plugin_cls + self._plugin_cls = _plugin_cls + super(CorePlugin, self).__init__(plugin_name) + +class GtkUIPlugin(PluginInitBase): + def __init__(self, plugin_name): + from gtkui import GtkUI as _plugin_cls + self._plugin_cls = _plugin_cls + super(GtkUIPlugin, self).__init__(plugin_name) + +class WebUIPlugin(PluginInitBase): + def __init__(self, plugin_name): + from webui import WebUI as _plugin_cls + self._plugin_cls = _plugin_cls + super(WebUIPlugin, self).__init__(plugin_name) diff --git a/deluge/plugins/extractor/extractor/common.py b/deluge/plugins/extractor/extractor/common.py new file mode 100644 index 000000000..598d513e9 --- /dev/null +++ b/deluge/plugins/extractor/extractor/common.py @@ -0,0 +1,27 @@ +# +# common.py +# +# Copyright (C) 2009 Andrew Resch +# +# Deluge is free software. +# +# You may 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. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# + +def get_resource(filename): + import pkg_resources, os + return pkg_resources.resource_filename("extractor", os.path.join("data", filename)) diff --git a/deluge/plugins/extractor/extractor/core.py b/deluge/plugins/extractor/extractor/core.py new file mode 100644 index 000000000..b28555621 --- /dev/null +++ b/deluge/plugins/extractor/extractor/core.py @@ -0,0 +1,114 @@ +# +# core.py +# +# Copyright (C) 2009 Andrew Resch +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# +# Deluge is free software. +# +# You may 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. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# + +import os + +from twisted.internet.utils import getProcessValue + +from deluge.log import LOG as log +from deluge.plugins.pluginbase import CorePluginBase +import deluge.component as component +import deluge.configmanager +from deluge.core.rpcserver import export + +DEFAULT_PREFS = { + "extract_path": "" +} + +# The first format is the source file, the second is the dest path +EXTRACT_COMMANDS = { + ".rar": ["unrar", "x -o+ -y"], + ".zip": ["unzip", ""], + ".tar.gz": ["tar", "xvzf"], + ".tar.bz2": ["tar", "xvjf"], + ".tar.lzma": ["tar", "--lzma xvf"] +} + +class Core(CorePluginBase): + def enable(self): + self.config = deluge.configmanager.ConfigManager("extractor.conf", DEFAULT_PREFS) + component.get("EventManager").register_event_handler("TorrentFinishedEvent", self._on_torrent_finished) + + def disable(self): + pass + + def update(self): + pass + + def _on_torrent_finished(self, torrent_id): + """ + This is called when a torrent finishes. We need to check to see if there + are any files to extract. + """ + # Get the save path + save_path = component.get("TorrentManager")[torrent_id].get_status(["save_path"])["save_path"] + files = component.get("TorrentManager")[torrent_id].get_files() + for f in files: + ext = os.path.splitext(f["path"]) + if ext in (".gz", ".bz2", ".lzma"): + # We need to check if this is a tar + if os.path.splitext(ext[0]) == ".tar": + cmd = EXTRACT_COMMANDS[".tar" + ext[1]] + else: + if ext[1] in EXTRACT_COMMANDS: + cmd = EXTRACT_COMMANDS[ext[1]] + else: + log.debug("Can't extract unknown file type: %s", ext[1]) + continue + + # Now that we have the cmd, lets run it to extract the files + fp = os.path.join(save_path, f["path"]) + if os.path.exists(self.config["extract_path"]): + dest = self.config["extract_path"] + else: + dest = None + + def on_extract_success(result, torrent_id): + # XXX: Emit an event + log.debug("Extract was successful for %s", torrent_id) + + def on_extract_failed(result, torrent_id): + # XXX: Emit an event + log.debug("Extract failed for %s", torrent_id) + + # Run the command and add some callbacks + d = getProcessValue(cmd[0], cmd[1:] + [fp], {}, dest) + d.addCallback(on_extract_success, torrent_id) + d.addErrback(on_extract_failed, torrent_id) + + @export() + def set_config(self, config): + "sets the config dictionary" + for key in config.keys(): + self.config[key] = config[key] + self.config.save() + + @export() + def get_config(self): + "returns the config dictionary" + return self.config.config diff --git a/deluge/plugins/extractor/extractor/data/extractor_prefs.glade b/deluge/plugins/extractor/extractor/data/extractor_prefs.glade new file mode 100644 index 000000000..0d3f4ccbb --- /dev/null +++ b/deluge/plugins/extractor/extractor/data/extractor_prefs.glade @@ -0,0 +1,81 @@ + + + + + + + + True + 5 + + + True + 0 + GTK_SHADOW_NONE + + + True + 12 + + + True + 5 + + + True + 5 + + + True + Extract to: + + + False + False + + + + + True + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + Select A Folder + + + 1 + + + + + True + True + + + 2 + + + + + + + + + + + True + <b>General</b> + True + + + label_item + + + + + False + False + + + + + + diff --git a/deluge/plugins/extractor/extractor/gtkui.py b/deluge/plugins/extractor/extractor/gtkui.py new file mode 100644 index 000000000..3ff4ff365 --- /dev/null +++ b/deluge/plugins/extractor/extractor/gtkui.py @@ -0,0 +1,82 @@ +# +# gtkui.py +# +# Copyright (C) 2009 Andrew Resch +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# +# Deluge is free software. +# +# You may 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. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# + +import gtk + +from deluge.log import LOG as log +from deluge.ui.client import client +from deluge.plugins.pluginbase import GtkPluginBase +import deluge.component as component +import deluge.common + +from common import get_resource + +class GtkUI(GtkPluginBase): + def enable(self): + self.glade = gtk.glade.XML(get_resource("extractor_prefs.glade")) + + component.get("Preferences").add_page("Extractor", self.glade.get_widget("extractor_prefs_box")) + component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs) + component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs) + + + def disable(self): + component.get("Preferences").remove_page("Extractor") + component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs) + component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs) + del self.glade + + def on_apply_prefs(self): + log.debug("applying prefs for Extractor") + if client.is_localhost(): + path = self.glade.get_widget("folderchooser_path").get_current_folder() + else: + path = self.glade.get_widget("entry_path").get_text() + + config = { + "extract_path": path + } + + client.extractor.set_config(config) + + def on_show_prefs(self): + if client.is_localhost(): + self.glade.get_widget("folderchooser_path").show() + self.glade.get_widget("entry_path").hide() + else: + self.glade.get_widget("folderchooser_path").hide() + self.glade.get_widget("entry_path").show() + self.glade.get_widget("folderchooser_path").show() + + def on_get_config(config): + if client.is_localhost(): + self.glade.get_widget("folderchooser_path").set_current_folder(config["extract_path"]) + else: + self.glade.get_widget("entry_path").set_text(config["extract_path"]) + + client.extractor.get_config().addCallback(on_get_config) diff --git a/deluge/plugins/extractor/extractor/webui.py b/deluge/plugins/extractor/extractor/webui.py new file mode 100644 index 000000000..65861ca4f --- /dev/null +++ b/deluge/plugins/extractor/extractor/webui.py @@ -0,0 +1,39 @@ +# +# webui.py +# +# Copyright (C) 2009 Andrew Resch +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# +# Deluge is free software. +# +# You may 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. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# + +from deluge.log import LOG as log +from deluge.ui.client import client +from deluge import component +from deluge.plugins.pluginbase import WebPluginBase + +class WebUI(WebPluginBase): + def enable(self): + pass + + def disable(self): + pass diff --git a/deluge/plugins/extractor/setup.py b/deluge/plugins/extractor/setup.py new file mode 100644 index 000000000..853756256 --- /dev/null +++ b/deluge/plugins/extractor/setup.py @@ -0,0 +1,62 @@ +# +# setup.py +# +# Copyright (C) 2009 Andrew Resch +# +# Basic plugin template created by: +# Copyright (C) 2008 Martijn Voncken +# Copyright (C) 2007-2009 Andrew Resch +# +# Deluge is free software. +# +# You may 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. +# +# deluge 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 deluge. If not, write to: +# The Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor +# Boston, MA 02110-1301, USA. +# + +from setuptools import setup + +__plugin_name__ = "Extractor" +__author__ = "Andrew Resch" +__author_email__ = "andrewresch@gmail.com" +__version__ = "0.1" +__url__ = "http://deluge-torrent.org" +__license__ = "GPLv3" +__description__ = "Extract files upon completion" +__long_description__ = """""" +__pkg_data__ = {__plugin_name__.lower(): ["template/*", "data/*"]} + +setup( + name=__plugin_name__, + version=__version__, + description=__description__, + author=__author__, + author_email=__author_email__, + url=__url__, + license=__license__, + long_description=__long_description__ if __long_description__ else __description__, + + packages=[__plugin_name__.lower()], + package_data = __pkg_data__, + + entry_points=""" + [deluge.plugin.core] + %s = %s:CorePlugin + [deluge.plugin.gtkui] + %s = %s:GtkUIPlugin + [deluge.plugin.webui] + %s = %s:WebUIPlugin + """ % ((__plugin_name__, __plugin_name__.lower())*3) +)