Change torrent saving/loading to use torrent options and update the

state format to support new options.
Some minor modifications to CoreProxy in client -- only run the 
do_multicall timer when 'connected' to a core.
This commit is contained in:
Andrew Resch 2008-02-12 21:29:39 +00:00
parent 31ae3488ba
commit 4c2ec1b8fb
6 changed files with 92 additions and 53 deletions

2
TODO
View File

@ -19,8 +19,6 @@
* Implement caching in core * Implement caching in core
* Use the batch torrent status info as a cache for other torrent status requests * Use the batch torrent status info as a cache for other torrent status requests
* Don't save fastresume files on exit for finished or paused torrents * Don't save fastresume files on exit for finished or paused torrents
* Clean-up TorrentManager and state saving.. Maybe use an 'options' dictionary
similar to one used when adding new torrents.
* Add Files and Peers tabs, but make them optional through View menu * Add Files and Peers tabs, but make them optional through View menu
* Add per-torrent speed settings to the torrent menu * Add per-torrent speed settings to the torrent menu
* Add per-torrent settings to the details pane.. max_download_speed, etc.. So * Add per-torrent settings to the details pane.. max_download_speed, etc.. So

View File

@ -62,11 +62,11 @@ class Component:
pass pass
def _stop(self): def _stop(self):
self._state = COMPONENT_STATE.index("Stopped")
try: try:
gobject.source_remove(self._timer) gobject.source_remove(self._timer)
except: except:
pass pass
self._state = COMPONENT_STATE.index("Stopped")
def shutdown(self): def shutdown(self):
pass pass
@ -121,7 +121,7 @@ class ComponentRegistry:
self.stop_component(component) self.stop_component(component)
def stop_component(self, component): def stop_component(self, component):
if self.components[component].get_state != \ if self.components[component].get_state() != \
COMPONENT_STATE.index("Stopped"): COMPONENT_STATE.index("Stopped"):
log.debug("Stopping component %s..", component) log.debug("Stopping component %s..", component)
self.components[component].stop() self.components[component].stop()

View File

