[Python-Modernize] lib2to3.fixes.fix_ws_comma

* Fixer that changes 'a ,b' into 'a, b'.
This commit is contained in:
Calum Lind 2014-09-03 15:42:27 +01:00
commit 38bc5d07f0
31 changed files with 544 additions and 544 deletions

View file

@ -10,7 +10,7 @@ def scan_for_methods(obj):
'__doc__': 'Methods available in %s' % obj.__name__.lower() '__doc__': 'Methods available in %s' % obj.__name__.lower()
} }
for d in dir(obj): for d in dir(obj):
if not hasattr(getattr(obj,d), '_rpcserver_export'): if not hasattr(getattr(obj, d), '_rpcserver_export'):
continue continue
methods[d] = getattr(obj, d) methods[d] = getattr(obj, d)
cobj = classobj(obj.__name__.lower(), (object,), methods) cobj = classobj(obj.__name__.lower(), (object,), methods)

View file

@ -51,14 +51,14 @@ log = logging.getLogger(__name__)
RE_VALID = re.compile("[a-z0-9_\-\.]*\Z") RE_VALID = re.compile("[a-z0-9_\-\.]*\Z")
KNOWN_STATES = ['Downloading','Seeding','Paused','Checking','Queued','Error'] KNOWN_STATES = ['Downloading', 'Seeding', 'Paused', 'Checking', 'Queued', 'Error']
STATE = "state" STATE = "state"
TRACKER = "tracker" TRACKER = "tracker"
KEYWORD = "keyword" KEYWORD = "keyword"
LABEL = "label" LABEL = "label"
CONFIG_DEFAULTS = { CONFIG_DEFAULTS = {
"torrent_labels":{}, #torrent_id:label_id "torrent_labels": {}, #torrent_id:label_id
"labels":{}, #label_id:{name:value} "labels": {}, #label_id:{name:value}
} }
CORE_OPTIONS = ["auto_add_trackers"] CORE_OPTIONS = ["auto_add_trackers"]
@ -157,7 +157,7 @@ class Core(CorePluginBase):
"""remove invalid data from config-file""" """remove invalid data from config-file"""
for torrent_id, label_id in list(self.torrent_labels.iteritems()): for torrent_id, label_id in list(self.torrent_labels.iteritems()):
if (not label_id in self.labels) or (not torrent_id in self.torrents): if (not label_id in self.labels) or (not torrent_id in self.torrents):
log.debug("label: rm %s:%s" % (torrent_id,label_id)) log.debug("label: rm %s:%s" % (torrent_id, label_id))
del self.torrent_labels[torrent_id] del self.torrent_labels[torrent_id]
def clean_initial_config(self): def clean_initial_config(self):
@ -191,9 +191,9 @@ class Core(CorePluginBase):
see label_set_options for more options. see label_set_options for more options.
""" """
label_id = label_id.lower() label_id = label_id.lower()
CheckInput(RE_VALID.match(label_id) , _("Invalid label, valid characters:[a-z0-9_-]")) CheckInput(RE_VALID.match(label_id), _("Invalid label, valid characters:[a-z0-9_-]"))
CheckInput(label_id, _("Empty Label")) CheckInput(label_id, _("Empty Label"))
CheckInput(not (label_id in self.labels) , _("Label already exists")) CheckInput(not (label_id in self.labels), _("Label already exists"))
self.labels[label_id] = dict(OPTIONS_DEFAULTS) self.labels[label_id] = dict(OPTIONS_DEFAULTS)
self.config.save() self.config.save()
@ -259,7 +259,7 @@ class Core(CorePluginBase):
} }
) )
def _has_auto_match(self, torrent ,label_options): def _has_auto_match(self, torrent, label_options):
"""match for auto_add fields""" """match for auto_add fields"""
for tracker_match in label_options["auto_add_trackers"]: for tracker_match in label_options["auto_add_trackers"]:
for tracker in torrent.trackers: for tracker in torrent.trackers:
@ -281,7 +281,7 @@ class Core(CorePluginBase):
"move_completed_to":string() or None "move_completed_to":string() or None
} }
""" """
CheckInput(label_id in self.labels , _("Unknown Label")) CheckInput(label_id in self.labels, _("Unknown Label"))
for key in options_dict.keys(): for key in options_dict.keys():
if not key in OPTIONS_DEFAULTS: if not key in OPTIONS_DEFAULTS:
raise Exception("label: Invalid options_dict key:%s" % key) raise Exception("label: Invalid options_dict key:%s" % key)
@ -289,16 +289,16 @@ class Core(CorePluginBase):
self.labels[label_id].update(options_dict) self.labels[label_id].update(options_dict)
#apply #apply
for torrent_id,label in self.torrent_labels.iteritems(): for torrent_id, label in self.torrent_labels.iteritems():
if label_id == label and torrent_id in self.torrents: if label_id == label and torrent_id in self.torrents:
self._set_torrent_options(torrent_id , label_id) self._set_torrent_options(torrent_id, label_id)
#auto add #auto add
options = self.labels[label_id] options = self.labels[label_id]
if options["auto_add"]: if options["auto_add"]:
for torrent_id, torrent in self.torrents.iteritems(): for torrent_id, torrent in self.torrents.iteritems():
if self._has_auto_match(torrent, options): if self._has_auto_match(torrent, options):
self.set_torrent(torrent_id , label_id) self.set_torrent(torrent_id, label_id)
self.config.save() self.config.save()
@ -308,7 +308,7 @@ class Core(CorePluginBase):
return self.labels[label_id] return self.labels[label_id]
@export @export
def set_torrent(self, torrent_id , label_id): def set_torrent(self, torrent_id, label_id):
""" """
assign a label to a torrent assign a label to a torrent
removes a label if the label_id parameter is empty. removes a label if the label_id parameter is empty.
@ -316,8 +316,8 @@ class Core(CorePluginBase):
if label_id == NO_LABEL: if label_id == NO_LABEL:
label_id = None label_id = None
CheckInput((not label_id) or (label_id in self.labels) , _("Unknown Label")) CheckInput((not label_id) or (label_id in self.labels), _("Unknown Label"))
CheckInput(torrent_id in self.torrents , _("Unknown Torrent")) CheckInput(torrent_id in self.torrents, _("Unknown Torrent"))
if torrent_id in self.torrent_labels: if torrent_id in self.torrent_labels:
self._unset_torrent_options(torrent_id, self.torrent_labels[torrent_id]) self._unset_torrent_options(torrent_id, self.torrent_labels[torrent_id])

View file

@ -79,16 +79,16 @@ class LabelSidebarMenu(object):
self.menu.connect("show", self.on_show, None) self.menu.connect("show", self.on_show, None)
def _add_item(self, id, label ,stock): def _add_item(self, id, label, stock):
"""I hate glade. """I hate glade.
id is automatically-added as self.item_<id> id is automatically-added as self.item_<id>
""" """
func = getattr(self,"on_%s" % id) func = getattr(self, "on_%s" % id)
item = gtk.ImageMenuItem(stock) item = gtk.ImageMenuItem(stock)
item.get_children()[0].set_label(label) item.get_children()[0].set_label(label)
item.connect("activate", func) item.connect("activate", func)
self.menu.prepend(item) self.menu.prepend(item)
setattr(self,"item_%s" % id, item) setattr(self, "item_%s" % id, item)
self.items.append(item) self.items.append(item)
return item return item
@ -145,8 +145,8 @@ class AddDialog(object):
self.dialog.set_transient_for(component.get("MainWindow").window) self.dialog.set_transient_for(component.get("MainWindow").window)
self.glade.signal_autoconnect({ self.glade.signal_autoconnect({
"on_add_ok":self.on_ok, "on_add_ok": self.on_ok,
"on_add_cancel":self.on_cancel, "on_add_cancel": self.on_cancel,
}) })
self.dialog.run() self.dialog.run()
@ -184,8 +184,8 @@ class OptionsDialog(object):
self.dialog = self.glade.get_widget("dlg_label_options") self.dialog = self.glade.get_widget("dlg_label_options")
self.dialog.set_transient_for(component.get("MainWindow").window) self.dialog.set_transient_for(component.get("MainWindow").window)
self.glade.signal_autoconnect({ self.glade.signal_autoconnect({
"on_options_ok":self.on_ok, "on_options_ok": self.on_ok,
"on_options_cancel":self.on_cancel, "on_options_cancel": self.on_cancel,
}) })
# Show the label name in the header label # Show the label name in the header label
@ -193,7 +193,7 @@ class OptionsDialog(object):
for chk_id, group in self.sensitive_groups: for chk_id, group in self.sensitive_groups:
chk = self.glade.get_widget(chk_id) chk = self.glade.get_widget(chk_id)
chk.connect("toggled",self.apply_sensitivity) chk.connect("toggled", self.apply_sensitivity)
client.label.get_options(self.label).addCallback(self.load_options) client.label.get_options(self.label).addCallback(self.load_options)
@ -245,7 +245,7 @@ class OptionsDialog(object):
self.dialog.destroy() self.dialog.destroy()
def apply_sensitivity(self, event=None): def apply_sensitivity(self, event=None):
for chk_id , sensitive_list in self.sensitive_groups: for chk_id, sensitive_list in self.sensitive_groups:
chk = self.glade.get_widget(chk_id) chk = self.glade.get_widget(chk_id)
sens = chk.get_active() and chk.get_property("sensitive") sens = chk.get_active() and chk.get_property("sensitive")
for widget_id in sensitive_list: for widget_id in sensitive_list:

View file

@ -74,12 +74,12 @@ class LabelMenu(gtk.MenuItem):
if label == NO_LABEL: if label == NO_LABEL:
item = gtk.MenuItem(_(NO_LABEL)) item = gtk.MenuItem(_(NO_LABEL))
else: else:
item = gtk.MenuItem(label.replace("_","__")) item = gtk.MenuItem(label.replace("_", "__"))
item.connect("activate", self.on_select_label, label) item.connect("activate", self.on_select_label, label)
self.sub_menu.append(item) self.sub_menu.append(item)
self.show_all() self.show_all()
def on_select_label(self, widget=None, label_id=None): def on_select_label(self, widget=None, label_id=None):
log.debug("select label:%s,%s" % (label_id ,self.get_torrent_ids()) ) log.debug("select label:%s,%s" % (label_id, self.get_torrent_ids()) )
for torrent_id in self.get_torrent_ids(): for torrent_id in self.get_torrent_ids():
client.label.set_torrent(torrent_id, label_id) client.label.set_torrent(torrent_id, label_id)

View file

@ -54,17 +54,17 @@ id = sclient.get_session_state()[0]
print("#add") print("#add")
sclient.label_add("test") sclient.label_add("test")
print("#set") print("#set")
sclient.label_set_torrent(id,"test") sclient.label_set_torrent(id, "test")
print(sclient.get_torrents_status({"label":"test"},"name")) print(sclient.get_torrents_status({"label":"test"}, "name"))
print("#set options") print("#set options")
sclient.label_set_options("test",{"max_download_speed":999}, True) sclient.label_set_options("test", {"max_download_speed":999}, True)
print(sclient.get_torrent_status(id, ["max_download_speed"]) , "999") print(sclient.get_torrent_status(id, ["max_download_speed"]), "999")
sclient.label_set_options("test",{"max_download_speed":9}, True) sclient.label_set_options("test", {"max_download_speed":9}, True)
print(sclient.get_torrent_status(id, ["max_download_speed"]) , "9") print(sclient.get_torrent_status(id, ["max_download_speed"]), "9")
sclient.label_set_options("test",{"max_download_speed":888}, False) sclient.label_set_options("test", {"max_download_speed":888}, False)
print(sclient.get_torrent_status(id, ["max_download_speed"]) , "9 (888)") print(sclient.get_torrent_status(id, ["max_download_speed"]), "9 (888)")
print(sclient.get_torrent_status(id,['name', 'tracker_host', 'label'])) print(sclient.get_torrent_status(id, ['name', 'tracker_host', 'label']))

View file

@ -63,12 +63,12 @@ class SchedulerSelectWidget(gtk.DrawingArea):
self.colors = [[115.0/255, 210.0/255, 22.0/255], [237.0/255, 212.0/255, 0.0/255], [204.0/255, 0.0/255, 0.0/255]] self.colors = [[115.0/255, 210.0/255, 22.0/255], [237.0/255, 212.0/255, 0.0/255], [204.0/255, 0.0/255, 0.0/255]]
self.button_state = [[0] * 7 for dummy in xrange(24)] self.button_state = [[0] * 7 for dummy in xrange(24)]
self.start_point = [0,0] self.start_point = [0, 0]
self.hover_point = [-1,-1] self.hover_point = [-1, -1]
self.hover_label = hover self.hover_label = hover
self.hover_days = DAYS self.hover_days = DAYS
self.mouse_press = False self.mouse_press = False
self.set_size_request(350,150) self.set_size_request(350, 150)
def set_button_state(self, state): def set_button_state(self, state):
self.button_state = [] self.button_state = []
@ -104,7 +104,7 @@ class SchedulerSelectWidget(gtk.DrawingArea):
if y > 6: y = 6 if y > 6: y = 6
elif y < 0: y = 0 elif y < 0: y = 0
return [x,y] return [x, y]
#mouse down #mouse down
def mouse_down(self, widget, event): def mouse_down(self, widget, event):
@ -148,7 +148,7 @@ class SchedulerSelectWidget(gtk.DrawingArea):
#clear hover text on mouse leave #clear hover text on mouse leave
def mouse_leave(self, widget, event): def mouse_leave(self, widget, event):
self.hover_label.set_text("") self.hover_label.set_text("")
self.hover_point = [-1,-1] self.hover_point = [-1, -1]
class GtkUI(GtkPluginBase): class GtkUI(GtkPluginBase):
def enable(self): def enable(self):

View file

@ -59,7 +59,7 @@ def default_formatter(value):
def size_formatter_scale(value): def size_formatter_scale(value):
scale = 1.0 scale = 1.0
for i in range(0,3): for i in range(0, 3):
scale = scale * 1024.0 scale = scale * 1024.0
if value / scale < 1024: if value / scale < 1024:
return scale return scale
@ -86,9 +86,9 @@ class Graph:
self.mean_selected = True self.mean_selected = True
self.legend_selected = True self.legend_selected = True
self.max_selected = True self.max_selected = True
self.black = (0, 0 , 0,) self.black = (0, 0, 0,)
self.interval = 2 # 2 secs self.interval = 2 # 2 secs
self.text_bg = (255, 255 , 255, 128) # prototyping self.text_bg = (255, 255, 255, 128) # prototyping
self.set_left_axis() self.set_left_axis()
def set_left_axis(self, **kargs): def set_left_axis(self, **kargs):

View file

@ -19,7 +19,7 @@ def test_sync():
n.savedUpSpeeds = upload n.savedUpSpeeds = upload
n.savedDownSpeeds = download n.savedDownSpeeds = download
n.draw(800,200) n.draw(800, 200)
n.surface.write_to_png('output_sync.png') n.surface.write_to_png('output_sync.png')
def test_async(): def test_async():
@ -69,7 +69,7 @@ def test_write():
surface.write_to_png(file_like) surface.write_to_png(file_like)
data = "".join(file_like.data) data = "".join(file_like.data)
f = open("file_like.png","wb") f = open("file_like.png", "wb")
f.write(data) f.write(data)
f.close() f.close()

View file

@ -5,7 +5,7 @@ sclient.set_core_uri()
def print_totals(totals): def print_totals(totals):
for name, value in totals.iteritems(): for name, value in totals.iteritems():
print(name , fsize(value)) print(name, fsize(value))
print("overhead:") print("overhead:")
print("up:", fsize(totals["total_upload"] - totals["total_payload_upload"] )) print("up:", fsize(totals["total_upload"] - totals["total_payload_upload"] ))

View file

@ -14,11 +14,11 @@ import os
import sys import sys
import deluge.common import deluge.common
parser = OptionParser() parser = OptionParser()
parser.add_option("-n", "--name", dest="name",help="plugin name") parser.add_option("-n", "--name", dest="name", help="plugin name")
parser.add_option("-m", "--module-name", dest="module",help="plugin name") parser.add_option("-m", "--module-name", dest="module", help="plugin name")
parser.add_option("-p", "--basepath", dest="path",help="base path") parser.add_option("-p", "--basepath", dest="path", help="base path")
parser.add_option("-a", "--author-name", dest="author_name",help="author name,for the GPL header") parser.add_option("-a", "--author-name", dest="author_name", help="author name,for the GPL header")
parser.add_option("-e", "--author-email", dest="author_email",help="author email,for the GPL header") parser.add_option("-e", "--author-email", dest="author_email", help="author email,for the GPL header")
parser.add_option("-u", "--url", dest="url", help="Homepage URL") parser.add_option("-u", "--url", dest="url", help="Homepage URL")
parser.add_option("-c", "--config", dest="configdir", help="location of deluge configuration") parser.add_option("-c", "--config", dest="configdir", help="location of deluge configuration")
@ -83,7 +83,7 @@ def create_plugin():
} }
filename = os.path.join(path, filename) filename = os.path.join(path, filename)
f = open(filename,"w") f = open(filename, "w")
if filename.endswith(".py") and include_gpl: if filename.endswith(".py") and include_gpl:
f.write(GPL % args) f.write(GPL % args)
f.write(template % args) f.write(template % args)
@ -97,20 +97,20 @@ def create_plugin():
os.mkdir(data_dir) os.mkdir(data_dir)
print("creating files..") print("creating files..")
write_file(plugin_base,"setup.py", SETUP) write_file(plugin_base, "setup.py", SETUP)
write_file(deluge_namespace, "__init__.py", NAMESPACE_INIT, False) write_file(deluge_namespace, "__init__.py", NAMESPACE_INIT, False)
write_file(plugins_namespace, "__init__.py", NAMESPACE_INIT, False) write_file(plugins_namespace, "__init__.py", NAMESPACE_INIT, False)
write_file(src,"__init__.py", INIT) write_file(src, "__init__.py", INIT)
write_file(src,"gtkui.py", GTKUI) write_file(src, "gtkui.py", GTKUI)
write_file(src,"webui.py", WEBUI) write_file(src, "webui.py", WEBUI)
write_file(src,"core.py", CORE) write_file(src, "core.py", CORE)
write_file(src, "common.py", COMMON) write_file(src, "common.py", COMMON)
write_file(data_dir, "config.glade", GLADE) write_file(data_dir, "config.glade", GLADE)
write_file(data_dir, "%s.js" % safe_name, DEFAULT_JS) write_file(data_dir, "%s.js" % safe_name, DEFAULT_JS)
#add an input parameter for this? #add an input parameter for this?
print("building dev-link..") print("building dev-link..")
write_file(plugin_base,"create_dev_link.sh", CREATE_DEV_LINK) write_file(plugin_base, "create_dev_link.sh", CREATE_DEV_LINK)
dev_link_path = os.path.join(plugin_base, "create_dev_link.sh") dev_link_path = os.path.join(plugin_base, "create_dev_link.sh")
os.system("chmod +x %s" % dev_link_path) #lazy.. os.system("chmod +x %s" % dev_link_path) #lazy..
os.system(dev_link_path) os.system(dev_link_path)

View file

