Skip to content

Commit c3ffd39

Browse files
committed
BUGFIX:
- LotAtc: port check for json server port showed wrong message small refactorings
1 parent 8b1ef56 commit c3ffd39

File tree

5 files changed

+110
-91
lines changed

5 files changed

+110
-91
lines changed

core/utils/cpu.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@
99

1010
logger = logging.getLogger(__name__)
1111

12+
__all__ = [
13+
"get_cpu_name",
14+
"get_processor_info",
15+
"get_cpu_set_information",
16+
"get_scheduling_classes",
17+
"get_cache_info",
18+
"get_e_core_affinity",
19+
"get_p_core_affinity",
20+
"get_cpus_from_affinity",
21+
"create_cpu_topology_visualization"
22+
]
1223

1324
# Define ULONG_PTR
1425
if ctypes.sizeof(ctypes.c_void_p) == 8: # 64-bit system

core/utils/network.py

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,97 @@
1+
import aiohttp
2+
import ipaddress
3+
import socket
4+
import sys
5+
6+
from contextlib import closing, suppress
17
from core import Port, PortType
2-
from typing import Iterable
8+
from typing import Iterable, TYPE_CHECKING
9+
10+
if TYPE_CHECKING:
11+
from core import Node
12+
13+
__all__ = [
14+
"is_open",
15+
"get_public_ip",
16+
"is_upnp_available",
17+
"generate_firewall_rules"
18+
]
19+
20+
API_URLS = [
21+
'https://api4.ipify.org/',
22+
'https://ipinfo.io/ip',
23+
'https://www.trackip.net/ip',
24+
'https://api4.my-ip.io/ip' # they have an issue with their cert atm, hope they get it fixed
25+
]
26+
27+
28+
def is_open(ip, port):
29+
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
30+
s.settimeout(1.0)
31+
return s.connect_ex((ip, int(port))) == 0
32+
33+
34+
async def get_public_ip(node: "Node | None" = None):
35+
for url in API_URLS:
36+
with suppress(aiohttp.ClientError, ValueError):
37+
async with aiohttp.ClientSession() as session:
38+
async with session.get(url, proxy=node.proxy if node else None,
39+
proxy_auth=node.proxy_auth if node else None) as resp:
40+
return ipaddress.ip_address(await resp.text()).compressed
41+
else:
42+
raise TimeoutError("Public IP could not be retrieved.")
343

4-
__all__ = ["generate_firewall_rules"]
44+
45+
if sys.version_info >= (3, 14):
46+
47+
def is_upnp_available() -> bool:
48+
from upnpy import UPnP
49+
50+
try:
51+
upnp = UPnP()
52+
devices = upnp.discover()
53+
if not devices:
54+
return False
55+
56+
# Look for an InternetGatewayDevice and its WANIPConnection (or WANPPPConnection) service
57+
for device in devices:
58+
if "InternetGatewayDevice" in (device.device_type or ""):
59+
try:
60+
# Try WANIPConnection first
61+
wan_services = device.get_services()
62+
has_wan = any(
63+
("WANIPConnection" in s.service_type) or ("WANPPPConnection" in s.service_type)
64+
for s in wan_services
65+
)
66+
if has_wan:
67+
return True
68+
except Exception:
69+
continue
70+
return False
71+
except Exception:
72+
return False
73+
74+
else:
75+
76+
def is_upnp_available() -> bool:
77+
import miniupnpc
78+
79+
try:
80+
upnp = miniupnpc.UPnP()
81+
devices = upnp.discover() # Discover UPnP-enabled devices
82+
if devices > 0:
83+
if upnp.selectigd():
84+
# UPnP is enabled and an IGD was found.
85+
return True
86+
else:
87+
# UPnP is enabled, but no Internet Gateway Device (IGD) is selected
88+
return False
89+
else:
90+
# No UPnP devices detected on the network.
91+
return False
92+
except Exception:
93+
# A UPnP device was found, but no IGD was found.
94+
return False
595

696

797
def fw_rule(port: int, protocol: str, name: str, description: str) -> str:
@@ -20,6 +110,7 @@ def fw_rule(port: int, protocol: str, name: str, description: str) -> str:
20110
)
21111
return cmd
22112

