Skip to content

Commit 37714c4

Browse files
committed
Add darwin implementation of reactive network handling
1 parent 5ef6adb commit 37714c4

4 files changed

Lines changed: 72 additions & 5 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ dependencies = [
3636
"pyobjc-framework-Cocoa<13; sys_platform == 'darwin'",
3737
"pyobjc-framework-CoreWLAN<13; sys_platform == 'darwin'",
3838
"pyobjc-framework-LaunchServices<13; sys_platform == 'darwin'",
39+
"pyobjc-framework-libdispatch>=12.1; sys_platform == 'darwin'",
40+
"pyobjc-framework-network>=12.1; sys_platform == 'darwin'",
3941
"pyqt6",
4042
"secretstorage; sys_platform != 'darwin'",
4143
]

src/vorta/network_status/darwin.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from collections.abc import Iterator
55
from datetime import datetime as dt
66

7+
import dispatch
8+
import Network
79
from CoreWLAN import CWInterface, CWNetwork, CWWiFiClient
810

911
from vorta.log import logger
@@ -13,6 +15,17 @@
1315
class DarwinNetworkStatus(NetworkStatusMonitor):
1416
def __init__(self) -> None:
1517
super().__init__()
18+
# Default state of none indicates we haven't received a path update yet
19+
self.nw_path = None
20+
self.nw_path_monitor = Network.nw_path_monitor_create()
21+
Network.nw_path_monitor_set_update_handler(self.nw_path_monitor, self._path_updated)
22+
# Needs a dispatch to get the first event
23+
Network.nw_path_monitor_set_queue(self.nw_path_monitor, dispatch.dispatch_get_main_queue())
24+
Network.nw_path_monitor_start(self.nw_path_monitor)
25+
26+
def _path_updated(self, path):
27+
self.nw_path = path
28+
self.network_status_changed.emit(self.is_network_active())
1629

1730
def is_network_metered(self) -> bool:
1831
interface: CWInterface = self._get_wifi_interface()
@@ -30,9 +43,16 @@ def is_network_metered(self) -> bool:
3043

3144
return is_ios_hotspot or any(is_network_metered_with_android(d) for d in get_network_devices())
3245

33-
def is_network_active(self) -> bool:
34-
# Not yet implemented
35-
return True
46+
def is_network_active(self):
47+
# We haven't received an update yet, surely it is coming soon
48+
if self.nw_path is None:
49+
return False
50+
# https://developer.apple.com/documentation/network/nw_path_status_satisfiable
51+
# Maybe making a network connection will work so treat it as active
52+
return Network.nw_path_get_status(self.nw_path) in (
53+
Network.nw_path_status_satisfied,
54+
Network.nw_path_status_satisfiable,
55+
)
3656

3757
def get_current_wifi(self) -> str | None:
3858
"""

tests/unit/test_kwallet.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import sys
12
from unittest.mock import patch
23

34
import pytest
45
from PyQt6.QtCore import QVariant
56

67
from vorta.keyring.kwallet import KWalletNotAvailableException, VortaKWallet5Keyring
78

9+
pytestmark = pytest.mark.skipif(sys.platform == 'darwin', reason="no kwallet on macos")
10+
811

912
@pytest.fixture
1013
def kwallet_keyring():

uv.lock

Lines changed: 44 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)