@ -49,7 +49,7 @@ print("\n\n")
if 0: #aclient non-core if 0: #aclient non-core
methods = sorted([m for m in dir(aclient) if not m.startswith('_') methods = sorted([m for m in dir(aclient) if not m.startswith('_')
if not m in ['add_torrent_file', 'has_callback', 'get_method', if not m in ['add_torrent_file', 'has_callback', 'get_method',
'methodHelp','methodSignature','list_methods','add_torrent_file_binary']]) 'methodHelp', 'methodSignature', 'list_methods', 'add_torrent_file_binary']])
for m in methods: for m in methods:
func = getattr(aclient, m) func = getattr(aclient, m)
@ -109,7 +109,7 @@ if 0: #keys
{{{ {{{
#!python #!python
>>>sorted(sclient.get_status_keys())""") >>>sorted(sclient.get_status_keys())""")
print("\n".join(textwrap.wrap(str(sorted(sclient.get_status_keys())),100))) print("\n".join(textwrap.wrap(str(sorted(sclient.get_status_keys())), 100)))
print("""}}}""") print("""}}}""")

View file

@ -151,7 +151,7 @@ class Win32IcoFile (object):
# change tile dimension to only encompass XOR image # change tile dimension to only encompass XOR image
im.size = im.size[0], im.size[1] / 2 im.size = im.size[0], im.size[1] / 2
d, e, o, a = im.tile[0] d, e, o, a = im.tile[0]
im.tile[0] = d, (0,0) + im.size, o, a im.tile[0] = d, (0, 0) + im.size, o, a
# figure out where AND mask image starts # figure out where AND mask image starts
mode = a[0] mode = a[0]

View file

@ -59,16 +59,16 @@ color_pairs = {
# Some default color schemes # Some default color schemes
schemes = { schemes = {
"input": ("white", "black"), "input": ("white", "black"),
"normal": ("white","black"), "normal": ("white", "black"),
"status": ("yellow", "blue", "bold"), "status": ("yellow", "blue", "bold"),
"info": ("white", "black", "bold"), "info": ("white", "black", "bold"),
"error": ("red", "black", "bold"), "error": ("red", "black", "bold"),
"success": ("green", "black", "bold"), "success": ("green", "black", "bold"),
"event": ("magenta", "black", "bold"), "event": ("magenta", "black", "bold"),
"selected": ("black", "white", "bold"), "selected": ("black", "white", "bold"),
"marked": ("white","blue","bold"), "marked": ("white", "blue", "bold"),
"selectedmarked": ("blue","white","bold"), "selectedmarked": ("blue", "white", "bold"),
"header": ("green","black","bold"), "header": ("green", "black", "bold"),
"filterstatus": ("green", "blue", "bold") "filterstatus": ("green", "blue", "bold")
} }
@ -107,7 +107,7 @@ def init_colors():
# but can also fail on others, so we try/except # but can also fail on others, so we try/except
try: try:
curses.init_pair(counter, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.init_pair(counter, curses.COLOR_WHITE, curses.COLOR_BLACK)
color_pairs[("white","black")] = counter color_pairs[("white", "black")] = counter
except: except:
pass pass

View file

@ -46,7 +46,7 @@ class Command(BaseCommand):
try: try:
at = component.get("AllTorrents") at = component.get("AllTorrents")
except KeyError: except KeyError:
at = AllTorrents(console.stdscr,console.encoding) at = AllTorrents(console.stdscr, console.encoding)
console.set_mode(at) console.set_mode(at)
at._go_top = True at._go_top = True
at.resume() at.resume()

View file

@ -77,7 +77,7 @@ class Console(_UI):
self.console_cmds = load_commands(os.path.join(UI_PATH, 'commands')) self.console_cmds = load_commands(os.path.join(UI_PATH, 'commands'))
class CommandOptionGroup(optparse.OptionGroup): class CommandOptionGroup(optparse.OptionGroup):
def __init__(self, parser, title, description=None, cmds=None): def __init__(self, parser, title, description=None, cmds=None):
optparse.OptionGroup.__init__(self,parser, title, description) optparse.OptionGroup.__init__(self, parser, title, description)
self.cmds = cmds self.cmds = cmds
def format_help(self, formatter): def format_help(self, formatter):
@ -91,7 +91,7 @@ class Console(_UI):
allnames = [cname] allnames = [cname]
allnames.extend(cmd.aliases) allnames.extend(cmd.aliases)
cname = "/".join(allnames) cname = "/".join(allnames)
result += formatter.format_heading(" - ".join([cname,cmd.__doc__])) result += formatter.format_heading(" - ".join([cname, cmd.__doc__]))
formatter.indent() formatter.indent()
result += "%*s%s\n" % (formatter.current_indent, "", cmd.usage.split('\n')[0]) result += "%*s%s\n" % (formatter.current_indent, "", cmd.usage.split('\n')[0])
formatter.dedent() formatter.dedent()
@ -400,7 +400,7 @@ Please use commands from the command line, eg:\n
no matches are found. no matches are found.
""" """
if self.interactive and isinstance(self.screen,deluge.ui.console.modes.legacy.Legacy): if self.interactive and isinstance(self.screen, deluge.ui.console.modes.legacy.Legacy):
return self.screen.match_torrent(string) return self.screen.match_torrent(string)
matches = [] matches = []
@ -413,7 +413,7 @@ Please use commands from the command line, eg:\n
def get_torrent_name(self, torrent_id): def get_torrent_name(self, torrent_id):
if self.interactive and hasattr(self.screen,"get_torrent_name"): if self.interactive and hasattr(self.screen, "get_torrent_name"):
return self.screen.get_torrent_name(torrent_id) return self.screen.get_torrent_name(torrent_id)
for tid, name in self.torrents: for tid, name in self.torrents:
@ -424,15 +424,15 @@ Please use commands from the command line, eg:\n
def set_batch_write(self, batch): def set_batch_write(self, batch):
if self.interactive and isinstance(self.screen,deluge.ui.console.modes.legacy.Legacy): if self.interactive and isinstance(self.screen, deluge.ui.console.modes.legacy.Legacy):
return self.screen.set_batch_write(batch) return self.screen.set_batch_write(batch)
def tab_complete_torrent(self, line): def tab_complete_torrent(self, line):
if self.interactive and isinstance(self.screen,deluge.ui.console.modes.legacy.Legacy): if self.interactive and isinstance(self.screen, deluge.ui.console.modes.legacy.Legacy):
return self.screen.tab_complete_torrent(line) return self.screen.tab_complete_torrent(line)
def tab_complete_path(self, line, type="file", ext="", sort="name", dirs_first=True): def tab_complete_path(self, line, type="file", ext="", sort="name", dirs_first=True):
if self.interactive and isinstance(self.screen,deluge.ui.console.modes.legacy.Legacy): if self.interactive and isinstance(self.screen, deluge.ui.console.modes.legacy.Legacy):
return self.screen.tab_complete_path(line, type=type, ext=ext, sort=sort, dirs_first=dirs_first) return self.screen.tab_complete_path(line, type=type, ext=ext, sort=sort, dirs_first=dirs_first)
def set_mode(self, mode): def set_mode(self, mode):
@ -447,7 +447,7 @@ Please use commands from the command line, eg:\n
def write(self, s): def write(self, s):
if self.interactive: if self.interactive:
if isinstance(self.screen,deluge.ui.console.modes.legacy.Legacy): if isinstance(self.screen, deluge.ui.console.modes.legacy.Legacy):
self.screen.write(s) self.screen.write(s)
else: else:
component.get("LegacyUI").add_line(s, False) component.get("LegacyUI").add_line(s, False)
@ -457,7 +457,7 @@ Please use commands from the command line, eg:\n
def write_event(self, s): def write_event(self, s):
if self.interactive: if self.interactive:
if isinstance(self.screen,deluge.ui.console.modes.legacy.Legacy): if isinstance(self.screen, deluge.ui.console.modes.legacy.Legacy):
self.events.append(s) self.events.append(s)
self.screen.write(s) self.screen.write(s)
else: else:

View file

@ -41,7 +41,7 @@ import deluge.component as component
from deluge.ui.common import TorrentInfo from deluge.ui.common import TorrentInfo
import deluge.common import deluge.common
import os,base64,glob import os, base64, glob
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -56,9 +56,9 @@ def __bracket_fixup(path):
if sentinal > 65535: if sentinal > 65535:
log.error("Can't fix brackets in path, path contains all possible sentinal characters") log.error("Can't fix brackets in path, path contains all possible sentinal characters")
return path return path
newpath = path.replace("]",unichr(sentinal)) newpath = path.replace("]", unichr(sentinal))
newpath = newpath.replace("[","[[]") newpath = newpath.replace("[", "[[]")
newpath = newpath.replace(unichr(sentinal),"[]]") newpath = newpath.replace(unichr(sentinal), "[]]")
return newpath return newpath
def add_torrent(t_file, options, success_cb, fail_cb, ress): def add_torrent(t_file, options, success_cb, fail_cb, ress):
@ -78,29 +78,29 @@ def add_torrent(t_file, options, success_cb, fail_cb, ress):
ress["total"] = num_files ress["total"] = num_files
if num_files <= 0: if num_files <= 0:
fail_cb("Doesn't exist",t_file,ress) fail_cb("Doesn't exist", t_file, ress)
for f in files: for f in files:
if is_url: if is_url:
client.core.add_torrent_url(f, t_options).addCallback(success_cb,f,ress).addErrback(fail_cb,f,ress) client.core.add_torrent_url(f, t_options).addCallback(success_cb, f, ress).addErrback(fail_cb, f, ress)
elif is_mag: elif is_mag:
client.core.add_torrent_magnet(f, t_options).addCallback(success_cb,f,ress).addErrback(fail_cb,f,ress) client.core.add_torrent_magnet(f, t_options).addCallback(success_cb, f, ress).addErrback(fail_cb, f, ress)
else: else:
if not os.path.exists(f): if not os.path.exists(f):
fail_cb("Doesn't exist",f,ress) fail_cb("Doesn't exist", f, ress)
continue continue
if not os.path.isfile(f): if not os.path.isfile(f):
fail_cb("Is a directory",f,ress) fail_cb("Is a directory", f, ress)
continue continue
try: try:
TorrentInfo(f) TorrentInfo(f)
except Exception as e: except Exception as e:
fail_cb(e.message,f,ress) fail_cb(e.message, f, ress)
continue continue
filename = os.path.split(f)[-1] filename = os.path.split(f)[-1]
filedump = base64.encodestring(open(f).read()) filedump = base64.encodestring(open(f).read())
client.core.add_torrent_file(filename, filedump, t_options).addCallback(success_cb,f,ress).addErrback(fail_cb,f,ress) client.core.add_torrent_file(filename, filedump, t_options).addCallback(success_cb, f, ress).addErrback(fail_cb, f, ress)

View file

@ -260,7 +260,7 @@ class AddTorrents(BaseMode, component.Component):
if (self.view_offset + self._listing_space) <= self.cursel + 1: if (self.view_offset + self._listing_space) <= self.cursel + 1:
self.view_offset = self.cursel - self._listing_space + 1 self.view_offset = self.cursel - self._listing_space + 1
def set_popup(self,pu): def set_popup(self, pu):
self.popup = pu self.popup = pu
self.refresh() self.refresh()
@ -431,21 +431,21 @@ class AddTorrents(BaseMode, component.Component):
"total": len(self.marked), "total": len(self.marked),
"fmsg":[]} "fmsg":[]}
def fail_cb(msg,t_file,ress): def fail_cb(msg, t_file, ress):
log.debug("failed to add torrent: %s: %s"%(t_file,msg)) log.debug("failed to add torrent: %s: %s"%(t_file, msg))
ress["fail"]+=1 ress["fail"]+=1
ress["fmsg"].append("{!input!} * %s: {!error!}%s"%(t_file,msg)) ress["fmsg"].append("{!input!} * %s: {!error!}%s"%(t_file, msg))
if (ress["succ"]+ress["fail"]) >= ress["total"]: if (ress["succ"]+ress["fail"]) >= ress["total"]:
self.alltorrentmode._report_add_status(ress["succ"],ress["fail"],ress["fmsg"]) self.alltorrentmode._report_add_status(ress["succ"], ress["fail"], ress["fmsg"])
def success_cb(tid,t_file,ress): def success_cb(tid, t_file, ress):
if tid: if tid:
log.debug("added torrent: %s (%s)"%(t_file,tid)) log.debug("added torrent: %s (%s)"%(t_file, tid))
ress["succ"]+=1 ress["succ"]+=1
if (ress["succ"]+ress["fail"]) >= ress["total"]: if (ress["succ"]+ress["fail"]) >= ress["total"]:
self.alltorrentmode._report_add_status(ress["succ"],ress["fail"],ress["fmsg"]) self.alltorrentmode._report_add_status(ress["succ"], ress["fail"], ress["fmsg"])
else: else:
fail_cb("Already in session (probably)",t_file,ress) fail_cb("Already in session (probably)", t_file, ress)
for m in self.marked: for m in self.marked:
filename = m filename = m
@ -472,7 +472,7 @@ class AddTorrents(BaseMode, component.Component):
ap = 0 ap = 0
else: else:
ap = 1 ap = 1
self.popup = InputPopup(self,"Add Torrents (Esc to cancel)",close_cb=_do_add, height_req=17) self.popup = InputPopup(self, "Add Torrents (Esc to cancel)", close_cb=_do_add, height_req=17)
msg = "Adding torrent files:" msg = "Adding torrent files:"
for i, m in enumerate(self.marked): for i, m in enumerate(self.marked):
@ -485,8 +485,8 @@ class AddTorrents(BaseMode, component.Component):
self.popup.add_text(msg) self.popup.add_text(msg)
self.popup.add_spaces(1) self.popup.add_spaces(1)
self.popup.add_text_input("Download Folder:","location", dl) self.popup.add_text_input("Download Folder:", "location", dl)
self.popup.add_select_input("Add Paused:","add_paused",["Yes","No"],[True,False],ap) self.popup.add_select_input("Add Paused:", "add_paused", ["Yes", "No"], [True, False], ap)
def _go_up(self): def _go_up(self):

View file

@ -56,7 +56,7 @@ from legacy import Legacy
from twisted.internet import defer from twisted.internet import defer
import format_utils,column import format_utils, column
try: try:
import curses import curses
@ -220,8 +220,8 @@ DEFAULT_PREFS = {
column_pref_names = ["queue", "name", "size", "state", "progress", "seeds", column_pref_names = ["queue", "name", "size", "state", "progress", "seeds",
"peers", "downspeed", "upspeed", "eta", "ratio", "avail", "peers", "downspeed", "upspeed", "eta", "ratio", "avail",
"added", "tracker", "savepath","downloaded","uploaded", "added", "tracker", "savepath", "downloaded", "uploaded",
"remaining", "owner","downloading_time","seeding_time", "remaining", "owner", "downloading_time", "seeding_time",
"completed", "seeds_peers_ratio", "complete_seen", "completed", "seeds_peers_ratio", "complete_seen",
"down_limit", "up_limit", "shared", "down_limit", "up_limit", "shared",
] ]
@ -339,7 +339,7 @@ class AllTorrents(BaseMode, component.Component):
component.start(["AllTorrents"]) component.start(["AllTorrents"])
self._info_fields = [ self._info_fields = [
("Name",None, ("name",)), ("Name", None, ("name",)),
("State", None, ("state",)), ("State", None, ("state",)),
("Down Speed", format_utils.format_speed, ("download_payload_rate",)), ("Down Speed", format_utils.format_speed, ("download_payload_rate",)),
("Up Speed", format_utils.format_speed, ("upload_payload_rate",)), ("Up Speed", format_utils.format_speed, ("upload_payload_rate",)),
@ -350,7 +350,7 @@ class AllTorrents(BaseMode, component.Component):
("Uploaded", deluge.common.fsize, ("total_uploaded",)), ("Uploaded", deluge.common.fsize, ("total_uploaded",)),
("Share Ratio", format_utils.format_float, ("ratio",)), ("Share Ratio", format_utils.format_float, ("ratio",)),
("Seeds", format_utils.format_seeds_peers, ("num_seeds", "total_seeds")), ("Seeds", format_utils.format_seeds_peers, ("num_seeds", "total_seeds")),
("Peers", format_utils.format_seeds_peers,("num_peers", "total_peers")), ("Peers", format_utils.format_seeds_peers, ("num_peers", "total_peers")),
("Active Time", deluge.common.ftime, ("active_time",)), ("Active Time", deluge.common.ftime, ("active_time",)),
("Seeding Time", deluge.common.ftime, ("seeding_time",)), ("Seeding Time", deluge.common.ftime, ("seeding_time",)),
("Complete Seen", format_utils.format_date_never, ("last_seen_complete",)), ("Complete Seen", format_utils.format_date_never, ("last_seen_complete",)),
@ -372,21 +372,21 @@ class AllTorrents(BaseMode, component.Component):
self.legacy_mode = Legacy(self.stdscr, self.encoding) self.legacy_mode = Legacy(self.stdscr, self.encoding)
if self.config["first_run"]: if self.config["first_run"]:
self.popup = MessagePopup(self,"Welcome to Deluge", HELP_STR, width_req=0.75) self.popup = MessagePopup(self, "Welcome to Deluge", HELP_STR, width_req=0.75)
self.config["first_run"] = False self.config["first_run"] = False
self.config.save() self.config.save()
# component start/update # component start/update
def start(self): def start(self):
component.get("SessionProxy").get_torrents_status(self.__status_dict, self.__status_fields).addCallback(self.set_state,False) component.get("SessionProxy").get_torrents_status(self.__status_dict, self.__status_fields).addCallback(self.set_state, False)
def update(self): def update(self):
component.get("SessionProxy").get_torrents_status(self.__status_dict, self.__status_fields).addCallback(self.set_state,True) component.get("SessionProxy").get_torrents_status(self.__status_dict, self.__status_fields).addCallback(self.set_state, True)
if self.__torrent_info_id: if self.__torrent_info_id:
component.get("SessionProxy").get_torrent_status(self.__torrent_info_id, self.__status_keys).addCallback(self._on_torrent_status) component.get("SessionProxy").get_torrent_status(self.__torrent_info_id, self.__status_keys).addCallback(self._on_torrent_status)
def update_config(self): def update_config(self):
self.config = ConfigManager("console.conf",DEFAULT_PREFS) self.config = ConfigManager("console.conf", DEFAULT_PREFS)
s_primary = self.config["sort_primary"] s_primary = self.config["sort_primary"]
s_secondary = self.config["sort_secondary"] s_secondary = self.config["sort_secondary"]
self.__cols_to_show = [ self.__cols_to_show = [
@ -417,14 +417,14 @@ class AllTorrents(BaseMode, component.Component):
def __update_columns(self): def __update_columns(self):
self.column_widths = [self.config["%s_width"%c] for c in self.__cols_to_show] self.column_widths = [self.config["%s_width"%c] for c in self.__cols_to_show]
req = sum(filter(lambda x:x >= 0,self.column_widths)) req = sum(filter(lambda x:x >= 0, self.column_widths))
if (req > self.cols): # can't satisfy requests, just spread out evenly if (req > self.cols): # can't satisfy requests, just spread out evenly
cw = int(self.cols/len(self.__columns)) cw = int(self.cols/len(self.__columns))
for i in range(0,len(self.column_widths)): for i in range(0, len(self.column_widths)):
self.column_widths[i] = cw self.column_widths[i] = cw
else: else:
rem = self.cols - req rem = self.cols - req
var_cols = len(filter(lambda x: x < 0,self.column_widths)) var_cols = len(filter(lambda x: x < 0, self.column_widths))
if (var_cols > 0): if (var_cols > 0):
vw = int(rem/var_cols) vw = int(rem/var_cols)
for i in range(0, len(self.column_widths)): for i in range(0, len(self.column_widths)):
@ -473,21 +473,21 @@ class AllTorrents(BaseMode, component.Component):
self.refresh() self.refresh()
def get_torrent_name(self, torrent_id): def get_torrent_name(self, torrent_id):
for p,i in enumerate(self._sorted_ids): for p, i in enumerate(self._sorted_ids):
if torrent_id == i: if torrent_id == i:
return self.torrent_names[p] return self.torrent_names[p]
return None return None
def _scroll_up(self, by): def _scroll_up(self, by):
prevoff = self.curoff prevoff = self.curoff
self.cursel = max(self.cursel - by,1) self.cursel = max(self.cursel - by, 1)
if ((self.cursel - 1) < self.curoff): if ((self.cursel - 1) < self.curoff):
self.curoff = max(self.cursel - 1,1) self.curoff = max(self.cursel - 1, 1)
return prevoff != self.curoff return prevoff != self.curoff
def _scroll_down(self, by): def _scroll_down(self, by):
prevoff = self.curoff prevoff = self.curoff
self.cursel = min(self.cursel + by,self.numtorrents) self.cursel = min(self.cursel + by, self.numtorrents)
if ((self.curoff + self.rows - 5) < self.cursel): if ((self.curoff + self.rows - 5) < self.cursel):
self.curoff = self.cursel - self.rows + 5 self.curoff = self.cursel - self.rows + 5
return prevoff != self.curoff return prevoff != self.curoff
@ -510,14 +510,14 @@ class AllTorrents(BaseMode, component.Component):
name = state["name"] name = state["name"]
off = int((self.cols/4)-(len(name)/2)) off = int((self.cols/4)-(len(name)/2))
self.popup.set_title(name) self.popup.set_title(name)
for i,f in enumerate(self._info_fields): for i, f in enumerate(self._info_fields):
if f[1] != None: if f[1] != None:
args = [] args = []
try: try:
for key in f[2]: for key in f[2]:
args.append(state[key]) args.append(state[key])
except: except:
log.debug("Could not get info field: %s",e) log.debug("Could not get info field: %s", e)
continue continue
info = f[1](*args) info = f[1](*args)
else: else:
@ -525,14 +525,14 @@ class AllTorrents(BaseMode, component.Component):
nl = len(f[0])+4 nl = len(f[0])+4
if (nl+len(info))>self.popup.width: if (nl+len(info))>self.popup.width:
self.popup.add_line("{!info!}%s: {!input!}%s"%(f[0],info[:(self.popup.width - nl)])) self.popup.add_line("{!info!}%s: {!input!}%s"%(f[0], info[:(self.popup.width - nl)]))
info = info[(self.popup.width - nl):] info = info[(self.popup.width - nl):]
n = self.popup.width-3 n = self.popup.width-3
chunks = [info[i:i+n] for i in xrange(0, len(info), n)] chunks = [info[i:i+n] for i in xrange(0, len(info), n)]
for c in chunks: for c in chunks:
self.popup.add_line(" %s"%c) self.popup.add_line(" %s"%c)
else: else:
self.popup.add_line("{!info!}%s: {!input!}%s"%(f[0],info)) self.popup.add_line("{!info!}%s: {!input!}%s"%(f[0], info))
self.refresh() self.refresh()
else: else:
self.__torrent_info_id = None self.__torrent_info_id = None
@ -627,34 +627,34 @@ class AllTorrents(BaseMode, component.Component):
def dodeets(arg): def dodeets(arg):
if arg and True in arg[0]: if arg and True in arg[0]:
self.stdscr.erase() self.stdscr.erase()
component.get("ConsoleUI").set_mode(AddTorrents(self,self.stdscr, self.config, self.encoding)) component.get("ConsoleUI").set_mode(AddTorrents(self, self.stdscr, self.config, self.encoding))
else: else:
self.messages.append(("Error","An error occurred trying to display add torrents screen")) self.messages.append(("Error", "An error occurred trying to display add torrents screen"))
component.stop(["AllTorrents"]).addCallback(dodeets) component.stop(["AllTorrents"]).addCallback(dodeets)
def show_torrent_details(self,tid): def show_torrent_details(self, tid):
def dodeets(arg): def dodeets(arg):
if arg and True in arg[0]: if arg and True in arg[0]:
self.stdscr.erase() self.stdscr.erase()
component.get("ConsoleUI").set_mode(TorrentDetail(self,tid,self.stdscr, self.config, self.encoding)) component.get("ConsoleUI").set_mode(TorrentDetail(self, tid, self.stdscr, self.config, self.encoding))
else: else:
self.messages.append(("Error","An error occurred trying to display torrent details")) self.messages.append(("Error", "An error occurred trying to display torrent details"))
component.stop(["AllTorrents"]).addCallback(dodeets) component.stop(["AllTorrents"]).addCallback(dodeets)
def show_preferences(self): def show_preferences(self):
def _on_get_config(config): def _on_get_config(config):
client.core.get_listen_port().addCallback(_on_get_listen_port,config) client.core.get_listen_port().addCallback(_on_get_listen_port, config)
def _on_get_listen_port(port,config): def _on_get_listen_port(port, config):
client.core.get_cache_status().addCallback(_on_get_cache_status,port,config) client.core.get_cache_status().addCallback(_on_get_cache_status, port, config)
def _on_get_cache_status(status,port,config): def _on_get_cache_status(status, port, config):
def doprefs(arg): def doprefs(arg):
if arg and True in arg[0]: if arg and True in arg[0]:
self.stdscr.erase() self.stdscr.erase()
component.get("ConsoleUI").set_mode(Preferences(self,config,self.config,port,status,self.stdscr,self.encoding)) component.get("ConsoleUI").set_mode(Preferences(self, config, self.config, port, status, self.stdscr, self.encoding))
else: else:
self.messages.append(("Error","An error occurred trying to display preferences")) self.messages.append(("Error", "An error occurred trying to display preferences"))
component.stop(["AllTorrents"]).addCallback(doprefs) component.stop(["AllTorrents"]).addCallback(doprefs)
client.core.get_config().addCallback(_on_get_config) client.core.get_config().addCallback(_on_get_config)
@ -664,9 +664,9 @@ class AllTorrents(BaseMode, component.Component):
def doevents(arg): def doevents(arg):
if arg and True in arg[0]: if arg and True in arg[0]:
self.stdscr.erase() self.stdscr.erase()
component.get("ConsoleUI").set_mode(EventView(self,self.stdscr,self.encoding)) component.get("ConsoleUI").set_mode(EventView(self, self.stdscr, self.encoding))
else: else:
self.messages.append(("Error","An error occurred trying to display events")) self.messages.append(("Error", "An error occurred trying to display events"))
component.stop(["AllTorrents"]).addCallback(doevents) component.stop(["AllTorrents"]).addCallback(doevents)
def __legacy_mode(self): def __legacy_mode(self):
@ -677,7 +677,7 @@ class AllTorrents(BaseMode, component.Component):
self.legacy_mode.refresh() self.legacy_mode.refresh()
curses.curs_set(2) curses.curs_set(2)
else: else:
self.messages.append(("Error","An error occurred trying to switch to legacy mode")) self.messages.append(("Error", "An error occurred trying to switch to legacy mode"))
component.stop(["AllTorrents"]).addCallback(dolegacy) component.stop(["AllTorrents"]).addCallback(dolegacy)
def _torrent_filter(self, idx, data): def _torrent_filter(self, idx, data):
@ -716,26 +716,26 @@ class AllTorrents(BaseMode, component.Component):
return True return True
def _show_torrent_filter_popup(self): def _show_torrent_filter_popup(self):
self.popup = SelectablePopup(self,"Filter Torrents", self._torrent_filter) self.popup = SelectablePopup(self, "Filter Torrents", self._torrent_filter)
self.popup.add_line("_All",data=FILTER.ALL) self.popup.add_line("_All", data=FILTER.ALL)
self.popup.add_line("Ac_tive",data=FILTER.ACTIVE) self.popup.add_line("Ac_tive", data=FILTER.ACTIVE)
self.popup.add_line("_Downloading",data=FILTER.DOWNLOADING,foreground="green") self.popup.add_line("_Downloading", data=FILTER.DOWNLOADING, foreground="green")
self.popup.add_line("_Seeding",data=FILTER.SEEDING,foreground="cyan") self.popup.add_line("_Seeding", data=FILTER.SEEDING, foreground="cyan")
self.popup.add_line("_Paused",data=FILTER.PAUSED) self.popup.add_line("_Paused", data=FILTER.PAUSED)
self.popup.add_line("_Error",data=FILTER.ERROR,foreground="red") self.popup.add_line("_Error", data=FILTER.ERROR, foreground="red")
self.popup.add_line("_Checking",data=FILTER.CHECKING,foreground="blue") self.popup.add_line("_Checking", data=FILTER.CHECKING, foreground="blue")
self.popup.add_line("Q_ueued",data=FILTER.QUEUED,foreground="yellow") self.popup.add_line("Q_ueued", data=FILTER.QUEUED, foreground="yellow")
self.popup.add_line("A_llocating",data=FILTER.ALLOCATING,foreground="yellow") self.popup.add_line("A_llocating", data=FILTER.ALLOCATING, foreground="yellow")
self.popup.add_line("_Moving",data=FILTER.MOVING,foreground="green") self.popup.add_line("_Moving", data=FILTER.MOVING, foreground="green")
def _report_add_status(self, succ_cnt, fail_cnt, fail_msgs): def _report_add_status(self, succ_cnt, fail_cnt, fail_msgs):
if fail_cnt == 0: if fail_cnt == 0:
self.report_message("Torrents Added","{!success!}Successfully added %d torrent(s)"%succ_cnt) self.report_message("Torrents Added", "{!success!}Successfully added %d torrent(s)"%succ_cnt)
else: else:
msg = ("{!error!}Failed to add the following %d torrent(s):\n {!input!}"%fail_cnt)+"\n ".join(fail_msgs) msg = ("{!error!}Failed to add the following %d torrent(s):\n {!input!}"%fail_cnt)+"\n ".join(fail_msgs)
if succ_cnt != 0: if succ_cnt != 0:
msg += "\n \n{!success!}Successfully added %d torrent(s)"%succ_cnt msg += "\n \n{!success!}Successfully added %d torrent(s)"%succ_cnt
self.report_message("Torrent Add Report",msg) self.report_message("Torrent Add Report", msg)
def _show_torrent_add_popup(self): def _show_torrent_add_popup(self):
@ -767,7 +767,7 @@ class AllTorrents(BaseMode, component.Component):
elif deluge.common.is_url(url): elif deluge.common.is_url(url):
client.core.add_torrent_url(url, t_options).addCallback(success_cb, url).addErrback(fail_cb, url) client.core.add_torrent_url(url, t_options).addCallback(success_cb, url).addErrback(fail_cb, url)
else: else:
self.messages.append(("Error","{!error!}Invalid URL or magnet link: %s" % url)) self.messages.append(("Error", "{!error!}Invalid URL or magnet link: %s" % url))
return return
log.debug("Adding Torrent(s): %s (dl path: %s) (paused: %d)", url, result["path"], result["add_paused"]) log.debug("Adding Torrent(s): %s (dl path: %s) (paused: %d)", url, result["path"], result["add_paused"])
@ -786,7 +786,7 @@ class AllTorrents(BaseMode, component.Component):
except KeyError: except KeyError:
pass pass
self.popup = InputPopup(self,"Add Torrent (Esc to cancel)", close_cb=do_add_from_url) self.popup = InputPopup(self, "Add Torrent (Esc to cancel)", close_cb=do_add_from_url)
self.popup.add_text_input("Enter torrent URL or Magnet link:", "url") self.popup.add_text_input("Enter torrent URL or Magnet link:", "url")
self.popup.add_text_input("Enter save path:", "path", dl) self.popup.add_text_input("Enter save path:", "path", dl)
self.popup.add_select_input("Add Paused:", "add_paused", ["Yes", "No"], [True, False], ap) self.popup.add_select_input("Add Paused:", "add_paused", ["Yes", "No"], [True, False], ap)
@ -801,7 +801,7 @@ class AllTorrents(BaseMode, component.Component):
elif data == 2: elif data == 2:
show_add_url_popup() show_add_url_popup()
self.popup = SelectablePopup(self,"Add torrent", option_chosen) self.popup = SelectablePopup(self, "Add torrent", option_chosen)
self.popup.add_line("From _File(s)", data=1) self.popup.add_line("From _File(s)", data=1)
self.popup.add_line("From _URL or Magnet", data=2) self.popup.add_line("From _URL or Magnet", data=2)
self.popup.add_line("_Cancel", data=0) self.popup.add_line("_Cancel", data=0)
@ -834,14 +834,14 @@ class AllTorrents(BaseMode, component.Component):
self.popup.add_checked_input(name, prop, state) self.popup.add_checked_input(name, prop, state)
def report_message(self,title,message): def report_message(self, title, message):
self.messages.append((title,message)) self.messages.append((title, message))
def clear_marks(self): def clear_marks(self):
self.marked = [] self.marked = []
self.last_mark = -1 self.last_mark = -1
def set_popup(self,pu): def set_popup(self, pu):
self.popup = pu self.popup = pu
self.refresh() self.refresh()
@ -857,8 +857,8 @@ class AllTorrents(BaseMode, component.Component):
# show a message popup if there's anything queued # show a message popup if there's anything queued
if self.popup == None and self.messages: if self.popup == None and self.messages:
title,msg = self.messages.popleft() title, msg = self.messages.popleft()
self.popup = MessagePopup(self,title,msg, width_req=1.0) self.popup = MessagePopup(self, title, msg, width_req=1.0)
if not lines: if not lines:
if component.get("ConsoleUI").screen != self: if component.get("ConsoleUI").screen != self:
@ -867,10 +867,10 @@ class AllTorrents(BaseMode, component.Component):
# Update the status bars # Update the status bars
if self._curr_filter == None: if self._curr_filter == None:
self.add_string(0,self.statusbars.topbar) self.add_string(0, self.statusbars.topbar)
else: else:
self.add_string(0,"%s {!filterstatus!}Current filter: %s"%(self.statusbars.topbar,self._curr_filter)) self.add_string(0, "%s {!filterstatus!}Current filter: %s"%(self.statusbars.topbar, self._curr_filter))
self.add_string(1,self.column_string) self.add_string(1, self.column_string)
if self.entering_search: if self.entering_search:
string = { string = {
@ -914,7 +914,7 @@ class AllTorrents(BaseMode, component.Component):
def draw_row(index): def draw_row(index):
if index not in cr: if index not in cr:
ts = curstate[sorted_ids[index]] ts = curstate[sorted_ids[index]]
cr[index] = (fr([gcv(name,ts) for name in cols],colw),ts["state"]) cr[index] = (fr([gcv(name, ts) for name in cols], colw), ts["state"])
return cr[index] return cr[index]
if lines: if lines:
@ -980,12 +980,12 @@ class AllTorrents(BaseMode, component.Component):
attr = "bold" attr = "bold"
if attr: if attr:
colorstr = "{!%s,%s,%s!}"%(fg,bg,attr) colorstr = "{!%s,%s,%s!}"%(fg, bg, attr)
else: else:
colorstr = "{!%s,%s!}"%(fg,bg) colorstr = "{!%s,%s!}"%(fg, bg)
try: try:
self.add_string(currow,"%s%s"%(colorstr,row[0]),trim=False) self.add_string(currow, "%s%s"%(colorstr, row[0]), trim=False)
except: except:
#Yeah, this should be fixed in some better way #Yeah, this should be fixed in some better way
pass pass
@ -1014,7 +1014,7 @@ class AllTorrents(BaseMode, component.Component):
curses.doupdate() curses.doupdate()
def _mark_unmark(self,idx): def _mark_unmark(self, idx):
if idx in self.marked: if idx in self.marked:
self.marked.remove(idx) self.marked.remove(idx)
self.last_mark = -1 self.last_mark = -1
@ -1059,7 +1059,7 @@ class AllTorrents(BaseMode, component.Component):
search_space = reversed(search_space) search_space = reversed(search_space)
search_string = self.search_string.lower() search_string = self.search_string.lower()
for i,n in search_space: for i, n in search_space:
n = n.lower() n = n.lower()
if n.find(search_string) != -1: if n.find(search_string) != -1:
if skip > 0: if skip > 0:
@ -1130,7 +1130,7 @@ class AllTorrents(BaseMode, component.Component):
elif c in [10, curses.KEY_ENTER]: elif c in [10, curses.KEY_ENTER]:
self.last_mark = -1 self.last_mark = -1
tid = self.current_torrent_id() tid = self.current_torrent_id()
torrent_actions_popup(self, [tid] ,details=True) torrent_actions_popup(self, [tid], details=True)
elif c == 27: elif c == 27:
self.search_string = "" self.search_string = ""
@ -1202,13 +1202,13 @@ class AllTorrents(BaseMode, component.Component):
if c == curses.KEY_UP: if c == curses.KEY_UP:
if self.cursel == 1: return if self.cursel == 1: return
if not self._scroll_up(1): if not self._scroll_up(1):
effected_lines = [self.cursel-1,self.cursel] effected_lines = [self.cursel-1, self.cursel]
elif c == curses.KEY_PPAGE: elif c == curses.KEY_PPAGE:
self._scroll_up(int(self.rows/2)) self._scroll_up(int(self.rows/2))
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
if self.cursel >= self.numtorrents: return if self.cursel >= self.numtorrents: return
if not self._scroll_down(1): if not self._scroll_down(1):
effected_lines = [self.cursel-2,self.cursel-1] effected_lines = [self.cursel-2, self.cursel-1]
elif c == curses.KEY_NPAGE: elif c == curses.KEY_NPAGE:
self._scroll_down(int(self.rows/2)) self._scroll_down(int(self.rows/2))
elif c == curses.KEY_HOME: elif c == curses.KEY_HOME:
@ -1219,7 +1219,7 @@ class AllTorrents(BaseMode, component.Component):
if self.cursel not in self.marked: if self.cursel not in self.marked:
self.marked.append(self.cursel) self.marked.append(self.cursel)
self.last_mark = self.cursel self.last_mark = self.cursel
torrent_actions_popup(self,self._selected_torrent_ids(), action=ACTION.REMOVE) torrent_actions_popup(self, self._selected_torrent_ids(), action=ACTION.REMOVE)
elif c == curses.KEY_RIGHT: elif c == curses.KEY_RIGHT:
# We enter a new mode for the selected torrent here # We enter a new mode for the selected torrent here
@ -1233,7 +1233,7 @@ class AllTorrents(BaseMode, component.Component):
if self.cursel not in self.marked: if self.cursel not in self.marked:
self.marked.append(self.cursel) self.marked.append(self.cursel)
self.last_mark = self.cursel self.last_mark = self.cursel
torrent_actions_popup(self,self._selected_torrent_ids(),details=True) torrent_actions_popup(self, self._selected_torrent_ids(), details=True)
return return
else: else:
if c > 31 and c < 256: if c > 31 and c < 256:
@ -1244,15 +1244,15 @@ class AllTorrents(BaseMode, component.Component):
self.__do_search("next") self.__do_search("next")
elif chr(c) == 'j': elif chr(c) == 'j':
if not self._scroll_up(1): if not self._scroll_up(1):
effected_lines = [self.cursel-1,self.cursel] effected_lines = [self.cursel-1, self.cursel]
elif chr(c) == 'k': elif chr(c) == 'k':
if not self._scroll_down(1): if not self._scroll_down(1):
effected_lines = [self.cursel-2,self.cursel-1] effected_lines = [self.cursel-2, self.cursel-1]
elif chr(c) == 'i': elif chr(c) == 'i':
cid = self.current_torrent_id() cid = self.current_torrent_id()
if cid: if cid:
def cb(): self.__torrent_info_id = None def cb(): self.__torrent_info_id = None
self.popup = Popup(self,"Info",close_cb=cb, height_req=20) self.popup = Popup(self, "Info", close_cb=cb, height_req=20)
self.popup.add_line("Getting torrent info...") self.popup.add_line("Getting torrent info...")
self.__torrent_info_id = cid self.__torrent_info_id = cid
elif chr(c) == 'm': elif chr(c) == 'm':
@ -1261,9 +1261,9 @@ class AllTorrents(BaseMode, component.Component):
elif chr(c) == 'M': elif chr(c) == 'M':
if self.last_mark >= 0: if self.last_mark >= 0:
if (self.cursel+1) > self.last_mark: if (self.cursel+1) > self.last_mark:
mrange = range(self.last_mark,self.cursel+1) mrange = range(self.last_mark, self.cursel+1)
else: else:
mrange = range(self.cursel-1,self.last_mark) mrange = range(self.cursel-1, self.last_mark)
self.marked.extend(mrange[1:]) self.marked.extend(mrange[1:])
effected_lines = mrange effected_lines = mrange
else: else:

View file

@ -122,7 +122,7 @@ class BaseMode(CursesStdIO):
def on_resize_norefresh(self, *args): def on_resize_norefresh(self, *args):
log.debug("on_resize_from_signal") log.debug("on_resize_from_signal")
# Get the new rows and cols value # Get the new rows and cols value
self.rows, self.cols = struct.unpack("hhhh", ioctl(0, termios.TIOCGWINSZ ,"\000"*8))[0:2] self.rows, self.cols = struct.unpack("hhhh", ioctl(0, termios.TIOCGWINSZ, "\000"*8))[0:2]
curses.resizeterm(self.rows, self.cols) curses.resizeterm(self.rows, self.cols)
def on_resize(self, *args): def on_resize(self, *args):
@ -177,7 +177,7 @@ class BaseMode(CursesStdIO):
# This is the last string so lets append some " " to it # This is the last string so lets append some " " to it
s += " " * (self.cols - (col + len(s)) - 1) s += " " * (self.cols - (col + len(s)) - 1)
if trim: if trim:
y,x = screen.getmaxyx() y, x = screen.getmaxyx()
if (col+len(s)) > x: if (col+len(s)) > x:
s = "%s..."%s[0:x-4-col] s = "%s..."%s[0:x-4-col]
screen.addstr(row, col, s, color) screen.addstr(row, col, s, color)
@ -192,7 +192,7 @@ class BaseMode(CursesStdIO):
pass pass
# This mode doesn't do anything with popups # This mode doesn't do anything with popups
def set_popup(self,popup): def set_popup(self, popup):
pass pass
# This mode doesn't support marking # This mode doesn't support marking
@ -209,7 +209,7 @@ class BaseMode(CursesStdIO):
self.draw_statusbars() self.draw_statusbars()
# Update the status bars # Update the status bars
self.add_string(1,"{!info!}Base Mode (or subclass hasn't overridden refresh)") self.add_string(1, "{!info!}Base Mode (or subclass hasn't overridden refresh)")
self.stdscr.redrawwin() self.stdscr.redrawwin()
self.stdscr.refresh() self.stdscr.refresh()

View file

@ -35,7 +35,7 @@
# a mode that show's a popup to select which host to connect to # a mode that show's a popup to select which host to connect to
import hashlib,time import hashlib, time
from collections import deque from collections import deque
@ -47,7 +47,7 @@ import deluge.component as component
from alltorrents import AllTorrents from alltorrents import AllTorrents
from basemode import BaseMode from basemode import BaseMode
from popup import SelectablePopup,MessagePopup from popup import SelectablePopup, MessagePopup
from input_popup import InputPopup from input_popup import InputPopup
@ -78,13 +78,13 @@ class ConnectionManager(BaseMode):
self.__update_popup() self.__update_popup()
def __update_popup(self): def __update_popup(self):
self.popup = SelectablePopup(self,"Select Host",self.__host_selected) self.popup = SelectablePopup(self, "Select Host", self.__host_selected)
self.popup.add_line("{!white,black,bold!}'Q'=quit, 'r'=refresh, 'a'=add new host, 'D'=delete host",selectable=False) self.popup.add_line("{!white,black,bold!}'Q'=quit, 'r'=refresh, 'a'=add new host, 'D'=delete host", selectable=False)
for host in self.config["hosts"]: for host in self.config["hosts"]:
if host[0] in self.statuses: if host[0] in self.statuses:
self.popup.add_line("%s:%d [Online] (%s)"%(host[1],host[2],self.statuses[host[0]]),data=host[0],foreground="green") self.popup.add_line("%s:%d [Online] (%s)"%(host[1], host[2], self.statuses[host[0]]), data=host[0], foreground="green")
else: else:
self.popup.add_line("%s:%d [Offline]"%(host[1],host[2]),data=host[0],foreground="red") self.popup.add_line("%s:%d [Offline]"%(host[1], host[2]), data=host[0], foreground="red")
self.inlist = True self.inlist = True
self.refresh() self.refresh()
@ -119,7 +119,7 @@ class ConnectionManager(BaseMode):
d.addCallback(on_connect, c, host[0]) d.addCallback(on_connect, c, host[0])
d.addErrback(on_connect_failed, host[0]) d.addErrback(on_connect_failed, host[0])
def __on_connected(self,result): def __on_connected(self, result):
component.start() component.start()
self.stdscr.erase() self.stdscr.erase()
at = AllTorrents(self.stdscr, self.encoding) at = AllTorrents(self.stdscr, self.encoding)
@ -132,18 +132,18 @@ class ConnectionManager(BaseMode):
client.connect(host[1], host[2], host[3], host[4]).addCallback(self.__on_connected) client.connect(host[1], host[2], host[3], host[4]).addCallback(self.__on_connected)
return False return False
def __do_add(self,result): def __do_add(self, result):
hostname = result["hostname"] hostname = result["hostname"]
try: try:
port = int(result["port"]) port = int(result["port"])
except ValueError: except ValueError:
self.report_message("Can't add host","Invalid port. Must be an integer") self.report_message("Can't add host", "Invalid port. Must be an integer")
return return
username = result["username"] username = result["username"]
password = result["password"] password = result["password"]
for host in self.config["hosts"]: for host in self.config["hosts"]:
if (host[1],host[2],host[3]) == (hostname, port, username): if (host[1], host[2], host[3]) == (hostname, port, username):
self.report_message("Can't add host","Host already in list") self.report_message("Can't add host", "Host already in list")
return return
newid = hashlib.sha1(str(time.time())).hexdigest() newid = hashlib.sha1(str(time.time())).hexdigest()
self.config["hosts"].append((newid, hostname, port, username, password)) self.config["hosts"].append((newid, hostname, port, username, password))
@ -152,24 +152,24 @@ class ConnectionManager(BaseMode):
def __add_popup(self): def __add_popup(self):
self.inlist = False self.inlist = False
self.popup = InputPopup(self,"Add Host (up & down arrows to navigate, esc to cancel)",close_cb=self.__do_add) self.popup = InputPopup(self, "Add Host (up & down arrows to navigate, esc to cancel)", close_cb=self.__do_add)
self.popup.add_text_input("Hostname:","hostname") self.popup.add_text_input("Hostname:", "hostname")
self.popup.add_text_input("Port:","port") self.popup.add_text_input("Port:", "port")
self.popup.add_text_input("Username:","username") self.popup.add_text_input("Username:", "username")
self.popup.add_text_input("Password:","password") self.popup.add_text_input("Password:", "password")
self.refresh() self.refresh()
def __delete_current_host(self): def __delete_current_host(self):
idx,data = self.popup.current_selection() idx, data = self.popup.current_selection()
log.debug("deleting host: %s",data) log.debug("deleting host: %s", data)
for host in self.config["hosts"]: for host in self.config["hosts"]:
if host[0] == data: if host[0] == data:
self.config["hosts"].remove(host) self.config["hosts"].remove(host)
break break
self.config.save() self.config.save()
def report_message(self,title,message): def report_message(self, title, message):
self.messages.append((title,message)) self.messages.append((title, message))
def refresh(self): def refresh(self):
self.stdscr.erase() self.stdscr.erase()
@ -177,8 +177,8 @@ class ConnectionManager(BaseMode):
self.stdscr.noutrefresh() self.stdscr.noutrefresh()
if self.popup == None and self.messages: if self.popup == None and self.messages:
title,msg = self.messages.popleft() title, msg = self.messages.popleft()
self.popup = MessagePopup(self,title,msg) self.popup = MessagePopup(self, title, msg)
if not self.popup: if not self.popup:
self.__update_popup() self.__update_popup()

View file

@ -61,7 +61,7 @@ class EventView(BaseMode):
self.stdscr.erase() self.stdscr.erase()
self.add_string(0,self.statusbars.topbar) self.add_string(0, self.statusbars.topbar)
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10)) hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10))
#This will quite likely fail when switching modes #This will quite likely fail when switching modes
try: try:
@ -76,7 +76,7 @@ class EventView(BaseMode):
pass pass
if events: if events:
for i,event in enumerate(events): for i, event in enumerate(events):
if i - self.offset >= self.rows - 2: if i - self.offset >= self.rows - 2:
more = len(events) - self.offset - self.rows + 2 more = len(events) - self.offset - self.rows + 2
if more > 0: if more > 0:
@ -86,11 +86,11 @@ class EventView(BaseMode):
elif i - self.offset < 0: elif i - self.offset < 0:
continue continue
try: try:
self.add_string(i+1-self.offset,event) self.add_string(i+1-self.offset, event)
except curses.error: except curses.error:
pass #This'll just cut the line. Note: This seriously should be fixed in a better way pass #This'll just cut the line. Note: This seriously should be fixed in a better way
else: else:
self.add_string(1,"{!white,black,bold!}No events to show yet") self.add_string(1, "{!white,black,bold!}No events to show yet")
if component.get("ConsoleUI").screen != self: if component.get("ConsoleUI").screen != self:
return return

View file

@ -72,7 +72,7 @@ def format_float(x):
return "%.3f"%x return "%.3f"%x
def format_seeds_peers(num, total): def format_seeds_peers(num, total):
return "%d (%d)"%(num,total) return "%d (%d)"%(num, total)
def format_progress(perc): def format_progress(perc):
if perc < 100: if perc < 100:
@ -81,7 +81,7 @@ def format_progress(perc):
return "100%" return "100%"
def format_pieces(num, size): def format_pieces(num, size):
return "%d (%s)"%(num,deluge.common.fsize(size)) return "%d (%s)"%(num, deluge.common.fsize(size))
def format_priority(prio): def format_priority(prio):
if prio == -2: return "[Mixed]" if prio == -2: return "[Mixed]"
@ -104,7 +104,7 @@ def trim_string(string, w, have_dbls):
idx = 0 idx = 0
while width < w: while width < w:
chrs.append(string[idx]) chrs.append(string[idx])
if unicodedata.east_asian_width(string[idx]) in ['W','F']: if unicodedata.east_asian_width(string[idx]) in ['W', 'F']:
width += 2 width += 2
else: else:
width += 1 width += 1
@ -126,16 +126,16 @@ def format_column(col, lim):
# for unicode strings. # for unicode strings.
if haveud and col.__class__ is unicode: if haveud and col.__class__ is unicode:
# might have some double width chars # might have some double width chars
col = ud_normalize("NFC",col) col = ud_normalize("NFC", col)
dbls = sum(eaw(c) in 'WF' for c in col) dbls = sum(eaw(c) in 'WF' for c in col)
size = len(col)+dbls size = len(col)+dbls
if (size >= lim - 1): if (size >= lim - 1):
return trim_string(col,lim,dbls>0) return trim_string(col, lim, dbls>0)
else: else:
return "%s%s"%(col," "*(lim-size)) return "%s%s"%(col, " "*(lim-size))
def format_row(row, column_widths): def format_row(row, column_widths):
return "".join([format_column(row[i],column_widths[i]) for i in range(0,len(row))]) return "".join([format_column(row[i], column_widths[i]) for i in range(0, len(row))])
import re import re
_strip_re = re.compile("\{!.*?!\}") _strip_re = re.compile("\{!.*?!\}")
@ -157,13 +157,13 @@ def wrap_string(string,width,min_lines=0,strip_colors=True):
ret = [] ret = []
s1 = string.split("\n") s1 = string.split("\n")
def insert_clr(s,offset,mtchs,clrs): def insert_clr(s, offset, mtchs, clrs):
end_pos = offset+len(s) end_pos = offset+len(s)
while mtchs and (mtchs[0] <= end_pos) and (mtchs[0] >= offset): while mtchs and (mtchs[0] <= end_pos) and (mtchs[0] >= offset):
mtc = mtchs.popleft()-offset mtc = mtchs.popleft()-offset
clr = clrs.popleft() clr = clrs.popleft()
end_pos += len(clr) end_pos += len(clr)
s = "%s%s%s"%(s[:mtc],clr,s[mtc:]) s = "%s%s%s"%(s[:mtc], clr, s[mtc:])
return s return s
for s in s1: for s in s1:
@ -174,16 +174,16 @@ def wrap_string(string,width,min_lines=0,strip_colors=True):
for m in _strip_re.finditer(s): for m in _strip_re.finditer(s):
mtchs.append(m.start()) mtchs.append(m.start())
clrs.append(m.group()) clrs.append(m.group())
cstr = _strip_re.sub('',s) cstr = _strip_re.sub('', s)
else: else:
cstr = s cstr = s
while len(cstr) > width: while len(cstr) > width:
sidx = cstr.rfind(" ",0,width-1) sidx = cstr.rfind(" ", 0, width-1)
sidx += 1 sidx += 1
if sidx > 0: if sidx > 0:
if strip_colors: if strip_colors:
to_app = cstr[0:sidx] to_app = cstr[0:sidx]
to_app = insert_clr(to_app,offset,mtchs,clrs) to_app = insert_clr(to_app, offset, mtchs, clrs)
ret.append(to_app) ret.append(to_app)
offset += len(to_app) offset += len(to_app)
else: else:
@ -196,7 +196,7 @@ def wrap_string(string,width,min_lines=0,strip_colors=True):
# can't find a reasonable split, just split at width # can't find a reasonable split, just split at width
if strip_colors: if strip_colors:
to_app = cstr[0:width] to_app = cstr[0:width]
to_app = insert_clr(to_app,offset,mtchs,clrs) to_app = insert_clr(to_app, offset, mtchs, clrs)
ret.append(to_app) ret.append(to_app)
offset += len(to_app) offset += len(to_app)
else: else:
@ -207,12 +207,12 @@ def wrap_string(string,width,min_lines=0,strip_colors=True):
break break
if cstr != None: if cstr != None:
if strip_colors: if strip_colors:
ret.append(insert_clr(cstr,offset,mtchs,clrs)) ret.append(insert_clr(cstr, offset, mtchs, clrs))
else: else:
ret.append(cstr) ret.append(cstr)
if min_lines>0: if min_lines>0:
for i in range(len(ret),min_lines): for i in range(len(ret), min_lines):
ret.append(" ") ret.append(" ")
#Carry colors over to the next line #Carry colors over to the next line
@ -236,7 +236,7 @@ def strwidth(string):
if not isinstance(string, unicode): if not isinstance(string, unicode):
string = unicode(string, 'utf-8') string = unicode(string, 'utf-8')
eaw = east_asian_width eaw = east_asian_width
length = sum( [1 + (eaw(c) in ['W','F']) for c in string] ) length = sum( [1 + (eaw(c) in ['W', 'F']) for c in string] )
#Using list comprehenstion for improved performance #Using list comprehenstion for improved performance
#The code above is equal to: #The code above is equal to:
#length = 0 #length = 0

View file

@ -42,7 +42,7 @@ try:
except ImportError: except ImportError:
pass pass
import logging,os,os.path import logging, os, os.path
from popup import Popup, ALIGN from popup import Popup, ALIGN
@ -69,7 +69,7 @@ class InputField:
pass pass
def set_depend(self,i,inverse=False): def set_depend(self,i,inverse=False):
if not isinstance(i,CheckedInput): if not isinstance(i, CheckedInput):
raise Exception("Can only depend on CheckedInputs") raise Exception("Can only depend on CheckedInputs")
self.depend = i self.depend = i
self.inverse = inverse self.inverse = inverse
@ -98,13 +98,13 @@ class CheckedInput(InputField):
def render(self, screen, row, width, active, col=1): def render(self, screen, row, width, active, col=1):
if self.checked and active: if self.checked and active:
self.parent.add_string(row,self.chkd_act,screen,col,False,True) self.parent.add_string(row, self.chkd_act, screen, col, False, True)
elif self.checked: elif self.checked:
self.parent.add_string(row,self.chkd_inact,screen,col,False,True) self.parent.add_string(row, self.chkd_inact, screen, col, False, True)
elif active: elif active:
self.parent.add_string(row,self.unchkd_act,screen,col,False,True) self.parent.add_string(row, self.unchkd_act, screen, col, False, True)
else: else:
self.parent.add_string(row,self.unchkd_inact,screen,col,False,True) self.parent.add_string(row, self.unchkd_inact, screen, col, False, True)
return 1 return 1
def handle_read(self, c): def handle_read(self, c):
@ -137,28 +137,28 @@ class CheckedPlusInput(InputField):
def render(self, screen, row, width, active, col=1): def render(self, screen, row, width, active, col=1):
isact = active and not self.child_active isact = active and not self.child_active
if self.checked and isact: if self.checked and isact:
self.parent.add_string(row,self.chkd_act,screen,col,False,True) self.parent.add_string(row, self.chkd_act, screen, col, False, True)
elif self.checked: elif self.checked:
self.parent.add_string(row,self.chkd_inact,screen,col,False,True) self.parent.add_string(row, self.chkd_inact, screen, col, False, True)
elif isact: elif isact:
self.parent.add_string(row,self.unchkd_act,screen,col,False,True) self.parent.add_string(row, self.unchkd_act, screen, col, False, True)
else: else:
self.parent.add_string(row,self.unchkd_inact,screen,col,False,True) self.parent.add_string(row, self.unchkd_inact, screen, col, False, True)
if active and self.checked and self.child_active: if active and self.checked and self.child_active:
self.parent.add_string(row+1,"(esc to leave)",screen,col,False,True) self.parent.add_string(row+1, "(esc to leave)", screen, col, False, True)
elif active and self.checked: elif active and self.checked:
self.parent.add_string(row+1,"(right arrow to edit)",screen,col,False,True) self.parent.add_string(row+1, "(right arrow to edit)", screen, col, False, True)
rows = 2 rows = 2
# show child # show child
if self.checked: if self.checked:
if isinstance(self.child,(TextInput,IntSpinInput,FloatSpinInput)): if isinstance(self.child, (TextInput, IntSpinInput, FloatSpinInput)):
crows = self.child.render(screen,row,width-self.msglen,self.child_active and active,col+self.msglen,self.msglen) crows = self.child.render(screen, row, width-self.msglen, self.child_active and active, col+self.msglen, self.msglen)
else: else:
crows = self.child.render(screen,row,width-self.msglen,self.child_active and active,col+self.msglen) crows = self.child.render(screen, row, width-self.msglen, self.child_active and active, col+self.msglen)
rows = max(rows,crows) rows = max(rows, crows)
else: else:
self.parent.add_string(row,"(enable to view/edit value)",screen,col+self.msglen,False,True) self.parent.add_string(row, "(enable to view/edit value)", screen, col+self.msglen, False, True)
return rows return rows
def handle_read(self, c): def handle_read(self, c):
@ -239,16 +239,16 @@ class IntSpinInput(InputField):
except: except:
self.real_value = False self.real_value = False
if not self.valstr: if not self.valstr:
self.parent.add_string(row,"%s {!input!}[ ]"%self.message,screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ ]"%self.message, screen, col, False, True)
elif active: elif active:
self.parent.add_string(row,"%s {!input!}[ {!black,white,bold!}%s{!input!} ]"%(self.message,self.valstr),screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ {!black,white,bold!}%s{!input!} ]"%(self.message, self.valstr), screen, col, False, True)
elif self.additional_formatting and self.valstr == self.default_str: elif self.additional_formatting and self.valstr == self.default_str:
self.parent.add_string(row,"%s {!input!}[ {!magenta,black!}%s{!input!} ]"%(self.message,self.valstr),screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ {!magenta,black!}%s{!input!} ]"%(self.message, self.valstr), screen, col, False, True)
else: else:
self.parent.add_string(row,"%s {!input!}[ %s ]"%(self.message,self.valstr),screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ %s ]"%(self.message, self.valstr), screen, col, False, True)
if active: if active:
self.move_func(row,self.cursor+self.cursoff+cursor_offset) self.move_func(row, self.cursor+self.cursoff+cursor_offset)
return 1 return 1
@ -273,10 +273,10 @@ class IntSpinInput(InputField):
self.cursor = len(self.valstr) self.cursor = len(self.valstr)
elif c == curses.KEY_LEFT: elif c == curses.KEY_LEFT:
if not self.real_value: return None if not self.real_value: return None
self.cursor = max(0,self.cursor-1) self.cursor = max(0, self.cursor-1)
elif c == curses.KEY_RIGHT: elif c == curses.KEY_RIGHT:
if not self.real_value: return None if not self.real_value: return None
self.cursor = min(len(self.valstr),self.cursor+1) self.cursor = min(len(self.valstr), self.cursor+1)
elif c == curses.KEY_HOME: elif c == curses.KEY_HOME:
if not self.real_value: return None if not self.real_value: return None
self.cursor = 0 self.cursor = 0
@ -409,15 +409,15 @@ class FloatSpinInput(InputField):
self.real_value = False self.real_value = False
if not self.valstr: if not self.valstr:
self.parent.add_string(row,"%s {!input!}[ ]"%self.message,screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ ]"%self.message, screen, col, False, True)
elif active: elif active:
self.parent.add_string(row,"%s {!input!}[ {!black,white,bold!}%s{!white,black!} ]"%(self.message,self.valstr),screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ {!black,white,bold!}%s{!white,black!} ]"%(self.message, self.valstr), screen, col, False, True)
elif self.additional_formatting and self.valstr == self.default_str: elif self.additional_formatting and self.valstr == self.default_str:
self.parent.add_string(row,"%s {!input!}[ {!magenta,black!}%s{!input!} ]"%(self.message,self.valstr),screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ {!magenta,black!}%s{!input!} ]"%(self.message, self.valstr), screen, col, False, True)
else: else:
self.parent.add_string(row,"%s {!input!}[ %s ]"%(self.message,self.valstr),screen,col,False,True) self.parent.add_string(row, "%s {!input!}[ %s ]"%(self.message, self.valstr), screen, col, False, True)
if active: if active:
self.move_func(row,self.cursor+self.cursoff+cursor_offset) self.move_func(row, self.cursor+self.cursoff+cursor_offset)
return 1 return 1
@ -444,10 +444,10 @@ class FloatSpinInput(InputField):
self.cursor = len(self.valstr) self.cursor = len(self.valstr)
elif c == curses.KEY_LEFT: elif c == curses.KEY_LEFT:
if not self.real_value: return None if not self.real_value: return None
self.cursor = max(0,self.cursor-1) self.cursor = max(0, self.cursor-1)
elif c == curses.KEY_RIGHT: elif c == curses.KEY_RIGHT:
if not self.real_value: return None if not self.real_value: return None
self.cursor = min(len(self.valstr),self.cursor+1) self.cursor = min(len(self.valstr), self.cursor+1)
elif c == curses.KEY_HOME: elif c == curses.KEY_HOME:
if not self.real_value: return None if not self.real_value: return None
self.cursor = 0 self.cursor = 0
@ -552,21 +552,21 @@ class SelectInput(InputField):
def render(self, screen, row, width, selected, col=1): def render(self, screen, row, width, selected, col=1):
if self.message: if self.message:
self.parent.add_string(row,self.message,screen,col,False,True) self.parent.add_string(row, self.message, screen, col, False, True)
row += 1 row += 1
off = col+1 off = col+1
for i,opt in enumerate(self.opts): for i, opt in enumerate(self.opts):
if selected and i == self.selidx: if selected and i == self.selidx:
self.parent.add_string(row,"{!black,white,bold!}[%s]"%opt,screen,off,False,True) self.parent.add_string(row, "{!black,white,bold!}[%s]"%opt, screen, off, False, True)
elif i == self.selidx: elif i == self.selidx:
if self.additional_formatting and i == self.default_option: if self.additional_formatting and i == self.default_option:
self.parent.add_string(row,"[{!magenta,black!}%s{!white,black!}]"%opt,screen,off,False,True) self.parent.add_string(row, "[{!magenta,black!}%s{!white,black!}]"%opt, screen, off, False, True)
elif self.additional_formatting: elif self.additional_formatting:
self.parent.add_string(row,"[{!white,blue!}%s{!white,black!}]"%opt,screen,off,False,True) self.parent.add_string(row, "[{!white,blue!}%s{!white,black!}]"%opt, screen, off, False, True)
else: else:
self.parent.add_string(row,"[{!white,black,underline!}%s{!white,black!}]"%opt,screen,off,False,True) self.parent.add_string(row, "[{!white,black,underline!}%s{!white,black!}]"%opt, screen, off, False, True)
else: else:
self.parent.add_string(row,"[%s]"%opt,screen,off,False,True) self.parent.add_string(row, "[%s]"%opt, screen, off, False, True)
off += len(opt)+3 off += len(opt)+3
if self.message: if self.message:
return 2 return 2
@ -575,15 +575,15 @@ class SelectInput(InputField):
def handle_read(self, c): def handle_read(self, c):
if c == curses.KEY_LEFT: if c == curses.KEY_LEFT:
self.selidx = max(0,self.selidx-1) self.selidx = max(0, self.selidx-1)
if c == curses.KEY_RIGHT: if c == curses.KEY_RIGHT:
self.selidx = min(len(self.opts)-1,self.selidx+1) self.selidx = min(len(self.opts)-1, self.selidx+1)
def get_value(self): def get_value(self):
return self.vals[self.selidx] return self.vals[self.selidx]
def set_value(self, nv): def set_value(self, nv):
for i,val in enumerate(self.vals): for i, val in enumerate(self.vals):
if nv == val: if nv == val:
self.selidx = i self.selidx = i
return return
@ -617,15 +617,15 @@ class TextInput(InputField):
self.cursor = len(self.value) self.cursor = len(self.value)
if self.message: if self.message:
self.parent.add_string(row,self.message,screen,col,False,True) self.parent.add_string(row, self.message, screen, col, False, True)
row += 1 row += 1
if selected: if selected:
if self.opts: if self.opts:
self.parent.add_string(row+1,self.opts[self.opt_off:],screen,col,False,True) self.parent.add_string(row+1, self.opts[self.opt_off:], screen, col, False, True)
if self.cursor > (width-3): if self.cursor > (width-3):
self.move_func(row,width-2) self.move_func(row, width-2)
else: else:
self.move_func(row,self.cursor+1+cursor_offset) self.move_func(row, self.cursor+1+cursor_offset)
slen = len(self.value)+3 slen = len(self.value)+3
if slen > width: if slen > width:
vstr = self.value[(slen-width):] vstr = self.value[(slen-width):]
@ -633,9 +633,9 @@ class TextInput(InputField):
vstr = self.value.ljust(width-2) vstr = self.value.ljust(width-2)
if self.additional_formatting and len(self.value) != 0 and self.value == self.default_value: if self.additional_formatting and len(self.value) != 0 and self.value == self.default_value:
self.parent.add_string(row,"{!magenta,white!}%s"%vstr,screen,col,False,False) self.parent.add_string(row, "{!magenta,white!}%s"%vstr, screen, col, False, False)
else: else:
self.parent.add_string(row,"{!black,white,bold!}%s"%vstr,screen,col,False,False) self.parent.add_string(row, "{!black,white,bold!}%s"%vstr, screen, col, False, False)
if self.message: if self.message:
return 3 return 3
@ -645,12 +645,12 @@ class TextInput(InputField):
def get_value(self): def get_value(self):
return self.value return self.value
def set_value(self,val): def set_value(self, val):
self.value = val self.value = val
self.cursor = len(self.value) self.cursor = len(self.value)
# most of the cursor,input stuff here taken from ui/console/screen.py # most of the cursor,input stuff here taken from ui/console/screen.py
def handle_read(self,c): def handle_read(self, c):
if c == 9 and self.docmp: if c == 9 and self.docmp:
# Keep track of tab hit count to know when it's double-hit # Keep track of tab hit count to know when it's double-hit
self.tab_count += 1 self.tab_count += 1
@ -668,7 +668,7 @@ class TextInput(InputField):
self.opt_off += self.width-3 self.opt_off += self.width-3
# now find previous double space, best guess at a split point # now find previous double space, best guess at a split point
# in future could keep opts unjoined to get this really right # in future could keep opts unjoined to get this really right
self.opt_off = self.opts.rfind(" ",0,self.opt_off)+2 self.opt_off = self.opts.rfind(" ", 0, self.opt_off)+2
if second_hit and self.opt_off == prev: # double tap and we're at the end if second_hit and self.opt_off == prev: # double tap and we're at the end
self.opt_off = 0 self.opt_off = 0
else: else:
@ -689,9 +689,9 @@ class TextInput(InputField):
# Cursor movement # Cursor movement
elif c == curses.KEY_LEFT: elif c == curses.KEY_LEFT:
self.cursor = max(0,self.cursor-1) self.cursor = max(0, self.cursor-1)
elif c == curses.KEY_RIGHT: elif c == curses.KEY_RIGHT:
self.cursor = min(len(self.value),self.cursor+1) self.cursor = min(len(self.value), self.cursor+1)
elif c == curses.KEY_HOME: elif c == curses.KEY_HOME:
self.cursor = 0 self.cursor = 0
elif c == curses.KEY_END: elif c == curses.KEY_END:
@ -730,7 +730,7 @@ class TextInput(InputField):
self.cursor+=1 self.cursor+=1
def complete(self,line): def complete(self, line):
line = os.path.abspath(os.path.expanduser(line)) line = os.path.abspath(os.path.expanduser(line))
ret = [] ret = []
if os.path.exists(line): if os.path.exists(line):
@ -773,7 +773,7 @@ class InputPopup(Popup):
close_cb=None, close_cb=None,
additional_formatting=True, additional_formatting=True,
immediate_action=False): immediate_action=False):
Popup.__init__(self,parent_mode,title, width_req=width_req, height_req=height_req, align=align, close_cb=close_cb) Popup.__init__(self, parent_mode, title, width_req=width_req, height_req=height_req, align=align, close_cb=close_cb)
self.inputs = [] self.inputs = []
self.lines = [] self.lines = []
self.current_input = 0 self.current_input = 0
@ -784,7 +784,7 @@ class InputPopup(Popup):
#We need to replicate some things in order to wrap our inputs #We need to replicate some things in order to wrap our inputs
self.encoding = parent_mode.encoding self.encoding = parent_mode.encoding
def move(self,r,c): def move(self, r, c):
self._cursor_row = r self._cursor_row = r
self._cursor_col = c self._cursor_col = c
@ -826,7 +826,7 @@ class InputPopup(Popup):
additional_formatting = self.additional_formatting)) additional_formatting = self.additional_formatting))
def add_checked_input(self, message, name, checked=False): def add_checked_input(self, message, name, checked=False):
self.inputs.append(CheckedInput(self,message,name,checked, self.inputs.append(CheckedInput(self, message, name, checked,
additional_formatting = self.additional_formatting)) additional_formatting = self.additional_formatting))
#def add_checked_plus_input(self, message, name, child) #def add_checked_plus_input(self, message, name, child)
@ -866,12 +866,12 @@ class InputPopup(Popup):
crow = 1 - self.lineoff crow = 1 - self.lineoff
spos = 0 spos = 0
for i,ipt in enumerate(self.inputs): for i, ipt in enumerate(self.inputs):
for line in self.lines: for line in self.lines:
if line[0] == i: if line[0] == i:
self.add_string(crow, line[1], self.screen, 1, pad=False) self.add_string(crow, line[1], self.screen, 1, pad=False)
crow += 1 crow += 1
crow += ipt.render(self.screen,crow,self.width,i==self.current_input) crow += ipt.render(self.screen, crow, self.width, i==self.current_input)
if (self.content_height > (self.height-2)): if (self.content_height > (self.height-2)):
lts = self.content_height-(self.height-3) lts = self.content_height-(self.height-3)
@ -879,16 +879,16 @@ class InputPopup(Popup):
sb_pos = int((self.height-2)*perc_sc)+1 sb_pos = int((self.height-2)*perc_sc)+1
if (sb_pos == 1) and (self.lineoff != 0): if (sb_pos == 1) and (self.lineoff != 0):
sb_pos += 1 sb_pos += 1
self.add_string(sb_pos, "{!red,black,bold!}#",self.screen,col=(self.width-1),pad=False,trim=False) self.add_string(sb_pos, "{!red,black,bold!}#", self.screen, col=(self.width-1), pad=False, trim=False)
if self._cursor_row >= 0: if self._cursor_row >= 0:
curses.curs_set(2) curses.curs_set(2)
self.screen.move(self._cursor_row,self._cursor_col) self.screen.move(self._cursor_row, self._cursor_col)
def handle_read(self, c): def handle_read(self, c):
if c == curses.KEY_UP: if c == curses.KEY_UP:
self.current_input = max(0,self.current_input-1) self.current_input = max(0, self.current_input-1)
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
self.current_input = min(len(self.inputs)-1,self.current_input+1) self.current_input = min(len(self.inputs)-1, self.current_input+1)
elif c == curses.KEY_ENTER or c == 10: elif c == curses.KEY_ENTER or c == 10:
if self.close_cb: if self.close_cb:
vals = {} vals = {}

View file

@ -51,7 +51,7 @@ import deluge.configmanager
from deluge.ui.console.modes import format_utils from deluge.ui.console.modes import format_utils
strwidth = format_utils.strwidth strwidth = format_utils.strwidth
import logging,os import logging, os
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
import re import re
@ -907,7 +907,7 @@ class Legacy(BaseMode, component.Component):
# Find all possible matches # Find all possible matches
for torrent_id, torrent_name in self.torrents: for torrent_id, torrent_name in self.torrents:
#Escape spaces to avoid, for example, expanding "Doc" into "Doctor Who" and removing everything containing one of these words #Escape spaces to avoid, for example, expanding "Doc" into "Doctor Who" and removing everything containing one of these words
escaped_name = torrent_name.replace(" ","\\ ") escaped_name = torrent_name.replace(" ", "\\ ")
#If we only matched one torrent, don't add the full name or it'll also get autocompleted #If we only matched one torrent, don't add the full name or it'll also get autocompleted
if match_count == 1: if match_count == 1:
if torrent_id.startswith(line): if torrent_id.startswith(line):

View file

@ -102,7 +102,7 @@ class Popup:
for line in self._lines[self.lineoff:]: for line in self._lines[self.lineoff:]:
if (crow >= self.height-1): if (crow >= self.height-1):
break break
self.parent.add_string(crow,line,self.screen,1,False,True) self.parent.add_string(crow, line, self.screen, 1, False, True)
crow+=1 crow+=1
def handle_resize(self): def handle_resize(self):
@ -148,17 +148,17 @@ class Popup:
elif self.align in [ALIGN.TOP_RIGHT, ALIGN.MIDDLE_RIGHT, ALIGN.BOTTOM_RIGHT]: elif self.align in [ALIGN.TOP_RIGHT, ALIGN.MIDDLE_RIGHT, ALIGN.BOTTOM_RIGHT]:
bx = self.parent.cols - wr - 1 bx = self.parent.cols - wr - 1
self.screen = curses.newwin(hr,wr,by,bx) self.screen = curses.newwin(hr, wr, by, bx)
self.x, self.y = bx, by self.x, self.y = bx, by
self.height,self.width = self.screen.getmaxyx() self.height, self.width = self.screen.getmaxyx()
def refresh(self): def refresh(self):
self.screen.erase() self.screen.erase()
self.screen.border(0,0,0,0) self.screen.border(0, 0, 0, 0)
toff = max(1, (self.width//2) - (len(self.title)//2)) toff = max(1, (self.width//2) - (len(self.title)//2))
self.parent.add_string(0,"{!white,black,bold!}%s"%self.title,self.screen,toff,False,True) self.parent.add_string(0, "{!white,black,bold!}%s"%self.title, self.screen, toff, False, True)
self._refresh_lines() self._refresh_lines()
if (len(self._lines) > (self.height-2)): if (len(self._lines) > (self.height-2)):
@ -167,7 +167,7 @@ class Popup:
sb_pos = int((self.height-2)*perc_sc)+1 sb_pos = int((self.height-2)*perc_sc)+1
if (sb_pos == 1) and (self.lineoff != 0): if (sb_pos == 1) and (self.lineoff != 0):
sb_pos += 1 sb_pos += 1
self.parent.add_string(sb_pos, "{!red,black,bold!}#",self.screen,col=(self.width-1),pad=False,trim=False) self.parent.add_string(sb_pos, "{!red,black,bold!}#", self.screen, col=(self.width-1), pad=False, trim=False)
self.screen.redrawwin() self.screen.redrawwin()
self.screen.noutrefresh() self.screen.noutrefresh()
@ -178,9 +178,9 @@ class Popup:
def handle_read(self, c): def handle_read(self, c):
p_off = self.height - 3 p_off = self.height - 3
if c == curses.KEY_UP: if c == curses.KEY_UP:
self.lineoff = max(0,self.lineoff -1) self.lineoff = max(0, self.lineoff -1)
elif c == curses.KEY_PPAGE: elif c == curses.KEY_PPAGE:
self.lineoff = max(0,self.lineoff - p_off) self.lineoff = max(0, self.lineoff - p_off)
elif c == curses.KEY_HOME: elif c == curses.KEY_HOME:
self.lineoff = 0 self.lineoff = 0
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
@ -223,7 +223,7 @@ class SelectablePopup(Popup):
are added. are added.
""" """
def __init__(self,parent_mode,title, selection_callback, args=(), align=ALIGN.DEFAULT, immediate_action=False): def __init__(self,parent_mode,title, selection_callback, args=(), align=ALIGN.DEFAULT, immediate_action=False):
Popup.__init__(self,parent_mode, title, align=align) Popup.__init__(self, parent_mode, title, align=align)
self._selection_callback = selection_callback self._selection_callback = selection_callback
self._selection_args = args self._selection_args = args
self._selectable_lines = [] self._selectable_lines = []
@ -244,7 +244,7 @@ class SelectablePopup(Popup):
self._udxs[len(self._lines)+1] = udx self._udxs[len(self._lines)+1] = udx
c = string[udx].lower() c = string[udx].lower()
self._hotkeys[c] = len(self._lines) self._hotkeys[c] = len(self._lines)
Popup.add_line(self,string) Popup.add_line(self, string)
self._line_foregrounds.append(foreground) self._line_foregrounds.append(foreground)
if selectable: if selectable:
self._selectable_lines.append(len(self._lines)-1) self._selectable_lines.append(len(self._lines)-1)
@ -254,7 +254,7 @@ class SelectablePopup(Popup):
def _refresh_lines(self): def _refresh_lines(self):
crow = 1 crow = 1
for row,line in enumerate(self._lines): for row, line in enumerate(self._lines):
if (crow >= self.height-1): if (crow >= self.height-1):
break break
if (row < self.lineoff): if (row < self.lineoff):
@ -272,18 +272,18 @@ class SelectablePopup(Popup):
if udx >= 0: if udx >= 0:
ustr = "{!%s,black,underline!}"%fg ustr = "{!%s,black,underline!}"%fg
if udx == 0: if udx == 0:
self.parent.add_string(crow,"- %s%c%s%s"%(ustr,line[0],colorstr,line[1:]),self.screen,1,False,True) self.parent.add_string(crow, "- %s%c%s%s"%(ustr, line[0], colorstr, line[1:]), self.screen, 1, False, True)
elif udx > 0: elif udx > 0:
# well, this is a litte gross # well, this is a litte gross
self.parent.add_string(crow,"- %s%s%s%c%s%s"%(colorstr,line[:udx],ustr,line[udx],colorstr,line[udx+1:]),self.screen,1,False,True) self.parent.add_string(crow, "- %s%s%s%c%s%s"%(colorstr, line[:udx], ustr, line[udx], colorstr, line[udx+1:]), self.screen, 1, False, True)
else: else:
self.parent.add_string(crow,"- %s%s"%(colorstr,line),self.screen,1,False,True) self.parent.add_string(crow, "- %s%s"%(colorstr, line), self.screen, 1, False, True)
crow+=1 crow+=1
def current_selection(self): def current_selection(self):
"Returns a tuple of (selected index, selected data)" "Returns a tuple of (selected index, selected data)"
idx = self._selectable_lines.index(self._selected) idx = self._selectable_lines.index(self._selected)
return (idx,self._select_data[idx]) return (idx, self._select_data[idx])
def add_divider(self,color="white"): def add_divider(self,color="white"):
if not self.divider: if not self.divider:
@ -354,13 +354,13 @@ class MessagePopup(Popup):
def __init__(self, parent_mode, title, message, align=ALIGN.DEFAULT, width_req=0.5): def __init__(self, parent_mode, title, message, align=ALIGN.DEFAULT, width_req=0.5):
self.message = message self.message = message
#self.width= int(parent_mode.cols/2) #self.width= int(parent_mode.cols/2)
Popup.__init__(self,parent_mode, title, align=align, width_req=width_req) Popup.__init__(self, parent_mode, title, align=align, width_req=width_req)
lns = format_utils.wrap_string(self.message,self.width-2,3,True) lns = format_utils.wrap_string(self.message, self.width-2, 3, True)
self.height_req = min(len(lns)+2,int(parent_mode.rows*2/3)) self.height_req = min(len(lns)+2, int(parent_mode.rows*2/3))
self.handle_resize() self.handle_resize()
self._lines = lns self._lines = lns
def handle_resize(self): def handle_resize(self):
Popup.handle_resize(self) Popup.handle_resize(self)
self.clear() self.clear()
self._lines = format_utils.wrap_string(self.message,self.width-2,3,True) self._lines = format_utils.wrap_string(self.message, self.width-2, 3, True)

View file

@ -33,7 +33,7 @@
# #
# #
from deluge.ui.console.modes.input_popup import TextInput,SelectInput,CheckedInput,IntSpinInput,FloatSpinInput,CheckedPlusInput from deluge.ui.console.modes.input_popup import TextInput, SelectInput, CheckedInput, IntSpinInput, FloatSpinInput, CheckedPlusInput
import deluge.ui.console.modes.alltorrents import deluge.ui.console.modes.alltorrents
from deluge.common import is_ip from deluge.common import is_ip
@ -63,28 +63,28 @@ class Header(NoInput):
if self.space_above: if self.space_above:
row += 1 row += 1
rows += 1 rows += 1
self.parent.add_string(row,self.header,screen,offset-1,False,True) self.parent.add_string(row, self.header, screen, offset-1, False, True)
if self.space_below: rows += 1 if self.space_below: rows += 1
return rows return rows
class InfoField(NoInput): class InfoField(NoInput):
def __init__(self,parent,label,value,name): def __init__(self, parent, label, value, name):
self.parent = parent self.parent = parent
self.label = label self.label = label
self.value = value self.value = value
self.txt = "%s %s"%(label,value) self.txt = "%s %s"%(label, value)
self.name = name self.name = name
def render(self, screen, row, width, active, offset): def render(self, screen, row, width, active, offset):
self.parent.add_string(row,self.txt,screen,offset-1,False,True) self.parent.add_string(row, self.txt, screen, offset-1, False, True)
return 1 return 1
def set_value(self, v): def set_value(self, v):
self.value = v self.value = v
if type(v) == float: if type(v) == float:
self.txt = "%s %.2f"%(self.label,self.value) self.txt = "%s %.2f"%(self.label, self.value)
else: else:
self.txt = "%s %s"%(self.label,self.value) self.txt = "%s %s"%(self.label, self.value)
class BasePane: class BasePane:
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
@ -97,22 +97,22 @@ class BasePane:
# have we scrolled down in the list # have we scrolled down in the list
self.input_offset = 0 self.input_offset = 0
def move(self,r,c): def move(self, r, c):
self._cursor_row = r self._cursor_row = r
self._cursor_col = c self._cursor_col = c
def add_config_values(self,conf_dict): def add_config_values(self, conf_dict):
for ipt in self.inputs: for ipt in self.inputs:
if not isinstance(ipt,NoInput): if not isinstance(ipt, NoInput):
# gross, have to special case in/out ports since they are tuples # gross, have to special case in/out ports since they are tuples
if ipt.name in ("listen_ports_to", "listen_ports_from", "out_ports_from", "out_ports_to", if ipt.name in ("listen_ports_to", "listen_ports_from", "out_ports_from", "out_ports_to",
"i2p_port", "i2p_hostname", "proxy_type", "proxy_username", "proxy_hostnames", "i2p_port", "i2p_hostname", "proxy_type", "proxy_username", "proxy_hostnames",
"proxy_password", "proxy_hostname", "proxy_port", "proxy_peer_connections", "proxy_password", "proxy_hostname", "proxy_port", "proxy_peer_connections",
"listen_interface"): "listen_interface"):
if ipt.name == "listen_ports_to": if ipt.name == "listen_ports_to":
conf_dict["listen_ports"] = (self.infrom.get_value(),self.into.get_value()) conf_dict["listen_ports"] = (self.infrom.get_value(), self.into.get_value())
elif ipt.name == "out_ports_to": elif ipt.name == "out_ports_to":
conf_dict["outgoing_ports"] = (self.outfrom.get_value(),self.outto.get_value()) conf_dict["outgoing_ports"] = (self.outfrom.get_value(), self.outto.get_value())
elif ipt.name == "listen_interface": elif ipt.name == "listen_interface":
interface = ipt.get_value().strip() interface = ipt.get_value().strip()
if is_ip(interface) or not interface: if is_ip(interface) or not interface:
@ -139,18 +139,18 @@ class BasePane:
else: else:
conf_dict[ipt.name] = ipt.get_value() conf_dict[ipt.name] = ipt.get_value()
if hasattr(ipt,"get_child"): if hasattr(ipt, "get_child"):
c = ipt.get_child() c = ipt.get_child()
conf_dict[c.name] = c.get_value() conf_dict[c.name] = c.get_value()
def update_values(self, conf_dict): def update_values(self, conf_dict):
for ipt in self.inputs: for ipt in self.inputs:
if not isinstance(ipt,NoInput): if not isinstance(ipt, NoInput):
try: try:
ipt.set_value(conf_dict[ipt.name]) ipt.set_value(conf_dict[ipt.name])
except KeyError: # just ignore if it's not in dict except KeyError: # just ignore if it's not in dict
pass pass
if hasattr(ipt,"get_child"): if hasattr(ipt, "get_child"):
try: try:
c = ipt.get_child() c = ipt.get_child()
c.set_value(conf_dict[c.name]) c.set_value(conf_dict[c.name])
@ -160,13 +160,13 @@ class BasePane:
def render(self, mode, screen, width, active): def render(self, mode, screen, width, active):
self._cursor_row = -1 self._cursor_row = -1
if self.active_input < 0: if self.active_input < 0:
for i,ipt in enumerate(self.inputs): for i, ipt in enumerate(self.inputs):
if not isinstance(ipt,NoInput): if not isinstance(ipt, NoInput):
self.active_input = i self.active_input = i
break break
drew_act = not active drew_act = not active
crow = 1 crow = 1
for i,ipt in enumerate(self.inputs): for i, ipt in enumerate(self.inputs):
if ipt.depend_skip() or i<self.input_offset: if ipt.depend_skip() or i<self.input_offset:
if active and i==self.active_input: if active and i==self.active_input:
self.input_offset-=1 self.input_offset-=1
@ -175,7 +175,7 @@ class BasePane:
continue continue
act = active and i==self.active_input act = active and i==self.active_input
if act: drew_act = True if act: drew_act = True
crow += ipt.render(screen,crow,width, act, self.offset) crow += ipt.render(screen, crow, width, act, self.offset)
if crow >= (mode.prefs_height): if crow >= (mode.prefs_height):
break break
@ -186,19 +186,19 @@ class BasePane:
if active and self._cursor_row >= 0: if active and self._cursor_row >= 0:
curses.curs_set(2) curses.curs_set(2)
screen.move(self._cursor_row,self._cursor_col+self.offset-1) screen.move(self._cursor_row, self._cursor_col+self.offset-1)
else: else:
curses.curs_set(0) curses.curs_set(0)
return crow return crow
# just handles setting the active input # just handles setting the active input
def handle_read(self,c): def handle_read(self, c):
if not self.inputs: # no inputs added yet if not self.inputs: # no inputs added yet
return return
if c == curses.KEY_UP: if c == curses.KEY_UP:
nc = max(0,self.active_input-1) nc = max(0, self.active_input-1)
while isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip(): while isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip():
nc-=1 nc-=1
if nc <= 0: break if nc <= 0: break
@ -206,7 +206,7 @@ class BasePane:
self.active_input = nc self.active_input = nc
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
ilen = len(self.inputs) ilen = len(self.inputs)
nc = min(self.active_input+1,ilen-1) nc = min(self.active_input+1, ilen-1)
while isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip(): while isinstance(self.inputs[nc], NoInput) or self.inputs[nc].depend_skip():
nc+=1 nc+=1
if nc >= ilen: if nc >= ilen:
@ -225,50 +225,50 @@ class BasePane:
self.inputs.append(InfoField(self.parent, label, value, name)) self.inputs.append(InfoField(self.parent, label, value, name))
def add_text_input(self, name, msg, dflt_val): def add_text_input(self, name, msg, dflt_val):
self.inputs.append(TextInput(self.parent,self.move,self.width,msg,name,dflt_val,False)) self.inputs.append(TextInput(self.parent, self.move, self.width, msg, name, dflt_val, False))
def add_select_input(self, name, msg, opts, vals, selidx): def add_select_input(self, name, msg, opts, vals, selidx):
self.inputs.append(SelectInput(self.parent,msg,name,opts,vals,selidx)) self.inputs.append(SelectInput(self.parent, msg, name, opts, vals, selidx))
def add_checked_input(self, name, message, checked): def add_checked_input(self, name, message, checked):
self.inputs.append(CheckedInput(self.parent,message,name,checked)) self.inputs.append(CheckedInput(self.parent, message, name, checked))
def add_checkedplus_input(self, name, message, child, checked): def add_checkedplus_input(self, name, message, child, checked):
self.inputs.append(CheckedPlusInput(self.parent,message,name,child,checked)) self.inputs.append(CheckedPlusInput(self.parent, message, name, child, checked))
def add_int_spin_input(self, name, message, value, min_val, max_val): def add_int_spin_input(self, name, message, value, min_val, max_val):
self.inputs.append(IntSpinInput(self.parent,message,name,self.move,value,min_val,max_val)) self.inputs.append(IntSpinInput(self.parent, message, name, self.move, value, min_val, max_val))
def add_float_spin_input(self, name, message, value, inc_amt, precision, min_val, max_val): def add_float_spin_input(self, name, message, value, inc_amt, precision, min_val, max_val):
self.inputs.append(FloatSpinInput(self.parent,message,name,self.move,value,inc_amt,precision,min_val,max_val)) self.inputs.append(FloatSpinInput(self.parent, message, name, self.move, value, inc_amt, precision, min_val, max_val))
class InterfacePane(BasePane): class InterfacePane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("General options", False) self.add_header("General options", False)
self.add_checked_input("ring_bell","Ring system bell when a download finishes",parent.console_config["ring_bell"]) self.add_checked_input("ring_bell", "Ring system bell when a download finishes", parent.console_config["ring_bell"])
self.add_header("New Console UI", True) self.add_header("New Console UI", True)
self.add_checked_input("separate_complete","List complete torrents after incomplete regardless of sorting order",parent.console_config["separate_complete"]) self.add_checked_input("separate_complete", "List complete torrents after incomplete regardless of sorting order", parent.console_config["separate_complete"])
self.add_checked_input("move_selection","Move selection when moving torrents in the queue",parent.console_config["move_selection"]) self.add_checked_input("move_selection", "Move selection when moving torrents in the queue", parent.console_config["move_selection"])
self.add_header("Legacy Mode", True) self.add_header("Legacy Mode", True)
self.add_checked_input("ignore_duplicate_lines","Do not store duplicate input in history",parent.console_config["ignore_duplicate_lines"]) self.add_checked_input("ignore_duplicate_lines", "Do not store duplicate input in history", parent.console_config["ignore_duplicate_lines"])
self.add_checked_input("save_legacy_history","Store and load command line history in Legacy mode",parent.console_config["save_legacy_history"]) self.add_checked_input("save_legacy_history", "Store and load command line history in Legacy mode", parent.console_config["save_legacy_history"])
self.add_header("", False) self.add_header("", False)
self.add_checked_input("third_tab_lists_all","Third tab lists all remaining torrents in legacy mode",parent.console_config["third_tab_lists_all"]) self.add_checked_input("third_tab_lists_all", "Third tab lists all remaining torrents in legacy mode", parent.console_config["third_tab_lists_all"])
self.add_int_spin_input("torrents_per_tab_press","Torrents per tab press",parent.console_config["torrents_per_tab_press"], 5, 100) self.add_int_spin_input("torrents_per_tab_press", "Torrents per tab press", parent.console_config["torrents_per_tab_press"], 5, 100)
class ColumnsPane(BasePane): class ColumnsPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("Columns To Display", True) self.add_header("Columns To Display", True)
default_prefs = deluge.ui.console.modes.alltorrents.DEFAULT_PREFS default_prefs = deluge.ui.console.modes.alltorrents.DEFAULT_PREFS
@ -282,29 +282,29 @@ class ColumnsPane(BasePane):
self.add_checked_input(pn, self.add_checked_input(pn,
deluge.ui.console.modes.alltorrents.prefs_to_names[cpn], deluge.ui.console.modes.alltorrents.prefs_to_names[cpn],
parent.console_config[pn]) parent.console_config[pn])
self.add_header("Column Widths (-1 = expand)",True) self.add_header("Column Widths (-1 = expand)", True)
for cpn in deluge.ui.console.modes.alltorrents.column_pref_names: for cpn in deluge.ui.console.modes.alltorrents.column_pref_names:
pn = "%s_width"%cpn pn = "%s_width"%cpn
if pn not in default_prefs: if pn not in default_prefs:
continue continue
self.add_int_spin_input(pn, self.add_int_spin_input(pn,
deluge.ui.console.modes.alltorrents.prefs_to_names[cpn], deluge.ui.console.modes.alltorrents.prefs_to_names[cpn],
parent.console_config[pn],-1,100) parent.console_config[pn], -1, 100)
class DownloadsPane(BasePane): class DownloadsPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("Folders") self.add_header("Folders")
self.add_text_input("download_location","Download To:",parent.core_config["download_location"]) self.add_text_input("download_location", "Download To:", parent.core_config["download_location"])
cmptxt = TextInput(self.parent,self.move,self.width,None,"move_completed_path",parent.core_config["move_completed_path"],False) cmptxt = TextInput(self.parent, self.move, self.width, None, "move_completed_path", parent.core_config["move_completed_path"], False)
self.add_checkedplus_input("move_completed","Move completed to:",cmptxt,parent.core_config["move_completed"]) self.add_checkedplus_input("move_completed", "Move completed to:", cmptxt, parent.core_config["move_completed"])
copytxt = TextInput(self.parent,self.move,self.width,None,"torrentfiles_location",parent.core_config["torrentfiles_location"],False) copytxt = TextInput(self.parent, self.move, self.width, None, "torrentfiles_location", parent.core_config["torrentfiles_location"], False)
self.add_checkedplus_input("copy_torrent_file","Copy of .torrent files to:",copytxt,parent.core_config["copy_torrent_file"]) self.add_checkedplus_input("copy_torrent_file", "Copy of .torrent files to:", copytxt, parent.core_config["copy_torrent_file"])
self.add_checked_input("del_copy_torrent_file","Delete copy of torrent file on remove",parent.core_config["del_copy_torrent_file"]) self.add_checked_input("del_copy_torrent_file", "Delete copy of torrent file on remove", parent.core_config["del_copy_torrent_file"])
self.add_header("Options",True) self.add_header("Options", True)
self.add_checked_input("prioritize_first_last_pieces", "Prioritize first and last pieces of torrent", self.add_checked_input("prioritize_first_last_pieces", "Prioritize first and last pieces of torrent",
parent.core_config["prioritize_first_last_pieces"]) parent.core_config["prioritize_first_last_pieces"])
self.add_checked_input("sequential_download", "", self.add_checked_input("sequential_download", "",
@ -316,108 +316,108 @@ class DownloadsPane(BasePane):
class NetworkPane(BasePane): class NetworkPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("Incomming Ports") self.add_header("Incomming Ports")
inrand = CheckedInput(parent,"Use Random Ports Active Port: %d"%parent.active_port,"random_port",parent.core_config["random_port"]) inrand = CheckedInput(parent, "Use Random Ports Active Port: %d"%parent.active_port, "random_port", parent.core_config["random_port"])
self.inputs.append(inrand) self.inputs.append(inrand)
listen_ports = parent.core_config["listen_ports"] listen_ports = parent.core_config["listen_ports"]
self.infrom = IntSpinInput(self.parent," From:","listen_ports_from",self.move,listen_ports[0],0,65535) self.infrom = IntSpinInput(self.parent, " From:", "listen_ports_from", self.move, listen_ports[0], 0, 65535)
self.infrom.set_depend(inrand,True) self.infrom.set_depend(inrand, True)
self.into = IntSpinInput(self.parent," To: ","listen_ports_to",self.move,listen_ports[1],0,65535) self.into = IntSpinInput(self.parent, " To: ", "listen_ports_to", self.move, listen_ports[1], 0, 65535)
self.into.set_depend(inrand,True) self.into.set_depend(inrand, True)
self.inputs.append(self.infrom) self.inputs.append(self.infrom)
self.inputs.append(self.into) self.inputs.append(self.into)
self.add_header("Outgoing Ports",True) self.add_header("Outgoing Ports", True)
outrand = CheckedInput(parent,"Use Random Ports","random_outgoing_ports",parent.core_config["random_outgoing_ports"]) outrand = CheckedInput(parent, "Use Random Ports", "random_outgoing_ports", parent.core_config["random_outgoing_ports"])
self.inputs.append(outrand) self.inputs.append(outrand)
out_ports = parent.core_config["outgoing_ports"] out_ports = parent.core_config["outgoing_ports"]
self.outfrom = IntSpinInput(self.parent," From:","out_ports_from",self.move,out_ports[0],0,65535) self.outfrom = IntSpinInput(self.parent, " From:", "out_ports_from", self.move, out_ports[0], 0, 65535)
self.outfrom.set_depend(outrand,True) self.outfrom.set_depend(outrand, True)
self.outto = IntSpinInput(self.parent," To: ","out_ports_to",self.move,out_ports[1],0,65535) self.outto = IntSpinInput(self.parent, " To: ", "out_ports_to", self.move, out_ports[1], 0, 65535)
self.outto.set_depend(outrand,True) self.outto.set_depend(outrand, True)
self.inputs.append(self.outfrom) self.inputs.append(self.outfrom)
self.inputs.append(self.outto) self.inputs.append(self.outto)
self.add_header("Interface",True) self.add_header("Interface", True)
self.add_text_input("listen_interface","IP address of the interface to listen on (leave empty for default):",parent.core_config["listen_interface"]) self.add_text_input("listen_interface", "IP address of the interface to listen on (leave empty for default):", parent.core_config["listen_interface"])
self.add_header("TOS",True) self.add_header("TOS", True)
self.add_text_input("peer_tos","Peer TOS Byte:",parent.core_config["peer_tos"]) self.add_text_input("peer_tos", "Peer TOS Byte:", parent.core_config["peer_tos"])
self.add_header("Network Extras") self.add_header("Network Extras")
self.add_checked_input("upnp","UPnP",parent.core_config["upnp"]) self.add_checked_input("upnp", "UPnP", parent.core_config["upnp"])
self.add_checked_input("natpmp","NAT-PMP",parent.core_config["natpmp"]) self.add_checked_input("natpmp", "NAT-PMP", parent.core_config["natpmp"])
self.add_checked_input("utpex","Peer Exchange",parent.core_config["utpex"]) self.add_checked_input("utpex", "Peer Exchange", parent.core_config["utpex"])
self.add_checked_input("lt_tex","Tracker Exchange",parent.core_config["lt_tex"]) self.add_checked_input("lt_tex", "Tracker Exchange", parent.core_config["lt_tex"])
self.add_checked_input("lsd","LSD",parent.core_config["lsd"]) self.add_checked_input("lsd", "LSD", parent.core_config["lsd"])
self.add_checked_input("dht","DHT",parent.core_config["dht"]) self.add_checked_input("dht", "DHT", parent.core_config["dht"])
self.add_header("Encryption",True) self.add_header("Encryption", True)
self.add_select_input("enc_in_policy","Inbound:",["Forced","Enabled","Disabled"],[0,1,2],parent.core_config["enc_in_policy"]) self.add_select_input("enc_in_policy", "Inbound:", ["Forced", "Enabled", "Disabled"], [0, 1, 2], parent.core_config["enc_in_policy"])
self.add_select_input("enc_out_policy","Outbound:",["Forced","Enabled","Disabled"],[0,1,2],parent.core_config["enc_out_policy"]) self.add_select_input("enc_out_policy", "Outbound:", ["Forced", "Enabled", "Disabled"], [0, 1, 2], parent.core_config["enc_out_policy"])
self.add_select_input("enc_level","Level:",["Handshake","Full Stream","Either"],[0,1,2],parent.core_config["enc_level"]) self.add_select_input("enc_level", "Level:", ["Handshake", "Full Stream", "Either"], [0, 1, 2], parent.core_config["enc_level"])
class BandwidthPane(BasePane): class BandwidthPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("Global Bandwidth Usage") self.add_header("Global Bandwidth Usage")
self.add_int_spin_input("max_connections_global","Maximum Connections:",parent.core_config["max_connections_global"],-1,9000) self.add_int_spin_input("max_connections_global", "Maximum Connections:", parent.core_config["max_connections_global"], -1, 9000)
self.add_int_spin_input("max_upload_slots_global","Maximum Upload Slots:",parent.core_config["max_upload_slots_global"],-1,9000) self.add_int_spin_input("max_upload_slots_global", "Maximum Upload Slots:", parent.core_config["max_upload_slots_global"], -1, 9000)
self.add_float_spin_input("max_download_speed","Maximum Download Speed (KiB/s):",parent.core_config["max_download_speed"],1.0,1,-1.0,60000.0) self.add_float_spin_input("max_download_speed", "Maximum Download Speed (KiB/s):", parent.core_config["max_download_speed"], 1.0, 1, -1.0, 60000.0)
self.add_float_spin_input("max_upload_speed","Maximum Upload Speed (KiB/s):",parent.core_config["max_upload_speed"],1.0,1,-1.0,60000.0) self.add_float_spin_input("max_upload_speed", "Maximum Upload Speed (KiB/s):", parent.core_config["max_upload_speed"], 1.0, 1, -1.0, 60000.0)
self.add_int_spin_input("max_half_open_connections","Maximum Half-Open Connections:",parent.core_config["max_half_open_connections"],-1,9999) self.add_int_spin_input("max_half_open_connections", "Maximum Half-Open Connections:", parent.core_config["max_half_open_connections"], -1, 9999)
self.add_int_spin_input("max_connections_per_second","Maximum Connection Attempts per Second:",parent.core_config["max_connections_per_second"],-1,9999) self.add_int_spin_input("max_connections_per_second", "Maximum Connection Attempts per Second:", parent.core_config["max_connections_per_second"], -1, 9999)
self.add_checked_input("ignore_limits_on_local_network","Ignore limits on local network",parent.core_config["ignore_limits_on_local_network"]) self.add_checked_input("ignore_limits_on_local_network", "Ignore limits on local network", parent.core_config["ignore_limits_on_local_network"])
self.add_checked_input("rate_limit_ip_overhead","Rate Limit IP Overhead",parent.core_config["rate_limit_ip_overhead"]) self.add_checked_input("rate_limit_ip_overhead", "Rate Limit IP Overhead", parent.core_config["rate_limit_ip_overhead"])
self.add_header("Per Torrent Bandwidth Usage",True) self.add_header("Per Torrent Bandwidth Usage", True)
self.add_int_spin_input("max_connections_per_torrent","Maximum Connections:",parent.core_config["max_connections_per_torrent"],-1,9000) self.add_int_spin_input("max_connections_per_torrent", "Maximum Connections:", parent.core_config["max_connections_per_torrent"], -1, 9000)
self.add_int_spin_input("max_upload_slots_per_torrent","Maximum Upload Slots:",parent.core_config["max_upload_slots_per_torrent"],-1,9000) self.add_int_spin_input("max_upload_slots_per_torrent", "Maximum Upload Slots:", parent.core_config["max_upload_slots_per_torrent"], -1, 9000)
self.add_float_spin_input("max_download_speed_per_torrent","Maximum Download Speed (KiB/s):",parent.core_config["max_download_speed_per_torrent"],1.0,1,-1.0,60000.0) self.add_float_spin_input("max_download_speed_per_torrent", "Maximum Download Speed (KiB/s):", parent.core_config["max_download_speed_per_torrent"], 1.0, 1, -1.0, 60000.0)
self.add_float_spin_input("max_upload_speed_per_torrent","Maximum Upload Speed (KiB/s):",parent.core_config["max_upload_speed_per_torrent"],1.0,1,-1.0,60000.0) self.add_float_spin_input("max_upload_speed_per_torrent", "Maximum Upload Speed (KiB/s):", parent.core_config["max_upload_speed_per_torrent"], 1.0, 1, -1.0, 60000.0)
class OtherPane(BasePane): class OtherPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("System Information") self.add_header("System Information")
self.add_info_field(" Help us improve Deluge by sending us your","","") self.add_info_field(" Help us improve Deluge by sending us your", "", "")
self.add_info_field(" Python version, PyGTK version, OS and processor","","") self.add_info_field(" Python version, PyGTK version, OS and processor", "", "")
self.add_info_field(" types. Absolutely no other information is sent.","","") self.add_info_field(" types. Absolutely no other information is sent.", "", "")
self.add_checked_input("send_info","Yes, please send anonymous statistics.",parent.core_config["send_info"]) self.add_checked_input("send_info", "Yes, please send anonymous statistics.", parent.core_config["send_info"])
self.add_header("GeoIP Database",True) self.add_header("GeoIP Database", True)
self.add_text_input("geoip_db_location","Location:",parent.core_config["geoip_db_location"]) self.add_text_input("geoip_db_location", "Location:", parent.core_config["geoip_db_location"])
class DaemonPane(BasePane): class DaemonPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("Port") self.add_header("Port")
self.add_int_spin_input("daemon_port","Daemon Port:",parent.core_config["daemon_port"],0,65535) self.add_int_spin_input("daemon_port", "Daemon Port:", parent.core_config["daemon_port"], 0, 65535)
self.add_header("Connections",True) self.add_header("Connections", True)
self.add_checked_input("allow_remote","Allow remote connections",parent.core_config["allow_remote"]) self.add_checked_input("allow_remote", "Allow remote connections", parent.core_config["allow_remote"])
self.add_header("Other",True) self.add_header("Other", True)
self.add_checked_input("new_release_check","Periodically check the website for new releases",parent.core_config["new_release_check"]) self.add_checked_input("new_release_check", "Periodically check the website for new releases", parent.core_config["new_release_check"])
class QueuePane(BasePane): class QueuePane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("General") self.add_header("General")
self.add_checked_input("queue_new_to_top","Queue new torrents to top",parent.core_config["queue_new_to_top"]) self.add_checked_input("queue_new_to_top", "Queue new torrents to top", parent.core_config["queue_new_to_top"])
self.add_header("Active Torrents",True) self.add_header("Active Torrents", True)
self.add_int_spin_input("max_active_limit","Total active:",parent.core_config["max_active_limit"],-1,9999) self.add_int_spin_input("max_active_limit", "Total active:", parent.core_config["max_active_limit"], -1, 9999)
self.add_int_spin_input("max_active_downloading","Total active downloading:",parent.core_config["max_active_downloading"],-1,9999) self.add_int_spin_input("max_active_downloading", "Total active downloading:", parent.core_config["max_active_downloading"], -1, 9999)
self.add_int_spin_input("max_active_seeding","Total active seeding:",parent.core_config["max_active_seeding"],-1,9999) self.add_int_spin_input("max_active_seeding", "Total active seeding:", parent.core_config["max_active_seeding"], -1, 9999)
self.add_checked_input("dont_count_slow_torrents","Do not count slow torrents",parent.core_config["dont_count_slow_torrents"]) self.add_checked_input("dont_count_slow_torrents", "Do not count slow torrents", parent.core_config["dont_count_slow_torrents"])
self.add_checked_input("auto_manage_prefer_seeds","Prefer Seeding over Downloading",parent.core_config["auto_manage_prefer_seeds"]) self.add_checked_input("auto_manage_prefer_seeds", "Prefer Seeding over Downloading", parent.core_config["auto_manage_prefer_seeds"])
self.add_header("Seeding",True) self.add_header("Seeding", True)
self.add_float_spin_input("share_ratio_limit","Share Ratio Limit:",parent.core_config["share_ratio_limit"],1.0,2,-1.0,100.0) self.add_float_spin_input("share_ratio_limit", "Share Ratio Limit:", parent.core_config["share_ratio_limit"], 1.0, 2, -1.0, 100.0)
self.add_float_spin_input("seed_time_ratio_limit","Share Time Ratio:",parent.core_config["seed_time_ratio_limit"],1.0,2,-1.0,100.0) self.add_float_spin_input("seed_time_ratio_limit", "Share Time Ratio:", parent.core_config["seed_time_ratio_limit"], 1.0, 2, -1.0, 100.0)
self.add_int_spin_input("seed_time_limit","Seed time (m):",parent.core_config["seed_time_limit"],-1,10000) self.add_int_spin_input("seed_time_limit", "Seed time (m):", parent.core_config["seed_time_limit"], -1, 10000)
seedratio = FloatSpinInput(self.parent,"","stop_seed_ratio",self.move,parent.core_config["stop_seed_ratio"],0.1,2,0.5,100.0) seedratio = FloatSpinInput(self.parent, "", "stop_seed_ratio", self.move, parent.core_config["stop_seed_ratio"], 0.1, 2, 0.5, 100.0)
self.add_checkedplus_input("stop_seed_at_ratio","Stop seeding when share ratio reaches:",seedratio,parent.core_config["stop_seed_at_ratio"]) self.add_checkedplus_input("stop_seed_at_ratio", "Stop seeding when share ratio reaches:", seedratio, parent.core_config["stop_seed_at_ratio"])
self.add_checked_input("remove_seed_at_ratio","Remove torrent when share ratio reached",parent.core_config["remove_seed_at_ratio"]) self.add_checked_input("remove_seed_at_ratio", "Remove torrent when share ratio reached", parent.core_config["remove_seed_at_ratio"])
class ProxyPane(BasePane): class ProxyPane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
@ -425,7 +425,7 @@ class ProxyPane(BasePane):
self.add_header("Proxy Settings") self.add_header("Proxy Settings")
self.add_header("Proxy", True) self.add_header("Proxy", True)
proxy = parent.core_config["proxy"] proxy = parent.core_config["proxy"]
self.add_int_spin_input("proxy_type","Type:", proxy["type"],0,5) self.add_int_spin_input("proxy_type", "Type:", proxy["type"], 0, 5)
self.add_info_field(" 0: None 1: Socks4 2: Socks5", "", "") self.add_info_field(" 0: None 1: Socks4 2: Socks5", "", "")
self.add_info_field(" 3: Socks5 Auth 4: HTTP 5: HTTP Auth", "", "") self.add_info_field(" 3: Socks5 Auth 4: HTTP 5: HTTP Auth", "", "")
self.add_text_input("proxy_username", "Username:", proxy["username"]) self.add_text_input("proxy_username", "Username:", proxy["username"])
@ -435,7 +435,7 @@ class ProxyPane(BasePane):
self.add_checked_input("proxy_hostnames", "Proxy hostnames", proxy["proxy_hostnames"]) self.add_checked_input("proxy_hostnames", "Proxy hostnames", proxy["proxy_hostnames"])
self.add_checked_input("proxy_peer_connections", "Proxy peer connections", proxy["proxy_peer_connections"]) self.add_checked_input("proxy_peer_connections", "Proxy peer connections", proxy["proxy_peer_connections"])
self.add_header("I2P Proxy",True) self.add_header("I2P Proxy", True)
i2p_proxy = parent.core_config["i2p_proxy"] i2p_proxy = parent.core_config["i2p_proxy"]
self.add_text_input("i2p_hostname", "Hostname:", i2p_proxy["hostname"]) self.add_text_input("i2p_hostname", "Hostname:", i2p_proxy["hostname"])
self.add_int_spin_input("i2p_port", "Port:", i2p_proxy["port"], 0, 65535) self.add_int_spin_input("i2p_port", "Port:", i2p_proxy["port"], 0, 65535)
@ -444,27 +444,27 @@ class ProxyPane(BasePane):
class CachePane(BasePane): class CachePane(BasePane):
def __init__(self, offset, parent, width): def __init__(self, offset, parent, width):
BasePane.__init__(self,offset,parent,width) BasePane.__init__(self, offset, parent, width)
self.add_header("Settings") self.add_header("Settings")
self.add_int_spin_input("cache_size","Cache Size (16 KiB blocks):",parent.core_config["cache_size"],0,99999) self.add_int_spin_input("cache_size", "Cache Size (16 KiB blocks):", parent.core_config["cache_size"], 0, 99999)
self.add_int_spin_input("cache_expiry","Cache Expiry (seconds):",parent.core_config["cache_expiry"],1,32000) self.add_int_spin_input("cache_expiry", "Cache Expiry (seconds):", parent.core_config["cache_expiry"], 1, 32000)
self.add_header("Status (press 'r' to refresh status)",True) self.add_header("Status (press 'r' to refresh status)", True)
self.add_header(" Write") self.add_header(" Write")
self.add_info_field(" Blocks Written:",self.parent.status["blocks_written"],"blocks_written") self.add_info_field(" Blocks Written:", self.parent.status["blocks_written"], "blocks_written")
self.add_info_field(" Writes:",self.parent.status["writes"],"writes") self.add_info_field(" Writes:", self.parent.status["writes"], "writes")
self.add_info_field(" Write Cache Hit Ratio:","%.2f"%self.parent.status["write_hit_ratio"],"write_hit_ratio") self.add_info_field(" Write Cache Hit Ratio:", "%.2f"%self.parent.status["write_hit_ratio"], "write_hit_ratio")
self.add_header(" Read") self.add_header(" Read")
self.add_info_field(" Blocks Read:",self.parent.status["blocks_read"],"blocks_read") self.add_info_field(" Blocks Read:", self.parent.status["blocks_read"], "blocks_read")
self.add_info_field(" Blocks Read hit:",self.parent.status["blocks_read_hit"],"blocks_read_hit") self.add_info_field(" Blocks Read hit:", self.parent.status["blocks_read_hit"], "blocks_read_hit")
self.add_info_field(" Reads:",self.parent.status["reads"],"reads") self.add_info_field(" Reads:", self.parent.status["reads"], "reads")
self.add_info_field(" Read Cache Hit Ratio:","%.2f"%self.parent.status["read_hit_ratio"],"read_hit_ratio") self.add_info_field(" Read Cache Hit Ratio:", "%.2f"%self.parent.status["read_hit_ratio"], "read_hit_ratio")
self.add_header(" Size") self.add_header(" Size")
self.add_info_field(" Cache Size:",self.parent.status["cache_size"],"cache_size") self.add_info_field(" Cache Size:", self.parent.status["cache_size"], "cache_size")
self.add_info_field(" Read Cache Size:",self.parent.status["read_cache_size"],"read_cache_size") self.add_info_field(" Read Cache Size:", self.parent.status["read_cache_size"], "read_cache_size")
def update_cache_status(self, status): def update_cache_status(self, status):
for ipt in self.inputs: for ipt in self.inputs:
if isinstance(ipt,InfoField): if isinstance(ipt, InfoField):
try: try:
ipt.set_value(status[ipt.name]) ipt.set_value(status[ipt.name])
except KeyError: except KeyError:

View file

@ -130,7 +130,7 @@ class Preferences(BaseMode):
# create the panes # create the panes
self.__calc_sizes() self.__calc_sizes()
self.action_input = SelectInput(self,None,None,["Cancel","Apply","OK"],[0,1,2],0) self.action_input = SelectInput(self, None, None, ["Cancel", "Apply", "OK"], [0, 1, 2], 0)
self.refresh() self.refresh()
def __calc_sizes(self): def __calc_sizes(self):
@ -151,22 +151,22 @@ class Preferences(BaseMode):
] ]
def __draw_catetories(self): def __draw_catetories(self):
for i,category in enumerate(self.categories): for i, category in enumerate(self.categories):
if i == self.cur_cat and self.active_zone == ZONE.CATEGORIES: if i == self.cur_cat and self.active_zone == ZONE.CATEGORIES:
self.add_string(i+1,"- {!black,white,bold!}%s"%category,pad=False) self.add_string(i+1, "- {!black,white,bold!}%s"%category, pad=False)
elif i == self.cur_cat: elif i == self.cur_cat:
self.add_string(i+1,"- {!black,white!}%s"%category,pad=False) self.add_string(i+1, "- {!black,white!}%s"%category, pad=False)
else: else:
self.add_string(i+1,"- %s"%category) self.add_string(i+1, "- %s"%category)
self.stdscr.vline(1,self.div_off,'|',self.rows-2) self.stdscr.vline(1, self.div_off, '|', self.rows-2)
def __draw_preferences(self): def __draw_preferences(self):
self.panes[self.cur_cat].render(self,self.stdscr, self.prefs_width, self.active_zone == ZONE.PREFRENCES) self.panes[self.cur_cat].render(self, self.stdscr, self.prefs_width, self.active_zone == ZONE.PREFRENCES)
def __draw_actions(self): def __draw_actions(self):
selected = self.active_zone == ZONE.ACTIONS selected = self.active_zone == ZONE.ACTIONS
self.stdscr.hline(self.rows-3,self.div_off+1,"_",self.cols) self.stdscr.hline(self.rows-3, self.div_off+1, "_", self.cols)
self.action_input.render(self.stdscr,self.rows-2,self.cols,selected,self.cols-22) self.action_input.render(self.stdscr, self.rows-2, self.cols, selected, self.cols-22)
def on_resize(self, *args): def on_resize(self, *args):
BaseMode.on_resize_norefresh(self, *args) BaseMode.on_resize_norefresh(self, *args)
@ -180,13 +180,13 @@ class Preferences(BaseMode):
def refresh(self): def refresh(self):
if self.popup == None and self.messages: if self.popup == None and self.messages:
title,msg = self.messages.popleft() title, msg = self.messages.popleft()
self.popup = MessagePopup(self,title,msg) self.popup = MessagePopup(self, title, msg)
self.stdscr.erase() self.stdscr.erase()
self.add_string(0,self.statusbars.topbar) self.add_string(0, self.statusbars.topbar)
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10)) hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10))
self.add_string(self.rows - 1, "%s%s"%(self.statusbars.bottombar,hstr)) self.add_string(self.rows - 1, "%s%s"%(self.statusbars.bottombar, hstr))
self.__draw_catetories() self.__draw_catetories()
self.__draw_actions() self.__draw_actions()
@ -207,9 +207,9 @@ class Preferences(BaseMode):
def __category_read(self, c): def __category_read(self, c):
# Navigate prefs # Navigate prefs
if c == curses.KEY_UP: if c == curses.KEY_UP:
self.cur_cat = max(0,self.cur_cat-1) self.cur_cat = max(0, self.cur_cat-1)
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
self.cur_cat = min(len(self.categories)-1,self.cur_cat+1) self.cur_cat = min(len(self.categories)-1, self.cur_cat+1)
def __prefs_read(self, c): def __prefs_read(self, c):
self.panes[self.cur_cat].handle_read(c) self.panes[self.cur_cat].handle_read(c)
@ -217,7 +217,7 @@ class Preferences(BaseMode):
def __apply_prefs(self): def __apply_prefs(self):
new_core_config = {} new_core_config = {}
for pane in self.panes: for pane in self.panes:
if not isinstance(pane,InterfacePane) and not isinstance(pane, ColumnsPane): if not isinstance(pane, InterfacePane) and not isinstance(pane, ColumnsPane):
pane.add_config_values(new_core_config) pane.add_config_values(new_core_config)
# Apply Core Prefs # Apply Core Prefs
if client.connected(): if client.connected():
@ -241,7 +241,7 @@ class Preferences(BaseMode):
for pane in self.panes: for pane in self.panes:
# could just access panes by index, but that would break if panes # could just access panes by index, but that would break if panes
# are ever reordered, so do it the slightly slower but safer way # are ever reordered, so do it the slightly slower but safer way
if isinstance(pane,InterfacePane) or isinstance(pane, ColumnsPane): if isinstance(pane, InterfacePane) or isinstance(pane, ColumnsPane):
pane.add_config_values(new_console_config) pane.add_config_values(new_console_config)
for key in new_console_config.keys(): for key in new_console_config.keys():
# The values do not match so this needs to be updated # The values do not match so this needs to be updated
@ -254,7 +254,7 @@ class Preferences(BaseMode):
self.parent_mode.update_config() self.parent_mode.update_config()
def __update_preferences(self,core_config): def __update_preferences(self, core_config):
self.core_config = core_config self.core_config = core_config
for pane in self.panes: for pane in self.panes:
pane.update_values(core_config) pane.update_values(core_config)
@ -298,7 +298,7 @@ class Preferences(BaseMode):
reactor.stop() reactor.stop()
return return
elif chr(c) == 'h': elif chr(c) == 'h':
self.popup = Popup(self,"Preferences Help") self.popup = Popup(self, "Preferences Help")
for l in HELP_LINES: for l in HELP_LINES:
self.popup.add_line(l) self.popup.add_line(l)
@ -313,7 +313,7 @@ class Preferences(BaseMode):
if self.active_zone < ZONE.CATEGORIES: if self.active_zone < ZONE.CATEGORIES:
self.active_zone = ZONE.ACTIONS self.active_zone = ZONE.ACTIONS
elif c == 114 and isinstance(self.panes[self.cur_cat],CachePane): elif c == 114 and isinstance(self.panes[self.cur_cat], CachePane):
client.core.get_cache_status().addCallback(self.panes[self.cur_cat].update_cache_status) client.core.get_cache_status().addCallback(self.panes[self.cur_cat].update_cache_status)
else: else:

