Refactor and tidyup code in torrent.py
This commit is contained in:
parent
25c7e40574
commit
9347a78482
|
@ -52,10 +52,11 @@ def sanitize_filepath(filepath, folder=False):
|
||||||
newfilepath = clean_filename(filepath)
|
newfilepath = clean_filename(filepath)
|
||||||
|
|
||||||
if folder is True:
|
if folder is True:
|
||||||
return newfilepath + "/"
|
newfilepath += "/"
|
||||||
else:
|
|
||||||
return newfilepath
|
return newfilepath
|
||||||
|
|
||||||
|
|
||||||
def convert_lt_files(self, files):
|
def convert_lt_files(self, files):
|
||||||
"""Indexes and decodes files from libtorrent get_files().
|
"""Indexes and decodes files from libtorrent get_files().
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ def convert_lt_files(self, files):
|
||||||
|
|
||||||
return filelist
|
return filelist
|
||||||
|
|
||||||
|
|
||||||
class TorrentOptions(dict):
|
class TorrentOptions(dict):
|
||||||
"""TorrentOptions create a dict of the torrent options.
|
"""TorrentOptions create a dict of the torrent options.
|
||||||
|
|
||||||
|
@ -639,7 +641,8 @@ class Torrent(object):
|
||||||
"""Sets the torrent status message.
|
"""Sets the torrent status message.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message (str): The status message
|
message (str): The status message.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.statusmsg = message
|
self.statusmsg = message
|
||||||
|
|
||||||
|
@ -648,24 +651,18 @@ class Torrent(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: The ETA in seconds.
|
int: The ETA in seconds.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
status = self.status
|
status = self.status
|
||||||
if self.is_finished and self.options["stop_at_ratio"]:
|
|
||||||
# We're a seed, so calculate the time to the 'stop_share_ratio'
|
|
||||||
if not status.upload_payload_rate:
|
|
||||||
return 0
|
|
||||||
stop_ratio = self.options["stop_ratio"]
|
|
||||||
return ((status.all_time_download * stop_ratio) - status.all_time_upload) // status.upload_payload_rate
|
|
||||||
|
|
||||||
left = status.total_wanted - status.total_wanted_done
|
|
||||||
|
|
||||||
if left <= 0 or status.download_payload_rate == 0:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
eta = left // status.download_payload_rate
|
|
||||||
except ZeroDivisionError:
|
|
||||||
eta = 0
|
eta = 0
|
||||||
|
if self.is_finished and self.options["stop_at_ratio"] and status.upload_payload_rate:
|
||||||
|
# We're a seed, so calculate the time to the 'stop_share_ratio'
|
||||||
|
eta = ((status.all_time_download * self.options["stop_ratio"]) -
|
||||||
|
status.all_time_upload) // status.upload_payload_rate
|
||||||
|
elif status.download_payload_rate:
|
||||||
|
left = status.total_wanted - status.total_wanted_done
|
||||||
|
if left > 0:
|
||||||
|
eta = left // status.download_payload_rate
|
||||||
|
|
||||||
return eta
|
return eta
|
||||||
|
|
||||||
|
@ -821,7 +818,36 @@ class Torrent(object):
|
||||||
"""Returns a magnet uri for this torrent"""
|
"""Returns a magnet uri for this torrent"""
|
||||||
return lt.make_magnet_uri(self.handle)
|
return lt.make_magnet_uri(self.handle)
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""The name of the torrent (distinct from the filenames).
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Can be manually set in options through `name` key. If the key is
|
||||||
|
reset to empty string "" it will return the original torrent name.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: the name of the torrent.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not self.options["name"]:
|
||||||
|
handle_name = self.handle.name()
|
||||||
|
if handle_name:
|
||||||
|
name = decode_string(handle_name)
|
||||||
|
else:
|
||||||
|
name = self.torrent_id
|
||||||
|
else:
|
||||||
|
name = self.options["name"]
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
def get_progress(self):
|
def get_progress(self):
|
||||||
|
"""The progress of this torrent's current task.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: The progress percentage (0 to 100).
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def get_size(files, path):
|
def get_size(files, path):
|
||||||
"""Returns total size of 'files' currently located in 'path'"""
|
"""Returns total size of 'files' currently located in 'path'"""
|
||||||
files = [os.path.join(path, f) for f in files]
|
files = [os.path.join(path, f) for f in files]
|
||||||
|
@ -834,6 +860,7 @@ class Torrent(object):
|
||||||
progress = dest_path_size / torrent_status["total_done"] * 100
|
progress = dest_path_size / torrent_status["total_done"] * 100
|
||||||
else:
|
else:
|
||||||
progress = self.status.progress * 100
|
progress = self.status.progress * 100
|
||||||
|
|
||||||
return progress
|
return progress
|
||||||
|
|
||||||
def get_status(self, keys, diff=False, update=False, all_keys=False):
|
def get_status(self, keys, diff=False, update=False, all_keys=False):
|
||||||
|
@ -880,26 +907,6 @@ class Torrent(object):
|
||||||
|
|
||||||
return status_dict
|
return status_dict
|
||||||
|
|
||||||
def get_name(self):
|
|
||||||
"""Return the name of the torrent
|
|
||||||
|
|
||||||
The name of the torrent (distinct from the filenames).
|
|
||||||
|
|
||||||
Can be manually set in options through `name` key. If the key is
|
|
||||||
reset to empty string "" it will return the original torrent name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: the name of the torrent
|
|
||||||
"""
|
|
||||||
if not self.options["name"]:
|
|
||||||
handle_name = self.handle.name()
|
|
||||||
if handle_name:
|
|
||||||
return decode_string(handle_name)
|
|
||||||
else:
|
|
||||||
return self.torrent_id
|
|
||||||
else:
|
|
||||||
return self.options["name"]
|
|
||||||
|
|
||||||
def update_status(self, status):
|
def update_status(self, status):
|
||||||
"""Updates the cached status.
|
"""Updates the cached status.
|
||||||
|
|
||||||
|
@ -913,9 +920,8 @@ class Torrent(object):
|
||||||
self.status_funcs = {
|
self.status_funcs = {
|
||||||
"active_time": lambda: self.status.active_time,
|
"active_time": lambda: self.status.active_time,
|
||||||
"all_time_download": lambda: self.status.all_time_download,
|
"all_time_download": lambda: self.status.all_time_download,
|
||||||
"storage_mode": lambda: self.status.storage_mode.name.split("_")[2], # Returns: sparse, allocate or compact
|
"storage_mode": lambda: self.status.storage_mode.name.split("_")[2], # sparse, allocate or compact
|
||||||
"distributed_copies": lambda: 0.0 if self.status.distributed_copies < 0 else
|
"distributed_copies": lambda: max(0.0, self.status.distributed_copies),
|
||||||
self.status.distributed_copies, # Adjust status.distributed_copies to return a non-negative value
|
|
||||||
"download_payload_rate": lambda: self.status.download_payload_rate,
|
"download_payload_rate": lambda: self.status.download_payload_rate,
|
||||||
"file_priorities": lambda: self.options["file_priorities"],
|
"file_priorities": lambda: self.options["file_priorities"],
|
||||||
"hash": lambda: self.torrent_id,
|
"hash": lambda: self.torrent_id,
|
||||||
|
@ -926,7 +932,7 @@ class Torrent(object):
|
||||||
"max_upload_slots": lambda: self.options["max_upload_slots"],
|
"max_upload_slots": lambda: self.options["max_upload_slots"],
|
||||||
"max_upload_speed": lambda: self.options["max_upload_speed"],
|
"max_upload_speed": lambda: self.options["max_upload_speed"],
|
||||||
"message": lambda: self.statusmsg,
|
"message": lambda: self.statusmsg,
|
||||||
"move_on_completed_path": lambda: self.options["move_completed_path"], # Deprecated, use move_completed_path
|
"move_on_completed_path": lambda: self.options["move_completed_path"], # Depr, use move_completed_path
|
||||||
"move_on_completed": lambda: self.options["move_completed"], # Deprecated, use move_completed
|
"move_on_completed": lambda: self.options["move_completed"], # Deprecated, use move_completed
|
||||||
"move_completed_path": lambda: self.options["move_completed_path"],
|
"move_completed_path": lambda: self.options["move_completed_path"],
|
||||||
"move_completed": lambda: self.options["move_completed"],
|
"move_completed": lambda: self.options["move_completed"],
|
||||||
|
@ -969,7 +975,7 @@ class Torrent(object):
|
||||||
"private": lambda: self.torrent_info.priv() if self.has_metadata else False,
|
"private": lambda: self.torrent_info.priv() if self.has_metadata else False,
|
||||||
"total_size": lambda: self.torrent_info.total_size() if self.has_metadata else 0,
|
"total_size": lambda: self.torrent_info.total_size() if self.has_metadata else 0,
|
||||||
"eta": self.get_eta,
|
"eta": self.get_eta,
|
||||||
"file_progress": self.get_file_progress, # Adjust progress to be 0-100 value
|
"file_progress": self.get_file_progress,
|
||||||
"files": self.get_files,
|
"files": self.get_files,
|
||||||
"orig_files": self.get_orig_files,
|
"orig_files": self.get_orig_files,
|
||||||
"is_seed": lambda: self.status.is_seeding,
|
"is_seed": lambda: self.status.is_seeding,
|
||||||
|
@ -989,10 +995,11 @@ class Torrent(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
"""Pause this torrent
|
"""Pause this torrent.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True is successful, otherwise False
|
bool: True is successful, otherwise False.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Turn off auto-management so the torrent will not be unpaused by lt queueing
|
# Turn off auto-management so the torrent will not be unpaused by lt queueing
|
||||||
self.handle.auto_managed(False)
|
self.handle.auto_managed(False)
|
||||||
|
@ -1017,7 +1024,7 @@ class Torrent(object):
|
||||||
log.debug("Torrent is being auto-managed, cannot resume!")
|
log.debug("Torrent is being auto-managed, cannot resume!")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Reset the status message just in case of resuming an Error"d torrent
|
# Reset the status message just in case of resuming an Error'd torrent
|
||||||
self.set_status_message("OK")
|
self.set_status_message("OK")
|
||||||
|
|
||||||
if self.status.is_finished:
|
if self.status.is_finished:
|
||||||
|
@ -1061,8 +1068,8 @@ class Torrent(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if successful, otherwise False
|
bool: True if successful, otherwise False
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
dest = decode_string(dest)
|
dest = decode_string(dest)
|
||||||
|
|
||||||
if not os.path.exists(dest):
|
if not os.path.exists(dest):
|
||||||
|
@ -1074,13 +1081,12 @@ class Torrent(object):
|
||||||
self.torrent_id, dest, ex)
|
self.torrent_id, dest, ex)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
dest_bytes = utf8_encoded(dest)
|
|
||||||
try:
|
try:
|
||||||
# libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
|
# libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
|
||||||
try:
|
try:
|
||||||
self.handle.move_storage(dest)
|
self.handle.move_storage(dest)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.handle.move_storage(dest_bytes)
|
self.handle.move_storage(utf8_encoded(dest))
|
||||||
except RuntimeError, ex:
|
except RuntimeError, ex:
|
||||||
log.error("Error calling libtorrent move_storage: %s", ex)
|
log.error("Error calling libtorrent move_storage: %s", ex)
|
||||||
return False
|
return False
|
||||||
|
@ -1098,6 +1104,7 @@ class Torrent(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None: The response with resume data is returned in a libtorrent save_resume_data_alert.
|
None: The response with resume data is returned in a libtorrent save_resume_data_alert.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
flags = lt.save_resume_flags_t.flush_disk_cache if flush_disk_cache else 0
|
flags = lt.save_resume_flags_t.flush_disk_cache if flush_disk_cache else 0
|
||||||
self.handle.save_resume_data(flags)
|
self.handle.save_resume_data(flags)
|
||||||
|
@ -1170,11 +1177,7 @@ class Torrent(object):
|
||||||
"""
|
"""
|
||||||
for index, filename in filenames:
|
for index, filename in filenames:
|
||||||
# Make sure filename is a unicode object
|
# Make sure filename is a unicode object
|
||||||
try:
|
filename = sanitize_filepath(decode_string(filename))
|
||||||
filename = unicode(filename, "utf-8")
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
filename = sanitize_filepath(filename)
|
|
||||||
# libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
|
# libtorrent needs unicode object if wstrings are enabled, utf8 bytestring otherwise
|
||||||
try:
|
try:
|
||||||
self.handle.rename_file(index, filename)
|
self.handle.rename_file(index, filename)
|
||||||
|
|
|
@ -435,16 +435,12 @@ class TorrentManager(component.Component):
|
||||||
# before adding to the session.
|
# before adding to the session.
|
||||||
if options["mapped_files"]:
|
if options["mapped_files"]:
|
||||||
for index, fname in options["mapped_files"].items():
|
for index, fname in options["mapped_files"].items():
|
||||||
try:
|
fname = sanitize_filepath(decode_string(fname))
|
||||||
fname = unicode(fname, "utf-8")
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
fname = sanitize_filepath(fname)
|
|
||||||
log.debug("renaming file index %s to %s", index, fname)
|
log.debug("renaming file index %s to %s", index, fname)
|
||||||
try:
|
try:
|
||||||
torrent_info.rename_file(index, fname)
|
torrent_info.rename_file(index, fname)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
torrent_info.rename_file(index, fname.encode("utf-8"))
|
torrent_info.rename_file(index, utf8_encoded(fname))
|
||||||
|
|
||||||
if options["pre_allocate_storage"]:
|
if options["pre_allocate_storage"]:
|
||||||
storage_mode = "allocate"
|
storage_mode = "allocate"
|
||||||
|
|
Loading…
Reference in New Issue