stuff
This commit is contained in:
@@ -2,11 +2,18 @@ import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from models import ServiceType, HostType
|
||||
from utils import IconLoader
|
||||
|
||||
|
||||
def escape_markup(text: str) -> str:
|
||||
"""Escape special characters for Pango markup."""
|
||||
return text.replace('&', '&').replace('<', '<').replace('>', '>')
|
||||
|
||||
|
||||
class HostItem:
|
||||
def __init__(self, host, open_service_callback):
|
||||
def __init__(self, host, location, open_service_callback):
|
||||
self.host = host
|
||||
self.location = location
|
||||
self.open_service_callback = open_service_callback
|
||||
self.widget = self._create_widget()
|
||||
|
||||
@@ -18,20 +25,12 @@ class HostItem:
|
||||
host_header = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8)
|
||||
host_box.pack_start(host_header, False, False, 0)
|
||||
|
||||
# Host type icon
|
||||
type_icons = {
|
||||
HostType.LINUX: "🐧",
|
||||
HostType.WINDOWS: "🪟",
|
||||
HostType.WINDOWS_SERVER: "🖥️",
|
||||
HostType.PROXMOX: "📦",
|
||||
HostType.ESXI: "📦",
|
||||
HostType.ROUTER: "🌐",
|
||||
HostType.SWITCH: "🔗"
|
||||
}
|
||||
icon = type_icons.get(self.host.host_type, "💻")
|
||||
|
||||
icon_label = Gtk.Label(label=icon)
|
||||
host_header.pack_start(icon_label, False, False, 0)
|
||||
# Host icon - custom or fallback to Material Icons
|
||||
icon_widget = IconLoader.get_host_icon_widget(self.host, size=24)
|
||||
icon_container = Gtk.Box()
|
||||
icon_container.set_size_request(32, 24) # Fixed size
|
||||
icon_container.set_center_widget(icon_widget)
|
||||
host_header.pack_start(icon_container, False, False, 0)
|
||||
|
||||
# Host details - compact single line
|
||||
details_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=1)
|
||||
@@ -39,8 +38,14 @@ class HostItem:
|
||||
|
||||
# Host name with IP inline
|
||||
name_label = Gtk.Label()
|
||||
name_label.set_markup(f"<b>{self.host.name}</b> <small>({self.host.host_type.value}) - <tt>{self.host.ip_address}</tt></small>")
|
||||
ip_display = self.host.get_ip_display()
|
||||
escaped_host_name = escape_markup(self.host.name)
|
||||
escaped_host_type = escape_markup(self.host.host_type.value)
|
||||
escaped_ip_display = escape_markup(ip_display)
|
||||
name_label.set_markup(f"<b>{escaped_host_name}</b> <small>({escaped_host_type}) - <tt>{escaped_ip_display}</tt></small>")
|
||||
name_label.set_halign(Gtk.Align.START)
|
||||
if len(self.host.ip_addresses) > 1:
|
||||
name_label.set_tooltip_text(f"All IPs: {', '.join(self.host.get_all_ips())}")
|
||||
details_vbox.pack_start(name_label, False, False, 0)
|
||||
|
||||
# Services section - compact button row
|
||||
@@ -52,9 +57,35 @@ class HostItem:
|
||||
|
||||
for service in self.host.services:
|
||||
if service.service_type in [ServiceType.WEB_GUI, ServiceType.SSH, ServiceType.RDP]: # Only show launchable services
|
||||
# Check if service is reachable
|
||||
is_reachable = self.location.is_service_reachable(self.host, service)
|
||||
is_external = self.location.get_external_url_for_service(self.host, service) is not None
|
||||
|
||||
service_btn = Gtk.Button(label=service.service_type.value)
|
||||
service_btn.get_style_context().add_class("suggested-action")
|
||||
service_btn.connect("clicked", lambda btn, s=service: self._on_service_clicked(s))
|
||||
|
||||
# Apply color-based styling
|
||||
if is_reachable:
|
||||
# Green styling for accessible services
|
||||
service_btn.get_style_context().add_class("suggested-action")
|
||||
service_btn.set_name("service-btn-accessible")
|
||||
if is_external and not self.location.connected:
|
||||
external_url = self.location.get_external_url_for_service(self.host, service)
|
||||
service_btn.set_tooltip_text(f"Open {service.name}\nExternal: {external_url}")
|
||||
else:
|
||||
service_btn.set_tooltip_text(f"Open {service.name}")
|
||||
else:
|
||||
# Red styling for inaccessible services
|
||||
service_btn.get_style_context().add_class("destructive-action")
|
||||
service_btn.set_name("service-btn-inaccessible")
|
||||
service_btn.set_tooltip_text(f"{service.name} - Not reachable (VPN disconnected)")
|
||||
|
||||
# Enable/disable based on reachability
|
||||
service_btn.set_sensitive(is_reachable)
|
||||
|
||||
# Connect handler only if reachable
|
||||
if is_reachable:
|
||||
service_btn.connect("clicked", lambda btn, s=service: self._on_service_clicked(s))
|
||||
|
||||
services_box.pack_start(service_btn, False, False, 0)
|
||||
|
||||
# Sub-hosts (VMs) section
|
||||
@@ -71,7 +102,7 @@ class HostItem:
|
||||
host_box.pack_start(subhosts_box, False, False, 0)
|
||||
|
||||
for subhost in self.host.sub_hosts:
|
||||
subhost_item = HostItem(subhost, self.open_service_callback)
|
||||
subhost_item = HostItem(subhost, self.location, self.open_service_callback)
|
||||
subhosts_box.pack_start(subhost_item.widget, False, False, 0)
|
||||
|
||||
return host_box
|
||||
|
||||
Reference in New Issue
Block a user