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
* 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
* 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 per-torrent speed settings to the torrent menu
* Add per-torrent settings to the details pane.. max_download_speed, etc.. So

View File

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

View File

@ -287,19 +287,15 @@ class Core(
"""De-registers a client with the signal manager."""
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
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()
if not isinstance(filedump, str):
filedump = filedump.data
torrent_id = self.torrents.add(filename, filedump=filedump,
save_path=save_path, options=options)
torrent_id = self.torrents.add(filename, filedump=filedump, options=options)
# Run the plugin hooks for 'post_torrent_add'
self.plugins.run_post_torrent_add(torrent_id)

View File

@ -83,7 +83,7 @@ class Torrent:
self.max_upload_speed = -1
self.max_download_speed = -1
self.private = False
self.prioritize = False
self.prioritize_first_last = False
# The tracker status
self.tracker_status = ""
@ -98,10 +98,12 @@ class Torrent:
self.trackers.append(tracker)
else:
self.trackers = trackers
self.set_trackers(self.trackers)
# Files dictionary
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):
"""Sets the tracker status"""
@ -128,7 +130,7 @@ class Torrent:
self.handle.torrent_info().set_priv(private)
def set_prioritize_first_last(self, prioritize):
pass
self.prioritize_first_last = prioritize
def set_save_path(self, 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
class TorrentState:
def __init__(self, torrent_id, filename, compact, paused, save_path,
total_uploaded, trackers):
self.torrent_id = torrent_id
def __init__(self,
filename,
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.total_uploaded = total_uploaded
self.trackers = trackers
# Options
self.compact = compact
self.paused = paused
self.save_path = save_path
self.total_uploaded = total_uploaded
self.trackers = trackers
self.max_connections = max_connections
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:
def __init__(self):
@ -130,9 +151,7 @@ class TorrentManager(component.Component):
"""Returns a list of torrent_ids"""
return self.torrents.keys()
def add(self, filename, filedump=None, options=None,
compact=None, paused=None, save_path=None, total_uploaded=0,
trackers=None):
def add(self, filename, filedump=None, options=None, total_uploaded=0, trackers=None):
"""Add a torrent to the manager and returns it's torrent_id"""
log.info("Adding torrent: %s", filename)
log.debug("options: %s", options)
@ -194,19 +213,8 @@ class TorrentManager(component.Component):
if not options.has_key(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
if compact:
if options["compact_allocation"]:
storage_mode = lt.storage_mode_t(2)
else:
storage_mode = lt.storage_mode_t(1)
@ -214,7 +222,7 @@ class TorrentManager(component.Component):
try:
handle = self.session.add_torrent(
lt.torrent_info(filedump),
str(save_path),
str(options["download_location"]),
resume_data=fastresume,
storage_mode=storage_mode,
paused=True)
@ -226,16 +234,12 @@ class TorrentManager(component.Component):
return None
# Create a Torrent object
torrent = Torrent(filename, handle, compact,
save_path, total_uploaded, trackers)
torrent = Torrent(filename, handle, options["compact_allocation"],
options["download_location"], total_uploaded, trackers)
# Add the torrent object to the dictionary
self.torrents[torrent.torrent_id] = torrent
# Set the trackers
if trackers != None:
torrent.set_trackers(trackers)
# Set per-torrent options
torrent.set_max_connections(options["max_connections_per_torrent"])
torrent.set_max_upload_slots(options["max_upload_slots_per_torrent"])
@ -252,7 +256,7 @@ class TorrentManager(component.Component):
torrent.set_file_priorities(options["file_priorities"])
# Resume the torrent if needed
if paused == False:
if options["add_paused"] == False:
handle.resume()
# Save the torrent file
@ -408,17 +412,48 @@ class TorrentManager(component.Component):
# Try to add the torrents in the state to the session
for torrent_state in state.torrents:
self.add(torrent_state.filename, compact=torrent_state.compact,
paused=torrent_state.paused, save_path=torrent_state.save_path,
total_uploaded=torrent_state.total_uploaded,
trackers=torrent_state.trackers)
try:
options = {
"compact_allocation": torrent_state.compact,
"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):
"""Save the state of the TorrentManager to the torrents.state file"""
state = TorrentManagerState()
# Create the state for each Torrent and append to the list
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)
# Pickle the TorrentManagerState object

View File

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