mirror of
https://github.com/markqvist/Sideband.git
synced 2025-01-12 07:59:42 -05:00
Added log viewer
This commit is contained in:
parent
922107df50
commit
9e992c83fd
@ -16,6 +16,7 @@ import multiprocessing.connection
|
|||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
from collections import deque
|
||||||
from .res import sideband_fb_data
|
from .res import sideband_fb_data
|
||||||
from .sense import Telemeter, Commands
|
from .sense import Telemeter, Commands
|
||||||
from .plugins import SidebandCommandPlugin, SidebandServicePlugin, SidebandTelemetryPlugin
|
from .plugins import SidebandCommandPlugin, SidebandServicePlugin, SidebandTelemetryPlugin
|
||||||
@ -110,6 +111,8 @@ class SidebandCore():
|
|||||||
|
|
||||||
DEFAULT_APPEARANCE = ["account", [0,0,0,1], [1,1,1,1]]
|
DEFAULT_APPEARANCE = ["account", [0,0,0,1], [1,1,1,1]]
|
||||||
|
|
||||||
|
LOG_DEQUE_MAXLEN = 256
|
||||||
|
|
||||||
aspect_filter = "lxmf.delivery"
|
aspect_filter = "lxmf.delivery"
|
||||||
def received_announce(self, destination_hash, announced_identity, app_data):
|
def received_announce(self, destination_hash, announced_identity, app_data):
|
||||||
# Add the announce to the directory announce
|
# Add the announce to the directory announce
|
||||||
@ -142,6 +145,7 @@ class SidebandCore():
|
|||||||
self.is_standalone = False
|
self.is_standalone = False
|
||||||
|
|
||||||
self.log_verbose = verbose
|
self.log_verbose = verbose
|
||||||
|
self.log_deque = deque(maxlen=self.LOG_DEQUE_MAXLEN)
|
||||||
self.owner_app = owner_app
|
self.owner_app = owner_app
|
||||||
self.reticulum = None
|
self.reticulum = None
|
||||||
self.webshare_server = None
|
self.webshare_server = None
|
||||||
@ -3630,6 +3634,14 @@ class SidebandCore():
|
|||||||
if self.is_client:
|
if self.is_client:
|
||||||
self.service_rpc_set_debug(debug)
|
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):
|
def __start_jobs_immediate(self):
|
||||||
if self.log_verbose:
|
if self.log_verbose:
|
||||||
selected_level = 6
|
selected_level = 6
|
||||||
@ -3637,7 +3649,7 @@ class SidebandCore():
|
|||||||
selected_level = 2
|
selected_level = 2
|
||||||
|
|
||||||
self.setstate("init.loadingstate", "Substantiating Reticulum")
|
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:
|
if self.is_service:
|
||||||
self.__start_rpc_listener()
|
self.__start_rpc_listener()
|
||||||
|
@ -1287,7 +1287,7 @@ layout_settings_screen = """
|
|||||||
MDLabel:
|
MDLabel:
|
||||||
id: scaling_info
|
id: scaling_info
|
||||||
markup: True
|
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
|
size_hint_y: None
|
||||||
text_size: self.width, None
|
text_size: self.width, None
|
||||||
height: self.texture_size[1]
|
height: self.texture_size[1]
|
||||||
|
@ -10,6 +10,7 @@ from kivymd.uix.recycleview import MDRecycleView
|
|||||||
from kivymd.uix.list import OneLineIconListItem
|
from kivymd.uix.list import OneLineIconListItem
|
||||||
from kivymd.uix.pickers import MDColorPicker
|
from kivymd.uix.pickers import MDColorPicker
|
||||||
from kivymd.icon_definitions import md_icons
|
from kivymd.icon_definitions import md_icons
|
||||||
|
from kivymd.toast import toast
|
||||||
from kivy.properties import StringProperty, BooleanProperty
|
from kivy.properties import StringProperty, BooleanProperty
|
||||||
from kivy.effects.scroll import ScrollEffect
|
from kivy.effects.scroll import ScrollEffect
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
@ -29,6 +30,7 @@ class Utilities():
|
|||||||
self.screen = None
|
self.screen = None
|
||||||
self.rnstatus_screen = None
|
self.rnstatus_screen = None
|
||||||
self.rnstatus_instance = None
|
self.rnstatus_instance = None
|
||||||
|
self.logviewer_screen = None
|
||||||
|
|
||||||
if not self.app.root.ids.screen_manager.has_screen("utilities_screen"):
|
if not self.app.root.ids.screen_manager.has_screen("utilities_screen"):
|
||||||
self.screen = Builder.load_string(layout_utilities_screen)
|
self.screen = Builder.load_string(layout_utilities_screen)
|
||||||
@ -72,17 +74,12 @@ class Utilities():
|
|||||||
|
|
||||||
import io
|
import io
|
||||||
from contextlib import redirect_stdout
|
from contextlib import redirect_stdout
|
||||||
output_marker = "===begin rnstatus output==="
|
|
||||||
output = "None"
|
output = "None"
|
||||||
with io.StringIO() as buffer, redirect_stdout(buffer):
|
with io.StringIO() as buffer, redirect_stdout(buffer):
|
||||||
print(output_marker, end="")
|
with RNS.logging_lock:
|
||||||
self.rnstatus_instance.main(rns_instance=RNS.Reticulum.get_instance())
|
self.rnstatus_instance.main(rns_instance=RNS.Reticulum.get_instance())
|
||||||
output = buffer.getvalue()
|
output = buffer.getvalue()
|
||||||
|
|
||||||
remainder = output[:output.find(output_marker)]
|
|
||||||
output = output[output.find(output_marker)+len(output_marker):]
|
|
||||||
print(remainder, end="")
|
|
||||||
|
|
||||||
def cb(dt):
|
def cb(dt):
|
||||||
self.rnstatus_screen.ids.rnstatus_output.text = f"[font=RobotoMono-Regular]{output}[/font]"
|
self.rnstatus_screen.ids.rnstatus_output.text = f"[font=RobotoMono-Regular]{output}[/font]"
|
||||||
Clock.schedule_once(cb, 0.2)
|
Clock.schedule_once(cb, 0.2)
|
||||||
@ -90,6 +87,44 @@ class Utilities():
|
|||||||
if self.app.root.ids.screen_manager.current == "rnstatus_screen":
|
if self.app.root.ids.screen_manager.current == "rnstatus_screen":
|
||||||
Clock.schedule_once(self.update_rnstatus, 1)
|
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 = """
|
layout_utilities_screen = """
|
||||||
MDScreen:
|
MDScreen:
|
||||||
@ -156,8 +191,8 @@ MDScreen:
|
|||||||
icon_size: dp(24)
|
icon_size: dp(24)
|
||||||
font_size: dp(16)
|
font_size: dp(16)
|
||||||
size_hint: [1.0, None]
|
size_hint: [1.0, None]
|
||||||
on_release: root.delegate.rnstatus_action(self)
|
on_release: root.delegate.logviewer_action(self)
|
||||||
disabled: True
|
disabled: False
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -177,12 +212,12 @@ MDScreen:
|
|||||||
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
|
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
|
||||||
right_action_items:
|
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)],
|
['close', lambda x: root.app.close_sub_utilities_action(self)],
|
||||||
]
|
]
|
||||||
|
|
||||||
MDScrollView:
|
MDScrollView:
|
||||||
id: sensors_scrollview
|
id: rnstatus_scrollview
|
||||||
size_hint_x: 1
|
size_hint_x: 1
|
||||||
size_hint_y: None
|
size_hint_y: None
|
||||||
size: [root.width, root.height-root.ids.top_bar.height]
|
size: [root.width, root.height-root.ids.top_bar.height]
|
||||||
@ -203,3 +238,46 @@ MDScreen:
|
|||||||
text_size: self.width, None
|
text_size: self.width, None
|
||||||
height: self.texture_size[1]
|
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]
|
||||||
|
"""
|
Loading…
Reference in New Issue
Block a user