mirror of
				https://github.com/liberatedsystems/Sideband_CE.git
				synced 2024-09-03 04:13:27 +02:00 
			
		
		
		
	Added telemetry system, location sharing and map view for shared locations
This commit is contained in:
		
							parent
							
								
									a9160b558b
								
							
						
					
					
						commit
						314499109c
					
				
							
								
								
									
										170
									
								
								sbapp/main.py
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								sbapp/main.py
									
									
									
									
									
								
							@ -44,8 +44,9 @@ from kivy.uix.screenmanager import FadeTransition, NoTransition
 | 
				
			|||||||
from kivymd.uix.list import OneLineIconListItem
 | 
					from kivymd.uix.list import OneLineIconListItem
 | 
				
			||||||
from kivy.properties import StringProperty
 | 
					from kivy.properties import StringProperty
 | 
				
			||||||
from kivymd.uix.pickers import MDColorPicker
 | 
					from kivymd.uix.pickers import MDColorPicker
 | 
				
			||||||
 | 
					from kivymd.uix.button import BaseButton, MDIconButton
 | 
				
			||||||
from sideband.sense import Telemeter
 | 
					from sideband.sense import Telemeter
 | 
				
			||||||
from mapview import MapMarker
 | 
					from mapview import CustomMapMarker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if RNS.vendor.platformutils.get_platform() == "android":
 | 
					if RNS.vendor.platformutils.get_platform() == "android":
 | 
				
			||||||
    from sideband.core import SidebandCore
 | 
					    from sideband.core import SidebandCore
 | 
				
			||||||