View file

@ -91,21 +91,21 @@ class ACTION:
QUEUE_BOTTOM=14 QUEUE_BOTTOM=14
TORRENT_OPTIONS=15 TORRENT_OPTIONS=15
def action_error(error,mode): def action_error(error, mode):
rerr = error.value rerr = error.value
mode.report_message("An Error Occurred","%s got error %s: %s"%(rerr.method,rerr.exception_type,rerr.exception_msg)) mode.report_message("An Error Occurred", "%s got error %s: %s"%(rerr.method, rerr.exception_type, rerr.exception_msg))
mode.refresh() mode.refresh()
def torrent_action(idx, data, mode, ids): def torrent_action(idx, data, mode, ids):
if ids: if ids:
if data==ACTION.PAUSE: if data==ACTION.PAUSE:
log.debug("Pausing torrents: %s",ids) log.debug("Pausing torrents: %s", ids)
client.core.pause_torrent(ids).addErrback(action_error,mode) client.core.pause_torrent(ids).addErrback(action_error, mode)
elif data==ACTION.RESUME: elif data==ACTION.RESUME:
log.debug("Resuming torrents: %s", ids) log.debug("Resuming torrents: %s", ids)
client.core.resume_torrent(ids).addErrback(action_error,mode) client.core.resume_torrent(ids).addErrback(action_error, mode)
elif data==ACTION.QUEUE: elif data==ACTION.QUEUE:
def do_queue(idx,qact,mode,ids): def do_queue(idx, qact, mode, ids):
def move_selection(r): def move_selection(r):
if mode.config["move_selection"]: if mode.config["move_selection"]:
queue_length = 0 queue_length = 0
@ -153,11 +153,11 @@ def torrent_action(idx, data, mode, ids):
if len(ids) == 1: if len(ids) == 1:
mode.clear_marks() mode.clear_marks()
return True return True
popup = SelectablePopup(mode,"Queue Action", do_queue, (mode, ids)) popup = SelectablePopup(mode, "Queue Action", do_queue, (mode, ids))
popup.add_line("_Top",data=ACTION.QUEUE_TOP) popup.add_line("_Top", data=ACTION.QUEUE_TOP)
popup.add_line("_Up",data=ACTION.QUEUE_UP) popup.add_line("_Up", data=ACTION.QUEUE_UP)
popup.add_line("_Down",data=ACTION.QUEUE_DOWN) popup.add_line("_Down", data=ACTION.QUEUE_DOWN)
popup.add_line("_Bottom",data=ACTION.QUEUE_BOTTOM) popup.add_line("_Bottom", data=ACTION.QUEUE_BOTTOM)
mode.set_popup(popup) mode.set_popup(popup)
return False return False
elif data==ACTION.REMOVE: elif data==ACTION.REMOVE:
@ -168,7 +168,7 @@ def torrent_action(idx, data, mode, ids):
wd = data["remove_files"] wd = data["remove_files"]
for tid in ids: for tid in ids:
log.debug("Removing torrent: %s, %d", tid, wd) log.debug("Removing torrent: %s, %d", tid, wd)
client.core.remove_torrent(tid,wd).addErrback(action_error,mode) client.core.remove_torrent(tid, wd).addErrback(action_error, mode)
rem_msg = "" rem_msg = ""
@ -209,23 +209,23 @@ def torrent_action(idx, data, mode, ids):
def do_move(res): def do_move(res):
import os.path import os.path
if os.path.exists(res["path"]) and not os.path.isdir(res["path"]): if os.path.exists(res["path"]) and not os.path.isdir(res["path"]):
mode.report_message("Cannot Move Download Folder","{!error!}%s exists and is not a directory"%res["path"]) mode.report_message("Cannot Move Download Folder", "{!error!}%s exists and is not a directory"%res["path"])
else: else:
log.debug("Moving %s to: %s",ids,res["path"]) log.debug("Moving %s to: %s", ids, res["path"])
client.core.move_storage(ids,res["path"]).addErrback(action_error,mode) client.core.move_storage(ids, res["path"]).addErrback(action_error, mode)
if len(ids) == 1: if len(ids) == 1:
mode.clear_marks() mode.clear_marks()
return True return True
popup = InputPopup(mode,"Move Download Folder (Esc to cancel)",close_cb=do_move) popup = InputPopup(mode, "Move Download Folder (Esc to cancel)", close_cb=do_move)
popup.add_text_input("Enter path to move to:","path") popup.add_text_input("Enter path to move to:", "path")
mode.set_popup(popup) mode.set_popup(popup)
return False return False
elif data==ACTION.RECHECK: elif data==ACTION.RECHECK:
log.debug("Rechecking torrents: %s", ids) log.debug("Rechecking torrents: %s", ids)
client.core.force_recheck(ids).addErrback(action_error,mode) client.core.force_recheck(ids).addErrback(action_error, mode)
elif data==ACTION.REANNOUNCE: elif data==ACTION.REANNOUNCE:
log.debug("Reannouncing torrents: %s",ids) log.debug("Reannouncing torrents: %s", ids)
client.core.force_reannounce(ids).addErrback(action_error,mode) client.core.force_reannounce(ids).addErrback(action_error, mode)
elif data==ACTION.DETAILS: elif data==ACTION.DETAILS:
log.debug("Torrent details") log.debug("Torrent details")
tid = mode.current_torrent_id() tid = mode.current_torrent_id()
@ -268,7 +268,7 @@ def torrent_action(idx, data, mode, ids):
def create_popup(status): def create_popup(status):
cb = lambda result, ids=ids: _do_set_torrent_options(ids, result) cb = lambda result, ids=ids: _do_set_torrent_options(ids, result)
option_popup = InputPopup(mode,"Set torrent options (Esc to cancel)",close_cb=cb, height_req=22) option_popup = InputPopup(mode, "Set torrent options (Esc to cancel)", close_cb=cb, height_req=22)
for (field, field_type) in torrent_options: for (field, field_type) in torrent_options:
caption = "{!info!}" + torrent_options_to_names[field] caption = "{!info!}" + torrent_options_to_names[field]
@ -319,20 +319,20 @@ def torrent_actions_popup(mode,tids,details=False, action = None):
if action != None: if action != None:
torrent_action(-1, action, mode, tids) torrent_action(-1, action, mode, tids)
return return
popup = SelectablePopup(mode,"Torrent Actions",torrent_action, (mode, tids)) popup = SelectablePopup(mode, "Torrent Actions", torrent_action, (mode, tids))
popup.add_line("_Pause",data=ACTION.PAUSE) popup.add_line("_Pause", data=ACTION.PAUSE)
popup.add_line("_Resume",data=ACTION.RESUME) popup.add_line("_Resume", data=ACTION.RESUME)
if details: if details:
popup.add_divider() popup.add_divider()
popup.add_line("Queue",data=ACTION.QUEUE) popup.add_line("Queue", data=ACTION.QUEUE)
popup.add_divider() popup.add_divider()
popup.add_line("_Update Tracker",data=ACTION.REANNOUNCE) popup.add_line("_Update Tracker", data=ACTION.REANNOUNCE)
popup.add_divider() popup.add_divider()
popup.add_line("Remo_ve Torrent",data=ACTION.REMOVE) popup.add_line("Remo_ve Torrent", data=ACTION.REMOVE)
popup.add_line("_Force Recheck",data=ACTION.RECHECK) popup.add_line("_Force Recheck", data=ACTION.RECHECK)
popup.add_line("_Move Download Folder",data=ACTION.MOVE_STORAGE) popup.add_line("_Move Download Folder", data=ACTION.MOVE_STORAGE)
popup.add_divider() popup.add_divider()
if details: if details:
popup.add_line("Torrent _Details",data=ACTION.DETAILS) popup.add_line("Torrent _Details", data=ACTION.DETAILS)
popup.add_line("Torrent _Options",data=ACTION.TORRENT_OPTIONS) popup.add_line("Torrent _Options", data=ACTION.TORRENT_OPTIONS)
mode.set_popup(popup) mode.set_popup(popup)