@ -287,19 +287,15 @@ class Core(
"""De-registers a client with the signal manager.""" """De-registers a client with the signal manager."""
self.signals.deregister_client(self.client_address) self.signals.deregister_client(self.client_address)
def export_add_torrent_file(self, filename, save_path, filedump, options): def export_add_torrent_file(self, filename, filedump, options):
"""Adds a torrent file to the libtorrent session """Adds a torrent file to the libtorrent session
This requires the torrents filename and a dump of it's content This requires the torrents filename and a dump of it's content
""" """
if save_path == "":
save_path = None
# Make sure we are sending a string to add() # Make sure we are sending a string to add()
if not isinstance(filedump, str): if not isinstance(filedump, str):
filedump = filedump.data filedump = filedump.data
torrent_id = self.torrents.add(filename, filedump=filedump, torrent_id = self.torrents.add(filename, filedump=filedump, options=options)
save_path=save_path, options=options)
# Run the plugin hooks for 'post_torrent_add' # Run the plugin hooks for 'post_torrent_add'
self.plugins.run_post_torrent_add(torrent_id) self.plugins.run_post_torrent_add(torrent_id)

View File

@ -83,7 +83,7 @@ class Torrent:
self.max_upload_speed = -1 self.max_upload_speed = -1
self.max_download_speed = -1 self.max_download_speed = -1
self.private = False self.private = False
self.prioritize = False self.prioritize_first_last = False
# The tracker status # The tracker status
self.tracker_status = "" self.tracker_status = ""
@ -98,10 +98,12 @@ class Torrent:
self.trackers.append(tracker) self.trackers.append(tracker)
else: else:
self.trackers = trackers self.trackers = trackers
self.set_trackers(self.trackers)
# Files dictionary # Files dictionary
self.files = self.get_files() self.files = self.get_files()
self.file_priorities = [] # Set the default file priorities to normal
self.file_priorities = [1]* len(self.files)
def set_tracker_status(self, status): def set_tracker_status(self, status):
"""Sets the tracker status""" """Sets the tracker status"""
@ -128,7 +130,7 @@ class Torrent:
self.handle.torrent_info().set_priv(private) self.handle.torrent_info().set_priv(private)
def set_prioritize_first_last(self, prioritize): def set_prioritize_first_last(self, prioritize):
pass self.prioritize_first_last = prioritize
def set_save_path(self, save_path): def set_save_path(self, save_path):
self.save_path = save_path self.save_path = save_path

View File

@ -48,15 +48,36 @@ from deluge.core.torrent import Torrent
from deluge.log import LOG as log from deluge.log import LOG as log
class TorrentState: class TorrentState:
def __init__(self, torrent_id, filename, compact, paused, save_path, def __init__(self,
total_uploaded, trackers): filename,
self.torrent_id = torrent_id total_uploaded,
trackers,
compact,
paused,
save_path,
max_connections,
max_upload_slots,
max_upload_speed,
max_download_speed,
prioritize_first_last,
private,
file_priorities
):
self.filename = filename self.filename = filename
self.total_uploaded = total_uploaded
self.trackers = trackers
# Options
self.compact = compact self.compact = compact
self.paused = paused self.paused = paused
self.save_path = save_path self.save_path = save_path
self.total_uploaded = total_uploaded self.max_connections = max_connections
self.trackers = trackers self.max_upload_slots = max_upload_slots
self.max_upload_speed = max_upload_speed
self.max_download_speed = max_download_speed
self.prioritize_first_last = prioritize_first_last
self.private = private
self.file_priorities = file_priorities
class TorrentManagerState: class TorrentManagerState:
def __init__(self): def __init__(self):
@ -130,9 +151,7 @@ class TorrentManager(component.Component):
"""Returns a list of torrent_ids""" """Returns a list of torrent_ids"""
return self.torrents.keys() return self.torrents.keys()
def add(self, filename, filedump=None, options=None, def add(self, filename, filedump=None, options=None, total_uploaded=0, trackers=None):
compact=None, paused=None, save_path=None, total_uploaded=0,
trackers=None):
"""Add a torrent to the manager and returns it's torrent_id""" """Add a torrent to the manager and returns it's torrent_id"""
log.info("Adding torrent: %s", filename) log.info("Adding torrent: %s", filename)
log.debug("options: %s", options) log.debug("options: %s", options)
@ -193,20 +212,9 @@ class TorrentManager(component.Component):
for key in options_keys: for key in options_keys:
if not options.has_key(key): if not options.has_key(key):
options[key] = self.config[key] options[key] = self.config[key]
if paused is None:
paused = options["add_paused"]
# Make sure we have a valid download_location
if save_path is None:
save_path = options["download_location"]
# Make sure we are adding it with the correct allocation method.
if compact is None:
compact = options["compact_allocation"]
# Set the right storage_mode # Set the right storage_mode
if compact: if options["compact_allocation"]:
storage_mode = lt.storage_mode_t(2) storage_mode = lt.storage_mode_t(2)
else: else:
storage_mode = lt.storage_mode_t(1) storage_mode = lt.storage_mode_t(1)
@ -214,7 +222,7 @@ class TorrentManager(component.Component):
try: try:
handle = self.session.add_torrent( handle = self.session.add_torrent(
lt.torrent_info(filedump), lt.torrent_info(filedump),
str(save_path), str(options["download_location"]),
resume_data=fastresume, resume_data=fastresume,
storage_mode=storage_mode, storage_mode=storage_mode,
paused=True) paused=True)
@ -226,15 +234,11 @@ class TorrentManager(component.Component):
return None return None
# Create a Torrent object # Create a Torrent object
torrent = Torrent(filename, handle, compact, torrent = Torrent(filename, handle, options["compact_allocation"],
save_path, total_uploaded, trackers) options["download_location"], total_uploaded, trackers)
# Add the torrent object to the dictionary # Add the torrent object to the dictionary
self.torrents[torrent.torrent_id] = torrent self.torrents[torrent.torrent_id] = torrent
# Set the trackers
if trackers != None:
torrent.set_trackers(trackers)
# Set per-torrent options # Set per-torrent options
torrent.set_max_connections(options["max_connections_per_torrent"]) torrent.set_max_connections(options["max_connections_per_torrent"])
@ -252,7 +256,7 @@ class TorrentManager(component.Component):
torrent.set_file_priorities(options["file_priorities"]) torrent.set_file_priorities(options["file_priorities"])
# Resume the torrent if needed # Resume the torrent if needed
if paused == False: if options["add_paused"] == False:
handle.resume() handle.resume()
# Save the torrent file # Save the torrent file
@ -408,17 +412,48 @@ class TorrentManager(component.Component):
# Try to add the torrents in the state to the session # Try to add the torrents in the state to the session
for torrent_state in state.torrents: for torrent_state in state.torrents:
self.add(torrent_state.filename, compact=torrent_state.compact, try:
paused=torrent_state.paused, save_path=torrent_state.save_path, options = {
total_uploaded=torrent_state.total_uploaded, "compact_allocation": torrent_state.compact,
trackers=torrent_state.trackers) "max_connections_per_torrent": torrent_state.max_connections,
"max_upload_slots_per_torrent": torrent_state.max_upload_slots,
"max_upload_speed_per_torrent": torrent_state.max_upload_speed,
"max_download_speed_per_torrent": torrent_state.max_download_speed,
"prioritize_first_last_pieces": torrent_state.prioritize_first_last,
"download_location": torrent_state.save_path,
"add_paused": torrent_state.paused,
"default_private": torrent_state.private,
"file_priorities": torrent_state.file_priorities
}
self.add(
torrent_state.filename,
options=options,
total_uploaded=torrent_state.total_uploaded,
trackers=torrent_state.trackers)
except AttributeError, e:
log.error("Torrent state file is either corrupt or incompatible!")
break
def save_state(self): def save_state(self):
"""Save the state of the TorrentManager to the torrents.state file""" """Save the state of the TorrentManager to the torrents.state file"""
state = TorrentManagerState() state = TorrentManagerState()
# Create the state for each Torrent and append to the list # Create the state for each Torrent and append to the list
for torrent in self.torrents.values(): for torrent in self.torrents.values():
torrent_state = TorrentState(*torrent.get_save_info()) torrent_state = TorrentState(
torrent.filename,
torrent.get_status(["total_uploaded"])["total_uploaded"],
torrent.trackers,
torrent.compact,
torrent.get_status(["paused"])["paused"],
torrent.save_path,
torrent.max_connections,
torrent.max_upload_slots,
torrent.max_upload_speed,
torrent.max_download_speed,
torrent.prioritize_first_last,
torrent.private,
torrent.file_priorities
)
state.torrents.append(torrent_state) state.torrents.append(torrent_state)
# Pickle the TorrentManagerState object # Pickle the TorrentManagerState object

View File

@ -58,7 +58,7 @@ class CoreProxy(gobject.GObject):
self._core = None self._core = None
self._multi = None self._multi = None
self._callbacks = [] self._callbacks = []
gobject.timeout_add(200, self.do_multicall) self._multi_timer = None
def call(self, func, callback, *args): def call(self, func, callback, *args):
if self._core is None or self._multi is None: if self._core is None or self._multi is None:
@ -84,7 +84,7 @@ class CoreProxy(gobject.GObject):
if len(self._callbacks) == 0: if len(self._callbacks) == 0:
return True return True
if self._multi is not None: if self._multi is not None and self._core is not None:
try: try:
try: try:
for i, ret in enumerate(self._multi()): for i, ret in enumerate(self._multi()):
@ -109,15 +109,23 @@ class CoreProxy(gobject.GObject):
log.info("Setting core uri as %s", uri) log.info("Setting core uri as %s", uri)
if uri == None and self._uri != None: if uri == None and self._uri != None:
self.emit("no_core")
self._uri = None self._uri = None
self._core = None self._core = None
self._multi = None self._multi = None
try:
gobject.source_remove(self._multi_timer)
except:
pass
self.emit("no_core")
return return
if uri != self._uri and self._uri != None: if uri != self._uri and self._uri != None:
self._core = None self._core = None
self._multi = None self._multi = None
try:
gobject.source_remove(self._multi_timer)
except:
pass
self.emit("no_core") self.emit("no_core")
self._uri = uri self._uri = uri
@ -133,6 +141,7 @@ class CoreProxy(gobject.GObject):
log.debug("Creating ServerProxy..") log.debug("Creating ServerProxy..")
self._core = xmlrpclib.ServerProxy(self._uri, allow_none=True) self._core = xmlrpclib.ServerProxy(self._uri, allow_none=True)
self._multi = xmlrpclib.MultiCall(self._core) self._multi = xmlrpclib.MultiCall(self._core)
self._multi_timer = gobject.timeout_add(200, self.do_multicall)
# Call any callbacks registered # Call any callbacks registered
self.emit("new_core") self.emit("new_core")
@ -189,8 +198,7 @@ def shutdown():
try: try:
get_core().call("shutdown", None) get_core().call("shutdown", None)
force_call(block=False) force_call(block=False)
except: finally:
# Ignore everything
set_core_uri(None) set_core_uri(None)
def force_call(block=True): def force_call(block=True):
@ -231,7 +239,7 @@ def add_torrent_file(torrent_files, torrent_options=None):
options = None options = None
get_core().call("add_torrent_file", None, get_core().call("add_torrent_file", None,
filename, str(), fdump, options) filename, fdump, options)
def add_torrent_url(torrent_url, options=None): def add_torrent_url(torrent_url, options=None):
"""Adds torrents to the core via url""" """Adds torrents to the core via url"""