diff --git a/app/ui/settings_dialog.glade b/app/ui/settings_dialog.glade
index f0394744..ee05d10e 100644
--- a/app/ui/settings_dialog.glade
+++ b/app/ui/settings_dialog.glade
@@ -40,10 +40,15 @@ Author: Dmitriy Yefremov
+
+
+
+
+ 1
+
+
+
+
+ 48
+ True
+ True
+ True
+ Save
+
+
+ True
+ False
+ gtk-save
+
+
+
+
+ end
+ 2
+
+
@@ -81,7 +126,7 @@ Author: Dmitriy Yefremov
False
- end
+ center
end
@@ -140,40 +185,26 @@ Author: Dmitriy Yefremov
True
False
- 1
- 1
+ 5
+ 5
0.019999999552965164
in
-
+
True
- True
- 2
- 2
- 2
- 2
+ False
+ vertical
+ 2
-
+
True
False
5
5
- 5
5
2
2
True
-
-
- True
- False
- Host:
-
-
- 0
- 0
-
-
True
@@ -187,217 +218,418 @@ Author: Dmitriy Yefremov
-
+
True
False
- Login:
+ Host:
0
- 2
-
-
-
-
- True
- False
- Password:
-
-
- 1
- 2
-
-
-
-
- True
- True
- 21
- network-workgroup-symbolic
-
-
- 1
- 1
-
-
-
-
- True
- False
- Port:
-
-
- 1
0
-
-
- True
- True
- root
- avatar-default-symbolic
- False
-
-
- 0
- 3
-
-
-
-
- True
- True
- False
- ●
- root
- emblem-readonly
- False
- password
-
-
- 1
- 3
-
-
-
-
-
-
- True
- False
- FTP
- False
+ False
+ True
+ 0
-
+
True
False
5
5
- 5
- 5
- 2
- 2
- True
-
+
True
False
- Port:
+ center
+ settings_stack
- 0
- 0
+ False
+ True
+ 0
-
- True
- True
- emblem-readonly
-
-
- 1
- 3
-
-
-
-
- True
- True
- avatar-default-symbolic
-
-
- 0
- 3
-
-
-
-
+
True
False
- Login:
+
+
+
- 0
- 2
+ True
+ True
+ 1
-
+
True
False
- Password:
- 1
- 2
+ False
+ True
+ 2
-
+
+ Test
+ 110
True
True
- 23
- network-workgroup-symbolic
+ True
+ Test connection
+ test_button_image
+ True
+
- 0
- 1
+ False
+ True
+ end
+ 2
-
+
True
False
- Timeout:
+
+
+
- 1
- 0
-
-
-
-
- True
- True
- Timeout between commands in seconds
- 2
- alarm-symbolic
- number
- telnet_timeout_adjustment
- True
-
-
- 1
- 1
+ True
+ True
+ 4
+ False
+ True
1
-
-
- True
- False
- Telnet
-
-
- 1
- False
-
-
-
-
-
-
+
+ True
+ False
+
+
+ True
+ False
+ 5
+ 5
+ 2
+ 5
+ 2
+ 2
+
+
+ True
+ False
+ Login:
+
+
+ 0
+ 0
+
+
+
+
+ True
+ True
+ True
+ root
+ avatar-default-symbolic
+ False
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Password:
+
+
+ 1
+ 0
+
+
+
+
+ True
+ True
+ True
+ False
+ ●
+ root
+ emblem-readonly
+ False
+ password
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+ Port:
+
+
+ 2
+ 0
+
+
+
+
+ True
+ True
+ 6
+ 21
+ network-workgroup-symbolic
+
+
+ 2
+ 1
+
+
+
+
+ ftp
+ FTP
+
+
+
+
+ True
+ False
+ 5
+ 5
+ 2
+ 5
+ 2
+ 2
+
+
+ True
+ False
+ Login:
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ Password:
+
+
+ 1
+ 0
+
+
+
+
+ True
+ True
+ True
+ avatar-default-symbolic
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Port:
+
+
+ 2
+ 0
+
+
+
+
+ True
+ True
+ 5
+ 6
+ 80
+ network-workgroup-symbolic
+
+
+ 2
+ 1
+
+
+
+
+ True
+ True
+ True
+ False
+ ●
+ root
+ emblem-readonly
+ False
+ password
+
+
+ 1
+ 1
+
+
+
+
+ http
+ HTTP
+ 1
+
+
+
+
+ True
+ False
+ 5
+ 5
+ 2
+ 5
+ 2
+ 2
+
+
+ True
+ False
+ Port:
+
+
+ 2
+ 0
+
+
+
+
+ True
+ True
+ 6
+ 23
+ network-workgroup-symbolic
+
+
+ 2
+ 1
+
+
+
+
+ True
+ False
+ Login:
+
+
+ 0
+ 0
+
+
+
+
+ True
+ True
+ 12
+ avatar-default-symbolic
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+ Password:
+
+
+ 1
+ 0
+
+
+
+
+ True
+ True
+ 12
+ emblem-readonly
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+ Timeout:
+
+
+ 3
+ 0
+
+
+
+
+ True
+ True
+ Timeout between commands in seconds
+ 2
+ 6
+ alarm-symbolic
+ number
+ telnet_timeout_adjustment
+ True
+
+
+ 3
+ 1
+
+
+
+
+ telnet
+ Telnet
+ 2
+
+
+
+
+ False
+ True
+ 2
+
@@ -415,14 +647,68 @@ Author: Dmitriy Yefremov
0
+
+
+ False
+ 1
+ True
+
+
+
+ False
+ True
+ expand
+
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ False
+ 16
+
+
+ True
+ False
+ Info
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+
+
+
+ False
+ True
+ 1
+
+
True
False
- 1
- 1
+ 5
+ 5
5
- 2
+ 5
True
@@ -696,36 +982,6 @@ Author: Dmitriy Yefremov
5
2
True
-
-
- True
- True
- /data
- gtk-edit
- folder-open-symbolic
- False
- Select
- Select
-
-
-
- 0
- 1
-
-
-
-
- True
- False
- Data path:
- 0
- 0.019999999552965164
-
-
- 0
- 0
-
-
True
@@ -752,6 +1008,36 @@ Author: Dmitriy Yefremov
3
+
+
+ True
+ False
+ Data path:
+ 0
+ 0.019999999552965164
+
+
+ 0
+ 0
+
+
+
+
+ True
+ True
+ /data
+ gtk-edit
+ folder-open-symbolic
+ False
+ Select
+ Select
+
+
+
+ 0
+ 1
+
+
@@ -765,7 +1051,7 @@ Author: Dmitriy Yefremov
False
True
- 5
+ 4
diff --git a/app/ui/settings_dialog.py b/app/ui/settings_dialog.py
index cca87c90..420ed319 100644
--- a/app/ui/settings_dialog.py
+++ b/app/ui/settings_dialog.py
@@ -1,3 +1,13 @@
+import socket
+from enum import Enum
+from ftplib import error_perm, FTP
+from urllib.error import URLError, HTTPError
+from urllib.parse import urlencode
+from urllib.request import urlopen
+from xml.dom.minidom import parse
+
+from app.commons import run_task, run_idle
+from app.connections import test_telnet
from app.properties import write_config, Profile, get_default_settings
from .uicommons import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN
from .main_helper import update_entry_data
@@ -7,6 +17,12 @@ def show_settings_dialog(transient, options):
return SettingsDialog(transient, options).show()
+class Property(Enum):
+ FTP = "ftp"
+ HTTP = "http"
+ TELNET = "telnet"
+
+
class SettingsDialog:
def __init__(self, transient, options):
@@ -14,7 +30,9 @@ class SettingsDialog:
"on_picons_dir_field_icon_press": self.on_picons_dir_field_icon_press,
"on_profile_changed": self.on_profile_changed,
"on_reset": self.on_reset,
- "apply_settings": self.apply_settings}
+ "apply_settings": self.apply_settings,
+ "on_connection_test": self.on_connection_test,
+ "on_info_bar_close": self.on_info_bar_close}
builder = Gtk.Builder()
builder.set_translation_domain(TEXT_DOMAIN)
@@ -27,6 +45,9 @@ class SettingsDialog:
self._port_field = builder.get_object("port_field")
self._login_field = builder.get_object("login_field")
self._password_field = builder.get_object("password_field")
+ self._http_login_field = builder.get_object("http_login_field")
+ self._http_password_field = builder.get_object("http_password_field")
+ self._http_port_field = builder.get_object("http_port_field")
self._telnet_login_field = builder.get_object("telnet_login_field")
self._telnet_password_field = builder.get_object("telnet_password_field")
self._telnet_port_field = builder.get_object("telnet_port_field")
@@ -40,13 +61,17 @@ class SettingsDialog:
self._enigma_radio_button = builder.get_object("enigma_radio_button")
self._neutrino_radio_button = builder.get_object("neutrino_radio_button")
self._support_ver5_check_button = builder.get_object("support_ver5_check_button")
-
+ self._settings_stack = builder.get_object("settings_stack")
+ self._info_bar = builder.get_object("info_bar")
+ self._message_label = builder.get_object("info_bar_message_label")
+ self._test_spinner = builder.get_object("test_spinner")
self._options = options
self._active_profile = options.get("profile")
self.set_settings()
profile = Profile(self._active_profile)
self._neutrino_radio_button.set_active(profile is Profile.NEUTRINO_MP)
self._support_ver5_check_button.set_sensitive(profile is not Profile.NEUTRINO_MP)
+ self._settings_stack.get_child_by_name(Property.HTTP.value).set_visible(profile is not Profile.NEUTRINO_MP)
def show(self):
response = self._dialog.run()
@@ -65,6 +90,7 @@ class SettingsDialog:
def on_profile_changed(self, item):
profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
+ self._settings_stack.get_child_by_name(Property.HTTP.value).set_visible(profile is not Profile.NEUTRINO_MP)
self.set_profile(profile)
self._support_ver5_check_button.set_sensitive(profile is Profile.ENIGMA_2)
@@ -89,6 +115,9 @@ class SettingsDialog:
self._port_field.set_text(options.get("port", ""))
self._login_field.set_text(options.get("user", ""))
self._password_field.set_text(options.get("password", ""))
+ self._http_login_field.set_text(options.get("http_user", ""))
+ self._http_password_field.set_text(options.get("http_password", ""))
+ self._http_port_field.set_text(options.get("http_port", "80"))
self._telnet_login_field.set_text(options.get("telnet_user", ""))
self._telnet_password_field.set_text(options.get("telnet_password", ""))
self._telnet_port_field.set_text(options.get("telnet_port", ""))
@@ -111,6 +140,9 @@ class SettingsDialog:
options["port"] = self._port_field.get_text()
options["user"] = self._login_field.get_text()
options["password"] = self._password_field.get_text()
+ options["http_user"] = self._http_login_field.get_text()
+ options["http_password"] = self._http_password_field.get_text()
+ options["http_port"] = self._http_port_field.get_text()
options["telnet_user"] = self._telnet_login_field.get_text()
options["telnet_password"] = self._telnet_password_field.get_text()
options["telnet_port"] = self._telnet_port_field.get_text()
@@ -124,6 +156,75 @@ class SettingsDialog:
if profile is Profile.ENIGMA_2:
options["v5_support"] = self._support_ver5_check_button.get_active()
+ @run_task
+ def on_connection_test(self, item):
+ if self._test_spinner.get_state() is Gtk.StateType.ACTIVE:
+ return
+ self.show_spinner(True)
+ current_property = Property(self._settings_stack.get_visible_child_name())
+ if current_property is Property.HTTP:
+ self.test_http()
+ elif current_property is Property.TELNET:
+ self.test_telnet()
+ elif current_property is Property.FTP:
+ self.test_ftp()
+
+ def test_http(self):
+ user, password = self._http_login_field.get_text(), self._http_password_field.get_text()
+ try:
+ params = urlencode({"text": "Connection test", "type": 2, "timeout": 5})
+ with urlopen("http://{}/web/message?%s".format(self._host_field.get_text()) % params, timeout=2) as f:
+ dom = parse(f)
+ for elem in dom.getElementsByTagName("e2simplexmlresult"):
+ for ch in elem.childNodes:
+ if ch.nodeType == ch.ELEMENT_NODE:
+ msg = "".join(t.nodeValue for t in ch.childNodes if t.nodeType == t.TEXT_NODE)
+ self.show_info_message(msg, Gtk.MessageType.INFO)
+ except (URLError, HTTPError) as e:
+ self.show_info_message(str(e), Gtk.MessageType.ERROR)
+ finally:
+ self.show_spinner(False)
+
+ def test_telnet(self):
+ timeout = int(self._telnet_timeout_spin_button.get_value())
+ host, port = self._host_field.get_text(), self._telnet_port_field.get_text()
+ user, password = self._telnet_login_field.get_text(), self._telnet_password_field.get_text()
+ try:
+ gen = test_telnet(host, port, user, password, timeout)
+ res = next(gen)
+ print(res)
+ res = next(gen)
+ self.show_info_message(str(res), Gtk.MessageType.INFO)
+ self.show_spinner(False)
+ except (socket.timeout, OSError) as e:
+ self.show_info_message(str(e), Gtk.MessageType.ERROR)
+ self.show_spinner(False)
+
+ def test_ftp(self):
+ host, port = self._host_field.get_text(), self._port_field.get_text()
+ user, password = self._login_field.get_text(), self._password_field.get_text()
+ try:
+ with FTP(host=host, user=user, passwd=password, timeout=5) as ftp:
+ self.show_info_message("OK. {}".format(ftp.getwelcome()), Gtk.MessageType.INFO)
+ except (error_perm, ConnectionRefusedError) as e:
+ self.show_info_message(str(e), Gtk.MessageType.ERROR)
+ finally:
+ self.show_spinner(False)
+
+ @run_idle
+ def show_info_message(self, text, message_type):
+ self._info_bar.set_visible(True)
+ self._info_bar.set_message_type(message_type)
+ self._message_label.set_text(text)
+
+ @run_idle
+ def show_spinner(self, show):
+ self._test_spinner.start() if show else self._test_spinner.stop()
+ self._test_spinner.set_state(Gtk.StateType.ACTIVE if show else Gtk.StateType.NORMAL)
+
+ def on_info_bar_close(self, bar=None, resp=None):
+ self._info_bar.set_visible(False)
+
if __name__ == "__main__":
pass