Replace deprecated session.num_connections with session_status.num_peers

This commit removes get_num_connections() from core and updates UIs
to use get_session_status with num_peers key.

Extra noise is from Flake8 changes
This commit is contained in:
Calum Lind 2014-01-17 12:20:59 +00:00
commit 624f2f66cf
6 changed files with 83 additions and 101 deletions

View file

@ -69,6 +69,7 @@ from deluge.core.rpcserver import export
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class Core(component.Component): class Core(component.Component):
def __init__(self, listen_interface=None): def __init__(self, listen_interface=None):
log.debug("Core init..") log.debug("Core init..")
@ -89,9 +90,10 @@ class Core(component.Component):
# Set the user agent # Set the user agent
self.settings = lt.session_settings() self.settings = lt.session_settings()
self.settings.user_agent = "Deluge/%(deluge_version)s libtorrent/%(lt_version)s" % \ self.settings.user_agent = "Deluge/%(deluge_version)s libtorrent/%(lt_version)s" % {
{ 'deluge_version': deluge.common.get_version(), 'deluge_version': deluge.common.get_version(),
'lt_version': self.get_libtorrent_version().rpartition(".")[0] } 'lt_version': self.get_libtorrent_version().rpartition(".")[0]
}
# Increase the alert queue size so that alerts don't get lost # Increase the alert queue size so that alerts don't get lost
self.settings.alert_queue_size = 10000 self.settings.alert_queue_size = 10000
@ -264,6 +266,7 @@ class Core(component.Component):
:returns: a Deferred which returns the torrent_id as a str or None :returns: a Deferred which returns the torrent_id as a str or None
""" """
log.info("Attempting to add url %s", url) log.info("Attempting to add url %s", url)
def on_download_success(filename): def on_download_success(filename):
# We got the file, so add it to the session # We got the file, so add it to the session
f = open(filename, "rb") f = open(filename, "rb")
@ -380,7 +383,8 @@ class Core(component.Component):
# Add in a couple ratios # Add in a couple ratios
try: try:
cache["write_hit_ratio"] = float((cache["blocks_written"] - cache["writes"])) / float(cache["blocks_written"]) cache["write_hit_ratio"] = float((cache["blocks_written"] -
cache["writes"])) / float(cache["blocks_written"])
except ZeroDivisionError: except ZeroDivisionError:
cache["write_hit_ratio"] = 0.0 cache["write_hit_ratio"] = 0.0
@ -453,7 +457,8 @@ class Core(component.Component):
@export @export
def get_torrent_status(self, torrent_id, keys, diff=False): def get_torrent_status(self, torrent_id, keys, diff=False):
torrent_keys, plugin_keys = self.torrentmanager.separate_keys(keys, [torrent_id]) torrent_keys, plugin_keys = self.torrentmanager.separate_keys(keys, [torrent_id])
return self.create_torrent_status(torrent_id, torrent_keys, plugin_keys, diff=diff, update=True, all_keys=not keys) return self.create_torrent_status(torrent_id, torrent_keys, plugin_keys, diff=diff, update=True,
all_keys=not keys)
@export @export
def get_torrents_status(self, filter_dict, keys, diff=False): def get_torrents_status(self, filter_dict, keys, diff=False):
@ -461,7 +466,6 @@ class Core(component.Component):
returns all torrents , optionally filtered by filter_dict. returns all torrents , optionally filtered by filter_dict.
""" """
torrent_ids = self.filtermanager.filter_torrent_ids(filter_dict) torrent_ids = self.filtermanager.filter_torrent_ids(filter_dict)
status_dict = {}.fromkeys(torrent_ids)
d = self.torrentmanager.torrents_status_update(torrent_ids, keys, diff=diff) d = self.torrentmanager.torrents_status_update(torrent_ids, keys, diff=diff)
def add_plugin_fields(args): def add_plugin_fields(args):
@ -475,7 +479,7 @@ class Core(component.Component):
return d return d
@export @export
def get_filter_tree(self , show_zero_hits=True, hide_cat=None): def get_filter_tree(self, show_zero_hits=True, hide_cat=None):
""" """
returns {field: [(value,count)] } returns {field: [(value,count)] }
for use in sidebar(s) for use in sidebar(s)
@ -517,11 +521,6 @@ class Core(component.Component):
"""Returns the active listen port""" """Returns the active listen port"""
return self.session.listen_port() return self.session.listen_port()
@export
def get_num_connections(self):
"""Returns the current number of connections"""
return self.session.num_connections()
@export @export
def get_available_plugins(self): def get_available_plugins(self):
"""Returns a list of plugins available in the core""" """Returns a list of plugins available in the core"""
@ -658,24 +657,24 @@ class Core(component.Component):
@export @export
def create_torrent(self, path, tracker, piece_length, comment, target, def create_torrent(self, path, tracker, piece_length, comment, target,
webseeds, private, created_by, trackers, add_to_session): webseeds, private, created_by, trackers, add_to_session):
log.debug("creating torrent..") log.debug("creating torrent..")
threading.Thread(target=self._create_torrent_thread, threading.Thread(target=self._create_torrent_thread,
args=( args=(
path, path,
tracker, tracker,
piece_length, piece_length,
comment, comment,
target, target,
webseeds, webseeds,
private, private,
created_by, created_by,
trackers, trackers,
add_to_session)).start() add_to_session)).start()
def _create_torrent_thread(self, path, tracker, piece_length, comment, target, def _create_torrent_thread(self, path, tracker, piece_length, comment, target,
webseeds, private, created_by, trackers, add_to_session): webseeds, private, created_by, trackers, add_to_session):
import deluge.metafile import deluge.metafile
deluge.metafile.make_meta_file( deluge.metafile.make_meta_file(
path, path,

View file

@ -37,7 +37,6 @@ import time
import logging import logging
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
import deluge
from deluge.plugins.pluginbase import CorePluginBase from deluge.plugins.pluginbase import CorePluginBase
from deluge import component from deluge import component
from deluge import configmanager from deluge import configmanager
@ -45,8 +44,8 @@ from deluge.core.rpcserver import export
DEFAULT_PREFS = { DEFAULT_PREFS = {
"test": "NiNiNi", "test": "NiNiNi",
"update_interval": 1, #2 seconds. "update_interval": 1, # 2 seconds.
"length": 150, # 2 seconds * 150 --> 5 minutes. "length": 150, # 2 seconds * 150 --> 5 minutes.
} }
DEFAULT_TOTALS = { DEFAULT_TOTALS = {
@ -59,25 +58,28 @@ DEFAULT_TOTALS = {
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def get_key(config, key): def get_key(config, key):
try: try:
return config[key] return config[key]
except KeyError: except KeyError:
return None return None
def mean(items): def mean(items):
try: try:
return sum(items)/ len(items) return sum(items) / len(items)
except Exception: except Exception:
return 0 return 0
class Core(CorePluginBase): class Core(CorePluginBase):
totals = {} #class var to catch only updating this once per session in enable. totals = {} # class var to catch only updating this once per session in enable.
def enable(self): def enable(self):
log.debug("Stats plugin enabled") log.debug("Stats plugin enabled")
self.core = component.get("Core") self.core = component.get("Core")
self.stats ={} self.stats = {}
self.count = {} self.count = {}
self.intervals = [1, 5, 30, 300] self.intervals = [1, 5, 30, 300]
@ -88,7 +90,6 @@ class Core(CorePluginBase):
self.last_update[i] = t self.last_update[i] = t
self.count[i] = 0 self.count[i] = 0
self.config = configmanager.ConfigManager("stats.conf", DEFAULT_PREFS) self.config = configmanager.ConfigManager("stats.conf", DEFAULT_PREFS)
self.saved_stats = configmanager.ConfigManager("stats.totals", DEFAULT_TOTALS) self.saved_stats = configmanager.ConfigManager("stats.totals", DEFAULT_TOTALS)
if self.totals == {}: if self.totals == {}:
@ -143,7 +144,7 @@ class Core(CorePluginBase):
stats.update(self.core.get_session_status([key])) stats.update(self.core.get_session_status([key]))
except AttributeError: except AttributeError:
pass pass
stats["num_connections"] = self.core.get_num_connections() stats["num_connections"] = stats["num_peers"]
stats.update(self.core.get_config_values(["max_download", stats.update(self.core.get_config_values(["max_download",
"max_upload", "max_upload",
"max_num_connections"])) "max_num_connections"]))
@ -169,7 +170,7 @@ class Core(CorePluginBase):
self.count[interval] = self.count[interval] + 1 self.count[interval] = self.count[interval] + 1
if self.count[interval] >= interval: if self.count[interval] >= interval:
self.last_update[interval] = update_time self.last_update[interval] = update_time
self.count[interval] = 0 self.count[interval] = 0
current_stats = self.stats[interval] current_stats = self.stats[interval]
for stat, stat_list in self.stats[base].iteritems(): for stat, stat_list in self.stats[base].iteritems():
try: try:
@ -197,7 +198,6 @@ class Core(CorePluginBase):
log.error("Stats save error", e) log.error("Stats save error", e)
return True return True
# export: # export:
@export @export
def get_stats(self, keys, interval): def get_stats(self, keys, interval):

View file

@ -39,17 +39,19 @@ from deluge.ui.client import client
import deluge.common import deluge.common
import deluge.component as component import deluge.component as component
class Command(BaseCommand): class Command(BaseCommand):
"""Shows a various status information from the daemon.""" """Shows a various status information from the daemon."""
option_list = BaseCommand.option_list + ( option_list = BaseCommand.option_list + (
make_option('-r', '--raw', action='store_true', default=False, dest='raw', make_option('-r', '--raw', action='store_true', default=False, dest='raw',
help='Don\'t format upload/download rates in KiB/s (useful for scripts that want to do their own parsing)'), help='Don\'t format upload/download rates in KiB/s \
make_option('-n', '--no-torrents', action='store_false', default=True, dest='show_torrents', (useful for scripts that want to do their own parsing)'),
help='Don\'t show torrent status (this will make the command a bit faster)'), make_option('-n', '--no-torrents', action='store_false', default=True, dest='show_torrents',
help='Don\'t show torrent status (this will make the command a bit faster)'),
) )
usage = "Usage: status [-r] [-n]" usage = "Usage: status [-r] [-n]"
def handle(self, *args, **options): def handle(self, *args, **options):
self.console = component.get("ConsoleUI") self.console = component.get("ConsoleUI")
self.status = None self.status = None
@ -63,34 +65,25 @@ class Command(BaseCommand):
def on_session_status(status): def on_session_status(status):
self.status = status self.status = status
if self.status != None and self.connections != None and self.torrents != None: if self.status is not None and self.connections is not None and self.torrents is not None:
self.print_status()
def on_num_connections(conns):
self.connections = conns
if self.status != None and self.connections != None and self.torrents != None:
self.print_status() self.print_status()
def on_torrents_status(status): def on_torrents_status(status):
self.torrents = status self.torrents = status
if self.status != None and self.connections != None and self.torrents != None: if self.status is not None and self.connections is not None and self.torrents is not None:
self.print_status() self.print_status()
def on_torrents_status_fail(reason): def on_torrents_status_fail(reason):
self.torrents = -1 self.torrents = -1
if self.status != None and self.connections != None and self.torrents != None: if self.status is not None and self.connections is not None and self.torrents is not None:
self.print_status() self.print_status()
deferreds = [] deferreds = []
ds = client.core.get_session_status(["payload_upload_rate","payload_download_rate","dht_nodes"]) ds = client.core.get_session_status(["num_peers", "payload_upload_rate", "payload_download_rate", "dht_nodes"])
ds.addCallback(on_session_status) ds.addCallback(on_session_status)
deferreds.append(ds) deferreds.append(ds)
dc = client.core.get_num_connections()
dc.addCallback(on_num_connections)
deferreds.append(dc)
if options["show_torrents"]: if options["show_torrents"]:
dt = client.core.get_torrents_status({}, ["state"]) dt = client.core.get_torrents_status({}, ["state"])
dt.addCallback(on_torrents_status) dt.addCallback(on_torrents_status)
@ -102,18 +95,19 @@ class Command(BaseCommand):
def print_status(self): def print_status(self):
self.console.set_batch_write(True) self.console.set_batch_write(True)
if self.raw: if self.raw:
self.console.write("{!info!}Total upload: %f"%self.status["payload_upload_rate"]) self.console.write("{!info!}Total upload: %f" % self.status["payload_upload_rate"])
self.console.write("{!info!}Total download: %f"%self.status["payload_download_rate"]) self.console.write("{!info!}Total download: %f" % self.status["payload_download_rate"])
else: else:
self.console.write("{!info!}Total upload: %s"%deluge.common.fspeed(self.status["payload_upload_rate"])) self.console.write("{!info!}Total upload: %s" % deluge.common.fspeed(self.status["payload_upload_rate"]))
self.console.write("{!info!}Total download: %s"%deluge.common.fspeed(self.status["payload_download_rate"])) self.console.write("{!info!}Total download: %s" %
self.console.write("{!info!}DHT Nodes: %i"%self.status["dht_nodes"]) deluge.common.fspeed(self.status["payload_download_rate"]))
self.console.write("{!info!}Total connections: %i"%self.connections) self.console.write("{!info!}DHT Nodes: %i" % self.status["dht_nodes"])
self.console.write("{!info!}Total connections: %i" % self.connections)
if self.torrents == -1: if self.torrents == -1:
self.console.write("{!error!}Error getting torrent info") self.console.write("{!error!}Error getting torrent info")
elif self.torrents != -2: elif self.torrents != -2:
self.console.write("{!info!}Total torrents: %i"%len(self.torrents)) self.console.write("{!info!}Total torrents: %i" % len(self.torrents))
states = ["Downloading","Seeding","Paused","Checking","Error","Queued"] states = ["Downloading", "Seeding", "Paused", "Checking", "Error", "Queued"]
state_counts = {} state_counts = {}
for state in states: for state in states:
state_counts[state] = 0 state_counts[state] = 0
@ -121,6 +115,6 @@ class Command(BaseCommand):
s = self.torrents[t] s = self.torrents[t]
state_counts[s["state"]] += 1 state_counts[s["state"]] += 1
for state in states: for state in states:
self.console.write("{!info!} %s: %i"%(state,state_counts[state])) self.console.write("{!info!} %s: %i" % (state, state_counts[state]))
self.console.set_batch_write(False) self.console.set_batch_write(False)

View file

@ -39,6 +39,7 @@ import deluge.component as component
import deluge.common import deluge.common
from deluge.ui.client import client from deluge.ui.client import client
class StatusBars(component.Component): class StatusBars(component.Component):
def __init__(self): def __init__(self):
component.Component.__init__(self, "StatusBars", 2, depend=["CoreConfig"]) component.Component.__init__(self, "StatusBars", 2, depend=["CoreConfig"])
@ -58,28 +59,22 @@ class StatusBars(component.Component):
self.update() self.update()
def update(self): def update(self):
def on_get_num_connections(result):
self.connections = result
client.core.get_num_connections().addCallback(on_get_num_connections)
def on_get_session_status(status): def on_get_session_status(status):
self.upload = deluge.common.fsize(status["payload_upload_rate"]) self.upload = deluge.common.fsize(status["payload_upload_rate"])
self.download = deluge.common.fsize(status["payload_download_rate"]) self.download = deluge.common.fsize(status["payload_download_rate"])
self.connections = status["num_peers"]
if "dht_nodes" in status: if "dht_nodes" in status:
self.dht = status["dht_nodes"] self.dht = status["dht_nodes"]
self.update_statusbars() self.update_statusbars()
keys = [ keys = ["num_peers", "payload_upload_rate", "payload_download_rate"]
"payload_upload_rate",
"payload_download_rate"]
if self.config["dht"]: if self.config["dht"]:
keys.append("dht_nodes") keys.append("dht_nodes")
client.core.get_session_status(keys).addCallback(on_get_session_status) client.core.get_session_status(keys).addCallback(on_get_session_status)
def update_statusbars(self): def update_statusbars(self):
# Update the topbar string # Update the topbar string
self.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version() self.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version()
@ -132,7 +127,6 @@ class StatusBars(component.Component):
else: else:
self.bottombar += " U: {!white,blue!}%s{!status!}" % self.upload self.bottombar += " U: {!white,blue!}%s{!status!}" % self.upload
if self.config["max_upload_speed"] > -1: if self.config["max_upload_speed"] > -1:
self.bottombar += " (%s " % self.config["max_upload_speed"] + _("KiB/s") + ")" self.bottombar += " (%s " % self.config["max_upload_speed"] + _("KiB/s") + ")"

View file

@ -46,6 +46,7 @@ from deluge.configmanager import ConfigManager
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class StatusBarItem: class StatusBarItem:
def __init__(self, image=None, stock=None, text=None, callback=None, tooltip=None): def __init__(self, image=None, stock=None, text=None, callback=None, tooltip=None):
self._widgets = [] self._widgets = []
@ -59,17 +60,17 @@ class StatusBarItem:
self._ebox.add(self._hbox) self._ebox.add(self._hbox)
# Add image from file or stock # Add image from file or stock
if image != None or stock != None: if image is not None or stock is not None:
if image != None: if image is not None:
self.set_image_from_file(image) self.set_image_from_file(image)
if stock != None: if stock is not None:
self.set_image_from_stock(stock) self.set_image_from_stock(stock)
# Add text # Add text
if text != None: if text is not None:
self.set_text(text) self.set_text(text)
if callback != None: if callback is not None:
self.set_callback(callback) self.set_callback(callback)
if tooltip: if tooltip:
@ -113,6 +114,7 @@ class StatusBarItem:
def get_text(self): def get_text(self):
return self._label.get_text() return self._label.get_text()
class StatusBar(component.Component): class StatusBar(component.Component):
def __init__(self): def __init__(self):
component.Component.__init__(self, "StatusBar", interval=3) component.Component.__init__(self, "StatusBar", interval=3)
@ -187,14 +189,14 @@ class StatusBar(component.Component):
image=deluge.common.get_pixmap("dht16.png"), tooltip=_("DHT Nodes")) image=deluge.common.get_pixmap("dht16.png"), tooltip=_("DHT Nodes"))
self.diskspace_item = self.add_item( self.diskspace_item = self.add_item(
stock=gtk.STOCK_HARDDISK, stock=gtk.STOCK_HARDDISK,
callback=self._on_diskspace_item_clicked, callback=self._on_diskspace_item_clicked,
tooltip=_("Free Disk Space")) tooltip=_("Free Disk Space"))
self.health_item = self.add_item( self.health_item = self.add_item(
stock=gtk.STOCK_DIALOG_ERROR, stock=gtk.STOCK_DIALOG_ERROR,
text=_("No Incoming Connections!"), text=_("No Incoming Connections!"),
callback=self._on_health_icon_clicked) callback=self._on_health_icon_clicked)
self.health = False self.health = False
@ -205,7 +207,7 @@ class StatusBar(component.Component):
self._on_dht(configs["dht"]) self._on_dht(configs["dht"])
# Get some config values # Get some config values
client.core.get_config_values(["max_connections_global", "max_download_speed", client.core.get_config_values(["max_connections_global", "max_download_speed",
"max_upload_speed", "dht"]).addCallback(update_config_values) "max_upload_speed", "dht"]).addCallback(update_config_values)
def stop(self): def stop(self):
# When stopped, we just show the not connected thingy # When stopped, we just show the not connected thingy
@ -274,8 +276,7 @@ class StatusBar(component.Component):
def send_status_request(self): def send_status_request(self):
# Sends an async request for data from the core # Sends an async request for data from the core
client.core.get_num_connections().addCallback(self._on_get_num_connections) keys = ["num_peers", "upload_rate", "download_rate", "payload_upload_rate", "payload_download_rate"]
keys = ["upload_rate", "download_rate", "payload_upload_rate", "payload_download_rate"]
if self.dht_status: if self.dht_status:
keys.append("dht_nodes") keys.append("dht_nodes")
@ -299,10 +300,6 @@ class StatusBar(component.Component):
self.max_connections = max_connections self.max_connections = max_connections
self.update_connections_label() self.update_connections_label()
def _on_get_num_connections(self, num_connections):
self.num_connections = num_connections
self.update_connections_label()
def _on_dht(self, value): def _on_dht(self, value):
self.dht_status = value self.dht_status = value
if value: if value:
@ -317,9 +314,11 @@ class StatusBar(component.Component):
self.upload_rate = deluge.common.fspeed(status["payload_upload_rate"]) self.upload_rate = deluge.common.fspeed(status["payload_upload_rate"])
self.download_protocol_rate = (status["download_rate"] - status["payload_download_rate"]) / 1024 self.download_protocol_rate = (status["download_rate"] - status["payload_download_rate"]) / 1024
self.upload_protocol_rate = (status["upload_rate"] - status["payload_upload_rate"]) / 1024 self.upload_protocol_rate = (status["upload_rate"] - status["payload_upload_rate"]) / 1024
self.num_connections = status["num_peers"]
self.update_download_label() self.update_download_label()
self.update_upload_label() self.update_upload_label()
self.update_traffic_label() self.update_traffic_label()
self.update_connections_label()
if "dht_nodes" in status: if "dht_nodes" in status:
self.dht_nodes = status["dht_nodes"] self.dht_nodes = status["dht_nodes"]
@ -402,7 +401,7 @@ class StatusBar(component.Component):
elif widget.get_name() == "other": elif widget.get_name() == "other":
value = common.show_other_dialog( value = common.show_other_dialog(
_("Set Maximum Download Speed"), _("KiB/s"), None, "downloading.svg", self.max_download_speed) _("Set Maximum Download Speed"), _("KiB/s"), None, "downloading.svg", self.max_download_speed)
if value == None: if value is None:
return return
else: else:
value = float(widget.get_children()[0].get_text().split(" ")[0]) value = float(widget.get_children()[0].get_text().split(" ")[0])
@ -430,7 +429,7 @@ class StatusBar(component.Component):
elif widget.get_name() == "other": elif widget.get_name() == "other":
value = common.show_other_dialog( value = common.show_other_dialog(
_("Set Maximum Upload Speed"), _("KiB/s"), None, "seeding.svg", self.max_upload_speed) _("Set Maximum Upload Speed"), _("KiB/s"), None, "seeding.svg", self.max_upload_speed)
if value == None: if value is None:
return return
else: else:
value = float(widget.get_children()[0].get_text().split(" ")[0]) value = float(widget.get_children()[0].get_text().split(" ")[0])
@ -457,7 +456,7 @@ class StatusBar(component.Component):
elif widget.get_name() == "other": elif widget.get_name() == "other":
value = common.show_other_dialog( value = common.show_other_dialog(
_("Set Maximum Connections"), "", gtk.STOCK_NETWORK, None, self.max_connections) _("Set Maximum Connections"), "", gtk.STOCK_NETWORK, None, self.max_connections)
if value == None: if value is None:
return return
else: else:
value = int(widget.get_children()[0].get_text().split(" ")[0]) value = int(widget.get_children()[0].get_text().split(" ")[0])

View file

@ -520,10 +520,8 @@ class WebApi(JSONComponent):
d.callback(ui_info) d.callback(ui_info)
return d return d
def got_connections(connections):
ui_info["stats"]["num_connections"] = connections
def got_stats(stats): def got_stats(stats):
ui_info["stats"]["num_connections"] = stats["num_peers"]
ui_info["stats"]["upload_rate"] = stats["payload_upload_rate"] ui_info["stats"]["upload_rate"] = stats["payload_upload_rate"]
ui_info["stats"]["download_rate"] = stats["payload_download_rate"] ui_info["stats"]["download_rate"] = stats["payload_download_rate"]
ui_info["stats"]["download_protocol_rate"] = stats["download_rate"] - stats["payload_download_rate"] ui_info["stats"]["download_protocol_rate"] = stats["download_rate"] - stats["payload_download_rate"]
@ -550,6 +548,7 @@ class WebApi(JSONComponent):
d2.addCallback(got_filters) d2.addCallback(got_filters)
d3 = client.core.get_session_status([ d3 = client.core.get_session_status([
"num_peers",
"payload_download_rate", "payload_download_rate",
"payload_upload_rate", "payload_upload_rate",
"download_rate", "download_rate",
@ -559,13 +558,10 @@ class WebApi(JSONComponent):
]) ])
d3.addCallback(got_stats) d3.addCallback(got_stats)
d4 = client.core.get_num_connections() d4 = client.core.get_free_space(self.core_config.get("download_location"))
d4.addCallback(got_connections) d4.addCallback(got_free_space)
d5 = client.core.get_free_space(self.core_config.get("download_location")) dl = DeferredList([d1, d2, d3, d4], consumeErrors=True)
d5.addCallback(got_free_space)
dl = DeferredList([d1, d2, d3, d4, d5], consumeErrors=True)
dl.addCallback(on_complete) dl.addCallback(on_complete)
return d return d