113+
23114
def generate_firewall_rules(ports: Iterable[Port]) -> str:
24115
"""
25116
Write a PowerShell script that adds inbound rules for the given ports.
@@ -37,7 +128,7 @@ def generate_firewall_rules(ports: Iterable[Port]) -> str:
37128
for p in ports:
38129
if p.typ is PortType.BOTH:
39130
# Create two separate rules
40-
for proto in (PortType.TCP, PortType.UDP):
131+
for proto in [PortType.TCP, PortType.UDP]:
41132
name = f"Allow {p.port}/{proto.value.lower()}"
42133
desc = f"Auto‑generated rule for inbound {p.port}/{proto.value.lower()}"
43134
lines.append(fw_rule(p.port, proto.value, name, desc))

core/utils/os.py

Lines changed: 2 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
11
from __future__ import annotations
22

3-
import aiohttp
43
import asyncio
5-
import ipaddress
64
import logging
75
import os
86
import pickle
97
import platform
108
import psutil
11-
import socket
129
import stat
1310
import subprocess
1411
import sys
1512

16-
from contextlib import closing, suppress
13+
from contextlib import suppress
1714
from logging.handlers import RotatingFileHandler
1815
from pathlib import Path
19-
from typing import TYPE_CHECKING, Generator
20-
21-
if TYPE_CHECKING:
22-
from core import Node
16+
from typing import Generator
2317

2418
if sys.platform == 'win32':
2519
import ctypes
@@ -30,16 +24,7 @@
3024

3125
from pywinauto.win32defines import SEE_MASK_NOCLOSEPROCESS, SW_HIDE, SW_SHOWMINNOACTIVE
3226

33-
API_URLS = [
34-
'https://api4.ipify.org/',
35-
'https://ipinfo.io/ip',
36-
'https://www.trackip.net/ip',
37-
'https://api4.my-ip.io/ip' # they have an issue with their cert atm, hope they get it fixed
38-
]
39-
4027
__all__ = [
41-
"is_open",
42-
"get_public_ip",
4328
"find_process",
4429
"find_process_async",
4530
"is_process_running",
@@ -56,7 +41,6 @@
5641
"get_password",
5742
"delete_password",
5843
"sanitize_filename",
59-
"is_upnp_available",
6044
"get_win32_error_message",
6145
"CloudRotatingFileHandler",
6246
"run_elevated",
@@ -67,23 +51,6 @@
6751
logger = logging.getLogger(__name__)
6852

6953

70-
def is_open(ip, port):
71-
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
72-
s.settimeout(1.0)
73-
return s.connect_ex((ip, int(port))) == 0
74-
75-
76-
async def get_public_ip(node: Node | None = None):
77-
for url in API_URLS:
78-
with suppress(aiohttp.ClientError, ValueError):
79-
async with aiohttp.ClientSession() as session:
80-
async with session.get(url, proxy=node.proxy if node else None,
81-
proxy_auth=node.proxy_auth if node else None) as resp:
82-
return ipaddress.ip_address(await resp.text()).compressed
83-
else:
84-
raise TimeoutError("Public IP could not be retrieved.")
85-
86-
8754
def find_process(proc: str, instance: str | None = None) -> Generator[psutil.Process, None, None]:
8855
proc_set = {name.casefold() for name in proc.split("|")}
8956

@@ -332,57 +299,6 @@ def get_win32_error_message(error_code: int) -> str:
332299
)
333300
return buffer.value.strip()
334301

335-
if sys.version_info >= (3, 14):
336-
337-
def is_upnp_available() -> bool:
338-
from upnpy import UPnP
339-
340-
try:
341-
upnp = UPnP()
342-
devices = upnp.discover()
343-
if not devices:
344-
return False
345-
346-
# Look for an InternetGatewayDevice and its WANIPConnection (or WANPPPConnection) service
347-
for device in devices:
348-
if "InternetGatewayDevice" in (device.device_type or ""):
349-
try:
350-
# Try WANIPConnection first
351-
wan_services = device.get_services()
352-
has_wan = any(
353-
("WANIPConnection" in s.service_type) or ("WANPPPConnection" in s.service_type)
354-
for s in wan_services
355-
)
356-
if has_wan:
357-
return True
358-
except Exception:
359-
continue
360-
return False
361-
except Exception:
362-
return False
363-
364-
else:
365-
366-
def is_upnp_available() -> bool:
367-
import miniupnpc
368-
369-
try:
370-
upnp = miniupnpc.UPnP()
371-
devices = upnp.discover() # Discover UPnP-enabled devices
372-
if devices > 0:
373-
if upnp.selectigd():
374-
# UPnP is enabled and an IGD was found.
375-
return True
376-
else:
377-
# UPnP is enabled, but no Internet Gateway Device (IGD) is selected
378-
return False
379-
else:
380-
# No UPnP devices detected on the network.
381-
return False
382-
except Exception:
383-
# A UPnP device was found, but no IGD was found.
384-
return False
385-
386302

387303
class CloudRotatingFileHandler(RotatingFileHandler):
388304
def shouldRollover(self, record):

extensions/lotatc/extension.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ async def prepare(self) -> bool:
135135
json_port = self.locals.get('lotatc_inst.options', {}).get('jsonserver_port', 8081)
136136
if type(self)._json_ports.get(json_port, self.server.name) != self.server.name:
137137
self.log.error(
138-
f" => {self.server.name}: {self.name} jsonserver_port {port} already in use by server {type(self)._ports[port]}!")
138+
f" => {self.server.name}: {self.name} jsonserver_port {json_port} already in use by "
139+
f"server {type(self)._json_ports[json_port]}!")
139140
return False
140141
else:
141142
type(self)._json_ports[json_port] = self.server.name

extensions/olympus/extension.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,5 +341,5 @@ def get_ports(self) -> dict[str, Port]:
341341
return {
342342
"Olympus " + self.backend_tag.capitalize(): Port(self.config.get(self.backend_tag, {}).get('port', 4512), PortType.TCP),
343343
"Olympus " + self.frontend_tag.capitalize(): Port(self.config.get(self.frontend_tag, {}).get('port', 3000), PortType.TCP, public=True),
344-
"Olympus WSPort": Port(self.config.get('audio', {}).get('WSPort', 4000), PortType.TCP)
344+
"Olympus WSPort": Port(self.config.get('audio', {}).get('WSPort', 4000), PortType.TCP, public=(self.config.get('audio', {}).get('WSEndpoint') is None))
345345
} if self.enabled else {}

0 commit comments

Comments
 (0)