@ -922,6 +923,11 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
            self.root.ids.message_send_button.disabled = False
 | 
					            self.root.ids.message_send_button.disabled = False
 | 
				
			||||||
        Clock.schedule_once(cb, 0.5)
 | 
					        Clock.schedule_once(cb, 0.5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def peer_show_location_action(self, sender):
 | 
				
			||||||
 | 
					        if self.root.ids.screen_manager.current == "messages_screen":
 | 
				
			||||||
 | 
					            context_dest = self.root.ids.messages_scrollview.active_conversation
 | 
				
			||||||
 | 
					            self.map_show_peer_location(context_dest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def message_propagation_action(self, sender):
 | 
					    def message_propagation_action(self, sender):
 | 
				
			||||||
        if self.outbound_mode_paper:
 | 
					        if self.outbound_mode_paper:
 | 
				
			||||||
            self.outbound_mode_paper = False
 | 
					            self.outbound_mode_paper = False
 | 
				
			||||||
@ -1289,6 +1295,10 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
                self.sideband.save_configuration()
 | 
					                self.sideband.save_configuration()
 | 
				
			||||||
                self.update_ui_theme()
 | 
					                self.update_ui_theme()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def save_advanced_stats(sender=None, event=None):
 | 
				
			||||||
 | 
					                self.sideband.config["advanced_stats"] = self.root.ids.settings_advanced_statistics.active
 | 
				
			||||||
 | 
					                self.sideband.save_configuration()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            def save_notifications_on(sender=None, event=None):
 | 
					            def save_notifications_on(sender=None, event=None):
 | 
				
			||||||
                self.sideband.config["notifications_on"] = self.root.ids.settings_notifications_on.active
 | 
					                self.sideband.config["notifications_on"] = self.root.ids.settings_notifications_on.active
 | 
				
			||||||
                self.sideband.save_configuration()
 | 
					                self.sideband.save_configuration()
 | 
				
			||||||
@ -1377,6 +1387,9 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
            self.root.ids.settings_eink_mode.active = self.sideband.config["eink_mode"]
 | 
					            self.root.ids.settings_eink_mode.active = self.sideband.config["eink_mode"]
 | 
				
			||||||
            self.root.ids.settings_eink_mode.bind(active=save_eink_mode)
 | 
					            self.root.ids.settings_eink_mode.bind(active=save_eink_mode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.root.ids.settings_advanced_statistics.active = self.sideband.config["advanced_stats"]
 | 
				
			||||||
 | 
					            self.root.ids.settings_advanced_statistics.bind(active=save_advanced_stats)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.root.ids.settings_start_announce.active = self.sideband.config["start_announce"]
 | 
					            self.root.ids.settings_start_announce.active = self.sideband.config["start_announce"]
 | 
				
			||||||
            self.root.ids.settings_start_announce.bind(active=save_start_announce)
 | 
					            self.root.ids.settings_start_announce.bind(active=save_start_announce)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2898,6 +2911,7 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.sideband.config["telemetry_icon"] = self.root.ids.telemetry_icon_preview.icon
 | 
					        self.sideband.config["telemetry_icon"] = self.root.ids.telemetry_icon_preview.icon
 | 
				
			||||||
        self.sideband.save_configuration()
 | 
					        self.sideband.save_configuration()
 | 
				
			||||||
 | 
					        self.own_appearance_changed = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def telemetry_enabled_toggle(self, sender=None, event=None):
 | 
					    def telemetry_enabled_toggle(self, sender=None, event=None):
 | 
				
			||||||
@ -2909,6 +2923,7 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    def telemetry_location_toggle(self, sender=None, event=None):
 | 
					    def telemetry_location_toggle(self, sender=None, event=None):
 | 
				
			||||||
        if self.root.ids.telemetry_s_location.active:
 | 
					        if self.root.ids.telemetry_s_location.active:
 | 
				
			||||||
 | 
					            if RNS.vendor.platformutils.is_android():
 | 
				
			||||||
                if not check_permission("android.permission.ACCESS_COARSE_LOCATION") or not check_permission("android.permission.ACCESS_FINE_LOCATION"):
 | 
					                if not check_permission("android.permission.ACCESS_COARSE_LOCATION") or not check_permission("android.permission.ACCESS_FINE_LOCATION"):
 | 
				
			||||||
                    RNS.log("Requesting location permission", RNS.LOG_DEBUG)
 | 
					                    RNS.log("Requesting location permission", RNS.LOG_DEBUG)
 | 
				
			||||||
                    request_permissions(["android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"])
 | 
					                    request_permissions(["android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"])
 | 
				
			||||||
@ -2984,6 +2999,7 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
        self.root.ids.telemetry_icon_preview.icon_color = color
 | 
					        self.root.ids.telemetry_icon_preview.icon_color = color
 | 
				
			||||||
        self.sideband.config["telemetry_fg"] = color
 | 
					        self.sideband.config["telemetry_fg"] = color
 | 
				
			||||||
        self.sideband.save_configuration()
 | 
					        self.sideband.save_configuration()
 | 
				
			||||||
 | 
					        self.own_appearance_changed = True
 | 
				
			||||||
        if hasattr(self, "color_picker") and self.color_picker != None:
 | 
					        if hasattr(self, "color_picker") and self.color_picker != None:
 | 
				
			||||||
            self.color_picker.dismiss()
 | 
					            self.color_picker.dismiss()
 | 
				
			||||||
            self.color_picker = None
 | 
					            self.color_picker = None
 | 
				
			||||||
@ -3000,6 +3016,8 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
        color = selected_color[:-1] + [1]
 | 
					        color = selected_color[:-1] + [1]
 | 
				
			||||||
        self.root.ids.telemetry_icon_preview.md_bg_color = color
 | 
					        self.root.ids.telemetry_icon_preview.md_bg_color = color
 | 
				
			||||||
        self.sideband.config["telemetry_bg"] = color
 | 
					        self.sideband.config["telemetry_bg"] = color
 | 
				
			||||||
 | 
					        self.sideband.save_configuration()
 | 
				
			||||||
 | 
					        self.own_appearance_changed = True
 | 
				
			||||||
        if hasattr(self, "color_picker") and self.color_picker != None:
 | 
					        if hasattr(self, "color_picker") and self.color_picker != None:
 | 
				
			||||||
            self.color_picker.dismiss()
 | 
					            self.color_picker.dismiss()
 | 
				
			||||||
            self.color_picker = None
 | 
					            self.color_picker = None
 | 
				
			||||||
@ -3057,7 +3075,7 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
            from mapview import MapView
 | 
					            from mapview import MapView
 | 
				
			||||||
            mapview = MapView(zoom=self.sideband.config["map_zoom"], lat=self.sideband.config["map_lat"], lon=self.sideband.config["map_lon"])
 | 
					            mapview = MapView(zoom=self.sideband.config["map_zoom"], lat=self.sideband.config["map_lat"], lon=self.sideband.config["map_lon"])
 | 
				
			||||||
            mapview.snap_to_zoom = False
 | 
					            mapview.snap_to_zoom = False
 | 
				
			||||||
            mapview.double_tap_zoom = False
 | 
					            mapview.double_tap_zoom = True
 | 
				
			||||||
            self.root.ids.map_layout.map = mapview
 | 
					            self.root.ids.map_layout.map = mapview
 | 
				
			||||||
            self.root.ids.map_layout.add_widget(self.root.ids.map_layout.map)
 | 
					            self.root.ids.map_layout.add_widget(self.root.ids.map_layout.map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -3073,11 +3091,71 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
            self.map_update_markers()
 | 
					            self.map_update_markers()
 | 
				
			||||||
        Clock.schedule_once(am_job, 0.6)
 | 
					        Clock.schedule_once(am_job, 0.6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def close_location_error_dialog(self, sender=None):
 | 
				
			||||||
 | 
					        if hasattr(self, "location_error_dialog") and self.location_error_dialog != None:
 | 
				
			||||||
 | 
					            self.location_error_dialog.dismiss()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def map_show(self, location):
 | 
				
			||||||
 | 
					        RNS.log(str(location), RNS.LOG_WARNING)
 | 
				
			||||||
 | 
					        if hasattr(self.root.ids.map_layout, "map") and self.root.ids.map_layout.map:
 | 
				
			||||||
 | 
					            self.root.ids.map_layout.map.lat = location["latitude"]
 | 
				
			||||||
 | 
					            self.root.ids.map_layout.map.lon = location["longtitude"]
 | 
				
			||||||
 | 
					            self.root.ids.map_layout.map.zoom = 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def map_show_peer_location(self, context_dest):
 | 
				
			||||||
 | 
					        location = self.sideband.peer_location(context_dest)
 | 
				
			||||||
 | 
					        if not location:
 | 
				
			||||||
 | 
					            self.location_error_dialog = MDDialog(
 | 
				
			||||||
 | 
					                title="No Location",
 | 
				
			||||||
 | 
					                text="During the last 24 hours, no location updates have been received from this peer. You can use the the [b]Situation Map[/b] to manually search for earlier telemetry.",
 | 
				
			||||||
 | 
					                buttons=[
 | 
				
			||||||
 | 
					                    MDRectangleFlatButton(
 | 
				
			||||||
 | 
					                        text="OK",
 | 
				
			||||||
 | 
					                        font_size=dp(18),
 | 
				
			||||||
 | 
					                        on_release=self.close_location_error_dialog
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            self.location_error_dialog.open()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.map_action()
 | 
				
			||||||
 | 
					            self.map_show(location)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def map_create_marker(self, source, telemetry, appearance):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            l = telemetry["location"]
 | 
				
			||||||
 | 
					            a_icon = appearance[0]
 | 
				
			||||||
 | 
					            a_fg = appearance[1]; a_bg = appearance[2]
 | 
				
			||||||
 | 
					            marker = CustomMapMarker(lat=l["latitude"], lon=l["longtitude"], icon_bg=a_bg)
 | 
				
			||||||
 | 
					            marker.source_dest = source
 | 
				
			||||||
 | 
					            marker.location_time = l["last_update"]
 | 
				
			||||||
 | 
					            marker.icon = MDMapIconButton(
 | 
				
			||||||
 | 
					                icon=a_icon, icon_color=a_fg,
 | 
				
			||||||
 | 
					                md_bg_color=a_bg, theme_icon_color="Custom",
 | 
				
			||||||
 | 
					                icon_size=dp(32),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            marker.icon._default_icon_pad = dp(16)
 | 
				
			||||||
 | 
					            marker.add_widget(marker.icon)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ########
 | 
				
			||||||
 | 
					            # marker.badge = MDMapIconButton(
 | 
				
			||||||
 | 
					            #     icon="network-strength-2", icon_color=[0,0,0,1],
 | 
				
			||||||
 | 
					            #     md_bg_color=[1,1,1,1], theme_icon_color="Custom",
 | 
				
			||||||
 | 
					            #     icon_size=dp(18),
 | 
				
			||||||
 | 
					            # )
 | 
				
			||||||
 | 
					            # marker.badge._default_icon_pad = dp(5)
 | 
				
			||||||
 | 
					            # marker.icon.add_widget(marker.badge)
 | 
				
			||||||
 | 
					            ########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return marker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            RNS.log("Could not create map marker for "+RNS.prettyhexrep(source)+": "+str(e), RNS.LOG_ERROR)
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def map_update_markers(self, sender=None):
 | 
					    def map_update_markers(self, sender=None):
 | 
				
			||||||
        # TODO: Remove
 | 
					 | 
				
			||||||
        # time_s = time.time()
 | 
					 | 
				
			||||||
        # RNS.log("Update map markers", RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
        earliest = time.time() - self.sideband.config["map_history_limit"]
 | 
					        earliest = time.time() - self.sideband.config["map_history_limit"]
 | 
				
			||||||
        telemetry_entries = self.sideband.list_telemetry(after=earliest)
 | 
					        telemetry_entries = self.sideband.list_telemetry(after=earliest)
 | 
				
			||||||
        own_address = self.sideband.lxmf_destination.hash
 | 
					        own_address = self.sideband.lxmf_destination.hash
 | 
				
			||||||
@ -3086,45 +3164,44 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
        # Add own marker if available
 | 
					        # Add own marker if available
 | 
				
			||||||
        retain_own = False
 | 
					        retain_own = False
 | 
				
			||||||
        own_telemetry = self.sideband.get_telemetry()
 | 
					        own_telemetry = self.sideband.get_telemetry()
 | 
				
			||||||
        if own_telemetry != None and "location" in own_telemetry and own_telemetry["location"]["latitude"] != None and own_telemetry["location"]["longtitude"] != None:
 | 
					        own_appearance = [
 | 
				
			||||||
 | 
					            self.sideband.config["telemetry_icon"],
 | 
				
			||||||
 | 
					            self.sideband.config["telemetry_fg"],
 | 
				
			||||||
 | 
					            self.sideband.config["telemetry_bg"]
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if own_telemetry != None and "location" in own_telemetry and own_telemetry["location"] != None and own_telemetry["location"]["latitude"] != None and own_telemetry["location"]["longtitude"] != None:
 | 
				
			||||||
                retain_own = True
 | 
					                retain_own = True
 | 
				
			||||||
            o = own_telemetry["location"]
 | 
					                
 | 
				
			||||||
                if not own_address in self.map_markers:
 | 
					                if not own_address in self.map_markers:
 | 
				
			||||||
                # TODO: Remove
 | 
					 | 
				
			||||||
                    RNS.log("Adding own marker", RNS.LOG_WARNING)
 | 
					                    RNS.log("Adding own marker", RNS.LOG_WARNING)
 | 
				
			||||||
                marker = MapMarker(lat=o["latitude"], lon=o["longtitude"])
 | 
					                    marker = self.map_create_marker(own_address, own_telemetry, own_appearance)
 | 
				
			||||||
                marker.source_dest = own_address
 | 
					                    if marker != None:
 | 
				
			||||||
                marker.latest_timestamp = o["last_update"]
 | 
					 | 
				
			||||||
                        self.map_markers[own_address] = marker
 | 
					                        self.map_markers[own_address] = marker
 | 
				
			||||||
                self.root.ids.map_layout.map.add_widget(marker)
 | 
					                        self.root.ids.map_layout.map.add_marker(marker)
 | 
				
			||||||
                        changes = True
 | 
					                        changes = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    marker = self.map_markers[own_address]
 | 
					                    marker = self.map_markers[own_address]
 | 
				
			||||||
                if o["last_update"] > marker.latest_timestamp:
 | 
					                    o = own_telemetry["location"]
 | 
				
			||||||
                    # TODO: Remove
 | 
					                    if o["last_update"] > marker.location_time or (hasattr(self, "own_appearance_changed") and self.own_appearance_changed):
 | 
				
			||||||
                    RNS.log("Updating own marker", RNS.LOG_WARNING)
 | 
					                        marker.location_time = o["last_update"]
 | 
				
			||||||
                    marker.latest_timestamp = o["last_update"]
 | 
					 | 
				
			||||||
                        marker.lat = o["latitude"]
 | 
					                        marker.lat = o["latitude"]
 | 
				
			||||||
                        marker.lon = o["longtitude"]
 | 
					                        marker.lon = o["longtitude"]
 | 
				
			||||||
 | 
					                        marker.icon.icon = own_appearance[0]
 | 
				
			||||||
 | 
					                        marker.icon.icon_color = own_appearance[1]
 | 
				
			||||||
 | 
					                        marker.icon.md_bg_color = own_appearance[2]
 | 
				
			||||||
 | 
					                        self.own_appearance_changed = False
 | 
				
			||||||
                        changes = True
 | 
					                        changes = True
 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    # TODO: Remove
 | 
					 | 
				
			||||||
                    RNS.log("Skipped updating own marker, no new location", RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            # TODO: Remove
 | 
					 | 
				
			||||||
            RNS.log("Not adding own marker, no data", RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            stale_markers = []
 | 
					            stale_markers = []
 | 
				
			||||||
            for marker in self.map_markers:
 | 
					            for marker in self.map_markers:
 | 
				
			||||||
                if not marker in telemetry_entries:
 | 
					                if not marker in telemetry_entries:
 | 
				
			||||||
                    if marker == own_address:
 | 
					                    if marker == own_address:
 | 
				
			||||||
                        if not retain_own:
 | 
					                        if not retain_own:
 | 
				
			||||||
                        # TODO: Remove
 | 
					 | 
				
			||||||
                        RNS.log("Setting own marker for removal: "+str(marker), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
                            stale_markers.append(marker)
 | 
					                            stale_markers.append(marker)
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                    # TODO: Remove
 | 
					 | 
				
			||||||
                    RNS.log("Setting marker for removal: "+str(marker), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
                        stale_markers.append(marker)
 | 
					                        stale_markers.append(marker)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for marker in stale_markers:
 | 
					            for marker in stale_markers:
 | 
				
			||||||
@ -3134,20 +3211,18 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
                except Exception as e:
 | 
					                except Exception as e:
 | 
				
			||||||
                    RNS.log("Error while removing map marker: "+str(e), RNS.LOG_ERROR)
 | 
					                    RNS.log("Error while removing map marker: "+str(e), RNS.LOG_ERROR)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            RNS.log("Error while updating own map marker: "+str(e), RNS.LOG_ERROR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for telemetry_source in telemetry_entries:
 | 
					        for telemetry_source in telemetry_entries:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
                skip = False
 | 
					                skip = False
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            # TODO: Remove
 | 
					 | 
				
			||||||
            RNS.log("Processing telemetry for "+RNS.prettyhexrep(telemetry_source)+"/"+RNS.prettyhexrep(self.sideband.lxmf_destination.hash), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if telemetry_source == own_address:
 | 
					                if telemetry_source == own_address:
 | 
				
			||||||
                # TODO: Remove
 | 
					 | 
				
			||||||
                RNS.log("Skipping own telemetry", RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
                    skip = True
 | 
					                    skip = True
 | 
				
			||||||
                elif telemetry_source in self.map_markers:
 | 
					                elif telemetry_source in self.map_markers:
 | 
				
			||||||
                    marker = self.map_markers[telemetry_source]
 | 
					                    marker = self.map_markers[telemetry_source]
 | 
				
			||||||
                    newest_timestamp = telemetry_entries[telemetry_source][0][0]
 | 
					                    newest_timestamp = telemetry_entries[telemetry_source][0][0]
 | 
				
			||||||
                if newest_timestamp <= marker.latest_timestamp:
 | 
					                    if newest_timestamp <= marker.location_time:
 | 
				
			||||||
                        skip = True
 | 
					                        skip = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                latest_viewable = None
 | 
					                latest_viewable = None
 | 
				
			||||||
@ -3158,8 +3233,6 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
                        t = Telemeter.from_packed(telemetry_data)
 | 
					                        t = Telemeter.from_packed(telemetry_data)
 | 
				
			||||||
                        if t != None:
 | 
					                        if t != None:
 | 
				
			||||||
                            telemetry = t.read_all()
 | 
					                            telemetry = t.read_all()
 | 
				
			||||||
                        # TODO: Remove
 | 
					 | 
				
			||||||
                        # RNS.log(str(telemetry)+" "+str(t), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
                            if "location" in telemetry and telemetry["location"]["latitude"] != None and telemetry["location"]["longtitude"] != None:
 | 
					                            if "location" in telemetry and telemetry["location"]["latitude"] != None and telemetry["location"]["longtitude"] != None:
 | 
				
			||||||
                                latest_viewable = telemetry
 | 
					                                latest_viewable = telemetry
 | 
				
			||||||
                                break
 | 
					                                break
 | 
				
			||||||
@ -3167,32 +3240,30 @@ class SidebandApp(MDApp):
 | 
				
			|||||||
                    if latest_viewable != None:
 | 
					                    if latest_viewable != None:
 | 
				
			||||||
                        l = latest_viewable["location"]
 | 
					                        l = latest_viewable["location"]
 | 
				
			||||||
                        if not telemetry_source in self.map_markers:
 | 
					                        if not telemetry_source in self.map_markers:
 | 
				
			||||||
                        marker = MapMarker(lat=l["latitude"], lon=l["longtitude"])
 | 
					                            marker = self.map_create_marker(telemetry_source, latest_viewable, self.sideband.peer_appearance(telemetry_source))
 | 
				
			||||||
                        marker.source_dest = telemetry_source
 | 
					                            if marker != None:
 | 
				
			||||||
                        marker.latest_timestamp = latest_viewable["time"]["utc"]
 | 
					 | 
				
			||||||
                                self.map_markers[telemetry_source] = marker
 | 
					                                self.map_markers[telemetry_source] = marker
 | 
				
			||||||
                        self.root.ids.map_layout.map.add_widget(marker)
 | 
					                                self.root.ids.map_layout.map.add_marker(marker)
 | 
				
			||||||
                                changes = True
 | 
					                                changes = True
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
                            marker = self.map_markers[telemetry_source]
 | 
					                            marker = self.map_markers[telemetry_source]
 | 
				
			||||||
                        marker.latest_timestamp = latest_viewable["time"]["utc"]
 | 
					                            marker.location_time = latest_viewable["time"]["utc"]
 | 
				
			||||||
                            marker.lat = l["latitude"]
 | 
					                            marker.lat = l["latitude"]
 | 
				
			||||||
                            marker.lon = l["longtitude"]
 | 
					                            marker.lon = l["longtitude"]
 | 
				
			||||||
 | 
					                            appearance = self.sideband.peer_appearance(telemetry_source)
 | 
				
			||||||
 | 
					                            marker.icon.icon = appearance[0]
 | 
				
			||||||
 | 
					                            marker.icon.icon_color = appearance[1]
 | 
				
			||||||
 | 
					                            marker.icon.md_bg_color = appearance[2]
 | 
				
			||||||
                            changes = True
 | 
					                            changes = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                RNS.log("Error while updating map entry for "+RNS.prettyhexrep(telemetry_source)+": "+str(e), RNS.LOG_ERROR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.last_map_update = time.time()
 | 
					        self.last_map_update = time.time()
 | 
				
			||||||
        if changes:
 | 
					        if changes:
 | 
				
			||||||
            mv = self.root.ids.map_layout.map
 | 
					            mv = self.root.ids.map_layout.map
 | 
				
			||||||
            mv.trigger_update(True)
 | 
					            mv.trigger_update(True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO: Remove
 | 
					 | 
				
			||||||
        # RNS.log("Updated map markers in "+RNS.prettytime(time.time()-time_s), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def map_add_marker(self, marker):
 | 
					 | 
				
			||||||
        marker = MapMarker(lat=0.0, lon=0.0)
 | 
					 | 
				
			||||||
        self.root.ids.map_layout.map.add_widget(marker)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ### Guide screen
 | 
					    ### Guide screen
 | 
				
			||||||
    ######################################
 | 
					    ######################################
 | 
				
			||||||
    def close_guide_action(self, sender=None):
 | 
					    def close_guide_action(self, sender=None):
 | 
				
			||||||
@ -3307,6 +3378,9 @@ Thank you very much for using Free Communications Systems.
 | 
				
			|||||||
class CustomOneLineIconListItem(OneLineIconListItem):
 | 
					class CustomOneLineIconListItem(OneLineIconListItem):
 | 
				
			||||||
    icon = StringProperty()
 | 
					    icon = StringProperty()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MDMapIconButton(MDIconButton):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def run():
 | 
					def run():
 | 
				
			||||||
    SidebandApp().run()
 | 
					    SidebandApp().run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -327,7 +327,7 @@ class MarkerMapLayer(MapLayer):
 | 
				
			|||||||
        marker.y = int(y - marker.height * marker.anchor_y)
 | 
					        marker.y = int(y - marker.height * marker.anchor_y)
 | 
				
			||||||
        if hasattr(marker, "children"):
 | 
					        if hasattr(marker, "children"):
 | 
				
			||||||
            if marker.children != None and len(marker.children) > 0:
 | 
					            if marker.children != None and len(marker.children) > 0:
 | 
				
			||||||
                c = marker.children[0]
 | 
					                for c in marker.children:
 | 
				
			||||||
                    c.x = marker.x
 | 
					                    c.x = marker.x
 | 
				
			||||||
                    c.y = marker.y+dp(16)
 | 
					                    c.y = marker.y+dp(16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -73,14 +73,14 @@ class SidebandCore():
 | 
				
			|||||||
    SERVICE_JOB_INTERVAL   = 1
 | 
					    SERVICE_JOB_INTERVAL   = 1
 | 
				
			||||||
    PERIODIC_JOBS_INTERVAL = 60
 | 
					    PERIODIC_JOBS_INTERVAL = 60
 | 
				
			||||||
    PERIODIC_SYNC_RETRY = 360
 | 
					    PERIODIC_SYNC_RETRY = 360
 | 
				
			||||||
    # TODO: Reset
 | 
					    TELEMETRY_INTERVAL = 60
 | 
				
			||||||
    # TELEMETRY_INTERVAL = 60
 | 
					 | 
				
			||||||
    TELEMETRY_INTERVAL = 10
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    IF_CHANGE_ANNOUNCE_MIN_INTERVAL = 6    # In seconds
 | 
					    IF_CHANGE_ANNOUNCE_MIN_INTERVAL = 6    # In seconds
 | 
				
			||||||
    AUTO_ANNOUNCE_RANDOM_MIN        = 90   # In minutes
 | 
					    AUTO_ANNOUNCE_RANDOM_MIN        = 90   # In minutes
 | 
				
			||||||
    AUTO_ANNOUNCE_RANDOM_MAX        = 480  # In minutes
 | 
					    AUTO_ANNOUNCE_RANDOM_MAX        = 480  # In minutes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DEFAULT_APPEARANCE = ["alpha-p-circle-outline", [0,0,0,1], [1,1,1,1]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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
 | 
				
			||||||
@ -305,7 +305,7 @@ class SidebandCore():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # Telemetry
 | 
					        # Telemetry
 | 
				
			||||||
        self.config["telemetry_enabled"] = False
 | 
					        self.config["telemetry_enabled"] = False
 | 
				
			||||||
        self.config["telemetry_icon"] = "alpha-p-circle-outline"
 | 
					        self.config["telemetry_icon"] = SidebandCore.DEFAULT_APPEARANCE[0]
 | 
				
			||||||
        self.config["telemetry_send_to_trusted"] = False
 | 
					        self.config["telemetry_send_to_trusted"] = False
 | 
				
			||||||
        self.config["telemetry_send_to_collector"] = False
 | 
					        self.config["telemetry_send_to_collector"] = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -315,6 +315,7 @@ class SidebandCore():
 | 
				
			|||||||
            self._db_initstate()
 | 
					            self._db_initstate()
 | 
				
			||||||
            self._db_initpersistent()
 | 
					            self._db_initpersistent()
 | 
				
			||||||
            self._db_inittelemetry()
 | 
					            self._db_inittelemetry()
 | 
				
			||||||
 | 
					            self._db_upgradetables()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.__save_config()
 | 
					        self.__save_config()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -338,6 +339,8 @@ class SidebandCore():
 | 
				
			|||||||
            self.config["debug"] = False
 | 
					            self.config["debug"] = False
 | 
				
			||||||
        if not "dark_ui" in self.config:
 | 
					        if not "dark_ui" in self.config:
 | 
				
			||||||
            self.config["dark_ui"] = True
 | 
					            self.config["dark_ui"] = True
 | 
				
			||||||
 | 
					        if not "advanced_stats" in self.config:
 | 
				
			||||||
 | 
					            self.config["advanced_stats"] = False
 | 
				
			||||||
        if not "lxmf_periodic_sync" in self.config:
 | 
					        if not "lxmf_periodic_sync" in self.config:
 | 
				
			||||||
            self.config["lxmf_periodic_sync"] = False
 | 
					            self.config["lxmf_periodic_sync"] = False
 | 
				
			||||||
        if not "lxmf_ignore_unknown" in self.config:
 | 
					        if not "lxmf_ignore_unknown" in self.config:
 | 
				
			||||||
@ -454,11 +457,11 @@ class SidebandCore():
 | 
				
			|||||||
            self.config["telemetry_send_to_collector"] = False
 | 
					            self.config["telemetry_send_to_collector"] = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not "telemetry_icon" in self.config:
 | 
					        if not "telemetry_icon" in self.config:
 | 
				
			||||||
            self.config["telemetry_icon"] = "alpha-p-circle-outline"
 | 
					            self.config["telemetry_icon"] = SidebandCore.DEFAULT_APPEARANCE[0]
 | 
				
			||||||
        if not "telemetry_fg" in self.config:
 | 
					        if not "telemetry_fg" in self.config:
 | 
				
			||||||
            self.config["telemetry_fg"] = [0,0,0,1]
 | 
					            self.config["telemetry_fg"] = SidebandCore.DEFAULT_APPEARANCE[1]
 | 
				
			||||||
        if not "telemetry_bg" in self.config:
 | 
					        if not "telemetry_bg" in self.config:
 | 
				
			||||||
            self.config["telemetry_bg"] = [1,1,1,1]
 | 
					            self.config["telemetry_bg"] = SidebandCore.DEFAULT_APPEARANCE[2]
 | 
				
			||||||
        if not "telemetry_send_appearance" in self.config:
 | 
					        if not "telemetry_send_appearance" in self.config:
 | 
				
			||||||
            self.config["telemetry_send_appearance"] = False
 | 
					            self.config["telemetry_send_appearance"] = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -503,6 +506,7 @@ class SidebandCore():
 | 
				
			|||||||
            self._db_initstate()
 | 
					            self._db_initstate()
 | 
				
			||||||
            self._db_initpersistent()
 | 
					            self._db_initpersistent()
 | 
				
			||||||
            self._db_inittelemetry()
 | 
					            self._db_inittelemetry()
 | 
				
			||||||
 | 
					            self._db_upgradetables()
 | 
				
			||||||
            self.__db_indices()
 | 
					            self.__db_indices()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __reload_config(self):
 | 
					    def __reload_config(self):
 | 
				
			||||||
@ -648,6 +652,9 @@ class SidebandCore():
 | 
				
			|||||||
            RNS.log("Error while getting peer name: "+str(e), RNS.LOG_ERROR)
 | 
					            RNS.log("Error while getting peer name: "+str(e), RNS.LOG_ERROR)
 | 
				
			||||||
            return ""
 | 
					            return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def peer_appearance(self, context_dest):
 | 
				
			||||||
 | 
					        return self._db_get_appearance(context_dest) or SidebandCore.DEFAULT_APPEARANCE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def peer_display_name(self, context_dest):
 | 
					    def peer_display_name(self, context_dest):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            existing_conv = self._db_conversation(context_dest)
 | 
					            existing_conv = self._db_conversation(context_dest)
 | 
				
			||||||
@ -730,6 +737,31 @@ class SidebandCore():
 | 
				
			|||||||
    def list_telemetry(self, context_dest = None, after = None, before = None, limit = None):
 | 
					    def list_telemetry(self, context_dest = None, after = None, before = None, limit = None):
 | 
				
			||||||
        return self._db_telemetry(context_dest = context_dest, after = after, before = before, limit = limit) or []
 | 
					        return self._db_telemetry(context_dest = context_dest, after = after, before = before, limit = limit) or []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def peer_telemetry(self, context_dest, after = None, before = None, limit = None):
 | 
				
			||||||
 | 
					        pts = self._db_telemetry(context_dest, after = after, before = before, limit = limit)
 | 
				
			||||||
 | 
					        if pts != None:
 | 
				
			||||||
 | 
					            if context_dest in pts:
 | 
				
			||||||
 | 
					                return pts[context_dest]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def peer_location(self, context_dest):
 | 
				
			||||||
 | 
					        after_time = time.time()-24*60*60
 | 
				
			||||||
 | 
					        pts = self.peer_telemetry(context_dest, after=after_time)
 | 
				
			||||||
 | 
					        for pt in pts:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                t = Telemeter.from_packed(pt[1]).read_all()
 | 
				
			||||||
 | 
					                RNS.log(str(t), RNS.LOG_WARNING)
 | 
				
			||||||
 | 
					                if "location" in t:
 | 
				
			||||||
 | 
					                    l = t["location"]
 | 
				
			||||||
 | 
					                    if "latitude" in l and "longtitude" in l:
 | 
				
			||||||
 | 
					                        if l["latitude"] != None and l["longtitude"] != None:
 | 
				
			||||||
 | 
					                            return l
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def list_messages(self, context_dest, after = None, before = None, limit = None):
 | 
					    def list_messages(self, context_dest, after = None, before = None, limit = None):
 | 
				
			||||||
        result = self._db_messages(context_dest, after, before, limit)
 | 
					        result = self._db_messages(context_dest, after, before, limit)
 | 
				
			||||||
        if result != None:
 | 
					        if result != None:
 | 
				
			||||||
@ -829,7 +861,7 @@ class SidebandCore():
 | 
				
			|||||||
        dbc = db.cursor()
 | 
					        dbc = db.cursor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dbc.execute("DROP TABLE IF EXISTS lxm")
 | 
					        dbc.execute("DROP TABLE IF EXISTS lxm")
 | 
				
			||||||
        dbc.execute("CREATE TABLE lxm (lxm_hash BLOB PRIMARY KEY, dest BLOB, source BLOB, title BLOB, tx_ts INTEGER, rx_ts INTEGER, state INTEGER, method INTEGER, t_encrypted INTEGER, t_encryption INTEGER, data BLOB)")
 | 
					        dbc.execute("CREATE TABLE lxm (lxm_hash BLOB PRIMARY KEY, dest BLOB, source BLOB, title BLOB, tx_ts INTEGER, rx_ts INTEGER, state INTEGER, method INTEGER, t_encrypted INTEGER, t_encryption INTEGER, data BLOB, extra BLOB)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dbc.execute("DROP TABLE IF EXISTS conv")
 | 
					        dbc.execute("DROP TABLE IF EXISTS conv")
 | 
				
			||||||
        dbc.execute("CREATE TABLE conv (dest_context BLOB PRIMARY KEY, last_tx INTEGER, last_rx INTEGER, unread INTEGER, type INTEGER, trust INTEGER, name BLOB, data BLOB)")
 | 
					        dbc.execute("CREATE TABLE conv (dest_context BLOB PRIMARY KEY, last_tx INTEGER, last_rx INTEGER, unread INTEGER, type INTEGER, trust INTEGER, name BLOB, data BLOB)")
 | 
				
			||||||
@ -837,6 +869,9 @@ class SidebandCore():
 | 
				
			|||||||
        dbc.execute("DROP TABLE IF EXISTS announce")
 | 
					        dbc.execute("DROP TABLE IF EXISTS announce")
 | 
				
			||||||
        dbc.execute("CREATE TABLE announce (id PRIMARY KEY, received INTEGER, source BLOB, data BLOB, dest_type BLOB)")
 | 
					        dbc.execute("CREATE TABLE announce (id PRIMARY KEY, received INTEGER, source BLOB, data BLOB, dest_type BLOB)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dbc.execute("DROP TABLE IF EXISTS telemetry")
 | 
				
			||||||
 | 
					        dbc.execute("CREATE TABLE IF NOT EXISTS telemetry (id INTEGER PRIMARY KEY, dest_context BLOB, ts INTEGER, data BLOB)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dbc.execute("DROP TABLE IF EXISTS state")
 | 
					        dbc.execute("DROP TABLE IF EXISTS state")
 | 
				
			||||||
        dbc.execute("CREATE TABLE state (property BLOB PRIMARY KEY, value BLOB)")
 | 
					        dbc.execute("CREATE TABLE state (property BLOB PRIMARY KEY, value BLOB)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -853,6 +888,23 @@ class SidebandCore():
 | 
				
			|||||||
        dbc.execute("CREATE UNIQUE INDEX IF NOT EXISTS idx_conv_dest_context ON conv(dest_context)")
 | 
					        dbc.execute("CREATE UNIQUE INDEX IF NOT EXISTS idx_conv_dest_context ON conv(dest_context)")
 | 
				
			||||||
        db.commit()
 | 
					        db.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _db_inittelemetry(self):
 | 
				
			||||||
 | 
					        db = self.__db_connect()
 | 
				
			||||||
 | 
					        dbc = db.cursor()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dbc.execute("CREATE TABLE IF NOT EXISTS telemetry (id INTEGER PRIMARY KEY, dest_context BLOB, ts INTEGER, data BLOB)")
 | 
				
			||||||
 | 
					        db.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _db_upgradetables(self):
 | 
				
			||||||
 | 
					        # TODO: Remove this again at some point in the future
 | 
				
			||||||
 | 
					        db = self.__db_connect()
 | 
				
			||||||
 | 
					        dbc = db.cursor()
 | 
				
			||||||
 | 
					        dbc.execute("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'lxm' AND sql LIKE '%extra%'")
 | 
				
			||||||
 | 
					        result = dbc.fetchall()
 | 
				
			||||||
 | 
					        if len(result) == 0:
 | 
				
			||||||
 | 
					            dbc.execute("ALTER TABLE lxm ADD COLUMN extra BLOB")
 | 
				
			||||||
 | 
					        db.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _db_initstate(self):
 | 
					    def _db_initstate(self):
 | 
				
			||||||
        db = self.__db_connect()
 | 
					        db = self.__db_connect()
 | 
				
			||||||
        dbc = db.cursor()
 | 
					        dbc = db.cursor()
 | 
				
			||||||
@ -930,13 +982,6 @@ class SidebandCore():
 | 
				
			|||||||
        dbc.execute("CREATE TABLE IF NOT EXISTS persistent (property BLOB PRIMARY KEY, value BLOB)")
 | 
					        dbc.execute("CREATE TABLE IF NOT EXISTS persistent (property BLOB PRIMARY KEY, value BLOB)")
 | 
				
			||||||
        db.commit()
 | 
					        db.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _db_inittelemetry(self):
 | 
					 | 
				
			||||||
        db = self.__db_connect()
 | 
					 | 
				
			||||||
        dbc = db.cursor()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        dbc.execute("CREATE TABLE IF NOT EXISTS telemetry (id INTEGER PRIMARY KEY, dest_context BLOB, ts INTEGER, data BLOB)")
 | 
					 | 
				
			||||||
        db.commit()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _db_getpersistent(self, prop):
 | 
					    def _db_getpersistent(self, prop):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            db = self.__db_connect()
 | 
					            db = self.__db_connect()
 | 
				
			||||||
@ -1079,10 +1124,7 @@ class SidebandCore():
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
            return results
 | 
					            return results
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _db_save_telemetry(self, context_dest, telemetry):
 | 
					    def _db_save_telemetry(self, context_dest, telemetry, physical_link = None):
 | 
				
			||||||
        # TODO: Remove
 | 
					 | 
				
			||||||
        # RNS.log("Saving telemetry for "+RNS.prettyhexrep(context_dest), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            remote_telemeter = Telemeter.from_packed(telemetry)
 | 
					            remote_telemeter = Telemeter.from_packed(telemetry)
 | 
				
			||||||
            telemetry_timestamp = remote_telemeter.read_all()["time"]["utc"]
 | 
					            telemetry_timestamp = remote_telemeter.read_all()["time"]["utc"]
 | 
				
			||||||
@ -1095,10 +1137,16 @@ class SidebandCore():
 | 
				
			|||||||
            result = dbc.fetchall()
 | 
					            result = dbc.fetchall()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if len(result) != 0:
 | 
					            if len(result) != 0:
 | 
				
			||||||
                # TODO: Remove
 | 
					 | 
				
			||||||
                # RNS.log("Telemetry entry already exists, ignoring", RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if physical_link != None and len(physical_link) != 0:
 | 
				
			||||||
 | 
					                remote_telemeter.synthesize("physical_link")
 | 
				
			||||||
 | 
					                if "rssi" in physical_link: remote_telemeter.sensors["physical_link"].rssi = physical_link["rssi"]
 | 
				
			||||||
 | 
					                if "snr" in physical_link: remote_telemeter.sensors["physical_link"].snr = physical_link["snr"]
 | 
				
			||||||
 | 
					                if "q" in physical_link: remote_telemeter.sensors["physical_link"].q = physical_link["q"]
 | 
				
			||||||
 | 
					                remote_telemeter.sensors["physical_link"].update_data()
 | 
				
			||||||
 | 
					                RNS.log("PACKED: "+str(remote_telemeter.read_all()), RNS.LOG_WARNING)
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            query = "INSERT INTO telemetry (dest_context, ts, data) values (?, ?, ?)"
 | 
					            query = "INSERT INTO telemetry (dest_context, ts, data) values (?, ?, ?)"
 | 
				
			||||||
            data = (context_dest, telemetry_timestamp, telemetry)
 | 
					            data = (context_dest, telemetry_timestamp, telemetry)
 | 
				
			||||||
            dbc.execute(query, data)
 | 
					            dbc.execute(query, data)
 | 
				
			||||||
@ -1110,14 +1158,12 @@ class SidebandCore():
 | 
				
			|||||||
            self.db = None
 | 
					            self.db = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _db_update_appearance(self, context_dest, timestamp, appearance):
 | 
					    def _db_update_appearance(self, context_dest, timestamp, appearance):
 | 
				
			||||||
        # TODO: Remove
 | 
					 | 
				
			||||||
        # RNS.log("Updating appearance for "+RNS.prettyhexrep(context_dest), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        conv = self._db_conversation(context_dest)
 | 
					        conv = self._db_conversation(context_dest)
 | 
				
			||||||
        data_dict = conv["data"]
 | 
					        data_dict = conv["data"]
 | 
				
			||||||
        if data_dict == None:
 | 
					        if data_dict == None:
 | 
				
			||||||
            data_dict = {}
 | 
					            data_dict = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if data_dict["appearance"] != appearance:
 | 
				
			||||||
            data_dict["appearance"] = appearance
 | 
					            data_dict["appearance"] = appearance
 | 
				
			||||||
            packed_dict = msgpack.packb(data_dict)
 | 
					            packed_dict = msgpack.packb(data_dict)
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -1130,6 +1176,27 @@ class SidebandCore():
 | 
				
			|||||||
            result = dbc.fetchall()
 | 
					            result = dbc.fetchall()
 | 
				
			||||||
            db.commit()
 | 
					            db.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _db_get_appearance(self, context_dest):
 | 
				
			||||||
 | 
					        conv = self._db_conversation(context_dest)
 | 
				
			||||||
 | 
					        data_dict = conv["data"]
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if data_dict != None and "appearance" in data_dict:
 | 
				
			||||||
 | 
					                def htf(cbytes):
 | 
				
			||||||
 | 
					                    d = 1.0/255.0
 | 
				
			||||||
 | 
					                    r = round(struct.unpack("!B", bytes([cbytes[0]]))[0]*d, 4)
 | 
				
			||||||
 | 
					                    g = round(struct.unpack("!B", bytes([cbytes[1]]))[0]*d, 4)
 | 
				
			||||||
 | 
					                    b = round(struct.unpack("!B", bytes([cbytes[2]]))[0]*d, 4)
 | 
				
			||||||
 | 
					                    return [r,g,b]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                appearance = [data_dict["appearance"][0], htf(data_dict["appearance"][1]), htf(data_dict["appearance"][2])]
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                return appearance
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            RNS.log("Could not retrieve appearance for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _db_conversation_set_telemetry(self, context_dest, send_telemetry=False):
 | 
					    def _db_conversation_set_telemetry(self, context_dest, send_telemetry=False):
 | 
				
			||||||
        conv = self._db_conversation(context_dest)
 | 
					        conv = self._db_conversation(context_dest)
 | 
				
			||||||
        data_dict = conv["data"]
 | 
					        data_dict = conv["data"]
 | 
				
			||||||
@ -1438,6 +1505,12 @@ class SidebandCore():
 | 
				
			|||||||
                if lxm.desired_method == LXMF.LXMessage.PAPER:
 | 
					                if lxm.desired_method == LXMF.LXMessage.PAPER:
 | 
				
			||||||
                    lxm.paper_packed = paper_packed_lxm
 | 
					                    lxm.paper_packed = paper_packed_lxm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                extras = None
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    extras = msgpack.unpackb(entry[11])
 | 
				
			||||||
 | 
					                except:
 | 
				
			||||||
 | 
					                    pass
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                message = {
 | 
					                message = {
 | 
				
			||||||
                    "hash": lxm.hash,
 | 
					                    "hash": lxm.hash,
 | 
				
			||||||
                    "dest": lxm.destination_hash,
 | 
					                    "dest": lxm.destination_hash,
 | 
				
			||||||
@ -1448,7 +1521,8 @@ class SidebandCore():
 | 
				
			|||||||
                    "sent": lxm.timestamp,
 | 
					                    "sent": lxm.timestamp,
 | 
				
			||||||
                    "state": entry[6],
 | 
					                    "state": entry[6],
 | 
				
			||||||
                    "method": entry[7],
 | 
					                    "method": entry[7],
 | 
				
			||||||
                    "lxm": lxm
 | 
					                    "lxm": lxm,
 | 
				
			||||||
 | 
					                    "extras": extras,
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                messages.append(message)
 | 
					                messages.append(message)
 | 
				
			||||||
@ -1470,7 +1544,14 @@ class SidebandCore():
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            packed_lxm = lxm.packed
 | 
					            packed_lxm = lxm.packed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        query = "INSERT INTO lxm (lxm_hash, dest, source, title, tx_ts, rx_ts, state, method, t_encrypted, t_encryption, data) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
 | 
					        extras = {}
 | 
				
			||||||
 | 
					        if lxm.rssi or lxm.snr or lxm.q:
 | 
				
			||||||
 | 
					            extras["rssi"] = lxm.rssi
 | 
				
			||||||
 | 
					            extras["snr"] = lxm.snr
 | 
				
			||||||
 | 
					            extras["q"] = lxm.q
 | 
				
			||||||
 | 
					        extras = msgpack.packb(extras)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = "INSERT INTO lxm (lxm_hash, dest, source, title, tx_ts, rx_ts, state, method, t_encrypted, t_encryption, data, extra) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
 | 
				
			||||||
        data = (
 | 
					        data = (
 | 
				
			||||||
            lxm.hash,
 | 
					            lxm.hash,
 | 
				
			||||||
            lxm.destination_hash,
 | 
					            lxm.destination_hash,
 | 
				
			||||||
@ -1483,10 +1564,10 @@ class SidebandCore():
 | 
				
			|||||||
            lxm.transport_encrypted,
 | 
					            lxm.transport_encrypted,
 | 
				
			||||||
            lxm.transport_encryption,
 | 
					            lxm.transport_encryption,
 | 
				
			||||||
            packed_lxm,
 | 
					            packed_lxm,
 | 
				
			||||||
 | 
					            extras
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dbc.execute(query, data)
 | 
					        dbc.execute(query, data)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        db.commit()
 | 
					        db.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not originator and lxm.fields != None:
 | 
					        if not originator and lxm.fields != None:
 | 
				
			||||||
@ -1494,7 +1575,12 @@ class SidebandCore():
 | 
				
			|||||||
                self._db_update_appearance(context_dest, lxm.timestamp, lxm.fields[LXMF.FIELD_ICON_APPEARANCE])
 | 
					                self._db_update_appearance(context_dest, lxm.timestamp, lxm.fields[LXMF.FIELD_ICON_APPEARANCE])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if LXMF.FIELD_TELEMETRY in lxm.fields:
 | 
					            if LXMF.FIELD_TELEMETRY in lxm.fields:
 | 
				
			||||||
                self._db_save_telemetry(context_dest, lxm.fields[LXMF.FIELD_TELEMETRY])
 | 
					                physical_link = {}
 | 
				
			||||||
 | 
					                if lxm.rssi or lxm.snr or lxm.q:
 | 
				
			||||||
 | 
					                    physical_link["rssi"] = lxm.rssi
 | 
				
			||||||
 | 
					                    physical_link["snr"] = lxm.snr
 | 
				
			||||||
 | 
					                    physical_link["q"] = lxm.q
 | 
				
			||||||
 | 
					                self._db_save_telemetry(context_dest, lxm.fields[LXMF.FIELD_TELEMETRY], physical_link=physical_link)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.__event_conversation_changed(context_dest)
 | 
					        self.__event_conversation_changed(context_dest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2258,7 +2344,7 @@ class SidebandCore():
 | 
				
			|||||||
            fields = {}
 | 
					            fields = {}
 | 
				
			||||||
            if send_appearance:
 | 
					            if send_appearance:
 | 
				
			||||||
                # TODO: REMOVE
 | 
					                # TODO: REMOVE
 | 
				
			||||||
                # RNS.log("Sending appearance", RNS.LOG_WARNING)
 | 
					                RNS.log("Sending appearance", RNS.LOG_WARNING)
 | 
				
			||||||
                def fth(c):
 | 
					                def fth(c):
 | 
				
			||||||
                    r = c[0]; g = c[1]; b = c[2]
 | 
					                    r = c[0]; g = c[1]; b = c[2]
 | 
				
			||||||
                    r = min(max(0, r), 1); g = min(max(0, g), 1); b = min(max(0, b), 1)
 | 
					                    r = min(max(0, r), 1); g = min(max(0, g), 1); b = min(max(0, b), 1)
 | 
				
			||||||
@ -2273,7 +2359,7 @@ class SidebandCore():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if send_telemetry:
 | 
					            if send_telemetry:
 | 
				
			||||||
                # TODO: REMOVE
 | 
					                # TODO: REMOVE
 | 
				
			||||||
                # RNS.log("Sending telemetry", RNS.LOG_WARNING)
 | 
					                RNS.log("Sending telemetry", RNS.LOG_WARNING)
 | 
				
			||||||
                fields[LXMF.FIELD_TELEMETRY] = self.latest_packed_telemetry
 | 
					                fields[LXMF.FIELD_TELEMETRY] = self.latest_packed_telemetry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return fields
 | 
					        return fields
 | 
				
			||||||
@ -2377,9 +2463,6 @@ class SidebandCore():
 | 
				
			|||||||
        self.setstate("lxm_uri_ingest.result", response)
 | 
					        self.setstate("lxm_uri_ingest.result", response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lxm_ingest(self, message, originator = False):
 | 
					    def lxm_ingest(self, message, originator = False):
 | 
				
			||||||
        # TODO: Remove
 | 
					 | 
				
			||||||
        RNS.log("MESSAGE FIELDS: "+str(message.fields), RNS.LOG_WARNING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        should_notify = False
 | 
					        should_notify = False
 | 
				
			||||||
        is_trusted = False
 | 
					        is_trusted = False
 | 
				
			||||||
        unread_reason_tx = False
 | 
					        unread_reason_tx = False
 | 
				
			||||||
@ -2535,7 +2618,7 @@ class SidebandCore():
 | 
				
			|||||||
            if message.unverified_reason == LXMF.LXMessage.SOURCE_UNKNOWN:
 | 
					            if message.unverified_reason == LXMF.LXMessage.SOURCE_UNKNOWN:
 | 
				
			||||||
                signature_string = "Cannot verify, source is unknown"
 | 
					                signature_string = "Cannot verify, source is unknown"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        RNS.log("LXMF delivery "+str(time_string)+". "+str(signature_string)+".")
 | 
					        RNS.log("LXMF delivery "+str(time_string)+". "+str(signature_string)+".", RNS.LOG_DEBUG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if self.config["lxmf_ignore_unknown"] == True:
 | 
					            if self.config["lxmf_ignore_unknown"] == True:
 | 
				
			||||||
 | 
				
			|||||||
@ -115,6 +115,7 @@ MDNavigationLayout:
 | 
				
			|||||||
                        [['menu', lambda x: nav_drawer.set_state("open")]]
 | 
					                        [['menu', lambda x: nav_drawer.set_state("open")]]
 | 
				
			||||||
                    right_action_items:
 | 
					                    right_action_items:
 | 
				
			||||||
                        [
 | 
					                        [
 | 
				
			||||||
 | 
					                        ['map-search', lambda x: root.ids.screen_manager.app.peer_show_location_action(self)],
 | 
				
			||||||
                        ['lan-connect', lambda x: root.ids.screen_manager.app.message_propagation_action(self)],
 | 
					                        ['lan-connect', lambda x: root.ids.screen_manager.app.message_propagation_action(self)],
 | 
				
			||||||
                        ['close', lambda x: root.ids.screen_manager.app.close_messages_action(self)],
 | 
					                        ['close', lambda x: root.ids.screen_manager.app.close_messages_action(self)],
 | 
				
			||||||
                        ]
 | 
					                        ]
 | 
				
			||||||
@ -1009,7 +1010,7 @@ MDNavigationLayout:
 | 
				
			|||||||
                            MDIconButton:
 | 
					                            MDIconButton:
 | 
				
			||||||
                                pos_hint: {"center_x": .5}
 | 
					                                pos_hint: {"center_x": .5}
 | 
				
			||||||
                                id: telemetry_icon_preview
 | 
					                                id: telemetry_icon_preview
 | 
				
			||||||
                                icon: "alpha-p-circle-outline"
 | 
					                                icon: "account"
 | 
				
			||||||
                                type: "large"
 | 
					                                type: "large"
 | 
				
			||||||
                                theme_icon_color: "Custom"
 | 
					                                theme_icon_color: "Custom"
 | 
				
			||||||
                                icon_color: [0, 0, 0, 1]
 | 
					                                icon_color: [0, 0, 0, 1]
 | 
				
			||||||
@ -1018,6 +1019,7 @@ MDNavigationLayout:
 | 
				
			|||||||
                                size_hint_y: None
 | 
					                                size_hint_y: None
 | 
				
			||||||
                                # width: dp(64)
 | 
					                                # width: dp(64)
 | 
				
			||||||
                                height: dp(80)
 | 
					                                height: dp(80)
 | 
				
			||||||
 | 
					                                on_release: root.ids.screen_manager.app.icons_action(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        MDRectangleFlatIconButton:
 | 
					                        MDRectangleFlatIconButton:
 | 
				
			||||||
@ -1589,6 +1591,21 @@ MDNavigationLayout:
 | 
				
			|||||||
                                    pos_hint: {"center_y": 0.3}
 | 
					                                    pos_hint: {"center_y": 0.3}
 | 
				
			||||||
                                    active: False
 | 
					                                    active: False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            MDBoxLayout:
 | 
				
			||||||
 | 
					                                orientation: "horizontal"
 | 
				
			||||||
 | 
					                                size_hint_y: None
 | 
				
			||||||
 | 
					                                padding: [0,0,dp(24),dp(0)]
 | 
				
			||||||
 | 
					                                height: dp(48)
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                MDLabel:
 | 
				
			||||||
 | 
					                                    text: "Advanced Statistics"
 | 
				
			||||||
 | 
					                                    font_style: "H6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                MDSwitch:
 | 
				
			||||||
 | 
					                                    id: settings_advanced_statistics
 | 
				
			||||||
 | 
					                                    pos_hint: {"center_y": 0.3}
 | 
				
			||||||
 | 
					                                    active: False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            MDBoxLayout:
 | 
					                            MDBoxLayout:
 | 
				
			||||||
                                orientation: "horizontal"
 | 
					                                orientation: "horizontal"
 | 
				
			||||||
                                size_hint_y: None
 | 
					                                size_hint_y: None
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user