mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-11 12:04:10 +00:00
Added autoadd plugin
This commit is contained in:
parent
e7c7b8f4db
commit
211d0bee5d
58
deluge/plugins/autoadd/autoadd/__init__.py
Normal file
58
deluge/plugins/autoadd/autoadd/__init__.py
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# __init__.py
|
||||
#
|
||||
# Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
#
|
||||
# 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)
|
42
deluge/plugins/autoadd/autoadd/common.py
Normal file
42
deluge/plugins/autoadd/autoadd/common.py
Normal file
@ -0,0 +1,42 @@
|
||||
#
|
||||
# common.py
|
||||
#
|
||||
# Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
#
|
||||
# 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("autoadd", os.path.join("data", filename))
|
316
deluge/plugins/autoadd/autoadd/core.py
Normal file
316
deluge/plugins/autoadd/autoadd/core.py
Normal file
@ -0,0 +1,316 @@
|
||||
#
|
||||
# core.py
|
||||
#
|
||||
# Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
#
|
||||
# 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._libtorrent import lt
|
||||
import os
|
||||
from deluge.log import LOG as log
|
||||
from deluge.plugins.pluginbase import CorePluginBase
|
||||
import deluge.component as component
|
||||
import deluge.configmanager
|
||||
from deluge.core.rpcserver import export
|
||||
from twisted.internet.task import LoopingCall, deferLater
|
||||
from twisted.internet import reactor
|
||||
from deluge.event import DelugeEvent
|
||||
|
||||
DEFAULT_PREFS = {
|
||||
"watchdirs":{},
|
||||
"next_id":1
|
||||
}
|
||||
|
||||
OPTIONS_AVAILABLE = { #option: builtin
|
||||
"enabled":False,
|
||||
"path":False,
|
||||
"abspath":False,
|
||||
"download_location":True,
|
||||
"max_download_speed":True,
|
||||
"max_upload_speed":True,
|
||||
"max_connections":True,
|
||||
"max_upload_slots":True,
|
||||
"prioritize_first_last":True,
|
||||
"auto_managed":True,
|
||||
"stop_at_ratio":True,
|
||||
"stop_ratio":True,
|
||||
"remove_at_ratio":True,
|
||||
"move_completed":True,
|
||||
"move_completed_path":True,
|
||||
"label":False,
|
||||
"add_paused":True
|
||||
}
|
||||
|
||||
MAX_NUM_ATTEMPTS = 10
|
||||
|
||||
class AutoaddOptionsChangedEvent(DelugeEvent):
|
||||
"""
|
||||
Emitted when a new command is added.
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def CheckInput(cond, message):
|
||||
if not cond:
|
||||
raise Exception(message)
|
||||
|
||||
class Core(CorePluginBase):
|
||||
def enable(self):
|
||||
|
||||
#reduce typing, assigning some values to self...
|
||||
self.config = deluge.configmanager.ConfigManager("autoadd.conf", DEFAULT_PREFS)
|
||||
self.watchdirs = self.config["watchdirs"]
|
||||
self.core_cfg = deluge.configmanager.ConfigManager("core.conf")
|
||||
|
||||
|
||||
# A list of filenames
|
||||
self.invalid_torrents = []
|
||||
# Filename:Attempts
|
||||
self.attempts = {}
|
||||
# Loopingcall timers for each enabled watchdir
|
||||
self.update_timers = {}
|
||||
deferLater(reactor, 5, self.enable_looping)
|
||||
|
||||
def enable_looping(self):
|
||||
#Enable all looping calls for enabled watchdirs here
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
if watchdir['enabled']:
|
||||
self.enable_watchdir(watchdir_id)
|
||||
|
||||
def disable(self):
|
||||
#disable all running looping calls
|
||||
for loopingcall in self.update_timers.itervalues():
|
||||
loopingcall.stop()
|
||||
self.config.save()
|
||||
pass
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
@export()
|
||||
def set_options(self, watchdir_id, options):
|
||||
"""
|
||||
update the options for a watch folder
|
||||
"""
|
||||
watchdir_id = str(watchdir_id)
|
||||
options = self._clean_unicode(options)
|
||||
CheckInput(watchdir_id in self.watchdirs , _("Watch folder does not exist."))
|
||||
if options.has_key('path'):
|
||||
options['abspath'] = os.path.abspath(options['path'])
|
||||
CheckInput(os.path.isdir(options['abspath']), _("Path does not exist."))
|
||||
for w_id, w in self.watchdirs.iteritems():
|
||||
if options['abspath'] == w['abspath'] and watchdir_id != w_id:
|
||||
raise Exception("Path is already being watched.")
|
||||
for key in options.keys():
|
||||
if not key in OPTIONS_AVAILABLE:
|
||||
if not key in [key+'_toggle' for key in OPTIONS_AVAILABLE.iterkeys()]:
|
||||
raise Exception("autoadd: Invalid options key:%s" % key)
|
||||
#disable the watch loop if it was active
|
||||
if watchdir_id in self.update_timers:
|
||||
self.disable_watchdir(watchdir_id)
|
||||
|
||||
self.watchdirs[watchdir_id].update(options)
|
||||
#re-enable watch loop if appropriate
|
||||
if self.watchdirs[watchdir_id]['enabled']:
|
||||
self.enable_watchdir(watchdir_id)
|
||||
self.config.save()
|
||||
component.get("EventManager").emit(AutoaddOptionsChangedEvent())
|
||||
|
||||
def load_torrent(self, filename):
|
||||
try:
|
||||
log.debug("Attempting to open %s for add.", filename)
|
||||
_file = open(filename, "rb")
|
||||
filedump = _file.read()
|
||||
if not filedump:
|
||||
raise RuntimeError, "Torrent is 0 bytes!"
|
||||
_file.close()
|
||||
except IOError, e:
|
||||
log.warning("Unable to open %s: %s", filename, e)
|
||||
raise e
|
||||
|
||||
# Get the info to see if any exceptions are raised
|
||||
info = lt.torrent_info(lt.bdecode(filedump))
|
||||
|
||||
return filedump
|
||||
|
||||
def update_watchdir(self, watchdir_id):
|
||||
watchdir_id = str(watchdir_id)
|
||||
watchdir = self.watchdirs[watchdir_id]
|
||||
if not watchdir['enabled']:
|
||||
# We shouldn't be updating because this watchdir is not enabled
|
||||
#disable the looping call
|
||||
self.update_timers[watchdir_id].stop()
|
||||
del self.update_timers[watchdir_id]
|
||||
return
|
||||
|
||||
# Check the auto add folder for new torrents to add
|
||||
if not os.path.isdir(watchdir["abspath"]):
|
||||
log.warning("Invalid AutoAdd folder: %s", watchdir["abspath"])
|
||||
#disable the looping call
|
||||
watchdir['enabled'] = False
|
||||
self.update_timers[watchdir_id].stop()
|
||||
del self.update_timers[watchdir_id]
|
||||
return
|
||||
|
||||
#Generate options dict for watchdir
|
||||
opts={}
|
||||
if watchdir.get('stop_at_ratio_toggle'):
|
||||
watchdir['stop_ratio_toggle'] = True
|
||||
for option, value in watchdir.iteritems():
|
||||
if OPTIONS_AVAILABLE.get(option):
|
||||
if watchdir.get(option+'_toggle', True):
|
||||
opts[option] = value
|
||||
opts = self._clean_unicode(opts)
|
||||
for filename in os.listdir(watchdir["abspath"]):
|
||||
if filename.split(".")[-1] == "torrent":
|
||||
try:
|
||||
filepath = os.path.join(watchdir["abspath"], filename)
|
||||
except UnicodeDecodeError, e:
|
||||
log.error("Unable to auto add torrent due to inproper filename encoding: %s", e)
|
||||
continue
|
||||
try:
|
||||
filedump = self.load_torrent(filepath)
|
||||
except (RuntimeError, Exception), e:
|
||||
# If the torrent is invalid, we keep track of it so that we
|
||||
# can try again on the next pass. This is because some
|
||||
# torrents may not be fully saved during the pass.
|
||||
log.debug("Torrent is invalid: %s", e)
|
||||
if filename in self.invalid_torrents:
|
||||
self.attempts[filename] += 1
|
||||
if self.attempts[filename] >= MAX_NUM_ATTEMPTS:
|
||||
os.rename(filepath, filepath + ".invalid")
|
||||
del self.attempts[filename]
|
||||
self.invalid_torrents.remove(filename)
|
||||
else:
|
||||
self.invalid_torrents.append(filename)
|
||||
self.attempts[filename] = 1
|
||||
continue
|
||||
|
||||
# The torrent looks good, so lets add it to the session
|
||||
torrent_id = component.get("TorrentManager").add(filedump=filedump, filename=filename, options=opts)
|
||||
if ('Label' in component.get("CorePluginManager").get_enabled_plugins()) and torrent_id:
|
||||
if watchdir.get('label_toggle', True) and watchdir.get('label'):
|
||||
label = component.get("CorePlugin.Label")
|
||||
if not watchdir['label'] in label.get_labels():
|
||||
label.add(watchdir['label'])
|
||||
label.set_torrent(torrent_id, watchdir['label'])
|
||||
os.remove(filepath)
|
||||
|
||||
@export
|
||||
def enable_watchdir(self, watchdir_id):
|
||||
watchdir_id = str(watchdir_id)
|
||||
self.watchdirs[watchdir_id]['enabled'] = True
|
||||
#If deluge core autoadd is enabled for this path, disable it
|
||||
#log.error(self.core_cfg['autoadd_enable'])
|
||||
if self.core_cfg.config.get('autoadd_enable'):
|
||||
log.error("glob: %s loc: %s" % (os.path.abspath(self.core_cfg['autoadd_location']), self.watchdirs[watchdir_id]['abspath']))
|
||||
if os.path.abspath(self.core_cfg['autoadd_location']) == self.watchdirs[watchdir_id]['abspath']:
|
||||
self.core_cfg['autoadd_enable'] = False
|
||||
#Enable the looping call
|
||||
self.update_timers[watchdir_id] = LoopingCall(self.update_watchdir, watchdir_id)
|
||||
self.update_timers[watchdir_id].start(5)
|
||||
self.config.save()
|
||||
component.get("EventManager").emit(AutoaddOptionsChangedEvent())
|
||||
|
||||
@export
|
||||
def disable_watchdir(self, watchdir_id):
|
||||
watchdir_id = str(watchdir_id)
|
||||
self.watchdirs[watchdir_id]['enabled'] = False
|
||||
#disable the looping call here
|
||||
self.update_timers[watchdir_id].stop()
|
||||
del self.update_timers[watchdir_id]
|
||||
self.config.save()
|
||||
component.get("EventManager").emit(AutoaddOptionsChangedEvent())
|
||||
|
||||
@export
|
||||
def set_config(self, config):
|
||||
"""sets the config dictionary"""
|
||||
for key in config.keys():
|
||||
self.config[key] = config[key]
|
||||
self.config.save()
|
||||
component.get("EventManager").emit(AutoaddOptionsChangedEvent())
|
||||
|
||||
@export
|
||||
def get_config(self):
|
||||
"""returns the config dictionary"""
|
||||
return self.config.config
|
||||
|
||||
@export()
|
||||
def get_watchdirs(self):
|
||||
return self.watchdirs.keys()
|
||||
|
||||
def _clean_unicode(self, options):
|
||||
opts = {}
|
||||
for key, value in options.iteritems():
|
||||
if isinstance(key, unicode):
|
||||
key = str(key)
|
||||
if isinstance(value, unicode):
|
||||
value = str(value)
|
||||
opts[key] = value
|
||||
return opts
|
||||
|
||||
#Labels:
|
||||
@export()
|
||||
def add(self, options={}):
|
||||
"""add a watchdir
|
||||
"""
|
||||
options = self._clean_unicode(options)
|
||||
abswatchdir = os.path.abspath(options['path'])
|
||||
CheckInput(os.path.isdir(abswatchdir) , _("Path does not exist."))
|
||||
CheckInput(os.access(abswatchdir, os.R_OK|os.W_OK), "You must have read and write access to watch folder.")
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
if watchdir['abspath'] == abswatchdir:
|
||||
raise Exception("Path is already being watched.")
|
||||
options.setdefault('enabled', False)
|
||||
options['abspath'] = abswatchdir
|
||||
watchdir_id = self.config['next_id']
|
||||
self.watchdirs[str(watchdir_id)] = options
|
||||
if options.get('enabled'):
|
||||
self.enable_watchdir(watchdir_id)
|
||||
self.config['next_id'] = watchdir_id + 1
|
||||
self.config.save()
|
||||
component.get("EventManager").emit(AutoaddOptionsChangedEvent())
|
||||
return watchdir_id
|
||||
|
||||
@export
|
||||
def remove(self, watchdir_id):
|
||||
"""remove a label"""
|
||||
watchdir_id = str(watchdir_id)
|
||||
CheckInput(watchdir_id in self.watchdirs, "Unknown Watchdir: %s" % self.watchdirs)
|
||||
if self.watchdirs[watchdir_id]['enabled']:
|
||||
self.disable_watchdir(watchdir_id)
|
||||
del self.watchdirs[watchdir_id]
|
||||
self.config.save()
|
||||
component.get("EventManager").emit(AutoaddOptionsChangedEvent())
|
50
deluge/plugins/autoadd/autoadd/data/autoadd.js
Normal file
50
deluge/plugins/autoadd/autoadd/data/autoadd.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Script: autoadd.js
|
||||
The client-side javascript code for the AutoAdd plugin.
|
||||
|
||||
Copyright:
|
||||
(C) GazpachoKing 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.
|
||||
*/
|
||||
|
||||
AutoAddPlugin = Ext.extend(Deluge.Plugin, {
|
||||
constructor: function(config) {
|
||||
config = Ext.apply({
|
||||
name: "AutoAdd"
|
||||
}, config);
|
||||
AutoAddPlugin.superclass.constructor.call(this, config);
|
||||
},
|
||||
|
||||
onDisable: function() {
|
||||
|
||||
},
|
||||
|
||||
onEnable: function() {
|
||||
|
||||
}
|
||||
});
|
||||
new AutoAddPlugin();
|
986
deluge/plugins/autoadd/autoadd/data/autoadd_options.glade
Normal file
986
deluge/plugins/autoadd/autoadd/data/autoadd_options.glade
Normal file
@ -0,0 +1,986 @@
|
||||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="error_dialog">
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes">AutoAdd Error</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="close" handler="on_error_dialog_close"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox12">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-error</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="error_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.46000000834465027</property>
|
||||
<property name="label" translatable="yes">Error</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="okbutton1">
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="response_id">-5</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_error_ok"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkDialog" id="options_dialog">
|
||||
<property name="title" translatable="yes">Watch Folder Properties</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="close" handler="on_options_dialog_close"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkNotebook" id="notebook1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment3">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox6">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="path_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFileChooserButton" id="path_chooser">
|
||||
<property name="visible">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes">Select A Folder</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="enabled">
|
||||
<property name="label" translatable="yes">Enable this watch folder</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_enabled_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Watch Folder</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame3">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment4">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox3">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="download_location_toggle">
|
||||
<property name="label" translatable="yes">Set download location</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox4">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="download_location_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFileChooserButton" id="download_location_chooser">
|
||||
<property name="visible">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes">Select A Folder</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label7">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Download Location</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment6">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox4">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="move_completed_toggle">
|
||||
<property name="label" translatable="yes">Set move completed location</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox5">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="move_completed_path_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFileChooserButton" id="move_completed_path_chooser">
|
||||
<property name="visible">True</property>
|
||||
<property name="action">select-folder</property>
|
||||
<property name="title" translatable="yes">Select A Folder</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="move_completed">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Move Completed</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="label_frame">
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment15">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox11">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="label_toggle">
|
||||
<property name="label" translatable="yes">Label: </property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label17">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Label</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Main</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_fill">False</property>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment11">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">3</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="max_upload_speed_toggle">
|
||||
<property name="label" translatable="yes">Max Upload Speed:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="max_connections_toggle">
|
||||
<property name="label" translatable="yes">Max Connections:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="max_upload_slots_toggle">
|
||||
<property name="label" translatable="yes">Max Upload Slots:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="max_download_speed">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">-1 -1 10000 1 10 10</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="digits">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="max_upload_speed">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">-1 -1 10000 1 10 10</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="digits">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="max_connections">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">-1 -1 10000 1 10 10</property>
|
||||
<property name="climb_rate">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="max_upload_slots">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="adjustment">-1 -1 10000 1 10 10</property>
|
||||
<property name="climb_rate">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label14">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="xpad">5</property>
|
||||
<property name="label" translatable="yes">KiB/s</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label15">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="xpad">5</property>
|
||||
<property name="label" translatable="yes">KiB/s</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="max_download_speed_toggle">
|
||||
<property name="label" translatable="yes">Max Download Speed:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Bandwidth</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment12">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table2">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">5</property>
|
||||
<property name="n_columns">4</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment13">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="stop_at_ratio_toggle">
|
||||
<property name="label" translatable="yes">Stop seed at ratio:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment14">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="remove_at_ratio">
|
||||
<property name="label" translatable="yes">Remove at ratio</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="auto_managed_toggle">
|
||||
<property name="label" translatable="yes">Auto Managed:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="remove_at_ratio_toggle">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="stop_ratio_toggle">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="stop_ratio">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="adjustment">2 0 100 0.10000000149 10 10</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="digits">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="auto_managed_box">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="auto_managed">
|
||||
<property name="label" translatable="yes">Yes</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="isnt_auto_managed">
|
||||
<property name="label" translatable="yes">No</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">auto_managed</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="stop_at_ratio">
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="add_paused_toggle">
|
||||
<property name="label" translatable="yes">Add Paused:</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_toggle_toggled"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="add_paused_box">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="add_paused">
|
||||
<property name="label" translatable="yes">Yes</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="isnt_add_paused">
|
||||
<property name="label" translatable="yes">No</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">add_paused</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label16">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Queue</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Options</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_fill">False</property>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox2">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="opts_cancel_button">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_opts_cancel"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="opts_add_button">
|
||||
<property name="label" translatable="yes">gtk-add</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_opts_add"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="opts_apply_button">
|
||||
<property name="label" translatable="yes">gtk-apply</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_opts_apply"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
116
deluge/plugins/autoadd/autoadd/data/config.glade
Normal file
116
deluge/plugins/autoadd/autoadd/data/config.glade
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkWindow" id="prefs_window">
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox9">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="prefs_box_1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="prefs_box">
|
||||
<property name="width_request">340</property>
|
||||
<property name="height_request">390</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<signal name="parent_set" handler="on_parent_set"/>
|
||||
<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="GtkVBox" id="watchdirs_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Watch Folders:</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>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="add_button">
|
||||
<property name="label" translatable="yes">gtk-add</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_add_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="remove_button">
|
||||
<property name="label" translatable="yes">gtk-remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_remove_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="edit_button">
|
||||
<property name="label" translatable="yes">gtk-edit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_edit_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
341
deluge/plugins/autoadd/autoadd/gtkui.py
Normal file
341
deluge/plugins/autoadd/autoadd/gtkui.py
Normal file
@ -0,0 +1,341 @@
|
||||
#
|
||||
# gtkui.py
|
||||
#
|
||||
# Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
#
|
||||
# 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
|
||||
|
||||
from deluge.log import LOG as log
|
||||
from deluge.ui.client import client
|
||||
from deluge.plugins.pluginbase import GtkPluginBase
|
||||
import deluge.component as component
|
||||
import deluge.common
|
||||
import os
|
||||
|
||||
from common import get_resource
|
||||
|
||||
class OptionsDialog():
|
||||
spin_ids = ["max_download_speed", "max_upload_speed", "stop_ratio"]
|
||||
spin_int_ids = ["max_upload_slots", "max_connections"]
|
||||
chk_ids = ["stop_at_ratio", "remove_at_ratio", "move_completed", "add_paused", "auto_managed"]
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
def show(self, options={}, watchdir_id=None):
|
||||
self.glade = gtk.glade.XML(get_resource("autoadd_options.glade"))
|
||||
self.glade.signal_autoconnect({
|
||||
"on_opts_add":self.on_add,
|
||||
"on_opts_apply":self.on_apply,
|
||||
"on_opts_cancel":self.on_cancel,
|
||||
"on_options_dialog_close":self.on_cancel,
|
||||
"on_error_ok":self.on_error_ok,
|
||||
"on_error_dialog_close":self.on_error_ok,
|
||||
"on_toggle_toggled":self.on_toggle_toggled
|
||||
})
|
||||
self.dialog = self.glade.get_widget("options_dialog")
|
||||
self.dialog.set_transient_for(component.get("Preferences").pref_dialog)
|
||||
self.err_dialog = self.glade.get_widget("error_dialog")
|
||||
self.err_dialog.set_transient_for(self.dialog)
|
||||
if watchdir_id:
|
||||
#We have an existing watchdir_id, we are editing
|
||||
self.glade.get_widget('opts_add_button').hide()
|
||||
self.glade.get_widget('opts_apply_button').show()
|
||||
self.watchdir_id = watchdir_id
|
||||
else:
|
||||
#We don't have an id, adding
|
||||
self.glade.get_widget('opts_add_button').show()
|
||||
self.glade.get_widget('opts_apply_button').hide()
|
||||
self.watchdir_id = None
|
||||
|
||||
self.load_options(options)
|
||||
self.dialog.run()
|
||||
|
||||
def load_options(self, options):
|
||||
self.glade.get_widget('enabled').set_active(options.get('enabled', False))
|
||||
self.glade.get_widget('download_location_toggle').set_active(options.get('download_location_toggle', False))
|
||||
self.glade.get_widget('label').set_text(options.get('label', ''))
|
||||
self.glade.get_widget('label_toggle').set_active(options.get('label_toggle', False))
|
||||
for id in self.spin_ids + self.spin_int_ids:
|
||||
self.glade.get_widget(id).set_value(options.get(id, 0))
|
||||
self.glade.get_widget(id+'_toggle').set_active(options.get(id+'_toggle', False))
|
||||
for id in self.chk_ids:
|
||||
self.glade.get_widget(id).set_active(bool(options.get(id, True)))
|
||||
self.glade.get_widget(id+'_toggle').set_active(options.get(id+'_toggle', False))
|
||||
if not options.get('add_paused', True):
|
||||
self.glade.get_widget('isnt_add_paused').set_active(True)
|
||||
if not options.get('auto_managed', True):
|
||||
self.glade.get_widget('isnt_auto_managed').set_active(True)
|
||||
for field in ['move_completed_path', 'path', 'download_location']:
|
||||
if client.is_localhost():
|
||||
self.glade.get_widget(field+"_chooser").set_filename(options.get(field, os.path.expanduser("~")))
|
||||
self.glade.get_widget(field+"_chooser").show()
|
||||
self.glade.get_widget(field+"_entry").hide()
|
||||
else:
|
||||
self.glade.get_widget(field+"_entry").set_text(options.get(field, ""))
|
||||
self.glade.get_widget(field+"_entry").show()
|
||||
self.glade.get_widget(field+"_chooser").hide()
|
||||
self.set_sensitive()
|
||||
|
||||
def on_get_enabled_plugins(result):
|
||||
if 'Label' in result:
|
||||
self.glade.get_widget('label_frame').show()
|
||||
else:
|
||||
self.glade.get_widget('label_frame').hide()
|
||||
self.glade.get_widget('label_toggle').set_active(False)
|
||||
|
||||
client.core.get_enabled_plugins().addCallback(on_get_enabled_plugins)
|
||||
|
||||
def set_sensitive(self):
|
||||
maintoggles = ['download_location', 'move_completed', 'label', \
|
||||
'max_download_speed', 'max_upload_speed', 'max_connections', \
|
||||
'max_upload_slots', 'add_paused', 'auto_managed', 'stop_at_ratio']
|
||||
[self.on_toggle_toggled(self.glade.get_widget(x+'_toggle')) for x in maintoggles]
|
||||
|
||||
def on_toggle_toggled(self, tb):
|
||||
toggle = str(tb.name).replace("_toggle", "")
|
||||
isactive = tb.get_active()
|
||||
if toggle == 'download_location':
|
||||
self.glade.get_widget('download_location_chooser').set_sensitive(isactive)
|
||||
self.glade.get_widget('download_location_entry').set_sensitive(isactive)
|
||||
elif toggle == 'move_completed':
|
||||
self.glade.get_widget('move_completed_path_chooser').set_sensitive(isactive)
|
||||
self.glade.get_widget('move_completed_path_entry').set_sensitive(isactive)
|
||||
self.glade.get_widget('move_completed').set_active(isactive)
|
||||
elif toggle == 'label':
|
||||
self.glade.get_widget('label').set_sensitive(isactive)
|
||||
elif toggle == 'max_download_speed':
|
||||
self.glade.get_widget('max_download_speed').set_sensitive(isactive)
|
||||
elif toggle == 'max_upload_speed':
|
||||
self.glade.get_widget('max_upload_speed').set_sensitive(isactive)
|
||||
elif toggle == 'max_connections':
|
||||
self.glade.get_widget('max_connections').set_sensitive(isactive)
|
||||
elif toggle == 'max_upload_slots':
|
||||
self.glade.get_widget('max_upload_slots').set_sensitive(isactive)
|
||||
elif toggle == 'add_paused':
|
||||
self.glade.get_widget('add_paused').set_sensitive(isactive)
|
||||
self.glade.get_widget('isnt_add_paused').set_sensitive(isactive)
|
||||
elif toggle == 'auto_managed':
|
||||
self.glade.get_widget('auto_managed').set_sensitive(isactive)
|
||||
self.glade.get_widget('isnt_auto_managed').set_sensitive(isactive)
|
||||
elif toggle == 'stop_at_ratio':
|
||||
self.glade.get_widget('remove_at_ratio_toggle').set_active(isactive)
|
||||
self.glade.get_widget('stop_ratio_toggle').set_active(isactive)
|
||||
self.glade.get_widget('stop_at_ratio').set_active(isactive)
|
||||
self.glade.get_widget('stop_ratio').set_sensitive(isactive)
|
||||
self.glade.get_widget('remove_at_ratio').set_sensitive(isactive)
|
||||
|
||||
def on_apply(self, Event=None):
|
||||
client.autoadd.set_options(str(self.watchdir_id), self.generate_opts()).addCallbacks(self.on_added, self.on_error_show)
|
||||
|
||||
def on_error_show(self, result):
|
||||
self.glade.get_widget('error_label').set_text(result.value.exception_msg)
|
||||
self.err_dialog = self.glade.get_widget('error_dialog')
|
||||
self.err_dialog.set_transient_for(self.dialog)
|
||||
result.cleanFailure()
|
||||
self.err_dialog.show()
|
||||
|
||||
def on_added(self, result):
|
||||
self.dialog.destroy()
|
||||
|
||||
def on_error_ok(self, Event=None):
|
||||
self.err_dialog.hide()
|
||||
|
||||
def on_add(self, Event=None):
|
||||
client.autoadd.add(self.generate_opts()).addCallbacks(self.on_added, self.on_error_show)
|
||||
|
||||
def on_cancel(self, Event=None):
|
||||
self.dialog.destroy()
|
||||
|
||||
def generate_opts(self):
|
||||
# generate options dict based on gtk objects
|
||||
options = {}
|
||||
options['enabled'] = self.glade.get_widget('enabled').get_active()
|
||||
if client.is_localhost():
|
||||
options['path'] = self.glade.get_widget('path_chooser').get_filename()
|
||||
options['download_location'] = self.glade.get_widget('download_location_chooser').get_filename()
|
||||
options['move_completed_path'] = self.glade.get_widget('move_completed_path_chooser').get_filename()
|
||||
else:
|
||||
options['path'] = self.glade.get_widget('path_entry').get_text()
|
||||
options['download_location'] = self.glade.get_widget('download_location_entry').get_text()
|
||||
options['move_completed_path'] = self.glade.get_widget('move_completed_path_entry').get_text()
|
||||
options['download_location_toggle'] = self.glade.get_widget('download_location_toggle').get_active()
|
||||
options['label'] = self.glade.get_widget('label').get_text().lower()
|
||||
options['label_toggle'] = self.glade.get_widget('label_toggle').get_active()
|
||||
|
||||
|
||||
for id in self.spin_ids:
|
||||
options[id] = self.glade.get_widget(id).get_value()
|
||||
options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active()
|
||||
for id in self.spin_int_ids:
|
||||
options[id] = self.glade.get_widget(id).get_value_as_int()
|
||||
options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active()
|
||||
for id in self.chk_ids:
|
||||
options[id] = self.glade.get_widget(id).get_active()
|
||||
options[id+'_toggle'] = self.glade.get_widget(id+'_toggle').get_active()
|
||||
return options
|
||||
|
||||
|
||||
class GtkUI(GtkPluginBase):
|
||||
def enable(self):
|
||||
|
||||
self.glade = gtk.glade.XML(get_resource("config.glade"))
|
||||
self.glade.signal_autoconnect({
|
||||
"on_add_button_clicked": self.on_add_button_clicked,
|
||||
"on_edit_button_clicked": self.on_edit_button_clicked,
|
||||
"on_remove_button_clicked": self.on_remove_button_clicked
|
||||
})
|
||||
self.opts_dialog = OptionsDialog()
|
||||
|
||||
component.get("PluginManager").register_hook("on_apply_prefs", self.on_apply_prefs)
|
||||
component.get("PluginManager").register_hook("on_show_prefs", self.on_show_prefs)
|
||||
client.register_event_handler("AutoaddOptionsChangedEvent", self.on_options_changed_event)
|
||||
|
||||
self.watchdirs = {}
|
||||
|
||||
vbox = self.glade.get_widget("watchdirs_vbox")
|
||||
sw = gtk.ScrolledWindow()
|
||||
sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
||||
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
|
||||
vbox.pack_start(sw, True, True, 0)
|
||||
|
||||
self.store = self.create_model()
|
||||
|
||||
self.treeView = gtk.TreeView(self.store)
|
||||
self.treeView.connect("cursor-changed", self.on_listitem_activated)
|
||||
self.treeView.connect("row-activated", self.on_edit_button_clicked)
|
||||
self.treeView.set_rules_hint(True)
|
||||
|
||||
self.create_columns(self.treeView)
|
||||
sw.add(self.treeView)
|
||||
sw.show_all()
|
||||
component.get("Preferences").add_page("AutoAdd", self.glade.get_widget("prefs_box"))
|
||||
|
||||
|
||||
def disable(self):
|
||||
component.get("Preferences").remove_page("AutoAdd")
|
||||
component.get("PluginManager").deregister_hook("on_apply_prefs", self.on_apply_prefs)
|
||||
component.get("PluginManager").deregister_hook("on_show_prefs", self.on_show_prefs)
|
||||
|
||||
def create_model(self):
|
||||
|
||||
store = gtk.ListStore(str, bool, str)
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
store.append([watchdir_id, watchdir['enabled'], watchdir['path']])
|
||||
return store
|
||||
|
||||
def create_columns(self, treeView):
|
||||
rendererToggle = gtk.CellRendererToggle()
|
||||
column = gtk.TreeViewColumn("On", rendererToggle, activatable=True, active=1)
|
||||
column.set_sort_column_id(1)
|
||||
treeView.append_column(column)
|
||||
tt = gtk.Tooltip()
|
||||
tt.set_text('Double-click to toggle')
|
||||
treeView.set_tooltip_cell(tt, None, None, rendererToggle)
|
||||
|
||||
rendererText = gtk.CellRendererText()
|
||||
column = gtk.TreeViewColumn("Path", rendererText, text=2)
|
||||
column.set_sort_column_id(2)
|
||||
treeView.append_column(column)
|
||||
tt2 = gtk.Tooltip()
|
||||
tt2.set_text('Double-click to edit')
|
||||
#treeView.set_tooltip_cell(tt2, None, column, None)
|
||||
treeView.set_has_tooltip(True)
|
||||
|
||||
def load_watchdir_list(self):
|
||||
pass
|
||||
|
||||
def add_watchdir_entry(self):
|
||||
pass
|
||||
|
||||
def on_add_button_clicked(self, Event=None):
|
||||
#display options_window
|
||||
self.opts_dialog.show()
|
||||
|
||||
def on_remove_button_clicked(self, Event=None):
|
||||
tree, tree_id = self.treeView.get_selection().get_selected()
|
||||
watchdir_id = str(self.store.get_value(tree_id, 0))
|
||||
if watchdir_id:
|
||||
client.autoadd.remove(watchdir_id)
|
||||
|
||||
def on_edit_button_clicked(self, Event=None, a=None, col=None):
|
||||
tree, tree_id = self.treeView.get_selection().get_selected()
|
||||
watchdir_id = str(self.store.get_value(tree_id, 0))
|
||||
if watchdir_id:
|
||||
if col and col.get_title() == 'On':
|
||||
if self.watchdirs[watchdir_id]['enabled']:
|
||||
client.autoadd.disable_watchdir(watchdir_id)
|
||||
else:
|
||||
client.autoadd.enable_watchdir(watchdir_id)
|
||||
else:
|
||||
self.opts_dialog.show(self.watchdirs[watchdir_id], watchdir_id)
|
||||
|
||||
def on_listitem_activated(self, treeview):
|
||||
tree, tree_id = self.treeView.get_selection().get_selected()
|
||||
if tree_id:
|
||||
self.glade.get_widget('edit_button').set_sensitive(True)
|
||||
self.glade.get_widget('remove_button').set_sensitive(True)
|
||||
else:
|
||||
self.glade.get_widget('edit_button').set_sensitive(False)
|
||||
self.glade.get_widget('remove_button').set_sensitive(False)
|
||||
|
||||
def on_apply_prefs(self):
|
||||
log.debug("applying prefs for AutoAdd")
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
client.autoadd.set_options(watchdir_id, watchdir)
|
||||
|
||||
def on_show_prefs(self):
|
||||
|
||||
client.autoadd.get_config().addCallback(self.cb_get_config)
|
||||
|
||||
def on_options_changed_event(self):
|
||||
client.autoadd.get_config().addCallback(self.cb_get_config)
|
||||
|
||||
def cb_get_config(self, config):
|
||||
"""callback for on show_prefs"""
|
||||
self.watchdirs = config.get('watchdirs', {})
|
||||
self.store.clear()
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
self.store.append([watchdir_id, watchdir['enabled'], watchdir['path']])
|
||||
if False: #self.watchdirs:
|
||||
self.glade.get_widget('remove_button').set_sensitive(True)
|
||||
self.glade.get_widget('edit_button').set_sensitive(True)
|
||||
else:
|
||||
self.glade.get_widget('remove_button').set_sensitive(False)
|
||||
self.glade.get_widget('edit_button').set_sensitive(False)
|
||||
|
55
deluge/plugins/autoadd/autoadd/webui.py
Normal file
55
deluge/plugins/autoadd/autoadd/webui.py
Normal file
@ -0,0 +1,55 @@
|
||||
#
|
||||
# webui.py
|
||||
#
|
||||
# Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
#
|
||||
# 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.log import LOG as log
|
||||
from deluge.ui.client import client
|
||||
from deluge import component
|
||||
from deluge.plugins.pluginbase import WebPluginBase
|
||||
|
||||
from common import get_resource
|
||||
|
||||
class WebUI(WebPluginBase):
|
||||
|
||||
scripts = [get_resource("autoadd.js")]
|
||||
|
||||
def enable(self):
|
||||
pass
|
||||
|
||||
def disable(self):
|
||||
pass
|
73
deluge/plugins/autoadd/setup.py
Normal file
73
deluge/plugins/autoadd/setup.py
Normal file
@ -0,0 +1,73 @@
|
||||
#
|
||||
# setup.py
|
||||
#
|
||||
# Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
#
|
||||
# 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
|
||||
|
||||
__plugin_name__ = "AutoAdd"
|
||||
__author__ = "Chase Sterling"
|
||||
__author_email__ = "chase.sterling@gmail.com"
|
||||
__version__ = "0.28"
|
||||
__url__ = "http://forum.deluge-torrent.org/viewtopic.php?f=9&t=26775"
|
||||
__license__ = "GPLv3"
|
||||
__description__ = "Monitors folders for .torrent files."
|
||||
__long_description__ = """"""
|
||||
__pkg_data__ = {__plugin_name__.lower(): ["template/*", "data/*"]}
|
||||
|
||||
setup(
|
||||
name=__plugin_name__,
|
||||
version=__version__,
|
||||
description=__description__,
|
||||
author=__author__,
|
||||
author_email=__author_email__,
|
||||
url=__url__,
|
||||
license=__license__,
|
||||
long_description=__long_description__ if __long_description__ else __description__,
|
||||
|
||||
packages=[__plugin_name__.lower()],
|
||||
package_data = __pkg_data__,
|
||||
|
||||
entry_points="""
|
||||
[deluge.plugin.core]
|
||||
%s = %s:CorePlugin
|
||||
[deluge.plugin.gtkui]
|
||||
%s = %s:GtkUIPlugin
|
||||
[deluge.plugin.webui]
|
||||
%s = %s:WebUIPlugin
|
||||
""" % ((__plugin_name__, __plugin_name__.lower())*3)
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user