summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDjLegolas <djlegolas@protonmail.com>2022-01-22 00:33:28 +0200
committerCalum Lind <calumlind+deluge@gmail.com>2022-02-13 11:36:04 +0000
commit2bd095e5bfc49cbe178fc0ba9df38b88afc238aa (patch)
tree87bdfac362f8915f53e12818b5f7a289f5837367
parent513d5f06e5545ad6f5b77a304395190bf55464b6 (diff)
downloaddeluge-2bd095e5bfc49cbe178fc0ba9df38b88afc238aa.tar.gz
deluge-2bd095e5bfc49cbe178fc0ba9df38b88afc238aa.tar.bz2
deluge-2bd095e5bfc49cbe178fc0ba9df38b88afc238aa.zip
[Core] Stopped using libtorrent deprecated functions
As part of the process of adding support to LT 2.0, we should stop using all deprecated function, as some (if not all) were removed. For this process, we should use the LT 1.2 upgrade (guide)[1]. The change includes: * stop using file entries directly * start using the torrent handle's set/unset flags * stop using url key in add_torrent_params (for magnet) * stop accessing resume_data from save_resume_data_alert * stop using deprecated session status keys in UI [1] https://libtorrent.org/upgrade_to_1.2-ref.html Closes: https://dev.deluge-torrent.org/ticket/3499 Closes: https://github.com/deluge-torrent/deluge/pull/342
-rw-r--r--DEPENDS.md2
-rw-r--r--deluge/core/torrent.py78
-rw-r--r--deluge/core/torrentmanager.py50
-rw-r--r--deluge/tests/test_torrent.py8
-rw-r--r--deluge/ui/console/cmdline/commands/status.py9
-rw-r--r--deluge/ui/console/modes/torrentdetail.py4
-rw-r--r--deluge/ui/console/widgets/statusbars.py12
-rw-r--r--deluge/ui/gtk3/statusbar.py20
-rw-r--r--deluge/ui/web/json_api.py12
9 files changed, 120 insertions, 75 deletions
diff --git a/DEPENDS.md b/DEPENDS.md
index 197556dd0..41a7ec09f 100644
--- a/DEPENDS.md
+++ b/DEPENDS.md
@@ -41,7 +41,7 @@ All modules will require the [common](#common) section dependencies.
## Core (deluged daemon)
-- [libtorrent] _>= 1.1.1_
+- [libtorrent] _>= 1.2.0_
- [GeoIP] or [pygeoip] - Optional: IP address country lookup. (_Debian: `python-geoip`_)
## GTK UI
diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py
index bae962770..55e825727 100644
--- a/deluge/core/torrent.py
+++ b/deluge/core/torrent.py
@@ -80,7 +80,7 @@ def convert_lt_files(files):
"""Indexes and decodes files from libtorrent get_files().
Args:
- files (list): The libtorrent torrent files.
+ files (file_storage): The libtorrent torrent files.
Returns:
list of dict: The files.
@@ -95,18 +95,18 @@ def convert_lt_files(files):
}
"""
filelist = []
- for index, _file in enumerate(files):
+ for index in range(files.num_files()):
try:
- file_path = _file.path.decode('utf8')
+ file_path = files.file_path(index).decode('utf8')
except AttributeError:
- file_path = _file.path
+ file_path = files.file_path(index)
filelist.append(
{
'index': index,
'path': file_path.replace('\\', '/'),
- 'size': _file.size,
- 'offset': _file.offset,
+ 'size': files.file_size(index),
+ 'offset': files.file_offset(index),
}
)
@@ -236,7 +236,7 @@ class Torrent:
self.magnet = magnet
self.status = self.handle.status()
- self.torrent_info = self.handle.get_torrent_info()
+ self.torrent_info = self.handle.torrent_file()
self.has_metadata = self.status.has_metadata
self.options = TorrentOptions()
@@ -275,6 +275,18 @@ class Torrent:
if log.isEnabledFor(logging.DEBUG):
log.debug('Torrent object created.')
+ def _set_handle_flags(self, flag: lt.torrent_flags, set_flag: bool):
+ """set or unset a flag to the lt handle
+
+ Args:
+ flag (lt.torrent_flags): the flag to set/unset
+ set_flag (bool): True for setting the flag, False for unsetting it
+ """
+ if set_flag:
+ self.handle.set_flags(flag)
+ else:
+ self.handle.unset_flags(flag)
+
def on_metadata_received(self):
"""Process the metadata received alert for this torrent"""
self.has_metadata = True
@@ -359,7 +371,7 @@ class Torrent:
"""Sets maximum download speed for this torrent.
Args:
- m_up_speed (float): Maximum download speed in KiB/s.
+ m_down_speed (float): Maximum download speed in KiB/s.
"""
self.options['max_download_speed'] = m_down_speed
if m_down_speed < 0:
@@ -391,7 +403,7 @@ class Torrent:
return
# A list of priorities for each piece in the torrent
- priorities = self.handle.piece_priorities()
+ priorities = self.handle.get_piece_priorities()
def get_file_piece(idx, byte_offset):
return self.torrent_info.map_file(idx, byte_offset, 0).piece
@@ -424,7 +436,10 @@ class Torrent:
sequential (bool): Enable sequential downloading.
"""
self.options['sequential_download'] = sequential
- self.handle.set_sequential_download(sequential)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.sequential_download,
+ set_flag=sequential,
+ )
def set_auto_managed(self, auto_managed):
"""Set auto managed mode, i.e. will be started or queued automatically.
@@ -434,7 +449,10 @@ class Torrent:
"""
self.options['auto_managed'] = auto_managed
if not (self.status.paused and not self.status.auto_managed):
- self.handle.auto_managed(auto_managed)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.auto_managed,
+ set_flag=auto_managed,
+ )
self.update_state()
def set_super_seeding(self, super_seeding):
@@ -444,7 +462,10 @@ class Torrent:
super_seeding (bool): Enable super seeding.
"""
self.options['super_seeding'] = super_seeding
- self.handle.super_seeding(super_seeding)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.super_seeding,
+ set_flag=super_seeding,
+ )
def set_stop_ratio(self, stop_ratio):
"""The seeding ratio to stop (or remove) the torrent at.
@@ -505,7 +526,7 @@ class Torrent:
self.handle.prioritize_files(file_priorities)
else:
log.debug('Unable to set new file priorities.')
- file_priorities = self.handle.file_priorities()
+ file_priorities = self.handle.get_file_priorities()
if 0 in self.options['file_priorities']:
# Previously marked a file 'skip' so check for any 0's now >0.
@@ -632,7 +653,10 @@ class Torrent:
elif status_error:
self.state = 'Error'
# auto-manage status will be reverted upon resuming.
- self.handle.auto_managed(False)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.auto_managed,
+ set_flag=False,
+ )
self.set_status_message(decode_bytes(status_error))
elif status.moving_storage:
self.state = 'Moving'
@@ -686,7 +710,10 @@ class Torrent:
session can resume.
"""
status = self.handle.status()
- self.handle.auto_managed(False)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.auto_managed,
+ set_flag=False,
+ )
self.forced_error = TorrentError(message, status.paused, restart_to_resume)
if not status.paused:
self.handle.pause()
@@ -700,7 +727,10 @@ class Torrent:
log.error('Restart deluge to clear this torrent error')
if not self.forced_error.was_paused and self.options['auto_managed']:
- self.handle.auto_managed(True)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.auto_managed,
+ set_flag=True,
+ )
self.forced_error = None
self.set_status_message('OK')
if update_state:
@@ -843,7 +873,7 @@ class Torrent:
def get_file_priorities(self):
"""Return the file priorities"""
- if not self.handle.has_metadata():
+ if not self.handle.status().has_metadata:
return []
if not self.options['file_priorities']:
@@ -932,10 +962,10 @@ class Torrent:
if self.has_metadata:
# Use the top-level folder as torrent name.
- filename = decode_bytes(self.torrent_info.file_at(0).path)
+ filename = decode_bytes(self.torrent_info.files().file_path(0))
name = filename.replace('\\', '/', 1).split('/', 1)[0]
else:
- name = decode_bytes(self.handle.name())
+ name = decode_bytes(self.handle.status().name)
if not name:
name = self.torrent_id
@@ -1152,7 +1182,10 @@ class Torrent:
"""
# Turn off auto-management so the torrent will not be unpaused by lt queueing
- self.handle.auto_managed(False)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.auto_managed,
+ set_flag=False,
+ )
if self.state == 'Error':
log.debug('Unable to pause torrent while in Error state')
elif self.status.paused:
@@ -1187,7 +1220,10 @@ class Torrent:
else:
# Check if torrent was originally being auto-managed.
if self.options['auto_managed']:
- self.handle.auto_managed(True)
+ self._set_handle_flags(
+ flag=lt.torrent_flags.auto_managed,
+ set_flag=True,
+ )
try:
self.handle.resume()
except RuntimeError as ex:
diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py
index ef1cabe6b..753bc894c 100644
--- a/deluge/core/torrentmanager.py
+++ b/deluge/core/torrentmanager.py
@@ -360,10 +360,9 @@ class TorrentManager(component.Component):
if torrent_id in self.prefetching_metadata:
return self.prefetching_metadata[torrent_id].defer
- add_torrent_params = {}
- add_torrent_params['save_path'] = gettempdir()
- add_torrent_params['url'] = magnet.strip().encode('utf8')
- add_torrent_params['flags'] = (
+ add_torrent_params = lt.parse_magnet_uri(magnet)
+ add_torrent_params.save_path = gettempdir()
+ add_torrent_params.flags = (
(
LT_DEFAULT_ADD_TORRENT_FLAGS
| lt.add_torrent_params_flags_t.flag_duplicate_is_error
@@ -401,7 +400,10 @@ class TorrentManager(component.Component):
metadata = b''
if isinstance(torrent_info, lt.torrent_info):
log.debug('prefetch metadata received')
- metadata = torrent_info.metadata()
+ if VersionSplit(LT_VERSION) < VersionSplit('2.0.0.0'):
+ metadata = torrent_info.metadata()
+ else:
+ metadata = torrent_info.info_section()
return torrent_id, b64encode(metadata)
@@ -436,14 +438,10 @@ class TorrentManager(component.Component):
elif magnet:
magnet_info = get_magnet_info(magnet)
if magnet_info:
- add_torrent_params['url'] = magnet.strip().encode('utf8')
add_torrent_params['name'] = magnet_info['name']
torrent_id = magnet_info['info_hash']
# Workaround lt 1.2 bug for magnet resume data with no metadata
- if resume_data and VersionSplit(LT_VERSION) >= VersionSplit('1.2.10.0'):
- add_torrent_params['info_hash'] = bytes(
- bytearray.fromhex(torrent_id)
- )
+ add_torrent_params['info_hash'] = bytes(bytearray.fromhex(torrent_id))
else:
raise AddTorrentError(
'Unable to add magnet, invalid magnet info: %s' % magnet
@@ -1399,22 +1397,18 @@ class TorrentManager(component.Component):
log.debug(
'Tracker Error Alert: %s [%s]', decode_bytes(alert.message()), error_message
)
- if VersionSplit(LT_VERSION) >= VersionSplit('1.2.0.0'):
- # libtorrent 1.2 added endpoint struct to each tracker. to prevent false updates
- # we will need to verify that at least one endpoint to the errored tracker is working
- for tracker in torrent.handle.trackers():
- if tracker['url'] == alert.url:
- if any(
- endpoint['last_error']['value'] == 0
- for endpoint in tracker['endpoints']
- ):
- torrent.set_tracker_status('Announce OK')
- else:
- torrent.set_tracker_status('Error: ' + error_message)
- break
- else:
- # preserve old functionality for libtorrent < 1.2
- torrent.set_tracker_status('Error: ' + error_message)
+ # libtorrent 1.2 added endpoint struct to each tracker. to prevent false updates
+ # we will need to verify that at least one endpoint to the errored tracker is working
+ for tracker in torrent.handle.trackers():
+ if tracker['url'] == alert.url:
+ if any(
+ endpoint['last_error']['value'] == 0
+ for endpoint in tracker['endpoints']
+ ):
+ torrent.set_tracker_status('Announce OK')
+ else:
+ torrent.set_tracker_status('Error: ' + error_message)
+ break
def on_alert_storage_moved(self, alert):
"""Alert handler for libtorrent storage_moved_alert"""
@@ -1488,7 +1482,9 @@ class TorrentManager(component.Component):
return
if torrent_id in self.torrents:
# libtorrent add_torrent expects bencoded resume_data.
- self.resume_data[torrent_id] = lt.bencode(alert.resume_data)
+ self.resume_data[torrent_id] = lt.bencode(
+ lt.write_resume_data(alert.params)
+ )
if torrent_id in self.waiting_on_resume_data:
self.waiting_on_resume_data[torrent_id].callback(None)
diff --git a/deluge/tests/test_torrent.py b/deluge/tests/test_torrent.py
index 811fc3f5b..6c07531dd 100644
--- a/deluge/tests/test_torrent.py
+++ b/deluge/tests/test_torrent.py
@@ -109,7 +109,7 @@ class TestTorrent(BaseTestCase):
# updates and will return old value. Also need to remove a priority
# value as one file is much smaller than piece size so doesn't show.
await prios_set # Delay to wait for alert from lt
- piece_prio = handle.piece_priorities()
+ piece_prio = handle.get_piece_priorities()
result = all(p in piece_prio for p in [3, 2, 0, 5, 6, 7])
assert result
@@ -151,9 +151,9 @@ class TestTorrent(BaseTestCase):
handle = self.session.add_torrent(atp)
self.torrent = Torrent(handle, {})
- priorities_original = handle.piece_priorities()
+ priorities_original = handle.get_piece_priorities()
self.torrent.set_prioritize_first_last_pieces(True)
- priorities = handle.piece_priorities()
+ priorities = handle.get_piece_priorities()
# The length of the list of new priorites is the same as the original
assert len(priorities_original) == len(priorities)
@@ -175,7 +175,7 @@ class TestTorrent(BaseTestCase):
self.torrent.set_prioritize_first_last_pieces(True)
# Reset pirorities
self.torrent.set_prioritize_first_last_pieces(False)
- priorities = handle.piece_priorities()
+ priorities = handle.get_piece_priorities()
# Test the priority of the prioritized pieces
for i in priorities:
diff --git a/deluge/ui/console/cmdline/commands/status.py b/deluge/ui/console/cmdline/commands/status.py
index 2ca1cda2f..05c9796ce 100644
--- a/deluge/ui/console/cmdline/commands/status.py
+++ b/deluge/ui/console/cmdline/commands/status.py
@@ -62,7 +62,12 @@ class Command(BaseCommand):
deferreds = []
ds = client.core.get_session_status(
- ['num_peers', 'payload_upload_rate', 'payload_download_rate', 'dht_nodes']
+ [
+ 'peer.num_peers_connected',
+ 'payload_upload_rate',
+ 'payload_download_rate',
+ 'dht.dht_nodes',
+ ]
)
ds.addCallback(on_session_status)
deferreds.append(ds)
@@ -92,7 +97,7 @@ class Command(BaseCommand):
'{!info!}Total download: %s'
% fspeed(self.status['payload_download_rate'])
)
- self.console.write('{!info!}DHT Nodes: %i' % self.status['dht_nodes'])
+ self.console.write('{!info!}DHT Nodes: %i' % self.status['dht.dht_nodes'])
if isinstance(self.torrents, int):
if self.torrents == -2:
diff --git a/deluge/ui/console/modes/torrentdetail.py b/deluge/ui/console/modes/torrentdetail.py
index eab9dfef1..bac9b9472 100644
--- a/deluge/ui/console/modes/torrentdetail.py
+++ b/deluge/ui/console/modes/torrentdetail.py
@@ -541,13 +541,13 @@ class TorrentDetail(BaseMode, PopupsHandler):
# Seed/peer info
s = '{{!info!}}{}:{{!green!}} {} {{!input!}}({})'.format(
torrent_data_fields['seeds']['name'],
- status['num_seeds'],
+ status['peer.num_peers_connected'],
status['total_seeds'],
)
row = self.add_string(row, s)
s = '{{!info!}}{}:{{!red!}} {} {{!input!}}({})'.format(
torrent_data_fields['peers']['name'],
- status['num_peers'],
+ status['peer.num_peers_connected'],
status['total_peers'],
)
row = self.add_string(row, s)
diff --git a/deluge/ui/console/widgets/statusbars.py b/deluge/ui/console/widgets/statusbars.py
index 57128eabf..1b9173707 100644
--- a/deluge/ui/console/widgets/statusbars.py
+++ b/deluge/ui/console/widgets/statusbars.py
@@ -36,19 +36,23 @@ class StatusBars(component.Component):
def on_get_session_status(status):
self.upload = deluge.common.fsize(status['payload_upload_rate'])
self.download = deluge.common.fsize(status['payload_download_rate'])
- self.connections = status['num_peers']
+ self.connections = status['peer.num_peers_connected']
if 'dht_nodes' in status:
- self.dht = status['dht_nodes']
+ self.dht = status['dht.dht_nodes']
self.update_statusbars()
def on_get_external_ip(external_ip):
self.external_ip = external_ip
- keys = ['num_peers', 'payload_upload_rate', 'payload_download_rate']
+ keys = [
+ 'peer.num_peers_connected',
+ 'payload_upload_rate',
+ 'payload_download_rate',
+ ]
if self.config['dht']:
- keys.append('dht_nodes')
+ keys.append('dht.dht_nodes')
client.core.get_session_status(keys).addCallback(on_get_session_status)
client.core.get_external_ip().addCallback(on_get_external_ip)
diff --git a/deluge/ui/gtk3/statusbar.py b/deluge/ui/gtk3/statusbar.py
index 3001a49ee..0a2e80095 100644
--- a/deluge/ui/gtk3/statusbar.py
+++ b/deluge/ui/gtk3/statusbar.py
@@ -317,18 +317,22 @@ class StatusBar(component.Component):
def send_status_request(self):
# Sends an async request for data from the core
keys = [
- 'num_peers',
+ 'peer.num_peers_connected',
'upload_rate',
'download_rate',
'payload_upload_rate',
'payload_download_rate',
+ 'net.sent_bytes',
+ 'net.recv_bytes',
+ 'net.sent_payload_bytes',
+ 'net.recv_payload_bytes',
]
if self.dht_status:
- keys.append('dht_nodes')
+ keys.append('dht.dht_nodes')
if not self.health:
- keys.append('has_incoming_connections')
+ keys.append('net.has_incoming_connections')
client.core.get_session_status(keys).addCallback(self._on_get_session_status)
client.core.get_free_space().addCallback(self._on_get_free_space)
@@ -367,18 +371,18 @@ class StatusBar(component.Component):
self.upload_protocol_rate = (
status['upload_rate'] - status['payload_upload_rate']
) // 1024
- self.num_connections = status['num_peers']
+ self.num_connections = status['peer.num_peers_connected']
self.update_download_label()
self.update_upload_label()
self.update_traffic_label()
self.update_connections_label()
- if 'dht_nodes' in status:
- self.dht_nodes = status['dht_nodes']
+ if 'dht.dht_nodes' in status:
+ self.dht_nodes = status['dht.dht_nodes']
self.update_dht_label()
- if 'has_incoming_connections' in status:
- self.health = status['has_incoming_connections']
+ if 'net.has_incoming_connections' in status:
+ self.health = status['net.has_incoming_connections']
if self.health:
self.remove_item(self.health_item)
diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py
index aa15d5ac6..e16c440ed 100644
--- a/deluge/ui/web/json_api.py
+++ b/deluge/ui/web/json_api.py
@@ -515,7 +515,7 @@ class WebApi(JSONComponent):
return d
def got_stats(stats):
- ui_info['stats']['num_connections'] = stats['num_peers']
+ ui_info['stats']['num_connections'] = stats['peer.num_peers_connected']
ui_info['stats']['upload_rate'] = stats['payload_upload_rate']
ui_info['stats']['download_rate'] = stats['payload_download_rate']
ui_info['stats']['download_protocol_rate'] = (
@@ -524,9 +524,9 @@ class WebApi(JSONComponent):
ui_info['stats']['upload_protocol_rate'] = (
stats['upload_rate'] - stats['payload_upload_rate']
)
- ui_info['stats']['dht_nodes'] = stats['dht_nodes']
+ ui_info['stats']['dht_nodes'] = stats['dht.dht_nodes']
ui_info['stats']['has_incoming_connections'] = stats[
- 'has_incoming_connections'
+ 'net.has_incoming_connections'
]
def got_filters(filters):
@@ -552,13 +552,13 @@ class WebApi(JSONComponent):
d3 = client.core.get_session_status(
[
- 'num_peers',
+ 'peer.num_peers_connected',
'payload_download_rate',
'payload_upload_rate',
'download_rate',
'upload_rate',
- 'dht_nodes',
- 'has_incoming_connections',
+ 'dht.dht_nodes',
+ 'net.has_incoming_connections',
]
)
d3.addCallback(got_stats)