Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3540][UI][core] Fix interface not being updated in thinclient #394

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions deluge/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,11 @@ def set_config(self, config: Dict[str, Any]):
continue
self.config[key] = config[key]

@export
def is_valid_interface(self, interface: str) -> bool:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have concerns about the naming of this method and the underlying problem we are solving.

In the first instance valid seems redundant but can understand clarification as a core method. Even if we were to use it I would suggest using it as a suffix rather than prefix is_interface_valid.

However I am leaning towards either core.has_interface or core.has_interface_name with perhaps more weight to the latter since common.is_interface seems to be my source of the contention. In addition the check if an IP is valid doesn't require a core method call and we don't actually check that the IP is assigned to one of the core host interfaces.

Perhaps core.has_interface will suffice as a core method with a future check that IP is assigned to an interface.

My final concern is that should we prevent the user from assigning an 'invalid' interface, e.g. interface is down briefly, and instead show a UI warning... That does increase the scope of this change so will need to revisit that

"""Returns True is valid interface"""
return deluge.common.is_interface(interface)

@export
def get_listen_port(self) -> int:
"""Returns the active listen port"""
Expand Down
22 changes: 21 additions & 1 deletion deluge/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from twisted.internet import defer

from deluge import error
from deluge.common import AUTH_LEVEL_NORMAL, get_localhost_auth
from deluge.common import AUTH_LEVEL_NORMAL, get_localhost_auth, get_version
from deluge.core.authmanager import AUTH_LEVEL_ADMIN
from deluge.ui.client import Client, DaemonSSLProxy, client

Expand Down Expand Up @@ -170,3 +170,23 @@ def on_failure(failure):

d.addCallbacks(self.fail, on_failure)
return d

@pytest_twisted.inlineCallbacks
def test_connection_version(self):
username, password = get_localhost_auth()
yield client.connect(
'localhost', self.listen_port, username=username, password=password
)

assert client.connection_version() == get_version()

@pytest_twisted.inlineCallbacks
def test_daemon_version_above(self):
username, password = get_localhost_auth()
yield client.connect(
'localhost', self.listen_port, username=username, password=password
)

assert client.is_daemon_version_equal_or_greater(get_version())
assert not client.is_daemon_version_equal_or_greater(f'{get_version()}1')
assert client.is_daemon_version_equal_or_greater('0.1.0')
23 changes: 22 additions & 1 deletion deluge/ui/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from twisted.internet.protocol import ClientFactory

from deluge import error
from deluge.common import get_localhost_auth, get_version
from deluge.common import VersionSplit, get_localhost_auth, get_version
from deluge.decorators import deprecated
from deluge.transfer import DelugeTransferProtocol

Expand Down Expand Up @@ -227,6 +227,7 @@ def clientConnectionLost(self, connector, reason): # NOQA: N802
self.daemon.host = None
self.daemon.port = None
self.daemon.username = None
self.daemon.daemon_info = None
self.daemon.connected = False

if (
Expand Down Expand Up @@ -260,6 +261,7 @@ def __init__(self, event_handlers=None):
self.host = None
self.port = None
self.username = None
self.daemon_info = None
self.authentication_level = 0

self.connected = False
Expand Down Expand Up @@ -741,6 +743,25 @@ def connection_info(self):

return None

def connection_version(self):
"""
Get the connected daemon version

Returns:
str: the daemon version
"""
if self.connected():
return self._daemon_proxy.daemon_info

return ''

def is_daemon_version_equal_or_greater(self, version_check):
if VersionSplit(version_check) and self.connected():
daemon_version = self.connection_version()
return VersionSplit(daemon_version) >= VersionSplit(version_check)

return False

def register_event_handler(self, event, handler):
"""
Registers a handler that will be called when an event is received from the daemon.
Expand Down
13 changes: 10 additions & 3 deletions deluge/ui/console/modes/preferences/preference_panes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import logging

from deluge.common import is_interface
from deluge.decorators import overrides
from deluge.i18n import get_languages
from deluge.ui.client import client
Expand Down Expand Up @@ -91,11 +90,19 @@ def add_config_values(self, conf_dict):
)
elif ipt.name == 'listen_interface':
listen_interface = ipt.get_value().strip()
if is_interface(listen_interface) or not listen_interface:
if (
client.is_daemon_version_equal_or_greater('2.1.1')
and client.core.is_valid_interface(listen_interface)
or not listen_interface
):
Comment on lines +93 to +97
Copy link
Member

@cas-- cas-- Jun 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Firstly this could be more readable with an intermediary variable and secondly the fallback should be True not False since we cannot check the validity of the interface. Also I don't think the version should specify patch number since this new core function in theory should bump the minor version.

Suggested change
if (
client.is_daemon_version_equal_or_greater('2.1.1')
and client.core.is_valid_interface(listen_interface)
or not listen_interface
):
listen_interface_valid=(
client.core.is_valid_interface(listen_interface)
if client.is_daemon_version_equal_or_greater('2.2')
else True
)
if listen_interface_valid or not listen_interface:

Oh and I just noticed that the call to client.core method will return a deferred so is always True so this will need a callback to get the actual result. That would lead us to look at the alternative option of not using the client daemon version check and instead handle the deferred fail for that method call. It might not be as explicit as the version check however...

conf_dict['listen_interface'] = listen_interface
elif ipt.name == 'outgoing_interface':
outgoing_interface = ipt.get_value().strip()
if is_interface(outgoing_interface) or not outgoing_interface:
if (
client.is_daemon_version_equal_or_greater('2.1.1')
and client.core.is_valid_interface(outgoing_interface)
or not outgoing_interface
):
conf_dict['outgoing_interface'] = outgoing_interface
elif ipt.name.startswith('proxy_'):
if ipt.name == 'proxy_type':
Expand Down
16 changes: 11 additions & 5 deletions deluge/ui/gtk3/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,15 +676,21 @@ def set_config(self, hide=False):
'chk_random_outgoing_ports'
).get_active()
incoming_address = self.builder.get_object('entry_interface').get_text().strip()
if deluge.common.is_interface(incoming_address) or not incoming_address:
if (
client.is_daemon_version_equal_or_greater('2.1.1')
and client.core.is_valid_interface(incoming_address)
or not incoming_address
):
new_core_config['listen_interface'] = incoming_address
outgoing_address = (
self.builder.get_object('entry_outgoing_interface').get_text().strip()
)
if deluge.common.is_interface(outgoing_address) or not outgoing_address:
new_core_config['outgoing_interface'] = (
self.builder.get_object('entry_outgoing_interface').get_text().strip()
)
if (
client.is_daemon_version_equal_or_greater('2.1.1')
and client.core.is_valid_interface(outgoing_address)
or not outgoing_address
):
new_core_config['outgoing_interface'] = outgoing_address
new_core_config['peer_tos'] = self.builder.get_object(
'entry_peer_tos'
).get_text()
Expand Down
2 changes: 1 addition & 1 deletion deluge/ui/web/js/deluge-all/preferences/NetworkPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Deluge.preferences.Network = Ext.extend(Ext.form.FormPanel, {
fieldset = this.add({
xtype: 'fieldset',
border: false,
title: _('Incoming Address'),
title: _('Incoming Interface'),
style: 'margin-bottom: 5px; padding-bottom: 0px;',
autoHeight: true,
labelWidth: 1,
Expand Down
Loading