Added log viewer

This commit is contained in:
Mark Qvist 2024-12-07 22:27:39 +01:00
parent 922107df50
commit 9e992c83fd
3 changed files with 104 additions and 14 deletions

View File

@ -16,6 +16,7 @@ import multiprocessing.connection
from copy import deepcopy
from threading import Lock
from collections import deque
from .res import sideband_fb_data
from .sense import Telemeter, Commands
from .plugins import SidebandCommandPlugin, SidebandServicePlugin, SidebandTelemetryPlugin
@ -110,6 +111,8 @@ class SidebandCore():
DEFAULT_APPEARANCE = ["account", [0,0,0,1], [1,1,1,1]]
LOG_DEQUE_MAXLEN = 256
aspect_filter = "lxmf.delivery"
def received_announce(self, destination_hash, announced_identity, app_data):
# Add the announce to the directory announce
@ -142,6 +145,7 @@ class SidebandCore():
self.is_standalone = False
self.log_verbose = verbose
self.log_deque = deque(maxlen=self.LOG_DEQUE_MAXLEN)
self.owner_app = owner_app
self.reticulum = None
self.webshare_server = None
@ -3630,6 +3634,14 @@ class SidebandCore():
if self.is_client:
self.service_rpc_set_debug(debug)
def _log_handler(self, message):
self.log_deque.append(message)
print(message)
# TODO: Get service log on Android
def get_log(self):
return "\n".join(self.log_deque)
def __start_jobs_immediate(self):
if self.log_verbose:
selected_level = 6
@ -3637,7 +3649,7 @@ class SidebandCore():
selected_level = 2
self.setstate("init.loadingstate", "Substantiating Reticulum")
self.reticulum = RNS.Reticulum(configdir=self.rns_configdir, loglevel=selected_level)
self.reticulum = RNS.Reticulum(configdir=self.rns_configdir, loglevel=selected_level, logdest=self._log_handler)
if self.is_service:
self.__start_rpc_listener()

View File

@ -1287,7 +1287,7 @@ layout_settings_screen = """
MDLabel:
id: scaling_info
markup: True
text: "You can scale the entire Sideband UI by specifying a scaling factor in the field below. After setting it, restart sideband for the scaling to take effect.\\n\\nSet to 0.0 to disable scaling adjustments."
text: "You can scale the entire Sideband UI by specifying a scaling factor in the field below. After setting it, restart sideband for the scaling to take effect.\\n\\nSet to 0.0 to disable scaling adjustments.\\n\\n[b]Please note![/b] On some devices, the default scaling factor will be higher than 1.0, and setting a smaller value will result in miniscule UI elements."
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]

View File

@ -10,6 +10,7 @@ from kivymd.uix.recycleview import MDRecycleView
from kivymd.uix.list import OneLineIconListItem
from kivymd.uix.pickers import MDColorPicker
from kivymd.icon_definitions import md_icons
from kivymd.toast import toast
from kivy.properties import StringProperty, BooleanProperty
from kivy.effects.scroll import ScrollEffect
from kivy.clock import Clock
@ -29,6 +30,7 @@ class Utilities():
self.screen = None
self.rnstatus_screen = None
self.rnstatus_instance = None
self.logviewer_screen = None
if not self.app.root.ids.screen_manager.has_screen("utilities_screen"):
self.screen = Builder.load_string(layout_utilities_screen)
@ -72,16 +74,11 @@ class Utilities():
import io
from contextlib import redirect_stdout
output_marker = "===begin rnstatus output==="
output = "None"
with io.StringIO() as buffer, redirect_stdout(buffer):
print(output_marker, end="")
self.rnstatus_instance.main(rns_instance=RNS.Reticulum.get_instance())
output = buffer.getvalue()
remainder = output[:output.find(output_marker)]
output = output[output.find(output_marker)+len(output_marker):]
print(remainder, end="")
with RNS.logging_lock:
self.rnstatus_instance.main(rns_instance=RNS.Reticulum.get_instance())
output = buffer.getvalue()
def cb(dt):
self.rnstatus_screen.ids.rnstatus_output.text = f"[font=RobotoMono-Regular]{output}[/font]"
@ -90,6 +87,44 @@ class Utilities():
if self.app.root.ids.screen_manager.current == "rnstatus_screen":
Clock.schedule_once(self.update_rnstatus, 1)
### Log viewer screen
######################################
def logviewer_action(self, sender=None):
if not self.app.root.ids.screen_manager.has_screen("logviewer_screen"):
self.logviewer_screen = Builder.load_string(layout_logviewer_screen)
self.logviewer_screen.app = self.app
self.logviewer_screen.delegate = self
self.app.root.ids.screen_manager.add_widget(self.logviewer_screen)
self.app.root.ids.screen_manager.transition.direction = "left"
self.app.root.ids.screen_manager.current = "logviewer_screen"
self.app.sideband.setstate("app.displaying", self.app.root.ids.screen_manager.current)
self.update_logviewer()
def update_logviewer(self, sender=None):
threading.Thread(target=self.update_logviewer_job, daemon=True).start()
def update_logviewer_job(self, sender=None):
try:
output = self.app.sideband.get_log()
except Exception as e:
output = f"An error occurred while retrieving log entries:\n{e}"
self.logviewer_screen.log_contents = output
def cb(dt):
self.logviewer_screen.ids.logviewer_output.text = f"[font=RobotoMono-Regular]{output}[/font]"
Clock.schedule_once(cb, 0.2)
if self.app.root.ids.screen_manager.current == "logviewer_screen":
Clock.schedule_once(self.update_logviewer, 1)
def logviewer_copy(self, sender=None):
Clipboard.copy(self.logviewer_screen.log_contents)
if True or RNS.vendor.platformutils.is_android():
toast("Log copied to clipboard")
layout_utilities_screen = """
MDScreen:
@ -156,8 +191,8 @@ MDScreen:
icon_size: dp(24)
font_size: dp(16)
size_hint: [1.0, None]
on_release: root.delegate.rnstatus_action(self)
disabled: True
on_release: root.delegate.logviewer_action(self)
disabled: False
"""
@ -177,12 +212,12 @@ MDScreen:
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
right_action_items:
[
['refresh', lambda x: root.delegate.update_rnstatus()],
# ['refresh', lambda x: root.delegate.update_rnstatus()],
['close', lambda x: root.app.close_sub_utilities_action(self)],
]
MDScrollView:
id: sensors_scrollview
id: rnstatus_scrollview
size_hint_x: 1
size_hint_y: None
size: [root.width, root.height-root.ids.top_bar.height]
@ -202,4 +237,47 @@ MDScreen:
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
"""
layout_logviewer_screen = """
MDScreen:
name: "logviewer_screen"
BoxLayout:
orientation: "vertical"
MDTopAppBar:
id: top_bar
title: "Log Viewer"
anchor_title: "left"
elevation: 0
left_action_items:
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
right_action_items:
[
['content-copy', lambda x: root.delegate.logviewer_copy()],
['close', lambda x: root.app.close_sub_utilities_action(self)],
]
MDScrollView:
id: logviewer_scrollview
size_hint_x: 1
size_hint_y: None
size: [root.width, root.height-root.ids.top_bar.height]
do_scroll_x: False
do_scroll_y: True
MDGridLayout:
cols: 1
padding: [dp(28), dp(14), dp(28), dp(28)]
size_hint_y: None
height: self.minimum_height
MDLabel:
id: logviewer_output
markup: True
text: ""
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
"""