mirror of
https://git.deluge-torrent.org/deluge
synced 2025-09-05 17:45:36 +00:00
Remove old plugins
This commit is contained in:
parent
6bed403412
commit
391513d378
30 changed files with 0 additions and 2141 deletions
|
@ -1,3 +0,0 @@
|
||||||
# this is a namespace package
|
|
||||||
import pkg_resources
|
|
||||||
pkg_resources.declare_namespace(__name__)
|
|
|
@ -1,3 +0,0 @@
|
||||||
# this is a namespace package
|
|
||||||
import pkg_resources
|
|
||||||
pkg_resources.declare_namespace(__name__)
|
|
|
@ -1,54 +0,0 @@
|
||||||
#
|
|
||||||
# __init__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
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)
|
|
|
@ -1,41 +0,0 @@
|
||||||
#
|
|
||||||
# common.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
import pkg_resources
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
def get_resource(filename):
|
|
||||||
return pkg_resources.resource_filename("deluge.plugins.example",
|
|
||||||
os.path.join("data", filename))
|
|
|
@ -1,57 +0,0 @@
|
||||||
#
|
|
||||||
# core.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
from deluge.plugins.pluginbase import CorePluginBase
|
|
||||||
import deluge.component as component
|
|
||||||
import deluge.configmanager
|
|
||||||
from deluge.core.rpcserver import export
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class Core(CorePluginBase):
|
|
||||||
def enable(self):
|
|
||||||
log.debug("Example core plugin enabled!")
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
log.debug("Example core plugin disabled!")
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
### Exported RPC methods ###
|
|
||||||
@export()
|
|
||||||
def example_method(self):
|
|
||||||
pass
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
Script: example.js
|
|
||||||
The client-side javascript code for the Example plugin.
|
|
||||||
|
|
||||||
Copyright:
|
|
||||||
(C) Damien Churchill 2009 <damoxc@gmail.com>
|
|
||||||
This program 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, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program 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 this program. If not, write to:
|
|
||||||
The Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
In addition, as a special exception, the copyright holders give
|
|
||||||
permission to link the code of portions of this program with the OpenSSL
|
|
||||||
library.
|
|
||||||
You must obey the GNU General Public License in all respects for all of
|
|
||||||
the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
exception, you may extend this exception to your version of the file(s),
|
|
||||||
but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
this exception statement from your version. If you delete this exception
|
|
||||||
statement from all source files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ExamplePlugin = Ext.extend(Deluge.Plugin, {
|
|
||||||
constructor: function(config) {
|
|
||||||
config = Ext.apply({
|
|
||||||
name: "Example"
|
|
||||||
}, config);
|
|
||||||
ExamplePlugin.superclass.constructor.call(this, config);
|
|
||||||
},
|
|
||||||
|
|
||||||
onDisable: function() {
|
|
||||||
Deluge.Preferences.removePage(this.prefsPage);
|
|
||||||
},
|
|
||||||
|
|
||||||
onEnable: function() {
|
|
||||||
this.prefsPage = new ExamplePreferencesPanel();
|
|
||||||
this.prefsPage = Deluge.Preferences.addPage(this.prefsPage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
new ExamplePlugin();
|
|
|
@ -1,50 +0,0 @@
|
||||||
#
|
|
||||||
# gtkui.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from deluge.ui.client import client
|
|
||||||
from deluge.plugins.pluginbase import GtkPluginBase
|
|
||||||
import deluge.component as component
|
|
||||||
import deluge.common
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class GtkUI(GtkPluginBase):
|
|
||||||
def enable(self):
|
|
||||||
pass
|
|
||||||
def disable(self):
|
|
||||||
pass
|
|
|
@ -1,56 +0,0 @@
|
||||||
#
|
|
||||||
# webui.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
from deluge.ui.client import client
|
|
||||||
from deluge import component
|
|
||||||
from deluge.plugins.pluginbase import WebPluginBase
|
|
||||||
|
|
||||||
from common import get_resource
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class WebUI(WebPluginBase):
|
|
||||||
|
|
||||||
scripts = [get_resource("example.js")]
|
|
||||||
|
|
||||||
# The enable and disable methods are not scrictly required on the WebUI
|
|
||||||
# plugins. They are only here if you need to register images/stylesheets
|
|
||||||
# with the webserver.
|
|
||||||
def enable(self):
|
|
||||||
log.debug("Example Web plugin enabled!")
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
log.debug("Example Web plugin disabled!")
|
|
|
@ -1,68 +0,0 @@
|
||||||
#
|
|
||||||
# setup.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# This program 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, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
#
|
|
||||||
# This program 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 this program. If not, write to:
|
|
||||||
# The Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin Street, Fifth Floor
|
|
||||||
# Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
__plugin_name__ = "Example"
|
|
||||||
__author__ = "Andrew Resch"
|
|
||||||
__author_email__ = "andrewresch@gmail.com"
|
|
||||||
__version__ = "1.2"
|
|
||||||
__url__ = "http://deluge-torrent.org"
|
|
||||||
__license__ = "GPLv3"
|
|
||||||
__description__ = "Example plugin"
|
|
||||||
__long_description__ = __description__
|
|
||||||
__pkg_data__ = {"deluge.plugins."+__plugin_name__.lower(): []}
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name=__plugin_name__,
|
|
||||||
version=__version__,
|
|
||||||
description=__description__,
|
|
||||||
author=__author__,
|
|
||||||
author_email=__author_email__,
|
|
||||||
url=__url__,
|
|
||||||
license=__license__,
|
|
||||||
long_description=__long_description__,
|
|
||||||
|
|
||||||
packages=find_packages(),
|
|
||||||
namespace_packages = ["deluge", "deluge.plugins"],
|
|
||||||
package_data = __pkg_data__,
|
|
||||||
|
|
||||||
entry_points="""
|
|
||||||
[deluge.plugin.core]
|
|
||||||
%s = deluge.plugins.%s:CorePlugin
|
|
||||||
[deluge.plugin.gtkui]
|
|
||||||
%s = deluge.plugins.%s:GtkUIPlugin
|
|
||||||
[deluge.plugin.web]
|
|
||||||
%s = deluge.plugins.%s:WebUIPlugin
|
|
||||||
""" % ((__plugin_name__, __plugin_name__.lower())*3)
|
|
||||||
)
|
|
|
@ -1,3 +0,0 @@
|
||||||
# this is a namespace package
|
|
||||||
import pkg_resources
|
|
||||||
pkg_resources.declare_namespace(__name__)
|
|
|
@ -1,3 +0,0 @@
|
||||||
# this is a namespace package
|
|
||||||
import pkg_resources
|
|
||||||
pkg_resources.declare_namespace(__name__)
|
|
|
@ -1,55 +0,0 @@
|
||||||
#
|
|
||||||
# feeder/__init__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
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)
|
|
|
@ -1,434 +0,0 @@
|
||||||
#
|
|
||||||
# core.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008-2009 Fredrik Eriksson <feeder@winterbird.org>
|
|
||||||
# Copyright (C) 2009 David Mohr <david@mcbf.net>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import feedparser # for parsing rss feeds
|
|
||||||
import threading # for threaded updates
|
|
||||||
import re # for regular expressions
|
|
||||||
from twisted.internet.task import LoopingCall
|
|
||||||
|
|
||||||
from deluge.plugins.pluginbase import CorePluginBase
|
|
||||||
import deluge.component as component
|
|
||||||
import deluge.configmanager
|
|
||||||
from deluge.core.rpcserver import export
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
DEFAULT_PREFS = {
|
|
||||||
"feeds": {},
|
|
||||||
"filters": {},
|
|
||||||
"updatetime": 15,
|
|
||||||
"history": []
|
|
||||||
}
|
|
||||||
|
|
||||||
# Helper classes
|
|
||||||
|
|
||||||
class Feed:
|
|
||||||
"""
|
|
||||||
Class for the Feed object (containging feed configurations)
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self.url = ""
|
|
||||||
self.cookies = {}
|
|
||||||
self.updatetime = 15
|
|
||||||
|
|
||||||
def get_config(self):
|
|
||||||
try:
|
|
||||||
tmp = self.cookies
|
|
||||||
except Exception, e:
|
|
||||||
log.debug("Old feed without cookies... updating")
|
|
||||||
self.cookies = {}
|
|
||||||
return {'url': self.url, 'updatetime': self.updatetime, 'cookies': self.cookies}
|
|
||||||
|
|
||||||
def set_config(self, config):
|
|
||||||
self.url = config['url']
|
|
||||||
self.updatetime = config['updatetime']
|
|
||||||
self.cookies = config['cookies']
|
|
||||||
|
|
||||||
|
|
||||||
class Filter:
|
|
||||||
"""
|
|
||||||
Class for the Filter object (containing filter configurations)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.regex = ""
|
|
||||||
self.feeds = [] #TODO activate filter per feed
|
|
||||||
self.all_feeds = True
|
|
||||||
self.active = True
|
|
||||||
|
|
||||||
# by default, set the configuration to match
|
|
||||||
# the per-torrent settings in deluge
|
|
||||||
def_conf = component.get("Core").get_config()
|
|
||||||
self.max_download_speed = def_conf['max_download_speed_per_torrent']
|
|
||||||
self.max_upload_speed = def_conf['max_upload_speed_per_torrent']
|
|
||||||
self.max_connections = def_conf['max_connections_per_torrent']
|
|
||||||
self.max_upload_slots = def_conf['max_upload_slots_per_torrent']
|
|
||||||
self.prioritize_first_last_pieces = def_conf['prioritize_first_last_pieces']
|
|
||||||
self.auto_managed = def_conf['auto_managed']
|
|
||||||
self.download_location = def_conf['download_location']
|
|
||||||
|
|
||||||
self.stop_at_ratio = def_conf['stop_seed_at_ratio']
|
|
||||||
self.stop_ratio = def_conf['stop_seed_ratio']
|
|
||||||
self.remove_at_ratio = def_conf['remove_seed_at_ratio']
|
|
||||||
|
|
||||||
def get_config(self):
|
|
||||||
def_conf = component.get("Core").get_config()
|
|
||||||
|
|
||||||
try:
|
|
||||||
tmp = self.active
|
|
||||||
except Exception, e:
|
|
||||||
log.debug("Old filter detected (pre 0.3), updating...")
|
|
||||||
self.active = True
|
|
||||||
|
|
||||||
try:
|
|
||||||
tmp = self.stop_at_ratio
|
|
||||||
tmp = self.stop_ratio
|
|
||||||
tmp = self.remove_at_ratio
|
|
||||||
except:
|
|
||||||
log.debug("Old filter detected (pre 0.4), updating...")
|
|
||||||
self.stop_at_ratio = def_conf['stop_seed_at_ratio']
|
|
||||||
self.stop_ratio = def_conf['stop_seed_ratio']
|
|
||||||
self.remove_at_ratio = def_conf['remove_seed_at_ratio']
|
|
||||||
|
|
||||||
conf = {
|
|
||||||
'regex': self.regex,
|
|
||||||
'feeds': self.feeds,
|
|
||||||
'all_feeds': self.all_feeds,
|
|
||||||
'active' : self.active,
|
|
||||||
'max_download_speed': self.max_download_speed,
|
|
||||||
'max_upload_speed': self.max_upload_speed,
|
|
||||||
'max_connections': self.max_connections,
|
|
||||||
'max_upload_slots': self.max_upload_slots,
|
|
||||||
'prioritize_first_last_pieces': self.prioritize_first_last_pieces,
|
|
||||||
'auto_managed': self.auto_managed,
|
|
||||||
'download_location':self.download_location,
|
|
||||||
'remove_at_ratio':self.remove_at_ratio,
|
|
||||||
'stop_ratio': self.stop_ratio,
|
|
||||||
'stop_at_ratio': self.stop_at_ratio }
|
|
||||||
|
|
||||||
return conf
|
|
||||||
|
|
||||||
def set_config(self, conf):
|
|
||||||
self.regex = conf['regex']
|
|
||||||
self.feeds = conf['feeds']
|
|
||||||
self.all_feeds = conf['all_feeds']
|
|
||||||
self.active = conf['active']
|
|
||||||
self.max_download_speed = int(conf['max_download_speed'])
|
|
||||||
self.max_upload_speed = int(conf['max_upload_speed'])
|
|
||||||
self.max_connections = int(conf['max_connections'])
|
|
||||||
self.max_upload_slots = int(conf['max_upload_slots'])
|
|
||||||
self.prioritize_first_last_pieces = conf['prioritize_first_last_pieces']
|
|
||||||
self.auto_managed = conf['auto_managed']
|
|
||||||
self.download_location = conf['download_location']
|
|
||||||
self.remove_at_ratio = conf['remove_at_ratio']
|
|
||||||
self.stop_ratio = float(conf['stop_ratio'])
|
|
||||||
self.stop_at_ratio = conf['stop_at_ratio']
|
|
||||||
|
|
||||||
|
|
||||||
class Core(CorePluginBase):
|
|
||||||
def enable(self):
|
|
||||||
self.config = deluge.configmanager.ConfigManager("feeder.conf", DEFAULT_PREFS)
|
|
||||||
self.feeds = {}
|
|
||||||
self.timers = {}
|
|
||||||
self.history = self.config['history']
|
|
||||||
self.time = 0
|
|
||||||
|
|
||||||
# Setting default timer to configured update time
|
|
||||||
for feed in self.config['feeds']:
|
|
||||||
self.timers[feed] = LoopingCall(self.update_feed, feed)
|
|
||||||
self.timers[feed].start( self.config['feeds'][feed].updatetime * 60)
|
|
||||||
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
self.config['history'] = self.history
|
|
||||||
self.config.save()
|
|
||||||
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#=================Exported functions==================
|
|
||||||
|
|
||||||
@export
|
|
||||||
def set_config(self, config):
|
|
||||||
"""sets the config dictionary"""
|
|
||||||
for key in config.keys():
|
|
||||||
self.config[key] = config[key]
|
|
||||||
self.config.save()
|
|
||||||
|
|
||||||
####################Configuration Getters##################
|
|
||||||
|
|
||||||
@export
|
|
||||||
def get_config(self):
|
|
||||||
"""returns the config dictionary"""
|
|
||||||
return self.config.config
|
|
||||||
|
|
||||||
@export
|
|
||||||
def get_feed_config(self, feedname):
|
|
||||||
"""Returns configuration for a feed"""
|
|
||||||
return self.config['feeds'][feedname].get_config()
|
|
||||||
|
|
||||||
@export
|
|
||||||
def get_filter_config(self, filtername):
|
|
||||||
"""Returns a configuration for a filter"""
|
|
||||||
return self.config['filters'][filtername].get_config()
|
|
||||||
|
|
||||||
####################Information Getters####################
|
|
||||||
|
|
||||||
@export
|
|
||||||
def get_feeds(self):
|
|
||||||
"""Returns a list of the configured feeds"""
|
|
||||||
feeds = []
|
|
||||||
for feedname in self.config['feeds']:
|
|
||||||
feeds.append(feedname)
|
|
||||||
feeds.sort(key=string.lower)
|
|
||||||
return feeds
|
|
||||||
|
|
||||||
@export
|
|
||||||
def get_filters(self):
|
|
||||||
"""Returns a list of all available filters"""
|
|
||||||
filters = []
|
|
||||||
for filter in self.config['filters']:
|
|
||||||
filters.append(filter)
|
|
||||||
filters.sort(key=string.lower)
|
|
||||||
return filters
|
|
||||||
|
|
||||||
@export
|
|
||||||
def get_items(self, feedname):
|
|
||||||
"""Returns a dictionary with feedname:link"""
|
|
||||||
try:
|
|
||||||
items = {}
|
|
||||||
feed = self.feeds[feedname]
|
|
||||||
for entry in feed['entries']:
|
|
||||||
items[entry.title] = entry.link
|
|
||||||
except Exception, e:
|
|
||||||
items = {}
|
|
||||||
log.warning("Feed '%s' not loaded", feedname)
|
|
||||||
return items
|
|
||||||
|
|
||||||
@export
|
|
||||||
def test_filter(self, regex):
|
|
||||||
filters = { "to_test":Filter() }
|
|
||||||
conf = filters["to_test"].get_config()
|
|
||||||
conf["regex"] = regex
|
|
||||||
filters["to_test"].set_config(conf)
|
|
||||||
hits = {}
|
|
||||||
for feed in self.feeds:
|
|
||||||
hits.update(self.run_filters(feed, filters, test=True))
|
|
||||||
return hits
|
|
||||||
|
|
||||||
@export
|
|
||||||
def add_feed(self, config):
|
|
||||||
"""adds/updates a feed and, for whatever reason, sets the default timeout"""
|
|
||||||
|
|
||||||
# save the feedname and remove it from the config
|
|
||||||
feedname = config['name']
|
|
||||||
del config['name']
|
|
||||||
|
|
||||||
# check if the feed already exists and save config
|
|
||||||
try:
|
|
||||||
conf = self.config['feeds'][feedname].get_config()
|
|
||||||
del self.config['feeds'][feedname]
|
|
||||||
except Exception, e:
|
|
||||||
conf = {}
|
|
||||||
|
|
||||||
# update configuration
|
|
||||||
for var in config:
|
|
||||||
conf[var] = config[var]
|
|
||||||
|
|
||||||
# save as default update time
|
|
||||||
try:
|
|
||||||
self.config['updatetime'] = config['updatetime']
|
|
||||||
except Exception, e:
|
|
||||||
log.warning("updatetime not set when adding feed %s", feedname)
|
|
||||||
|
|
||||||
# Create the new feed
|
|
||||||
newfeed = Feed()
|
|
||||||
newfeed.set_config(conf)
|
|
||||||
|
|
||||||
# Add a timer (with default timer for now, since we can't get ttl just yet)...
|
|
||||||
self.timers[feedname] = LoopingCall(self.update_feed, feedname)
|
|
||||||
|
|
||||||
# Save the new feed
|
|
||||||
self.config['feeds'].update({feedname: newfeed })
|
|
||||||
self.config.save()
|
|
||||||
|
|
||||||
# Start the timeout, which will also update the new feed
|
|
||||||
self.timers[feedname].start(newfeed.updatetime * 60)
|
|
||||||
|
|
||||||
@export
|
|
||||||
def remove_feed(self, feedname):
|
|
||||||
"""Remove a feed"""
|
|
||||||
if self.feeds.has_key(feedname): # Check if we have the feed saved and remove it
|
|
||||||
del self.feeds[feedname]
|
|
||||||
if self.timers.has_key(feedname): # Check if we have a timer for this feed and remove it
|
|
||||||
self.timers[feedname].stop()
|
|
||||||
del self.timers[feedname]
|
|
||||||
if self.config['feeds'].has_key(feedname): # Check if we have the feed in the configuration and remove it
|
|
||||||
del self.config['feeds'][feedname]
|
|
||||||
self.config.save()
|
|
||||||
|
|
||||||
@export
|
|
||||||
def add_filter(self, name):
|
|
||||||
"""Adds a new filter to the configuration"""
|
|
||||||
if not self.config['filters'].has_key(name): # we don't want to add a filter that already exists
|
|
||||||
self.config['filters'][name] = Filter()
|
|
||||||
self.config.save()
|
|
||||||
|
|
||||||
@export
|
|
||||||
def set_filter_config(self, filtername, conf):
|
|
||||||
"""Changes the options for a filter"""
|
|
||||||
oldconf = self.config['filters'][filtername].get_config()
|
|
||||||
for item in conf:
|
|
||||||
oldconf[item] = conf[item]
|
|
||||||
|
|
||||||
self.config['filters'][filtername].set_config(oldconf)
|
|
||||||
self.config.save()
|
|
||||||
for feed in self.config['feeds']: # we would like to check if the filter now matches something new
|
|
||||||
self.run_filters(feed)
|
|
||||||
|
|
||||||
@export
|
|
||||||
def remove_filter(self, name):
|
|
||||||
"""Removes a filter"""
|
|
||||||
if self.config['filters'].has_key(name): # Can't remove a filter that doesn't exists
|
|
||||||
del self.config['filters'][name]
|
|
||||||
self.config.save()
|
|
||||||
|
|
||||||
#=================Internal functions================
|
|
||||||
|
|
||||||
def update_feed(self, feedname):
|
|
||||||
"""Start a thread to update a single feed"""
|
|
||||||
threading.Thread(
|
|
||||||
target=self.update_feed_thread,
|
|
||||||
args=(self.on_feed_updated, feedname)).start()
|
|
||||||
|
|
||||||
# Need to return true to not destoy timer...
|
|
||||||
return True
|
|
||||||
|
|
||||||
def update_feed_thread(self, callback, feedname):
|
|
||||||
"""updates a feed"""
|
|
||||||
feed = self.config['feeds'][feedname]
|
|
||||||
try:
|
|
||||||
self.feeds[feedname] = feedparser.parse(feed.url)
|
|
||||||
except Exception, e:
|
|
||||||
log.warning("Error parsing feed %s: %s", feedname, e)
|
|
||||||
else:
|
|
||||||
callback(feedname)
|
|
||||||
|
|
||||||
def on_feed_updated(self, feedname):
|
|
||||||
"""Run stuff when a feed has been updated"""
|
|
||||||
|
|
||||||
# Not all feeds contain a ttl value, but if it does
|
|
||||||
# we would like to obey it
|
|
||||||
try:
|
|
||||||
if not self.feeds[feedname].ttl == self.config['feeds'][feedname].updatetime:
|
|
||||||
log.debug("feed '%s' request a ttl of %s, updating timer", feedname, self.feeds[feedname].ttl)
|
|
||||||
self.config['feeds'][feedname].updatetime = self.feeds[feedname].ttl
|
|
||||||
self.timers[feedname].stop()
|
|
||||||
self.timers[feedname].start(self.config['feeds'][feedname].updatetime * 60)
|
|
||||||
except Exception, e:
|
|
||||||
log.debug("feed '%s' has no ttl set, will use default timer", feedname)
|
|
||||||
|
|
||||||
# Run filters on the feed
|
|
||||||
self.run_filters(feedname)
|
|
||||||
|
|
||||||
def run_filters(self, feedname, filters={}, test=False):
|
|
||||||
"""Test all available filters on the given feed"""
|
|
||||||
if not filters:
|
|
||||||
filters = self.config['filters']
|
|
||||||
log.debug("will test filters %s", filters)
|
|
||||||
hits = {}
|
|
||||||
# Test every entry...
|
|
||||||
for entry in self.feeds[feedname]['entries']:
|
|
||||||
# ...and every filter
|
|
||||||
for filter in filters:
|
|
||||||
# We need to be able to run feeds saved before implementation of actiave/deactivate filter (pre 0.3) TODO
|
|
||||||
try:
|
|
||||||
if not filters[filter].active:
|
|
||||||
continue
|
|
||||||
except:
|
|
||||||
log.debug("old filter, will assume filter is activated")
|
|
||||||
|
|
||||||
if filters[filter].regex == "": # we don't want a empty regex...
|
|
||||||
log.warning("Filter '%s' has not been configured, ignoring!", filter)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# if the filter isn't supposed to be run on this feed we don't want to run it...
|
|
||||||
# if filter.all_feeds or self.config['filters'][filter].feeds.has_element(feedname) : # ...apparently has_element doesn't work on arrays... TODO
|
|
||||||
if self.test_filter(entry, filters[filter].regex):
|
|
||||||
if test:
|
|
||||||
hits[entry.title] = entry.link
|
|
||||||
else:
|
|
||||||
opts = filters[filter].get_config()
|
|
||||||
#remove filter options that should not be passed on to the torrent.
|
|
||||||
del opts['regex']
|
|
||||||
del opts['feeds']
|
|
||||||
del opts['all_feeds']
|
|
||||||
|
|
||||||
# history patch from Darrell Enns, slightly modified :)
|
|
||||||
# check history to prevent multiple adds of the same torrent
|
|
||||||
log.debug("testing %s", entry.link)
|
|
||||||
if not entry.link in self.history:
|
|
||||||
self.add_torrent(entry.link, opts, self.feeds[feedname].cookies)
|
|
||||||
self.history.append(entry.link)
|
|
||||||
|
|
||||||
#limit history to 50 entries
|
|
||||||
if len(self.history)>50:
|
|
||||||
self.history=self.history[-50:]
|
|
||||||
log.debug("wrapping history")
|
|
||||||
else:
|
|
||||||
log.debug("'%s' is in history, will not download", entry.link)
|
|
||||||
return hits
|
|
||||||
|
|
||||||
|
|
||||||
def test_filter(self, entry, filter):
|
|
||||||
"""Tests a filter to a given rss entry"""
|
|
||||||
f = re.compile(filter, re.IGNORECASE)
|
|
||||||
if f.search(entry.title) or f.search(entry.link):
|
|
||||||
log.debug("RSS item '%s' matches filter '%s'", entry.title, filter)
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def add_torrent(self, url, torrent_options, headers):
|
|
||||||
log.debug("Attempting to add torrent %s", url)
|
|
||||||
component.get("Core").add_torrent_url(url, torrent_options, headers)
|
|
|
@ -1,50 +0,0 @@
|
||||||
#
|
|
||||||
# gtkui.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from deluge.ui.client import client
|
|
||||||
from deluge.plugins.pluginbase import GtkPluginBase
|
|
||||||
import deluge.component as component
|
|
||||||
import deluge.common
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class GtkUI(GtkPluginBase):
|
|
||||||
def enable(self):
|
|
||||||
pass
|
|
||||||
def disable(self):
|
|
||||||
pass
|
|
|
@ -1,13 +0,0 @@
|
||||||
$def with (entries, feedname)
|
|
||||||
$:render.header("things", '')
|
|
||||||
<div class="panel" >
|
|
||||||
<div>
|
|
||||||
<h3>Feed items for feed $feedname</h3>
|
|
||||||
<ul>
|
|
||||||
$entries
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<a href="/config/feeder">back to config</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
$:render.footer()
|
|
|
@ -1,50 +0,0 @@
|
||||||
$def with (filter_settings_form, filter)
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Deluge:things</title>
|
|
||||||
<link rel="icon" href="/static/images/deluge-icon.png" type="image/png" />
|
|
||||||
<link rel="shortcut icon" href="/static/images/deluge-icon.png" type="image/png" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/template_style.css" />
|
|
||||||
<script language="javascript" src="/static/deluge.js"></script>
|
|
||||||
<script language="javascript" src="/static/mootools-1.2-core.js"></script>
|
|
||||||
|
|
||||||
<script language="javascript" src="/static/mootools-1.2-more.js"></script>
|
|
||||||
<script language="javascript" src="/static/mooui.js"></script>
|
|
||||||
<script language="javascript" src="/static/deluge-moo.js"></script>
|
|
||||||
<script language="javascript" src="/gettext.js"></script>
|
|
||||||
<script language="javascript" src="/label/data/label.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<form method="post" action='$base/feeder/filter_settings/$filter'>
|
|
||||||
<div class="info">
|
|
||||||
<h3>Filter</h3>
|
|
||||||
<table>
|
|
||||||
$:(filter_settings_form.as_table(["regex", "active"]))
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>Speed</h3>
|
|
||||||
<table>
|
|
||||||
$:(filter_settings_form.as_table(["max_download_speed", "max_upload_speed", "max_upload_slots", "max_connections"]))
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>Seed options</h3>
|
|
||||||
<table>
|
|
||||||
$:(filter_settings_form.as_table(["stop_ratio", "stop_at_ratio", "remove_at_ratio"]))
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>Other options</h3>
|
|
||||||
<table>
|
|
||||||
$:(filter_settings_form.as_table(["prioritize_first_last_pieces", "auto_managed", "download_location"]))
|
|
||||||
</table>
|
|
||||||
<input type="submit" name="submit" value="$_('Save')" />
|
|
||||||
|
|
||||||
</form>
|
|
||||||
<h3>Matches</h3>
|
|
||||||
$:filter_settings_form.post_html()
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,39 +0,0 @@
|
||||||
$def with (filters, new_filter_form)
|
|
||||||
$:render.header("things", '')
|
|
||||||
<table><tr>
|
|
||||||
<td>
|
|
||||||
<table><tr></td>
|
|
||||||
<div class="info">
|
|
||||||
<h3>Filters</h3>
|
|
||||||
</div></td></tr>
|
|
||||||
<tr><td>
|
|
||||||
<div class="info">
|
|
||||||
<ul>
|
|
||||||
$filters
|
|
||||||
</ul>
|
|
||||||
<form method="post" action='$base/feeder/filters'>
|
|
||||||
$:(new_filter_form.as_p(["name"]))
|
|
||||||
<input type="submit" name="submit" class="form_input" value="$_('Add filter')" />
|
|
||||||
</form>
|
|
||||||
<p><a href="/config/feeder">back to config</a>
|
|
||||||
</div></td></tr></table>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="panel">
|
|
||||||
<iframe style="border-style:hidden;" id="filter_settings" width=100% height=600>
|
|
||||||
</iframe>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr></table>
|
|
||||||
|
|
||||||
<script language="javascript">
|
|
||||||
function load_options(filter){
|
|
||||||
\$('filter_settings').src = state.base_url + '/feeder/filter_settings/' + filter;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script language="javascript">
|
|
||||||
new InputSensitivitySetter({prefix:"id_",groups:[
|
|
||||||
["name"]
|
|
||||||
]});
|
|
||||||
</script>
|
|
||||||
$:render.footer()
|
|
|
@ -1,279 +0,0 @@
|
||||||
#
|
|
||||||
# webui.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 Fredrik Eriksson <feeder@winterbird.org>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007, 2008 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import feedparser # for proccessing feed entries
|
|
||||||
import os
|
|
||||||
from deluge.ui.client import sclient, aclient
|
|
||||||
from deluge.plugins.webuipluginbase import WebUIPluginBase
|
|
||||||
from deluge import component
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
api = component.get("WebPluginApi")
|
|
||||||
forms = api.forms
|
|
||||||
|
|
||||||
class feed_page:
|
|
||||||
"Class for showing feed items"
|
|
||||||
@api.deco.deluge_page
|
|
||||||
def GET(self, feedname):
|
|
||||||
entries = sclient.feeder_get_items(feedname)
|
|
||||||
items = ""
|
|
||||||
for item in entries:
|
|
||||||
items = """%(old)s
|
|
||||||
<a href="%(link)s">
|
|
||||||
<li>%(entry)s</li>
|
|
||||||
</a>""" % { "old":items, "entry":item, "link":entries[item]}
|
|
||||||
return api.render.feeder.feeds(items, feedname)
|
|
||||||
|
|
||||||
class filter_page:
|
|
||||||
"Class for showing filters / filter settings"
|
|
||||||
@api.deco.deluge_page
|
|
||||||
def GET(self, args):
|
|
||||||
new_filter = new_filter_form()
|
|
||||||
filters = sclient.feeder_get_filters()
|
|
||||||
|
|
||||||
# List filters
|
|
||||||
txt = ""
|
|
||||||
for filter in filters:
|
|
||||||
txt = """%(old)s
|
|
||||||
<li onclick=\"load_options('%(new)s')\">
|
|
||||||
%(new)s
|
|
||||||
</li>""" % {'old':txt, 'new':filter}
|
|
||||||
|
|
||||||
return api.render.feeder.filters(txt, new_filter)
|
|
||||||
|
|
||||||
def POST(self):
|
|
||||||
"Saves the new filter"
|
|
||||||
name = api.utils.get_newforms_data(new_filter_form)['name']
|
|
||||||
sclient.feeder_add_filter(name)
|
|
||||||
return self.GET(name)
|
|
||||||
|
|
||||||
class new_filter_form(forms.Form):
|
|
||||||
"basic form for a new label"
|
|
||||||
name = forms.CharField(label="")
|
|
||||||
|
|
||||||
class filter_settings_page:
|
|
||||||
"Class for showing filter settings"
|
|
||||||
@api.deco.deluge_page
|
|
||||||
def GET(self, filter):
|
|
||||||
form = filter_settings_form(filter)
|
|
||||||
return api.render.feeder.filter_settings(form, filter)
|
|
||||||
|
|
||||||
def POST(self, filter):
|
|
||||||
opts = api.utils.get_newforms_data(filter_settings_form)
|
|
||||||
|
|
||||||
# apparently the "Unlimited" options still have to be changed
|
|
||||||
# to -1 (wtf?)
|
|
||||||
# FIXME there is probably a very much better way to ensure that
|
|
||||||
# all values have the right types... not to mention to convert "Unlimited"
|
|
||||||
# to -1...
|
|
||||||
try:
|
|
||||||
opts['max_upload_speed'] = int(opts['max_upload_speed'])
|
|
||||||
except:
|
|
||||||
opts['max_upload_speed'] = int(-1)
|
|
||||||
try:
|
|
||||||
opts['max_download_speed'] = int(opts['max_download_speed'])
|
|
||||||
except:
|
|
||||||
opts['max_download_speed'] = int(-1)
|
|
||||||
try:
|
|
||||||
opts['max_connections'] = int(opts['max_connections'])
|
|
||||||
except:
|
|
||||||
opts['max_connections'] = int(-1)
|
|
||||||
try:
|
|
||||||
opts['max_upload_slots'] = int(opts['max_upload_slots'])
|
|
||||||
except:
|
|
||||||
opts['max_upload_slots'] = int(-1)
|
|
||||||
"""opts['max_upload_slots'] = long(opts['max_upload_slots'])
|
|
||||||
opts['max_connections'] = long(opts['max_connections'])"""
|
|
||||||
|
|
||||||
# TODO filter settings per feed not implemented.
|
|
||||||
opts['feeds'] = []
|
|
||||||
|
|
||||||
sclient.feeder_set_filter_config(filter, opts)
|
|
||||||
return self.GET(filter)
|
|
||||||
|
|
||||||
class filter_settings_form(forms.Form):
|
|
||||||
"form for filter settings"
|
|
||||||
|
|
||||||
def __init__(self, filter, test=False):
|
|
||||||
self.filtername = filter # We want to save our filtername
|
|
||||||
forms.Form.__init__(self)
|
|
||||||
|
|
||||||
def initial_data(self):
|
|
||||||
self.conf = sclient.feeder_get_filter_config(self.filtername)
|
|
||||||
return self.conf
|
|
||||||
|
|
||||||
def post_html(self):
|
|
||||||
regex = self.conf["regex"]
|
|
||||||
hits = sclient.feeder_test_filter(regex)
|
|
||||||
if not hits:
|
|
||||||
return "No hits"
|
|
||||||
list = ""
|
|
||||||
for hit in hits:
|
|
||||||
list = """%(old)s
|
|
||||||
<li><a href="%(link)s" >%(name)s</a></li>
|
|
||||||
""" % { "old":list, "link":hits[hit], "name":hit }
|
|
||||||
return """
|
|
||||||
<ul>
|
|
||||||
%s
|
|
||||||
</ul>
|
|
||||||
""" % list
|
|
||||||
|
|
||||||
regex = forms.CharField(_("regular_expression"))
|
|
||||||
all_feeds = forms.CheckBox(_("all_feeds"))
|
|
||||||
active = forms.CheckBox(_("active"))
|
|
||||||
|
|
||||||
#maximum:
|
|
||||||
max_download_speed = forms.DelugeFloat(_("max_download_speed"))
|
|
||||||
max_upload_speed = forms.DelugeFloat(_("max_upload_speed"))
|
|
||||||
max_upload_slots = forms.DelugeInt(_("max_upload_slots"))
|
|
||||||
max_connections = forms.DelugeInt(_("max_connections"))
|
|
||||||
|
|
||||||
stop_ratio = forms.DelugeFloat(_("stop_ratio"))
|
|
||||||
stop_at_ratio = forms.CheckBox(_("stop_at_ratio"))
|
|
||||||
remove_at_ratio = forms.CheckBox(_("remove_at_ratio"))
|
|
||||||
|
|
||||||
#queue:
|
|
||||||
auto_managed = forms.CheckBox(_("is_auto_managed"))
|
|
||||||
prioritize_first_last_pieces = forms.CheckBox(_("prioritize_first_last_pieces"))
|
|
||||||
|
|
||||||
download_location = forms.ServerFolder(_("download_location"))
|
|
||||||
|
|
||||||
class remove_feed_page:
|
|
||||||
"Class for deleting feeds, redirects to setting page"
|
|
||||||
@api.deco.deluge_page
|
|
||||||
def GET(self, feedname):
|
|
||||||
sclient.feeder_remove_feed(feedname)
|
|
||||||
return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Redirecting back to settings</title>
|
|
||||||
<meta http-equiv="refresh" content="0; URL=/config/feeder">
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>"""
|
|
||||||
|
|
||||||
class remove_filter_page:
|
|
||||||
"Class for deleting filters, redirects to setting page"
|
|
||||||
@api.deco.deluge_page
|
|
||||||
def GET(self, name):
|
|
||||||
sclient.feeder_remove_filter(name)
|
|
||||||
return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Redirecting back to settings</title>
|
|
||||||
<meta http-equiv="refresh" content="0; URL=/config/feeder">
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>"""
|
|
||||||
|
|
||||||
|
|
||||||
class WebUI(WebUIPluginBase):
|
|
||||||
#map url's to classes: [(url,class), ..]
|
|
||||||
urls = [('/feeder/filters', filter_page),
|
|
||||||
('/feeder/filter_settings/(.*)', filter_settings_page),
|
|
||||||
('/feeder/feed_remove/(.*)', remove_feed_page),
|
|
||||||
('/feeder/filter_remove/(.*)', remove_filter_page),
|
|
||||||
('/feeder/feed/(.*)', feed_page)]
|
|
||||||
|
|
||||||
def enable(self):
|
|
||||||
api.config_page_manager.register('plugins', 'feeder' ,ConfigForm)
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
api.config_page_manager.deregister('feeder')
|
|
||||||
|
|
||||||
class ConfigForm(forms.Form):
|
|
||||||
#meta:
|
|
||||||
title = _("feeder")
|
|
||||||
|
|
||||||
#load/save:
|
|
||||||
def initial_data(self):
|
|
||||||
return sclient.feeder_get_config()
|
|
||||||
|
|
||||||
def save(self, data):
|
|
||||||
cfg = dict(data)
|
|
||||||
sclient.feeder_add_feed(cfg)
|
|
||||||
|
|
||||||
def pre_html(self):
|
|
||||||
feeds = sclient.feeder_get_feeds()
|
|
||||||
filters = sclient.feeder_get_filters()
|
|
||||||
filterlist = ""
|
|
||||||
for filter in filters:
|
|
||||||
filterlist = """ %(old)s <li>%(new)s
|
|
||||||
<a href="/feeder/filter_remove/%(new)s">
|
|
||||||
<img src="/static/images/16/list-remove.png" alt="Remove" />
|
|
||||||
</a></li>""" % {'old':filterlist, 'new':filter}
|
|
||||||
feedlist = ""
|
|
||||||
for feed in feeds:
|
|
||||||
feedlist = """%(old)s
|
|
||||||
<li> <a href="/feeder/feed/%(new)s"> %(new)s (%(entrys)s torrents)</a>
|
|
||||||
<a href="/feeder/feed_remove/%(new)s">
|
|
||||||
<img src="/static/images/16/list-remove.png" alt="Remove" />
|
|
||||||
</a></li>""" % {'old':feedlist, 'new':feed, 'entrys':len(sclient.feeder_get_items(feed))}
|
|
||||||
|
|
||||||
return """
|
|
||||||
<table width=100%%><tr><td>
|
|
||||||
<h3>Feeds</h3>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<h3>Filters</h3>
|
|
||||||
</td></tr>
|
|
||||||
<tr><td>
|
|
||||||
<div class="info">
|
|
||||||
<ul>
|
|
||||||
%(feeds)s
|
|
||||||
</ul></div>
|
|
||||||
</td><td>
|
|
||||||
<div class="info">
|
|
||||||
<ul>
|
|
||||||
%(filters)s
|
|
||||||
</ul></div>
|
|
||||||
<a href="/feeder/filters">Add/modify filters</a>
|
|
||||||
</td></tr>
|
|
||||||
</table>
|
|
||||||
<h3>Add/change feed settings</h3>""" % {'feeds':feedlist, 'filters':filterlist}
|
|
||||||
|
|
||||||
name = forms.CharField(label=_("Name of feed"))
|
|
||||||
url = forms.URLField(label=_("URL of feed"))
|
|
||||||
updatetime = forms.IntegerField(label=_("Defualt refresh time"))
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
#
|
|
||||||
# setup.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 Fredrik Eriksson <feeder@winterbird.org>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007, 2008 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
__plugin_name__ = "Feeder"
|
|
||||||
__author__ = "Fredrik Eriksson"
|
|
||||||
__author_email__ = "feeder@winterbird.org"
|
|
||||||
__version__ = "0.4"
|
|
||||||
__url__ = ""
|
|
||||||
__license__ = "GPLv3"
|
|
||||||
__description__ = "A plugin for automatically downloadning torrents from a RSS-feed"
|
|
||||||
__long_description__ = """"""
|
|
||||||
__pkg_data__ = {"deluge.plugins."+__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__,
|
|
||||||
|
|
||||||
packages=find_packages(),
|
|
||||||
namespace_packages = ["deluge", "deluge.plugins"],
|
|
||||||
package_data = __pkg_data__,
|
|
||||||
|
|
||||||
entry_points="""
|
|
||||||
[deluge.plugin.core]
|
|
||||||
%s = deluge.plugins.%s:CorePlugin
|
|
||||||
[deluge.plugin.gtkui]
|
|
||||||
%s = deluge.plugins.%s:GtkUIPlugin
|
|
||||||
[deluge.plugin.web]
|
|
||||||
%s = deluge.plugins.%s:WebUIPlugin
|
|
||||||
""" % ((__plugin_name__, __plugin_name__.lower())*3)
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
BASEDIR=$(cd `dirname $0` && pwd)
|
|
||||||
CONFIG_DIR=$( test -z $1 && echo "" || echo "$1")
|
|
||||||
[ -d "$CONFIG_DIR/plugins" ] || echo "Config dir "$CONFIG_DIR" is either not a directory or is not a proper deluge config directory. Exiting"
|
|
||||||
[ -d "$CONFIG_DIR/plugins" ] || exit 1
|
|
||||||
cd $BASEDIR
|
|
||||||
test -d $BASEDIR/temp || mkdir $BASEDIR/temp
|
|
||||||
export PYTHONPATH=$BASEDIR/temp
|
|
||||||
python setup.py build develop --install-dir $BASEDIR/temp
|
|
||||||
cp $BASEDIR/temp/*.egg-link $CONFIG_DIR/plugins
|
|
||||||
rm -fr $BASEDIR/temp
|
|
|
@ -1,3 +0,0 @@
|
||||||
# this is a namespace package
|
|
||||||
import pkg_resources
|
|
||||||
pkg_resources.declare_namespace(__name__)
|
|
|
@ -1,3 +0,0 @@
|
||||||
# this is a namespace package
|
|
||||||
import pkg_resources
|
|
||||||
pkg_resources.declare_namespace(__name__)
|
|
|
@ -1,58 +0,0 @@
|
||||||
#
|
|
||||||
# __init__.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
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)
|
|
|
@ -1,43 +0,0 @@
|
||||||
#
|
|
||||||
# common.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
def get_resource(filename):
|
|
||||||
import pkg_resources, os
|
|
||||||
return pkg_resources.resource_filename("deluge.plugins.freespace",
|
|
||||||
os.path.join("data", filename))
|
|
|
@ -1,202 +0,0 @@
|
||||||
#
|
|
||||||
# core.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import os, statvfs
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from twisted.internet import task
|
|
||||||
from deluge.plugins.pluginbase import CorePluginBase
|
|
||||||
from deluge.event import DelugeEvent
|
|
||||||
import deluge.component as component
|
|
||||||
import deluge.configmanager
|
|
||||||
from deluge.core.rpcserver import export
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class LowDiskSpaceEvent(DelugeEvent):
|
|
||||||
"""Triggered when the available space for a specific path is getting
|
|
||||||
too low.
|
|
||||||
"""
|
|
||||||
def __init__(self, percents_dict):
|
|
||||||
"""
|
|
||||||
:param percents: dictionary of path keys with their respecive
|
|
||||||
occupation percentages.
|
|
||||||
"""
|
|
||||||
self._args = [percents_dict]
|
|
||||||
|
|
||||||
DEFAULT_PREFS = {
|
|
||||||
"enabled": False,
|
|
||||||
"percent": 90
|
|
||||||
}
|
|
||||||
|
|
||||||
class Core(CorePluginBase):
|
|
||||||
CLEANUP_TIMEOUT_SECS = 3600 # One hour
|
|
||||||
|
|
||||||
def enable(self):
|
|
||||||
self.config = deluge.configmanager.ConfigManager("freespace.conf",
|
|
||||||
DEFAULT_PREFS)
|
|
||||||
self.notifications_sent = {}
|
|
||||||
|
|
||||||
self._timer = task.LoopingCall(self.update)
|
|
||||||
self._interval = 60 * 5 # every 5 minutes
|
|
||||||
if self.config['enabled']:
|
|
||||||
self._timer.start(self._interval, False)
|
|
||||||
|
|
||||||
self._cleanup = task.LoopingCall(self.__cleanup_notifications)
|
|
||||||
self._cleanup.start(self._interval, False)
|
|
||||||
|
|
||||||
try:
|
|
||||||
component.get("CorePlugin.Notifications"). \
|
|
||||||
register_custom_email_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_email_notification
|
|
||||||
)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
component.get("EventManager").register_event_handler(
|
|
||||||
"PluginEnabledEvent", self.__on_plugin_enabled
|
|
||||||
)
|
|
||||||
component.get("EventManager").register_event_handler(
|
|
||||||
"PluginDisabledEvent", self.__on_plugin_disabled
|
|
||||||
)
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
try:
|
|
||||||
component.get("CorePlugin.Notifications"). \
|
|
||||||
deregister_custom_email_notification("LowDiskSpaceEvent")
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
component.get("EventManager").deregister_event_handler(
|
|
||||||
"PluginEnabledEvent", self.__on_plugin_enabled
|
|
||||||
)
|
|
||||||
component.get("EventManager").deregister_event_handler(
|
|
||||||
"PluginDisabledEvent", self.__on_plugin_disabled
|
|
||||||
)
|
|
||||||
self._cleanup.stop()
|
|
||||||
if self._timer.running:
|
|
||||||
self._timer.stop()
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
log.debug('Updating %s FreeSpace', self.__class__.__name__)
|
|
||||||
nots = {}
|
|
||||||
for path in self.__gather_paths_to_check():
|
|
||||||
log.debug("Checking path %s", path)
|
|
||||||
if os.path.exists(path):
|
|
||||||
free_percent = self.__get_free_space(path)
|
|
||||||
if (100 - free_percent) > self.config['percent']:
|
|
||||||
if path not in self.notifications_sent:
|
|
||||||
self.notifications_sent[path] = datetime.utcnow()
|
|
||||||
nots[path] = (100 - free_percent)
|
|
||||||
else:
|
|
||||||
log.warning("Running low on disk space on %s but "
|
|
||||||
"notifications were already triggered.",
|
|
||||||
path)
|
|
||||||
if nots:
|
|
||||||
component.get("EventManager").emit(LowDiskSpaceEvent(nots))
|
|
||||||
|
|
||||||
|
|
||||||
@export
|
|
||||||
def set_config(self, config):
|
|
||||||
"sets the config dictionary"
|
|
||||||
if not self.config['enabled'] and config['enabled']:
|
|
||||||
self._timer.start(self._interval, False)
|
|
||||||
elif self.config['enabled'] and not config['enabled']:
|
|
||||||
self._timer.stop()
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def __gather_paths_to_check(self):
|
|
||||||
self.over_percentage = {}
|
|
||||||
torrent_manager = component.get('TorrentManager')
|
|
||||||
paths = set()
|
|
||||||
for torrent_id in torrent_manager.get_torrent_list():
|
|
||||||
status = torrent_manager[torrent_id].get_status([
|
|
||||||
'is_finished',
|
|
||||||
'move_on_completed_path',
|
|
||||||
'save_path'
|
|
||||||
])
|
|
||||||
if not status['is_finished']:
|
|
||||||
paths.add(status['move_on_completed_path'])
|
|
||||||
paths.add(status['save_path'])
|
|
||||||
return paths
|
|
||||||
|
|
||||||
def __get_free_space(self, path):
|
|
||||||
log.debug("Calculating free space on %s", path)
|
|
||||||
stat = os.statvfs(path)
|
|
||||||
free_blocks = stat[statvfs.F_BAVAIL]
|
|
||||||
total_blocks = stat[statvfs.F_BLOCKS]
|
|
||||||
free_percent = free_blocks * 100 / total_blocks
|
|
||||||
return free_percent
|
|
||||||
|
|
||||||
def __custom_email_notification(self, ocupied_percents):
|
|
||||||
|
|
||||||
subject = _("Low Disk Space Warning")
|
|
||||||
message = _("You're running low on disk space:\n")
|
|
||||||
|
|
||||||
for path, ocupied_percent in ocupied_percents.iteritems():
|
|
||||||
message += ' %s%% %s %s\n' % (ocupied_percent, _("ocupation in"), path)
|
|
||||||
# "\"%s\"%% space occupation on %s") % (ocupied_percent, path)
|
|
||||||
return subject, message
|
|
||||||
|
|
||||||
def __on_plugin_enabled(self, plugin_name):
|
|
||||||
if plugin_name == 'Notifications':
|
|
||||||
component.get("CorePlugin.Notifications"). \
|
|
||||||
register_custom_email_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_email_notification
|
|
||||||
)
|
|
||||||
|
|
||||||
def __on_plugin_disabled(self, plugin_name):
|
|
||||||
if plugin_name == 'Notifications':
|
|
||||||
component.get("CorePlugin.Notifications"). \
|
|
||||||
deregister_custom_email_notification("LowDiskSpaceEvent")
|
|
||||||
|
|
||||||
def __cleanup_notifications(self):
|
|
||||||
now = datetime.now()
|
|
||||||
for path, when in self.notifications_sent.copy().iteritems():
|
|
||||||
if when <= (now -timedelta(seconds=self.CLEANUP_TIMEOUT_SECS)):
|
|
||||||
log.debug("Removing old(%s) path from notified paths: %s",
|
|
||||||
when, path)
|
|
||||||
self.notifications_sent.pop(path)
|
|
|
@ -1,100 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<glade-interface>
|
|
||||||
<!-- interface-requires gtk+ 2.6 -->
|
|
||||||
<!-- interface-naming-policy toplevel-contextual -->
|
|
||||||
<widget class="GtkWindow" id="window1">
|
|
||||||
<child>
|
|
||||||
<widget class="GtkHBox" id="prefs_box">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkFrame" id="frame1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label_xalign">0</property>
|
|
||||||
<property name="shadow_type">none</property>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkAlignment" id="alignment1">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="left_padding">12</property>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkVBox" id="vbox2">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkHBox" id="hbox2">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkCheckButton" id="enabled">
|
|
||||||
<property name="label" translatable="yes">Consider low when</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkSpinButton" id="percent">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="max_length">2</property>
|
|
||||||
<property name="invisible_char">●</property>
|
|
||||||
<property name="adjustment">90 0 99 1 10 0</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="padding">5</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label14">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label">%</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label4">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes">of the disk is occupied.</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="padding">5</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label2">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="label" translatable="yes"><b>Free Space Checking</b></property>
|
|
||||||
<property name="use_markup">True</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="type">label_item</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
</glade-interface>
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
Script: freespace.js
|
|
||||||
The client-side javascript code for the FreeSpace plugin.
|
|
||||||
|
|
||||||
Copyright:
|
|
||||||
(C) Pedro Algarvio 2009 <damoxc@gmail.com>
|
|
||||||
This program 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, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program 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 this program. If not, write to:
|
|
||||||
The Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
In addition, as a special exception, the copyright holders give
|
|
||||||
permission to link the code of portions of this program with the OpenSSL
|
|
||||||
library.
|
|
||||||
You must obey the GNU General Public License in all respects for all of
|
|
||||||
the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
exception, you may extend this exception to your version of the file(s),
|
|
||||||
but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
this exception statement from your version. If you delete this exception
|
|
||||||
statement from all source files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
FreeSpacePlugin = Ext.extend(Deluge.Plugin, {
|
|
||||||
constructor: function(config) {
|
|
||||||
config = Ext.apply({
|
|
||||||
name: "FreeSpace"
|
|
||||||
}, config);
|
|
||||||
FreeSpacePlugin.superclass.constructor.call(this, config);
|
|
||||||
},
|
|
||||||
|
|
||||||
onDisable: function() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
onEnable: function() {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
new FreeSpacePlugin();
|
|
|
@ -1,162 +0,0 @@
|
||||||
#
|
|
||||||
# gtkui.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
import gtk
|
|
||||||
import gtk.glade
|
|
||||||
import logging
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class GtkUI(GtkPluginBase):
|
|
||||||
|
|
||||||
def enable(self):
|
|
||||||
log.debug('Enabling %s FreeSpace', self.__class__.__name__)
|
|
||||||
self.glade = gtk.glade.XML(get_resource("config.glade"))
|
|
||||||
self.prefs = self.glade.get_widget('prefs_box')
|
|
||||||
parent = self.prefs.get_parent()
|
|
||||||
if parent:
|
|
||||||
parent.remove(self.prefs)
|
|
||||||
|
|
||||||
self.downloads_vbox = component.get("Preferences").builder.get_object('downloads_vbox')
|
|
||||||
self.downloads_vbox.pack_start(self.prefs, False, True, 0)
|
|
||||||
|
|
||||||
component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs)
|
|
||||||
component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs)
|
|
||||||
|
|
||||||
try:
|
|
||||||
notifications = component.get("GtkPlugin.Notifications")
|
|
||||||
notifications.register_custom_popup_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_popup_notification
|
|
||||||
)
|
|
||||||
notifications.register_custom_blink_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_blink_notification
|
|
||||||
)
|
|
||||||
notifications.register_custom_sound_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_sound_notification
|
|
||||||
)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
client.register_event_handler("PluginEnabledEvent", self.__on_plugin_enabled)
|
|
||||||
client.register_event_handler("PluginDisabledEvent", self.__on_plugin_disabled)
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
self.downloads_vbox.remove(self.prefs)
|
|
||||||
component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs)
|
|
||||||
component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs)
|
|
||||||
try:
|
|
||||||
notifications = component.get("GtkPlugin.Notifications")
|
|
||||||
notifications.deregister_custom_popup_notification(
|
|
||||||
"LowDiskSpaceEvent"
|
|
||||||
)
|
|
||||||
notifications.deregister_custom_blink_notification(
|
|
||||||
"LowDiskSpaceEvent"
|
|
||||||
)
|
|
||||||
notifications.deregister_custom_sound_notification(
|
|
||||||
"LowDiskSpaceEvent"
|
|
||||||
)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
client.deregister_event_handler("PluginEnabledEvent", self.__on_plugin_enabled)
|
|
||||||
client.deregister_event_handler("PluginDisabledEvent", self.__on_plugin_disabled)
|
|
||||||
|
|
||||||
def on_apply_prefs(self):
|
|
||||||
log.debug("applying prefs for FreeSpace")
|
|
||||||
config = {
|
|
||||||
"enabled": self.glade.get_widget('enabled').get_active(),
|
|
||||||
"percent": self.glade.get_widget('percent').get_value()
|
|
||||||
}
|
|
||||||
client.freespace.set_config(config)
|
|
||||||
|
|
||||||
def on_show_prefs(self):
|
|
||||||
client.freespace.get_config().addCallback(self.cb_get_config)
|
|
||||||
|
|
||||||
def cb_get_config(self, config):
|
|
||||||
"callback for on show_prefs"
|
|
||||||
self.glade.get_widget('enabled').set_active(config['enabled'])
|
|
||||||
self.glade.get_widget('percent').set_value(config['percent'])
|
|
||||||
|
|
||||||
def __custom_popup_notification(self, ocupied_percents):
|
|
||||||
title = _("Low Free Space")
|
|
||||||
message = ''
|
|
||||||
for path, percent in ocupied_percents.iteritems():
|
|
||||||
message += '%s%% %s\n' % (percent, path)
|
|
||||||
message += '\n'
|
|
||||||
return title, message
|
|
||||||
|
|
||||||
def __custom_blink_notification(self, ocupied_percents):
|
|
||||||
return True # Yes, do blink
|
|
||||||
|
|
||||||
def __custom_sound_notification(self, ocupied_percents):
|
|
||||||
return '' # Use default sound
|
|
||||||
|
|
||||||
def __on_plugin_enabled(self, plugin_name):
|
|
||||||
if plugin_name == 'Notifications':
|
|
||||||
notifications = component.get("GtkPlugin.Notifications")
|
|
||||||
notifications.register_custom_popup_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_popup_notification
|
|
||||||
)
|
|
||||||
notifications.register_custom_blink_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_blink_notification
|
|
||||||
)
|
|
||||||
notifications.register_custom_sound_notification(
|
|
||||||
"LowDiskSpaceEvent", self.__custom_sound_notification
|
|
||||||
)
|
|
||||||
|
|
||||||
def __on_plugin_disabled(self, plugin_name):
|
|
||||||
pass
|
|
||||||
# if plugin_name == 'Notifications':
|
|
||||||
# notifications = component.get("GtkPlugin.Notifications")
|
|
||||||
# notifications.deregister_custom_popup_notification(
|
|
||||||
# "LowDiskSpaceEvent"
|
|
||||||
# )
|
|
||||||
# notifications.deregister_custom_blink_notification(
|
|
||||||
# "LowDiskSpaceEvent"
|
|
||||||
# )
|
|
||||||
# notifications.deregister_custom_sound_notification(
|
|
||||||
# "LowDiskSpaceEvent"
|
|
||||||
# )
|
|
|
@ -1,57 +0,0 @@
|
||||||
#
|
|
||||||
# webui.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
import logging
|
|
||||||
from deluge.ui.client import client
|
|
||||||
from deluge import component
|
|
||||||
from deluge.plugins.pluginbase import WebPluginBase
|
|
||||||
|
|
||||||
from common import get_resource
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class WebUI(WebPluginBase):
|
|
||||||
|
|
||||||
scripts = [get_resource("freespace.js")]
|
|
||||||
|
|
||||||
def enable(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def disable(self):
|
|
||||||
pass
|
|
|
@ -1,72 +0,0 @@
|
||||||
#
|
|
||||||
# setup.py
|
|
||||||
#
|
|
||||||
# Copyright (C) 2009-2010 Pedro Algarvio <pedro@algarvio.me>
|
|
||||||
#
|
|
||||||
# Basic plugin template created by:
|
|
||||||
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
|
|
||||||
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
|
|
||||||
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# In addition, as a special exception, the copyright holders give
|
|
||||||
# permission to link the code of portions of this program with the OpenSSL
|
|
||||||
# library.
|
|
||||||
# You must obey the GNU General Public License in all respects for all of
|
|
||||||
# the code used other than OpenSSL. If you modify file(s) with this
|
|
||||||
# exception, you may extend this exception to your version of the file(s),
|
|
||||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
|
||||||
# this exception statement from your version. If you delete this exception
|
|
||||||
# statement from all source files in the program, then also delete it here.
|
|
||||||
#
|
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
|
|
||||||
__plugin_name__ = "FreeSpace"
|
|
||||||
__author__ = "Pedro Algarvio"
|
|
||||||
__author_email__ = "pedro@algarvio.me"
|
|
||||||
__version__ = "0.1"
|
|
||||||
__url__ = "http://deluge.ufsoft.org/hg/Notification/"
|
|
||||||
__license__ = "GPLv3"
|
|
||||||
__description__ = "Plugin which continuously checks for available free space."
|
|
||||||
__long_description__ = __description__
|
|
||||||
__pkg_data__ = {"deluge.plugins."+__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=find_packages(),
|
|
||||||
namespace_packages = ["deluge", "deluge.plugins"],
|
|
||||||
package_data = __pkg_data__,
|
|
||||||
|
|
||||||
entry_points="""
|
|
||||||
[deluge.plugin.core]
|
|
||||||
%s = deluge.plugins.%s:CorePlugin
|
|
||||||
[deluge.plugin.gtkui]
|
|
||||||
%s = deluge.plugins.%s:GtkUIPlugin
|
|
||||||
""" % ((__plugin_name__, __plugin_name__.lower())*2)
|
|
||||||
)
|
|
Loading…
Add table
Add a link
Reference in a new issue