View file

@ -45,7 +45,7 @@ from collections import deque
from deluge.ui.sessionproxy import SessionProxy from deluge.ui.sessionproxy import SessionProxy
from popup import Popup,SelectablePopup,MessagePopup from popup import Popup, SelectablePopup, MessagePopup
from add_util import add_torrent from add_util import add_torrent
from input_popup import InputPopup from input_popup import InputPopup
import deluge.ui.console.colors as colors import deluge.ui.console.colors as colors
@ -158,12 +158,12 @@ class TorrentDetail(BaseMode, component.Component):
# don't keep getting the files once we've got them once # don't keep getting the files once we've got them once
if state.get("files"): if state.get("files"):
self.files_sep = "{!green,black,bold,underline!}%s"%(("Files (torrent has %d files)"%len(state["files"])).center(self.cols)) self.files_sep = "{!green,black,bold,underline!}%s"%(("Files (torrent has %d files)"%len(state["files"])).center(self.cols))
self.file_list,self.file_dict = self.build_file_list(state["files"],state["file_progress"],state["file_priorities"]) self.file_list, self.file_dict = self.build_file_list(state["files"], state["file_progress"], state["file_priorities"])
self._status_keys.remove("files") self._status_keys.remove("files")
else: else:
self.files_sep = "{!green,black,bold,underline!}%s"%(("Files (File list unknown)").center(self.cols)) self.files_sep = "{!green,black,bold,underline!}%s"%(("Files (File list unknown)").center(self.cols))
need_prio_update = True need_prio_update = True
self.__fill_progress(self.file_list,state["file_progress"]) self.__fill_progress(self.file_list, state["file_progress"])
for i, prio in enumerate(state["file_priorities"]): for i, prio in enumerate(state["file_priorities"]):
if self.file_dict[i][6] != prio: if self.file_dict[i][6] != prio:
need_prio_update = True need_prio_update = True
@ -185,7 +185,7 @@ class TorrentDetail(BaseMode, component.Component):
# #
# Also returns a dictionary that maps index values to the file leaves # Also returns a dictionary that maps index values to the file leaves
# for fast updating of progress and priorities # for fast updating of progress and priorities
def build_file_list(self, file_tuples,prog,prio): def build_file_list(self, file_tuples, prog, prio):
ret = [] ret = []
retdict = {} retdict = {}
diridx = maxint diridx = maxint
@ -197,12 +197,12 @@ class TorrentDetail(BaseMode, component.Component):
if not cur or p != cur[-1][0]: if not cur or p != cur[-1][0]:
cl = [] cl = []
if p == fin: if p == fin:
ent = [p,f["index"],f["size"],cl,False, ent = [p, f["index"], f["size"], cl, False,
format_utils.format_progress(prog[f["index"]]*100), format_utils.format_progress(prog[f["index"]]*100),
prio[f["index"]]] prio[f["index"]]]
retdict[f["index"]] = ent retdict[f["index"]] = ent
else: else:
ent = [p,diridx,-1,cl,False,0,-1] ent = [p, diridx, -1, cl, False, 0, -1]
retdict[diridx] = ent retdict[diridx] = ent
diridx-=1 diridx-=1
cur.append(ent) cur.append(ent)
@ -210,8 +210,8 @@ class TorrentDetail(BaseMode, component.Component):
else: else:
cur = cur[-1][3] cur = cur[-1][3]
self.__build_sizes(ret) self.__build_sizes(ret)
self.__fill_progress(ret,prog) self.__fill_progress(ret, prog)
return (ret,retdict) return (ret, retdict)
# fill in the sizes of the directory entries based on their children # fill in the sizes of the directory entries based on their children
def __build_sizes(self, fs): def __build_sizes(self, fs):
@ -227,12 +227,12 @@ class TorrentDetail(BaseMode, component.Component):
# fills in progress fields in all entries based on progs # fills in progress fields in all entries based on progs
# returns the # of bytes complete in all the children of fs # returns the # of bytes complete in all the children of fs
def __fill_progress(self,fs,progs): def __fill_progress(self, fs, progs):
if not progs: return 0 if not progs: return 0
tb = 0 tb = 0
for f in fs: for f in fs:
if f[3]: # dir, has some children if f[3]: # dir, has some children
bd = self.__fill_progress(f[3],progs) bd = self.__fill_progress(f[3], progs)
f[5] = format_utils.format_progress((bd/f[2])*100) f[5] = format_utils.format_progress((bd/f[2])*100)
else: # file, update own prog and add to total else: # file, update own prog and add to total
bd = f[2]*progs[f[1]] bd = f[2]*progs[f[1]]
@ -240,7 +240,7 @@ class TorrentDetail(BaseMode, component.Component):
tb += bd tb += bd
return tb return tb
def __fill_prio(self,fs): def __fill_prio(self, fs):
for f in fs: for f in fs:
if f[3]: # dir, so fill in children and compute our prio if f[3]: # dir, so fill in children and compute our prio
self.__fill_prio(f[3]) self.__fill_prio(f[3])
@ -251,30 +251,30 @@ class TorrentDetail(BaseMode, component.Component):
f[6] = s.pop() f[6] = s.pop()
def __update_columns(self): def __update_columns(self):
self.column_widths = [-1,15,15,20] self.column_widths = [-1, 15, 15, 20]
req = sum(filter(lambda x:x >= 0,self.column_widths)) req = sum(filter(lambda x:x >= 0, self.column_widths))
if (req > self.cols): # can't satisfy requests, just spread out evenly if (req > self.cols): # can't satisfy requests, just spread out evenly
cw = int(self.cols/len(self.column_names)) cw = int(self.cols/len(self.column_names))
for i in range(0,len(self.column_widths)): for i in range(0, len(self.column_widths)):
self.column_widths[i] = cw self.column_widths[i] = cw
else: else:
rem = self.cols - req rem = self.cols - req
var_cols = len(filter(lambda x: x < 0,self.column_widths)) var_cols = len(filter(lambda x: x < 0, self.column_widths))
vw = int(rem/var_cols) vw = int(rem/var_cols)
for i in range(0, len(self.column_widths)): for i in range(0, len(self.column_widths)):
if (self.column_widths[i] < 0): if (self.column_widths[i] < 0):
self.column_widths[i] = vw self.column_widths[i] = vw
self.column_string = "{!green,black,bold!}%s"%("".join(["%s%s"%(self.column_names[i]," "*(self.column_widths[i]-len(self.column_names[i]))) for i in range(0,len(self.column_names))])) self.column_string = "{!green,black,bold!}%s"%("".join(["%s%s"%(self.column_names[i], " "*(self.column_widths[i]-len(self.column_names[i]))) for i in range(0, len(self.column_names))]))
def report_message(self,title,message): def report_message(self, title, message):
self.messages.append((title,message)) self.messages.append((title, message))
def clear_marks(self): def clear_marks(self):
self.marked = {} self.marked = {}
def set_popup(self,pu): def set_popup(self, pu):
self.popup = pu self.popup = pu
self.refresh() self.refresh()
@ -304,7 +304,7 @@ class TorrentDetail(BaseMode, component.Component):
#self.__get_file_by_name(old_folder, self.file_list)[0] = new_folder.strip("/") #self.__get_file_by_name(old_folder, self.file_list)[0] = new_folder.strip("/")
component.get("SessionProxy").get_torrent_status(self.torrentid, self._status_keys).addCallback(self.set_state) component.get("SessionProxy").get_torrent_status(self.torrentid, self._status_keys).addCallback(self.set_state)
def draw_files(self,files,depth,off,idx): def draw_files(self, files, depth, off, idx):
color_selected = "blue" color_selected = "blue"
color_partially_selected = "magenta" color_partially_selected = "magenta"
@ -315,7 +315,7 @@ class TorrentDetail(BaseMode, component.Component):
# kick out if we're going to draw too low on the screen # kick out if we're going to draw too low on the screen
if (off >= self.rows-1): if (off >= self.rows-1):
self.more_to_draw = True self.more_to_draw = True
return -1,-1 return -1, -1
self.file_limit = idx self.file_limit = idx
@ -374,22 +374,22 @@ class TorrentDetail(BaseMode, component.Component):
else: # file else: # file
xchar = '-' xchar = '-'
r = format_utils.format_row(["%s%s %s"%(" "*depth,xchar,fl[0]), r = format_utils.format_row(["%s%s %s"%(" "*depth, xchar, fl[0]),
deluge.common.fsize(fl[2]),fl[5], deluge.common.fsize(fl[2]), fl[5],
format_utils.format_priority(fl[6])], format_utils.format_priority(fl[6])],
self.column_widths) self.column_widths)
self.add_string(off,"%s%s"%(color_string,r),trim=False) self.add_string(off, "%s%s"%(color_string, r), trim=False)
off += 1 off += 1
if fl[3] and fl[4]: if fl[3] and fl[4]:
# recurse if we have children and are expanded # recurse if we have children and are expanded
off,idx = self.draw_files(fl[3],depth+1,off,idx+1) off, idx = self.draw_files(fl[3], depth+1, off, idx+1)
if off < 0: return (off,idx) if off < 0: return (off, idx)
else: else:
idx += 1 idx += 1
return (off,idx) return (off, idx)
def __get_file_list_length(self, file_list=None): def __get_file_list_length(self, file_list=None):
""" """
@ -518,12 +518,12 @@ class TorrentDetail(BaseMode, component.Component):
def refresh(self,lines=None): def refresh(self,lines=None):
# show a message popup if there's anything queued # show a message popup if there's anything queued
if self.popup == None and self.messages: if self.popup == None and self.messages:
title,msg = self.messages.popleft() title, msg = self.messages.popleft()
self.popup = MessagePopup(self,title,msg) self.popup = MessagePopup(self, title, msg)
# Update the status bars # Update the status bars
self.stdscr.erase() self.stdscr.erase()
self.add_string(0,self.statusbars.topbar) self.add_string(0, self.statusbars.topbar)
#This will quite likely fail when switching modes #This will quite likely fail when switching modes
try: try:
@ -552,11 +552,11 @@ class TorrentDetail(BaseMode, component.Component):
self._listing_start = off self._listing_start = off
self._listing_space = self.rows - self._listing_start self._listing_space = self.rows - self._listing_start
self.add_string(off,self.column_string) self.add_string(off, self.column_string)
if self.file_list: if self.file_list:
off += 1 off += 1
self.more_to_draw = False self.more_to_draw = False
self.draw_files(self.file_list,0,off,0) self.draw_files(self.file_list, 0, off, 0)
if component.get("ConsoleUI").screen != self: if component.get("ConsoleUI").screen != self:
return return
@ -589,8 +589,8 @@ class TorrentDetail(BaseMode, component.Component):
self.refresh() self.refresh()
def file_list_up(self, rows=1): def file_list_up(self, rows=1):
self.current_file_idx = max(0,self.current_file_idx-rows) self.current_file_idx = max(0, self.current_file_idx-rows)
self.file_off = min(self.file_off,self.current_file_idx) self.file_off = min(self.file_off, self.current_file_idx)
self.refresh() self.refresh()
def back_to_overview(self): def back_to_overview(self):
@ -608,18 +608,18 @@ class TorrentDetail(BaseMode, component.Component):
for f in files: for f in files:
#Do not set priorities for the whole dir, just selected contents #Do not set priorities for the whole dir, just selected contents
if f[3]: if f[3]:
self.build_prio_list(f[3],ret_list,parent_prio,selected_prio) self.build_prio_list(f[3], ret_list, parent_prio, selected_prio)
else: # file, need to add to list else: # file, need to add to list
if f[1] in self.marked or parent_prio >= 0: if f[1] in self.marked or parent_prio >= 0:
# selected (or parent selected), use requested priority # selected (or parent selected), use requested priority
ret_list.append((f[1],selected_prio)) ret_list.append((f[1], selected_prio))
else: else:
# not selected, just keep old priority # not selected, just keep old priority
ret_list.append((f[1],f[6])) ret_list.append((f[1], f[6]))
def do_priority(self, idx, data, was_empty): def do_priority(self, idx, data, was_empty):
plist = [] plist = []
self.build_prio_list(self.file_list,plist,-1,data) self.build_prio_list(self.file_list, plist, -1, data)
plist.sort() plist.sort()
priorities = [p[1] for p in plist] priorities = [p[1] for p in plist]
log.debug("priorities: %s", priorities) log.debug("priorities: %s", priorities)
@ -634,14 +634,14 @@ class TorrentDetail(BaseMode, component.Component):
def show_priority_popup(self, was_empty): def show_priority_popup(self, was_empty):
func = lambda idx, data, we=was_empty: self.do_priority(idx, data, we) func = lambda idx, data, we=was_empty: self.do_priority(idx, data, we)
if self.marked: if self.marked:
self.popup = SelectablePopup(self,"Set File Priority", func) self.popup = SelectablePopup(self, "Set File Priority", func)
self.popup.add_line("_Do Not Download",data=deluge.common.FILE_PRIORITY["Do Not Download"], foreground="red") self.popup.add_line("_Do Not Download", data=deluge.common.FILE_PRIORITY["Do Not Download"], foreground="red")
self.popup.add_line("_Normal Priority",data=deluge.common.FILE_PRIORITY["Normal Priority"]) self.popup.add_line("_Normal Priority", data=deluge.common.FILE_PRIORITY["Normal Priority"])
self.popup.add_line("_High Priority",data=deluge.common.FILE_PRIORITY["High Priority"], foreground="yellow") self.popup.add_line("_High Priority", data=deluge.common.FILE_PRIORITY["High Priority"], foreground="yellow")
self.popup.add_line("H_ighest Priority",data=deluge.common.FILE_PRIORITY["Highest Priority"], foreground="green") self.popup.add_line("H_ighest Priority", data=deluge.common.FILE_PRIORITY["Highest Priority"], foreground="green")
self.popup._selected = 1 self.popup._selected = 1
def __mark_unmark(self,idx): def __mark_unmark(self, idx):
""" """
Selects or unselects file or a catalog(along with contained files) Selects or unselects file or a catalog(along with contained files)
""" """
@ -838,7 +838,7 @@ class TorrentDetail(BaseMode, component.Component):
new_fname = "%s/%s/" % (old_fname.strip("/").rpartition("/")[0], result["new_foldername"]) new_fname = "%s/%s/" % (old_fname.strip("/").rpartition("/")[0], result["new_foldername"])
self._do_rename_folder(tid, old_fname, new_fname) self._do_rename_folder(tid, old_fname, new_fname)
popup = InputPopup(self,"Rename folder (Esc to cancel)",close_cb=do_rename) popup = InputPopup(self, "Rename folder (Esc to cancel)", close_cb=do_rename)
popup.add_text("{!info!}Renaming folder:{!input!}") popup.add_text("{!info!}Renaming folder:{!input!}")
popup.add_text(" * %s\n" % old_filename) popup.add_text(" * %s\n" % old_filename)
popup.add_text_input("Enter new folder name:", "new_foldername", old_filename.strip("/")) popup.add_text_input("Enter new folder name:", "new_foldername", old_filename.strip("/"))
@ -850,7 +850,7 @@ class TorrentDetail(BaseMode, component.Component):
fname = "%s/%s" % (self.full_names[idx].rpartition("/")[0], result["new_filename"]) fname = "%s/%s" % (self.full_names[idx].rpartition("/")[0], result["new_filename"])
self._do_rename_file(tid, idx, fname) self._do_rename_file(tid, idx, fname)
popup = InputPopup(self,"Rename file (Esc to cancel)",close_cb=do_rename) popup = InputPopup(self, "Rename file (Esc to cancel)", close_cb=do_rename)
popup.add_text("{!info!}Renaming file:{!input!}") popup.add_text("{!info!}Renaming file:{!input!}")
popup.add_text(" * %s\n" % old_filename) popup.add_text(" * %s\n" % old_filename)
popup.add_text_input("Enter new filename:", "new_filename", old_filename) popup.add_text_input("Enter new filename:", "new_filename", old_filename)
@ -924,10 +924,10 @@ class TorrentDetail(BaseMode, component.Component):
elif chr(c) == 'c': elif chr(c) == 'c':
self.marked = {} self.marked = {}
elif chr(c) == 'a': elif chr(c) == 'a':
torrent_actions_popup(self,[self.torrentid],details=False) torrent_actions_popup(self, [self.torrentid], details=False)
return return
elif chr(c) == 'o': elif chr(c) == 'o':
torrent_actions_popup(self,[self.torrentid],action=ACTION.TORRENT_OPTIONS) torrent_actions_popup(self, [self.torrentid], action=ACTION.TORRENT_OPTIONS)
return return
elif chr(c) == 'h': elif chr(c) == 'h':
self.popup = MessagePopup(self, "Help", HELP_STR, width_req=0.75) self.popup = MessagePopup(self, "Help", HELP_STR, width_req=0.75)

