Big code clean-up in torrentmanager and torrent. This breaks

torrent.state.  Sorry.
This commit is contained in:
Andrew Resch 2008-06-07 00:20:36 +00:00
parent abbba8bf3b
commit bf00795050
4 changed files with 254 additions and 267 deletions

View File

@ -65,6 +65,7 @@ DEFAULT_PREFS = {
"listen_ports": [6881, 6891],
"torrentfiles_location": os.path.join(deluge.configmanager.get_config_dir(), "torrentfiles"),
"plugins_location": os.path.join(deluge.configmanager.get_config_dir(), "plugins"),
"state_location": os.path.join(deluge.configmanager.get_config_dir(), "state"),
"prioritize_first_last_pieces": False,
"random_port": True,
"dht": False,
@ -88,7 +89,6 @@ DEFAULT_PREFS = {
"autoadd_location": "",
"autoadd_enable": False,
"add_paused": False,
"default_private": False,
"max_active_seeding": -1,
"max_active_downloading": -1,
"queue_new_to_top": False,
@ -207,6 +207,8 @@ class Core(
# Register set functions in the Config
self.config.register_set_function("torrentfiles_location",
self._on_set_torrentfiles_location)
self.config.register_set_function("state_location",
self._on_set_state_location)
self.config.register_set_function("listen_ports",
self._on_set_listen_ports)
self.config.register_set_function("random_port",
@ -300,12 +302,31 @@ class Core(
"""Adds a torrent file to the libtorrent session
This requires the torrents filename and a dump of it's content
"""
# Make sure we are sending a string to add()
# Turn the filedump into a torrent_info
if not isinstance(filedump, str):
filedump = filedump.data
# filedump = "".join(chr(b) for b in filedump)
try:
torrent_info = lt.torrent_info(lt.bdecode(filedump))
except RuntimeError, e:
log.warn("Unable to decode torrent file: %s", e)
return None
torrent_id = self.torrents.add(torrent_info=torrent_info, options=options)
torrent_id = self.torrents.add(filename, filedump=filedump, options=options)
# Here we need to save a copy of the filedump for state purposes
# and also if the user wishes to save a copy of the torrent elsewhere.
if torrent_id:
# Write the .torrent file to the state directory
try:
save_file = open(os.path.join(self.config["state_location"],
torrent_id + ".torrent"),
"wb")
save_file.write(filedump)
save_file.close()
except IOError, e:
log.warning("Unable to save torrent file: %s", e)
# Run the plugin hooks for 'post_torrent_add'
self.plugins.run_post_torrent_add(torrent_id)
@ -497,11 +518,7 @@ class Core(
def export_set_torrent_max_download_speed(self, torrent_id, value):
"""Sets a torrents max download speed"""
return self.torrents[torrent_id].set_max_download_speed(value)
def export_set_torrent_private_flag(self, torrent_id, value):
"""Sets a torrents private flag"""
return self.torrents[torrent_id].set_private_flag(value)
def export_set_torrent_file_priorities(self, torrent_id, priorities):
"""Sets a torrents file priorities"""
return self.torrents[torrent_id].set_file_priorities(priorities)
@ -636,7 +653,14 @@ class Core(
shutil.copy2(os.path.join(root, file), value)
except Exception, e:
log.debug("Unable to copy file to %s: %s", value, e)
def _on_set_state_location(self, key, value):
if not os.access(value, os.F_OK):
try:
os.makedirs(value)
except Exception, e:
log.debug("Unable to make directory: %s", e)
def _on_set_listen_ports(self, key, value):
# Only set the listen ports if random_port is not true
if self.config["random_port"] is not True:

View File

@ -47,8 +47,7 @@ TORRENT_STATE = deluge.common.TORRENT_STATE
class Torrent:
"""Torrent holds information about torrents added to the libtorrent session.
"""
def __init__(self, filename, handle, compact, save_path, total_uploaded=0,
trackers=None):
def __init__(self, handle, options, state=None):
log.debug("Creating torrent object %s", str(handle.info_hash()))
# Get the core config
self.config = ConfigManager("core.conf")
@ -56,41 +55,32 @@ class Torrent:
# Get a reference to the TorrentQueue
self.torrentqueue = component.get("TorrentQueue")
self.signals = component.get("SignalManager")
# Set the filename
self.filename = filename
# Set the libtorrent handle
self.handle = handle
# Set the torrent_id for this torrent
self.torrent_id = str(handle.info_hash())
# This is for saving the total uploaded between sessions
self.total_uploaded = total_uploaded
# Set the allocation mode
self.compact = compact
# Where the torrent is being saved to
self.save_path = save_path
# Status message holds error info about the torrent
self.statusmsg = "OK"
# The torrents state
self.state = ""
# Holds status info so that we don't need to keep getting it from lt
self.status = self.handle.status()
self.torrent_info = self.handle.get_torrent_info()
# Various torrent options
self.max_connections = -1
self.max_upload_slots = -1
self.max_upload_speed = -1
self.max_download_speed = -1
self.private = False
self.prioritize_first_last = False
# Files dictionary
self.files = self.get_files()
# Set the default file priorities to normal
self.file_priorities = [1]* len(self.files)
# The tracker status
self.tracker_status = ""
# Tracker list
if trackers == None:
# Default total_uploaded to 0, this may be changed by the state
self.total_uploaded = 0
# Load values from state if we have it
if state is not None:
# This is for saving the total uploaded between sessions
self.total_uploaded = state.total_uploaded
# Set the trackers
self.set_trackers(state.trackers)
else:
# Tracker list
self.trackers = []
# Create a list of trackers
for value in self.handle.trackers():
@ -98,17 +88,33 @@ class Torrent:
tracker["url"] = value.url
tracker["tier"] = value.tier
self.trackers.append(tracker)
else:
self.trackers = trackers
self.set_trackers(self.trackers)
# Files dictionary
self.files = self.get_files()
# Set the default file priorities to normal
self.file_priorities = [1]* len(self.files)
# Set resolve_countries to True
self.handle.resolve_countries(True)
# Various torrent options
self.set_max_connections(options["max_connections_per_torrent"])
self.set_max_upload_slots(options["max_upload_slots_per_torrent"])
self.set_max_upload_speed(options["max_upload_speed_per_torrent"])
self.set_max_download_speed(options["max_download_speed_per_torrent"])
self.set_prioritize_first_last(options["prioritize_first_last_pieces"])
self.handle.resolve_countries(True)
if options.has_key("file_priorities"):
self.set_file_priorities(options["file_priorities"])
# Set the allocation mode
self.compact = options["compact_allocation"]
# Where the torrent is being saved to
self.save_path = options["download_location"]
# Status message holds error info about the torrent
self.statusmsg = "OK"
# The torrents state
self.state = ""
# The tracker status
self.tracker_status = ""
# This variable is to prevent a state change to 'Paused' when it should
# be 'Queued'
self.next_pause_is_queued = False
log.debug("Torrent object created.")
@ -132,10 +138,6 @@ class Torrent:
self.max_download_speed = m_down_speed
self.handle.set_download_limit(int(m_down_speed * 1024))
def set_private_flag(self, private):
self.private = private
#self.handle.get_torrent_info().set_priv(private)
def set_prioritize_first_last(self, prioritize):
self.prioritize_first_last = prioritize
@ -155,6 +157,30 @@ class Torrent:
self.file_priorities = file_priorities
self.handle.prioritize_files(file_priorities)
def set_trackers(self, trackers):
"""Sets trackers"""
if trackers == None:
trackers = []
log.debug("Setting trackers for %s: %s", self.torrent_id, trackers)
tracker_list = []
for tracker in trackers:
new_entry = lt.announce_entry(tracker["url"])
new_entry.tier = tracker["tier"]
tracker_list.append(new_entry)
self.handle.replace_trackers(tracker_list)
# Print out the trackers
for t in self.handle.trackers():
log.debug("tier: %s tracker: %s", t.tier, t.url)
# Set the tracker list in the torrent object
self.trackers = trackers
if len(trackers) > 0:
# Force a reannounce if there is at least 1 tracker
self.force_reannounce()
def set_state_based_on_ltstate(self):
"""Updates the state based on what libtorrent's state for the torrent is"""
@ -183,8 +209,18 @@ class Torrent:
if state != self.state:
if state == "Queued" and not self.handle.is_paused():
component.get("TorrentManager").append_not_state_paused(self.torrent_id)
#component.get("TorrentManager").append_not_state_paused(self.torrent_id)
self.next_pause_is_queued = True
self.handle.pause()
if state == "Error" and not self.handle.is_paused():
self.next_pause_is_queued = True
if state == "Paused":
if self.next_pause_is_queued:
self.state = "Queued"
self.next_pause_is_queued = False
else:
self.state = "Paused"
log.debug("Setting %s's state to %s", self.torrent_id, state)
self.state = state
@ -256,7 +292,6 @@ class Torrent:
def get_queue_position(self):
# We augment the queue position + 1 so that the user sees a 1 indexed
# list.
return self.torrentqueue[self.torrent_id] + 1
def get_peers(self):
@ -335,13 +370,13 @@ class Torrent:
"max_upload_speed": self.max_upload_speed,
"max_download_speed": self.max_download_speed,
"prioritize_first_last": self.prioritize_first_last,
"private": self.private,
"message": self.statusmsg,
"hash": self.torrent_id
}
fns = {
"name": self.torrent_info.name,
"private": self.torrent_info.priv,
"total_size": self.torrent_info.total_size,
"num_files": self.torrent_info.num_files,
"num_pieces": self.torrent_info.num_pieces,
@ -372,14 +407,13 @@ class Torrent:
status_dict[key] = fns[key]()
return status_dict
def apply_options(self):
"""Applies the per-torrent options that are set."""
self.handle.set_max_connections(self.max_connections)
self.handle.set_max_uploads(self.max_upload_slots)
self.handle.set_upload_limit(int(self.max_upload_speed * 1024))
self.handle.set_download_limit(int(self.max_download_speed * 1024))
self.handle.get_torrent_info().set_priv(self.private)
self.handle.prioritize_files(self.file_priorities)
self.handle.resolve_countries(True)
@ -472,8 +506,8 @@ class Torrent:
"""Writes the .fastresume file for the torrent"""
resume_data = lt.bencode(self.handle.write_resume_data())
path = "%s/%s.fastresume" % (
self.config["torrentfiles_location"],
self.filename)
self.config["state_location"],
self.torrent_id)
log.debug("Saving fastresume file: %s", path)
try:
fastresume = open(path, "wb")
@ -485,14 +519,25 @@ class Torrent:
def delete_fastresume(self):
"""Deletes the .fastresume file"""
path = "%s/%s.fastresume" % (
self.config["torrentfiles_location"],
self.filename)
self.config["state_location"],
self.torrent_id)
log.debug("Deleting fastresume file: %s", path)
try:
os.remove(path)
except Exception, e:
log.warning("Unable to delete the fastresume file: %s", e)
def delete_torrentfile(self):
"""Deletes the .torrent file in the state"""
path = "%s/%s.torrent" % (
self.config["state_location"],
self.torrent_id)
log.debug("Deleting torrent file: %s", path)
try:
os.remove(path)
except Exception, e:
log.warning("Unable to delete the torrent file: %s", e)
def force_reannounce(self):
"""Force a tracker reannounce"""
try:
@ -512,52 +557,3 @@ class Torrent:
return False
return True
def set_trackers(self, trackers):
"""Sets trackers"""
if trackers == None:
trackers = []
log.debug("Setting trackers for %s: %s", self.torrent_id, trackers)
tracker_list = []
for tracker in trackers:
new_entry = lt.announce_entry(tracker["url"])
new_entry.tier = tracker["tier"]
tracker_list.append(new_entry)
self.handle.replace_trackers(tracker_list)
# Print out the trackers
for t in self.handle.trackers():
log.debug("tier: %s tracker: %s", t.tier, t.url)
# Set the tracker list in the torrent object
self.trackers = trackers
if len(trackers) > 0:
# Force a reannounce if there is at least 1 tracker
self.force_reannounce()
def save_torrent_file(self, filedump=None):
"""Saves a torrent file"""
log.debug("Attempting to save torrent file: %s", self.filename)
# Test if the torrentfiles_location is accessible
if os.access(
os.path.join(self.config["torrentfiles_location"]), os.F_OK) \
is False:
# The directory probably doesn't exist, so lets create it
try:
os.makedirs(os.path.join(self.config["torrentfiles_location"]))
except IOError, e:
log.warning("Unable to create torrent files directory: %s", e)
# Write the .torrent file to the torrent directory
try:
save_file = open(os.path.join(self.config["torrentfiles_location"],
self.filename),
"wb")
if filedump == None:
filedump = self.handle.get_torrent_info().create_torrent()
save_file.write(lt.bencode(filedump))
save_file.close()
except IOError, e:
log.warning("Unable to save torrent file: %s", e)

View File

@ -51,8 +51,7 @@ from deluge.log import LOG as log
class TorrentState:
def __init__(self,
torrent_id,
filename,
torrent_id,
total_uploaded,
trackers,
compact,
@ -63,12 +62,10 @@ class TorrentState:
max_upload_speed,
max_download_speed,
prioritize_first_last,
private,
file_priorities,
queue
):
self.torrent_id = torrent_id
self.filename = filename
self.total_uploaded = total_uploaded
self.trackers = trackers
self.queue = queue
@ -82,7 +79,6 @@ class TorrentState:
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:
@ -108,9 +104,6 @@ class TorrentManager(component.Component):
# Create the torrents dict { torrent_id: Torrent }
self.torrents = {}
# List of torrents to not set state 'Paused' on lt alert
self.not_state_paused = []
# Register set functions
self.config.register_set_function("max_connections_per_torrent",
@ -172,105 +165,119 @@ class TorrentManager(component.Component):
def get_torrent_list(self):
"""Returns a list of torrent_ids"""
return self.torrents.keys()
def get_torrent_info_from_file(self, filepath):
"""Returns a torrent_info for the file specified or None"""
torrent_info = None
# Get the torrent data from the torrent file
try:
log.debug("Attempting to create torrent_info from %s", filepath)
_file = open(filepath, "rb")
torrent_info = lt.torrent_info(lt.bdecode(_file.read()))
_file.close()
except (IOError, RuntimeError), e:
log.warning("Unable to open %s: %s", filepath, e)
return torrent_info
def append_not_state_paused(self, torrent_id):
"""Appends to a list of torrents that we will not set state Paused to
when we receive the paused alert from libtorrent. The torrents are removed
from this list once we receive the alert they have been paused in libtorrent."""
if torrent_id not in self.not_state_paused:
self.not_state_paused.append(torrent_id)
def add(self, filename, filedump=None, options=None, total_uploaded=0,
trackers=None, queue=-1, state=None, save_state=True):
"""Add a torrent to the manager and returns it's torrent_id"""
log.info("Adding torrent: %s", filename)
log.debug("options: %s", options)
# Make sure 'filename' is a python string
filename = str(filename)
# Convert the filedump data array into a string of bytes
if filedump is not None:
# If the filedump is already of type str, then it's already been
# joined.
if type(filedump) is not str:
filedump = "".join(chr(b) for b in filedump)
try:
filedump = lt.bdecode(filedump)
except RuntimeError, e:
log.warn("Unable to decode torrent file: %s", e)
return None
else:
# Get the data from the file
filedump = self.load_torrent(filename)
if not filedump:
log.warning("Unable to load torrent file..")
return None
# Attempt to load fastresume data
def get_resume_data_from_file(self, torrent_id):
"""Returns an entry with the resume data or None"""
fastresume = None
try:
_file = open(
os.path.join(
self.config["torrentfiles_location"],
filename + ".fastresume"),
self.config["state_location"],
torrent_id + ".fastresume"),
"rb")
try:
fastresume = lt.bdecode(_file.read())
except RuntimeError, e:
log.warning("Unable to bdecode fastresume file: %s", e)
fastresume = None
_file.close()
except IOError, e:
log.debug("Unable to load .fastresume: %s", e)
fastresume = None
handle = None
return fastresume
def add(self, torrent_info=None, state=None, options=None, save_state=True):
"""Add a torrent to the manager and returns it's torrent_id"""
if torrent_info is None and state is None:
log.debug("You must specify a valid torrent_info or a torrent state object!")
return
# Check if options is None and load defaults
options_keys = [
"compact_allocation",
"max_connections_per_torrent",
"max_upload_slots_per_torrent",
"max_upload_speed_per_torrent",
"max_download_speed_per_torrent",
"prioritize_first_last_pieces",
"download_location",
"add_paused",
"default_private"
]
log.debug("torrentmanager.add")
add_torrent_params = {}
if torrent_info is None:
# We have no torrent_info so we need to add the torrent with information
# from the state object.
if options == None:
# Populate the options dict from state
options = {}
for key in options_keys:
options[key] = self.config[key]
options["max_connections_per_torrent"] = state.max_connections
options["max_upload_slots_per_torrent"] = state.max_upload_slots
options["max_upload_speed_per_torrent"] = state.max_upload_speed
options["max_download_speed_per_torrent"] = state.max_download_speed
options["prioritize_first_last_pieces"] = state.prioritize_first_last
options["file_priorities"] = state.file_priorities
options["compact_allocation"] = state.compact
options["download_location"] = state.save_path
add_torrent_params["ti"] =\
self.get_torrent_info_from_file(
os.path.join(self.config["state_location"], state.torrent_id + ".torrent"))
add_torrent_params["resume_data"] = self.get_resume_data_from_file(state.torrent_id)
else:
for key in options_keys:
if not options.has_key(key):
# We have a torrent_info object so we're not loading from state.
# Check if options is None and load defaults
options_keys = [
"compact_allocation",
"max_connections_per_torrent",
"max_upload_slots_per_torrent",
"max_upload_speed_per_torrent",
"max_download_speed_per_torrent",
"prioritize_first_last_pieces",
"download_location",
"add_paused",
]
if options == None:
options = {}
for key in options_keys:
options[key] = self.config[key]
else:
for key in options_keys:
if not options.has_key(key):
options[key] = self.config[key]
add_torrent_params["ti"] = torrent_info
add_torrent_params["resume_data"] = None
#log.info("Adding torrent: %s", filename)
log.debug("options: %s", options)
# Set the right storage_mode
if options["compact_allocation"]:
storage_mode = lt.storage_mode_t(2)
else:
storage_mode = lt.storage_mode_t(1)
# Fill in the rest of the add_torrent_params dictionary
add_torrent_params["save_path"] = str(options["download_location"])
add_torrent_params["storage_mode"] = storage_mode
add_torrent_params["paused"] = True
add_torrent_params["auto_managed"] = False
add_torrent_params["duplicate_is_error"] = True
# We need to pause the AlertManager momentarily to prevent alerts
# for this torrent being generated before a Torrent object is created.
component.pause("AlertManager")
# Create the torrent parameters struct for the torrent's options
t_params = {}
t_params["ti"] = lt.torrent_info(filedump)
t_params["save_path"] = str(options["download_location"])
t_params["resume_data"] = fastresume
t_params["storage_mode"] = storage_mode
t_params["paused"] = True
t_params["auto_managed"] = False
t_params["duplicate_is_error"] = True
handle = None
try:
handle = self.session.add_torrent(t_params)
handle = self.session.add_torrent(add_torrent_params)
except RuntimeError, e:
log.warning("Error adding torrent: %s", e)
@ -278,76 +285,59 @@ class TorrentManager(component.Component):
log.debug("torrent handle is invalid!")
# The torrent was not added to the session
component.resume("AlertManager")
return None
return
log.debug("handle id: %s", str(handle.info_hash()))
# Create a Torrent object
torrent = Torrent(filename, handle, options["compact_allocation"],
options["download_location"], total_uploaded, trackers)
torrent = Torrent(handle, options, state)
# Add the torrent object to the dictionary
self.torrents[torrent.torrent_id] = torrent
component.resume("AlertManager")
# Add the torrent to the queue
if queue == -1 and self.config["queue_new_to_top"]:
self.queue.insert(0, torrent.torrent_id)
if state is not None:
self.queue.insert(state.queue, torrent.torrent_id)
else:
self.queue.insert(queue, torrent.torrent_id)
if self.config["queue_new_to_top"]:
self.queue.insert(0, torrent.torrent_id)
else:
self.queue.append(torrent.torrent_id)
# Set per-torrent options
torrent.set_max_connections(options["max_connections_per_torrent"])
torrent.set_max_upload_slots(options["max_upload_slots_per_torrent"])
torrent.set_max_upload_speed(options["max_upload_speed_per_torrent"])
torrent.set_max_download_speed(
options["max_download_speed_per_torrent"])
torrent.set_prioritize_first_last(
options["prioritize_first_last_pieces"])
torrent.set_private_flag(options["default_private"])
if options.has_key("file_priorities"):
if options["file_priorities"] != None:
log.debug("set file priorities: %s", options["file_priorities"])
torrent.set_file_priorities(options["file_priorities"])
log.debug("state: %s", state)
# Resume the torrent if needed
if state == "Queued":
torrent.state = "Queued"
elif state == "Paused" or state == "Error":
if state == "Paused" or state == "Error":
torrent.state = "Paused"
if state == None and not options["add_paused"]:
elif state == None and not options["add_paused"]:
torrent.handle.resume()
# We set the state based on libtorrent's state
torrent.set_state_based_on_ltstate()
if state == None and options["add_paused"]:
elif state == None and options["add_paused"]:
torrent.set_state = "Paused"
# Emit the torrent_added signal
self.signals.emit("torrent_added", torrent.torrent_id)
# Save the torrent file
torrent.save_torrent_file(filedump)
if save_state:
# Save the session state
self.save_state()
# Emit the torrent_added signal
self.signals.emit("torrent_added", torrent.torrent_id)
return torrent.torrent_id
def load_torrent(self, filename):
"""Load a torrent file and return it's torrent info"""
def load_torrent(self, torrent_id):
"""Load a torrent file from state and return it's torrent info"""
filedump = None
# Get the torrent data from the torrent file
try:
log.debug("Attempting to open %s for add.", filename)
log.debug("Attempting to open %s for add.", torrent_id)
_file = open(
os.path.join(
self.config["torrentfiles_location"], filename),
self.config["state_location"], torrent_id + ".torrent"),
"rb")
filedump = lt.bdecode(_file.read())
_file.close()
except (IOError, RuntimeError), e:
log.warning("Unable to open %s: %s", filename, e)
log.warning("Unable to open %s: %s", torrent_id, e)
return False
return filedump
@ -379,6 +369,9 @@ class TorrentManager(component.Component):
# Remove the .fastresume if it exists
self.torrents[torrent_id].delete_fastresume()
# Remove the .torrent file in the state
self.torrents[torrent_id].delete_torrentfile()
# Remove the torrent from the queue
self.queue.remove(torrent_id)
@ -417,15 +410,12 @@ class TorrentManager(component.Component):
def force_recheck(self, torrent_id):
"""Forces a re-check of the torrent's data"""
log.debug("force recheck is broken for the time being")
return
log.debug("Doing a forced recheck on %s", torrent_id)
torrent = self.torrents[torrent_id]
paused = self.torrents[torrent_id].handle.is_paused()
torrent_info = None
### Check for .torrent file prior to removing and make a copy if needed
if os.access(os.path.join(self.config["torrentfiles_location"] +\
"/" + torrent.filename), os.F_OK) is False:
torrent_info = torrent.handle.get_torrent_info().create_torrent()
torrent.save_torrent_file()
torrent_info = torrent.handle.get_torrent_info()
# We need to pause the AlertManager momentarily to prevent alerts
# for this torrent being generated before a Torrent object is created.
@ -439,11 +429,11 @@ class TorrentManager(component.Component):
return False
# Remove the fastresume file if there
torrent.delete_fastresume()
#torrent.delete_fastresume()
# Load the torrent info from file if needed
if torrent_info == None:
torrent_info = self.load_torrent(torrent.filename)
torrent_info = self.load_torrent(torrent.torrent_id)
# Next we re-add the torrent
@ -489,7 +479,7 @@ class TorrentManager(component.Component):
try:
log.debug("Opening torrent state file for load.")
state_file = open(
os.path.join(self.config["config_location"], "torrents.state"), "rb")
os.path.join(self.config["state_location"], "torrents.state"), "rb")
state = cPickle.load(state_file)
state_file.close()
except IOError:
@ -506,37 +496,20 @@ class TorrentManager(component.Component):
fr_first = []
for torrent_state in state.torrents:
if os.path.exists(os.path.join(
self.config["torrentfiles_location"],
torrent_state.filename, ".fastresume")):
self.config["state_location"],
torrent_state.torrent_id, ".fastresume")):
fr_first.insert(0, torrent_state)
else:
fr_first.append(torrent_state)
for torrent_state in fr_first:
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": True,
"default_private": torrent_state.private,
"file_priorities": torrent_state.file_priorities
}
# We need to resume all non-add_paused torrents after plugin hook
if torrent_state.state not in ["Paused", "Queued", "Error"]:
resume_torrents.append(torrent_state.torrent_id)
self.add(
torrent_state.filename,
options=options,
total_uploaded=torrent_state.total_uploaded,
trackers=torrent_state.trackers,
queue=torrent_state.queue,
state=torrent_state.state,
state=torrent_state,
save_state=False)
except AttributeError, e:
@ -559,7 +532,6 @@ class TorrentManager(component.Component):
for torrent in self.torrents.values():
torrent_state = TorrentState(
torrent.torrent_id,
torrent.filename,
torrent.get_status(["total_uploaded"])["total_uploaded"],
torrent.trackers,
torrent.compact,
@ -570,7 +542,6 @@ class TorrentManager(component.Component):
torrent.max_upload_speed,
torrent.max_download_speed,
torrent.prioritize_first_last,
torrent.private,
torrent.file_priorities,
torrent.get_status(["queue"])["queue"] - 1 # We subtract 1 due to augmentation
)
@ -580,7 +551,7 @@ class TorrentManager(component.Component):
try:
log.debug("Saving torrent state file.")
state_file = open(
os.path.join(self.config["config_location"], "torrents.state"),
os.path.join(self.config["state_location"], "torrents.state"),
"wb")
cPickle.dump(state, state_file)
state_file.close()
@ -640,13 +611,9 @@ class TorrentManager(component.Component):
# Get the torrent_id
torrent_id = str(alert.handle.info_hash())
# Set the torrent state
log.debug("not_state_paused: %s", self.not_state_paused)
if not torrent_id in self.not_state_paused:
log.debug("Setting state 'Paused'..")
self.torrents[torrent_id].set_state("Paused")
component.get("SignalManager").emit("torrent_paused", torrent_id)
else:
self.not_state_paused.remove(torrent_id)
log.debug("Setting state 'Paused'..")
self.torrents[torrent_id].set_state("Paused")
component.get("SignalManager").emit("torrent_paused", torrent_id)
# Write the fastresume file
self.torrents[torrent_id].write_fastresume()
@ -731,4 +698,4 @@ class TorrentManager(component.Component):
torrent_id = str(alert.handle.info_hash())
self.torrents[torrent_id].set_state("Error")
self.torrents[torrent_id].set_status_message(str(alert.msg()))
self.not_state_paused.append(torrent_id)

View File

@ -200,7 +200,7 @@ class TorrentQueue(component.Component):
try:
return self.queue.index(torrent_id)
except ValueError:
return None
return -1
def append(self, torrent_id):
"""Append torrent_id to the bottom of the queue"""