-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds a connection info expander to the UI. Uses the NM api for querying, except where I could not find any functions (e.g. rx and tx bytes, which are gathered from standard file locations). If it cannot find the data, as this is not foolproof, it will set it to N/A, the application will keep working. Note that glade changed the property names from `_` to `-`, but this still works on the VMS. Apparently `_` are an old format that is not used any more in glade. Signed-off-by: jwijenbergh <[email protected]>
- Loading branch information
1 parent
a9a4643
commit e20c0da
Showing
7 changed files
with
827 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import logging | ||
import time | ||
from datetime import timedelta | ||
from pathlib import Path | ||
from typing import Optional, TextIO | ||
|
||
from ..nm import get_iface, get_ipv4, get_ipv6, get_timestamp | ||
from ..utils import cache, get_human_readable_bytes, translated_property | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
LINUX_NET_FOLDER = Path("/sys/class/net") | ||
|
||
|
||
class NetworkStats: | ||
|
||
default_text = translated_property("N/A") | ||
|
||
# These properties define an LRU cache | ||
# This cache is used so that we do not query these every second | ||
@property # type: ignore | ||
@cache | ||
def ipv4(self) -> str: | ||
_ipv4 = get_ipv4() | ||
if _ipv4 is None: | ||
_ipv4 = self.default_text | ||
return _ipv4 | ||
|
||
@property # type: ignore | ||
@cache | ||
def ipv6(self) -> str: | ||
_ipv6 = get_ipv6() | ||
if _ipv6 is None: | ||
_ipv6 = self.default_text | ||
return _ipv6 | ||
|
||
@property # type: ignore | ||
@cache | ||
def upload_file(self) -> Optional[TextIO]: | ||
return self.open_file("tx_bytes") | ||
|
||
@property # type: ignore | ||
@cache | ||
def download_file(self) -> Optional[TextIO]: | ||
return self.open_file("rx_bytes") | ||
|
||
@property # type: ignore | ||
@cache | ||
def start_bytes_upload(self) -> Optional[int]: | ||
return self.get_file_bytes(self.upload_file) # type: ignore | ||
|
||
@property # type: ignore | ||
@cache | ||
def start_bytes_download(self) -> Optional[int]: | ||
return self.get_file_bytes(self.download_file) # type: ignore | ||
|
||
@property # type: ignore | ||
@cache | ||
def iface(self) -> Optional[str]: | ||
return get_iface() | ||
|
||
@property # type: ignore | ||
@cache | ||
def timestamp(self) -> Optional[int]: | ||
return get_timestamp() | ||
|
||
@property | ||
def download(self) -> str: | ||
""" | ||
Get the download as a human readable string | ||
""" | ||
file_bytes_download = self.get_file_bytes(self.download_file) # type: ignore | ||
if file_bytes_download is None: | ||
return self.default_text | ||
if file_bytes_download <= self.start_bytes_download: # type: ignore | ||
return get_human_readable_bytes(0) | ||
return get_human_readable_bytes(file_bytes_download - self.start_bytes_download) # type: ignore | ||
|
||
@property | ||
def upload(self) -> str: | ||
""" | ||
Get the upload as a human readable string | ||
""" | ||
file_bytes_upload = self.get_file_bytes(self.upload_file) # type: ignore | ||
if file_bytes_upload is None: | ||
return self.default_text | ||
if file_bytes_upload <= self.start_bytes_upload: # type: ignore | ||
return get_human_readable_bytes(0) | ||
return get_human_readable_bytes(file_bytes_upload - self.start_bytes_upload) # type:ignore | ||
|
||
@property | ||
def duration(self) -> str: | ||
""" | ||
Get the duration of the connection, in "HH:MM:SS" | ||
""" | ||
if self.timestamp is None: | ||
logger.warning("Network Stats: failed to get timestamp") | ||
return self.default_text | ||
now_unix_seconds = int(time.time()) | ||
duration = now_unix_seconds - self.timestamp # type: ignore | ||
return str(timedelta(seconds=duration)) | ||
|
||
def open_file(self, filename: str) -> Optional[TextIO]: | ||
""" | ||
Helper function to open a statistics network file | ||
""" | ||
if not self.iface: | ||
logger.warning(f"Network Stats: {filename}, failed to get interface") | ||
return None | ||
filepath = LINUX_NET_FOLDER / self.iface / "statistics" / filename # type: ignore | ||
if not filepath.is_file(): | ||
logger.warning(f"Network Stats: {filepath} is not a file") | ||
return None | ||
return open(filepath, "r") | ||
|
||
def get_file_bytes(self, filehandler: Optional[TextIO]) -> Optional[int]: | ||
""" | ||
Helper function to get a statistics file to calculate the total data transfer | ||
""" | ||
# If the interface is not set | ||
# or the file is not present, we cannot get the stat | ||
if not self.iface: | ||
# Warning was already shown | ||
return None | ||
if not filehandler: | ||
# Warning was already shown | ||
return None | ||
|
||
# Get the statistic from the file | ||
# and go to the beginning | ||
try: | ||
stat = int(filehandler.readline()) | ||
except ValueError: | ||
stat = 0 | ||
filehandler.seek(0) | ||
return stat | ||
|
||
def cleanup(self): | ||
""" | ||
Cleanup the network stats by closing the files | ||
""" | ||
if self.download_file: | ||
self.download_file.close() | ||
if self.upload_file: | ||
self.upload_file.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.