View file

@ -145,7 +145,7 @@ class CreateTorrentDialog:
"""Adjusts the recommended piece based on the file/folder/path selected.""" """Adjusts the recommended piece based on the file/folder/path selected."""
size = self.files_treestore[0][2] size = self.files_treestore[0][2]
model = self.builder.get_object("combo_piece_size").get_model() model = self.builder.get_object("combo_piece_size").get_model()
for index,value in enumerate(model): for index, value in enumerate(model):
psize = self.parse_piece_size_text(value[0]) psize = self.parse_piece_size_text(value[0])
pieces = size / psize pieces = size / psize
if pieces < 2048 or (index + 1) == len(model): if pieces < 2048 or (index + 1) == len(model):

View file

@ -585,16 +585,16 @@ def icon_name_to_host(icon):
return icon.rpartition('.')[0] return icon.rpartition('.')[0]
MIME_MAP = { MIME_MAP = {
"image/gif" : "gif", "image/gif": "gif",
"image/jpeg" : "jpg", "image/jpeg": "jpg",
"image/png" : "png", "image/png": "png",
"image/vnd.microsoft.icon" : "ico", "image/vnd.microsoft.icon": "ico",
"image/x-icon" : "ico", "image/x-icon": "ico",
"gif" : "image/gif", "gif": "image/gif",
"jpg" : "image/jpeg", "jpg": "image/jpeg",
"jpeg" : "image/jpeg", "jpeg": "image/jpeg",
"png" : "image/png", "png": "image/png",
"ico" : "image/vnd.microsoft.icon", "ico": "image/vnd.microsoft.icon",
} }
def mimetype_to_extension(mimetype): def mimetype_to_extension(mimetype):