diff --git a/docs/example_plugins/gpsd_location.py b/docs/example_plugins/gpsd_location.py index 2c3e713..30165fb 100644 --- a/docs/example_plugins/gpsd_location.py +++ b/docs/example_plugins/gpsd_location.py @@ -103,7 +103,7 @@ class GpsdLocationPlugin(SidebandTelemetryPlugin): telemeter.sensors["location"].accuracy = self.accuracy telemeter.sensors["location"].stale_time = 5 telemeter.sensors["location"].set_update_time(self.last_update) - + else: RNS.log("No location from GPSd yet", RNS.LOG_DEBUG) diff --git a/docs/example_plugins/view.py b/docs/example_plugins/view.py index 874575f..78f7d73 100644 --- a/docs/example_plugins/view.py +++ b/docs/example_plugins/view.py @@ -71,7 +71,7 @@ class ViewSource(): try: if self.is_stale(): self.update() - + if self.source_data != None: max_dimension = quality_presets[preset]["max"] quality = quality_presets[preset]["quality"] @@ -121,13 +121,13 @@ class CameraSource(ViewSource): if not ret: self.camera_ready = False break - + if not self.frame_queue.empty(): try: self.frame_queue.get_nowait() except queue.Empty: pass - + self.frame_queue.put(frame) except Exception as e: @@ -140,9 +140,9 @@ class CameraSource(ViewSource): self.start_reading() while not self.camera_ready: time.sleep(0.2) - + retval, frame = self.camera.read() - + if not retval: self.source_data = None else: @@ -154,8 +154,8 @@ class CameraSource(ViewSource): try: self.camera.release() except: - pass - + pass + self.camera = None self.camera_ready = False @@ -185,14 +185,14 @@ class StreamSource(ViewSource): if not ret: self.stream_ready = False else: - self.stream_ready = True + self.stream_ready = True if not self.frame_queue.empty(): if self.frame_queue.qsize() > 1: try: self.frame_queue.get_nowait() except queue.Empty: pass - + self.frame_queue.put(frame) RNS.log(f"{self)} idled", RNS.LOG_DEBUG) @@ -220,8 +220,8 @@ class StreamSource(ViewSource): try: self.stream.release() except: - pass - + pass + self.stream = None self.stream_ready = False @@ -306,7 +306,7 @@ class ViewCommandPlugin(SidebandCommandPlugin): if not source in self.sources: self.message_response("The specified view source does not exist on this system", requestor) - + else: image_field = self.sources[source].get_image_field(quality_preset) image_timestamp = self.timestamp_str(self.sources[source].last_update) diff --git a/docs/utilities/rns_audio_call_calc.py b/docs/utilities/rns_audio_call_calc.py index 238aa45..c87f9c1 100644 --- a/docs/utilities/rns_audio_call_calc.py +++ b/docs/utilities/rns_audio_call_calc.py @@ -77,7 +77,7 @@ def simulate(link_speed=9600, audio_slot_ms=70, codec_rate=1200, method="msgpack PAYLOAD_LATENCY = round(ENCRYPTED_PAYLOAD_LEN*PER_BYTE_LATENCY_MS, 1) RAW_DATA_LATENCY = round(AUDIO_LEN*PER_BYTE_LATENCY_MS, 1) PACKING_LATENCY = round(PACKING_OVERHEAD*PER_BYTE_LATENCY_MS, 1) - + DATA_LATENCY = round(ENCRYPTED_PAYLOAD_LEN*PER_BYTE_LATENCY_MS, 1) ENCRYPTION_LATENCY = round((ENCRYPTED_PAYLOAD_LEN-PL_LEN)*PER_BYTE_LATENCY_MS, 1) if ENCRYPTED_PAYLOAD_LEN-PL_LEN == 1: diff --git a/recipes/codec2/__init__.py b/recipes/codec2/__init__.py index 44219bc..f9b7883 100644 --- a/recipes/codec2/__init__.py +++ b/recipes/codec2/__init__.py @@ -27,7 +27,7 @@ class Codec2Recipe(Recipe): # variable `LIBS`''' # return ' -lcodec2{version} -lssl{version}'.format(version=self.version) - def build_arch(self, arch): + def build_arch(self, arch): with current_directory(self.get_build_dir(arch.arch)): env = self.get_recipe_env(arch) flags = [ diff --git a/recipes/opusfile/__init__.py b/recipes/opusfile/__init__.py index e82282b..885a8f7 100644 --- a/recipes/opusfile/__init__.py +++ b/recipes/opusfile/__init__.py @@ -33,7 +33,7 @@ class OpusFileRecipe(Recipe): # env['CFLAGS'] += openssl_recipe.include_flags(arch) # env['LDFLAGS'] += openssl_recipe.link_dirs_flags(arch) # env['LIBS'] = openssl_recipe.link_libs_flags() - + from rich.pretty import pprint pprint(env) time.sleep(5) diff --git a/recipes/pycodec2/__init__.py b/recipes/pycodec2/__init__.py index cb4918b..0b5e419 100644 --- a/recipes/pycodec2/__init__.py +++ b/recipes/pycodec2/__init__.py @@ -21,7 +21,7 @@ class PyCodec2Recipe(CythonRecipe): env['LDFLAGS'] += f' -L{self.ctx.get_libs_dir(arch.arch)}' env['LDFLAGS'] += f' -L{self.ctx.libs_dir}' env['LDFLAGS'] += codec2_recipe.link_dirs_flags(arch) - + return env def build_arch(self, arch): @@ -32,7 +32,7 @@ class PyCodec2Recipe(CythonRecipe): # print(arch) # shprint(sh.Command("pwd")) # shprint(sh.Command("ls")) - + # pe_args = ["--replace-needed", "libcodec2.so.1.2", "libcodec2.so", "build/lib.linux-x86_64-3.11/pycodec2/pycodec2.cpython-311-x86_64-linux-gnu.so"] # shprint(sh.Command("patchelf"), *pe_args) diff --git a/sbapp/kivymd/uix/chip/chip.py b/sbapp/kivymd/uix/chip/chip.py index c9f3593..05b0f36 100755 --- a/sbapp/kivymd/uix/chip/chip.py +++ b/sbapp/kivymd/uix/chip/chip.py @@ -294,18 +294,18 @@ Example of filtering orientation: "vertical" ''' ) - - + + class CustomOneLineIconListItem(OneLineIconListItem): icon = StringProperty() - - + + class PreviewIconsScreen(MDScreen): filter = ListProperty() # list of tags for filtering icons - + def set_filter_chips(self): '''Asynchronously creates and adds chips to the container.''' - + async def set_filter_chips(): for tag in ["Outline", "Off", "On"]: await asynckivy.sleep(0) @@ -318,7 +318,7 @@ Example of filtering ) chip.bind(active=lambda x, y, z=tag: self.set_filter(y, z)) self.ids.chip_box.add_widget(chip) - + asynckivy.start(set_filter_chips()) def set_filter(self, active: bool, tag: str) -> None: diff --git a/sbapp/main.py b/sbapp/main.py index b695e7c..5db2e89 100644 --- a/sbapp/main.py +++ b/sbapp/main.py @@ -350,7 +350,7 @@ class SidebandApp(MDApp): self.check_permissions() self.check_bluetooth_permissions() self.start_service() - + Clock.schedule_interval(self.jobs, 1.5) def dismiss_splash(dt): @@ -367,7 +367,7 @@ class SidebandApp(MDApp): self.sideband.setstate("app.running", True) self.sideband.setstate("app.foreground", True) Clock.schedule_once(sjob, 6.5) - + def start_service(self): if RNS.vendor.platformutils.is_android(): RNS.log(f"Running on Android API level {android_api_version)}") @@ -385,7 +385,7 @@ class SidebandApp(MDApp): # Pre-load announce stream widgets self.update_loading_text() - + self.loader_init() if not RNS.vendor.platformutils.is_android(): self.telemetry_init() @@ -511,7 +511,7 @@ class SidebandApp(MDApp): self.input_font = "defaultinput" else: self.input_font = language - + RNS.log(f"Setting input language to {self.input_font)}", RNS.LOG_DEBUG) # def modify_input_font(self, ids): @@ -538,7 +538,7 @@ class SidebandApp(MDApp): self.color_hover = colors["Light"]["CardsDialogs"] else: self.color_hover = colors["Light"]["AppBar"] - + self.apply_eink_mods() self.set_bars_colors() @@ -665,7 +665,7 @@ class SidebandApp(MDApp): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -695,7 +695,7 @@ class SidebandApp(MDApp): if self.conversations_view != None: self.conversations_view.ids.conversations_scrollview.effect_cls = ScrollEffect self.conversations_view.ids.conversations_scrollview.scroll = 1 - + else: RNS.log("Conversations view did not exist", RNS.LOG_DEBUG) @@ -718,7 +718,7 @@ class SidebandApp(MDApp): if RNS.vendor.platformutils.get_platform() == "android": mActivity = autoclass('org.kivy.android.PythonActivity').mActivity Context = autoclass('android.content.Context') - + if android_api_version > 30: bt_permission_name = "android.permission.BLUETOOTH_CONNECT" else: @@ -771,7 +771,7 @@ class SidebandApp(MDApp): if not check_permission("android.permission.POST_NOTIFICATIONS"): RNS.log("Requesting notification permission", RNS.LOG_DEBUG) request_permissions(["android.permission.POST_NOTIFICATIONS"]) - + self.check_permissions() def request_microphone_permission(self): @@ -803,7 +803,7 @@ class SidebandApp(MDApp): def dl_ok(s): dialog.dismiss() self.request_storage_permission() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -815,7 +815,7 @@ class SidebandApp(MDApp): if not check_permission("android.permission.WRITE_EXTERNAL_STORAGE"): RNS.log("Requesting storage write permission", RNS.LOG_DEBUG) request_permissions(["android.permission.WRITE_EXTERNAL_STORAGE"]) - + if not check_permission("android.permission.READ_EXTERNAL_STORAGE"): RNS.log("Requesting storage read permission", RNS.LOG_DEBUG) request_permissions(["android.permission.READ_EXTERNAL_STORAGE"]) @@ -861,7 +861,7 @@ class SidebandApp(MDApp): if intent_action == "android.intent.action.WEB_SEARCH": SearchManager = autoclass('android.app.SearchManager') data = intent.getStringExtra(SearchManager.QUERY) - + if data.lower().startswith(LXMF.LXMessage.URI_SCHEMA): action = "lxm_uri" @@ -880,7 +880,7 @@ class SidebandApp(MDApp): def ingest_lxm_uri(self, lxm_uri): RNS.log(f"Ingesting LXMF paper message from URI: {lxm_uri)}", RNS.LOG_DEBUG) self.sideband.lxm_ingest_uri(lxm_uri) - + def build(self): FONT_PATH = f"{self.sideband.asset_dir}/fonts" if RNS.vendor.platformutils.is_darwin(): @@ -926,7 +926,7 @@ class SidebandApp(MDApp): def dl_ok(s): dialog.dismiss() self.quit_action(s) - + ok_button.bind(on_release=dl_ok) self.final_load_completed = False dialog.open() @@ -1034,7 +1034,7 @@ class SidebandApp(MDApp): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -1055,7 +1055,7 @@ class SidebandApp(MDApp): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -1165,7 +1165,7 @@ class SidebandApp(MDApp): if modifiers[0] == "ctrl": if text == "q": self.quit_action(self) - + if text == "w": if self.root.ids.screen_manager.current == "conversations_screen": if self.include_conversations and not self.include_objects: @@ -1182,11 +1182,11 @@ class SidebandApp(MDApp): self.close_sub_telemetry_action() else: self.open_conversations(direction="right") - + if text == "s" or text == "d": if self.root.ids.screen_manager.current == "messages_screen": self.message_send_action() - + if text == "l": if self.root.ids.screen_manager.current == "messages_screen": self.message_propagation_action(self) @@ -1194,7 +1194,7 @@ class SidebandApp(MDApp): self.map_layers_action() else: self.announces_action(self) - + if text == "m": if self.root.ids.screen_manager.current == "messages_screen": context_dest = self.messages_view.ids.messages_scrollview.active_conversation @@ -1204,13 +1204,13 @@ class SidebandApp(MDApp): self.map_show_peer_location(context_dest) else: self.map_action(self) - + if text == "p": if self.root.ids.screen_manager.current == "map_screen": self.map_settings_action() else: self.settings_action(self) - + if text == "t": if self.root.ids.screen_manager.current == "messages_screen": self.object_details_action(self.messages_view, from_conv=True) @@ -1240,15 +1240,15 @@ class SidebandApp(MDApp): self.conversations_action(self, direction="right") else: self.conversations_action(self, direction="right") - + if len(modifiers) > 0 and modifiers[0] == 'ctrl' and (text == "g"): self.guide_action(self) - + if text == "n": if self.root.ids.screen_manager.current == "conversations_screen": if not hasattr(self, "dialog_open") or not self.dialog_open: self.new_conversation_action(self) - + def keyboard_event(self, window, key, *largs): if self.keyboard_enabled: # Handle escape/back @@ -1365,7 +1365,7 @@ class SidebandApp(MDApp): ) def dl_yes(s): dialog.dismiss() - + yes_button.bind(on_release=dl_yes) dialog.open() @@ -1441,7 +1441,7 @@ class SidebandApp(MDApp): self.root.ids.screen_manager.current = "messages_screen" self.sideband.setstate("app.displaying", self.root.ids.screen_manager.current) - + self.sideband.read_conversation(context_dest) self.sideband.setstate("app.flags.unread_conversations", True) @@ -1503,7 +1503,7 @@ class SidebandApp(MDApp): try: RNS.log(f"Processing {self.attach_type)} attachment \"{self.attach_path)}\"", RNS.LOG_DEBUG) fbn = os.path.basename(self.attach_path) - + if self.attach_type == "file": with open(self.attach_path, "rb") as af: attachment = [fbn, af.read()] @@ -1586,7 +1586,7 @@ class SidebandApp(MDApp): self.messages_view.ids.message_text.text = "" self.messages_view.ids.messages_scrollview.scroll_y = 0 self.jobs(0) - + elif self.sideband.send_message(msg_content, context_dest, self.outbound_mode_propagation, attachment = attachment, image = image, audio = audio): self.messages_view.ids.message_text.text = "" self.messages_view.ids.messages_scrollview.scroll_y = 0 @@ -1647,7 +1647,7 @@ class SidebandApp(MDApp): tf = open(path, "rb") tf.close() self.attach_path = path - + if RNS.vendor.platformutils.is_android(): toast(f"Attached \"{fbn)}\"") else: @@ -1713,7 +1713,7 @@ class SidebandApp(MDApp): ) ok_button.bind(on_release=ate_dialog.dismiss) ate_dialog.open() - + else: if RNS.vendor.platformutils.get_platform() == "android": toast("No file access, check permissions!") @@ -1798,7 +1798,7 @@ class SidebandApp(MDApp): elif audio_field[0] >= LXMF.AM_CODEC2_700C and audio_field[0] <= LXMF.AM_CODEC2_3200: temp_path = f"{self.sideband.rec_cache}/msg.ogg" from sideband.audioproc import samples_to_ogg, decode_codec2, detect_codec2 - + target_rate = 8000 if RNS.vendor.platformutils.is_linux(): target_rate = 48000 @@ -1812,7 +1812,7 @@ class SidebandApp(MDApp): self.last_msg_audio = None self.display_codec2_error() return - + else: raise NotImplementedError(audio_field[0]) @@ -1822,7 +1822,7 @@ class SidebandApp(MDApp): self.request_microphone_permission() else: from sbapp.plyer import audio - + self.msg_sound = audio self.msg_sound._file_path = temp_path @@ -1866,7 +1866,7 @@ class SidebandApp(MDApp): def cb(dt): self.msg_audio.start() Clock.schedule_once(cb, 0.15) - + def message_ptt_up_action(self, sender=None): if not self.sideband.ui_recording: @@ -1920,12 +1920,12 @@ class SidebandApp(MDApp): audio = AudioSegment( bytes(opus_file.as_array()), frame_rate=opus_file.frequency, - sample_width=opus_file.bytes_per_sample, + sample_width=opus_file.bytes_per_sample, channels=opus_file.channels, ) audio = audio.split_to_mono()[0] audio = audio.apply_gain(-audio.max_dBFS) - + if self.audio_msg_mode >= LXMF.AM_CODEC2_700C and self.audio_msg_mode <= LXMF.AM_CODEC2_3200: audio = audio.set_frame_rate(8000) audio = audio.set_sample_width(2) @@ -2013,9 +2013,9 @@ class SidebandApp(MDApp): self.rec_dialog.playing = False self.rec_dialog.play_item.children[0].children[0].icon = "play" self.rec_dialog.play_item.text = f"[size={ss)}]Play[/size]" - + self.msg_audio._finished_callback = a_finished - + def a_save(sender): if self.rec_dialog.recording: a_rec_action(sender) @@ -2038,7 +2038,7 @@ class SidebandApp(MDApp): self.update_message_widgets() toast("Added recorded audio to message") - + except Exception as e: RNS.trace_exception(e) @@ -2085,7 +2085,7 @@ class SidebandApp(MDApp): def message_attach_action(self, attach_type=None, nodialog=False): file_attach_types = ["lbimg", "defimg", "hqimg", "file"] rec_attach_types = ["audio"] - + self.attach_path = None self.rec_dialog_is_open = False if attach_type in file_attach_types: @@ -2131,7 +2131,7 @@ class SidebandApp(MDApp): DialogItem(IconLeftWidget(icon="account-voice", on_release=a_audio_lb), text=f"[size={ss)}]Low-bandwidth Voice[/size]", on_release=a_audio_lb), DialogItem(IconLeftWidget(icon="microphone-message", on_release=a_audio_hq), text=f"[size={ss)}]High-quality Voice[/size]", on_release=a_audio_hq), DialogItem(IconLeftWidget(icon="file-outline", on_release=a_file), text=f"[size={ss)}]File Attachment[/size]", on_release=a_file)] - + if RNS.vendor.platformutils.is_windows(): ad_items.pop(3) ad_items.pop(3) @@ -2200,7 +2200,7 @@ class SidebandApp(MDApp): mode_item.icon = "upload-network" self.messages_view.ids.message_text.hint_text = "Message for propagation" # self.root.ids.message_text.hint_text = "Write message for delivery via propagation nodes" - + def key_query_action(self, sender): context_dest = self.messages_view.ids.messages_scrollview.active_conversation if self.sideband.request_key(context_dest): @@ -2227,7 +2227,7 @@ class SidebandApp(MDApp): ### Conversations screen - ###################################### + ###################################### def conversations_action(self, sender=None, direction="left", no_transition=False): self.rec_dialog_is_open = False if self.include_objects: @@ -2266,7 +2266,7 @@ class SidebandApp(MDApp): def open_conversations(self, direction="left"): self.root.ids.screen_manager.transition.direction = direction self.root.ids.nav_drawer.set_state("closed") - + if not self.conversations_view: self.conversations_view = Conversations(self) @@ -2301,7 +2301,7 @@ class SidebandApp(MDApp): except Exception as e: RNS.log(f"An error occurred while retrieving connectivity status: {e)}", RNS.LOG_ERROR) return "Could not retrieve connectivity status" - + def connectivity_status(self, sender): hs = dp(22) @@ -2337,7 +2337,7 @@ class SidebandApp(MDApp): try: cancel_button = MDRectangleFlatButton(text="Cancel",font_size=dp(18)) ingest_button = MDRectangleFlatButton(text="Read LXM",font_size=dp(18), theme_text_color="Custom", line_color=self.color_accept, text_color=self.color_accept) - + dialog = MDDialog( title="Ingest Paper Message", text="You can read LXMF paper messages into this program by scanning a QR-code containing the message with your device camera or QR-scanner app, and then opening the resulting link in Sideband.\n\nAlternatively, you can copy an [b]lxm://[/b] link from any source to your clipboard, and ingest it using the [i]Read LXM[/i] button below.", @@ -2391,7 +2391,7 @@ class SidebandApp(MDApp): ) def dl_yes(s): dialog.dismiss() - + yes_button.bind(on_release=dl_yes) dialog.open() else: @@ -2413,7 +2413,7 @@ class SidebandApp(MDApp): # elevation=0, ) dialog.d_content = dialog_content - def dl_close(s): + def dl_close(s): self.sideband.setstate("app.flags.lxmf_sync_dialog_open", False) dialog.dismiss() self.message_sync_dialog.d_content.ids.sync_progress.value = 0.1 @@ -2421,7 +2421,7 @@ class SidebandApp(MDApp): # self.sideband.cancel_lxmf_sync() - def dl_stop(s): + def dl_stop(s): # self.sideband.setstate("app.flags.lxmf_sync_dialog_open", False) # dialog.dismiss() self.sideband.cancel_lxmf_sync() @@ -2435,7 +2435,7 @@ class SidebandApp(MDApp): self.message_sync_dialog = dialog self.sync_dialog = dialog_content self.sync_dialog.stop_button = stop_button - + s_state = self.sideband.message_router.propagation_transfer_state if s_state > LXMF.LXMRouter.PR_PATH_REQUESTED and s_state <= LXMF.LXMRouter.PR_COMPLETE: dsp = self.sideband.get_sync_progress()*100 @@ -2465,7 +2465,7 @@ class SidebandApp(MDApp): try: cancel_button = MDRectangleFlatButton(text="Cancel",font_size=dp(18)) create_button = MDRectangleFlatButton(text="Create",font_size=dp(18), theme_text_color="Custom", line_color=self.color_accept, text_color=self.color_accept) - + dialog_content = NewConv() dialog = MDDialog( title="New Conversation", @@ -2687,22 +2687,22 @@ class SidebandApp(MDApp): if sender.active: if sender != self.settings_screen.ids.settings_lang_default: self.settings_screen.ids.settings_lang_default.active = False - + if sender != self.settings_screen.ids.settings_lang_chinese: self.settings_screen.ids.settings_lang_chinese.active = False - + if sender != self.settings_screen.ids.settings_lang_japanese: self.settings_screen.ids.settings_lang_japanese.active = False - + if sender != self.settings_screen.ids.settings_lang_korean: self.settings_screen.ids.settings_lang_korean.active = False - + if sender != self.settings_screen.ids.settings_lang_devangari: self.settings_screen.ids.settings_lang_devangari.active = False - + if sender != self.settings_screen.ids.settings_lang_hebrew: self.settings_screen.ids.settings_lang_hebrew.active = False - + if self.settings_screen.ids.settings_lang_default.active: self.sideband.config["input_language"] = None self.settings_screen.ids.settings_display_name.font_name = "defaultinput" @@ -3089,35 +3089,35 @@ class SidebandApp(MDApp): def con_collapse_local(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_local_fields, collapse) pass - + def con_collapse_tcp(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_tcp_fields, collapse) pass - + def con_collapse_i2p(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_i2p_fields, collapse) pass - + def con_collapse_bluetooth(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_bluetooth_fields, collapse) pass - + def con_collapse_rnode(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_rnode_fields, collapse) pass - + def con_collapse_modem(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_modem_fields, collapse) pass - + def con_collapse_serial(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_serial_fields, collapse) pass - + def con_collapse_transport(collapse=True): # self.widget_hide(self.connectivity_screen.ids.connectivity_transport_fields, collapse) pass - + def save_connectivity(sender=None, event=None): self.sideband.config["connect_transport"] = self.connectivity_screen.ids.connectivity_enable_transport.active self.sideband.config["connect_local"] = self.connectivity_screen.ids.connectivity_use_local.active @@ -3294,12 +3294,12 @@ class SidebandApp(MDApp): self.connectivity_screen.ids.connectivity_tcp_port.bind(focus=focus_save) self.connectivity_screen.ids.connectivity_tcp_ifac_netname.bind(focus=focus_save) self.connectivity_screen.ids.connectivity_tcp_ifac_passphrase.bind(focus=focus_save) - + self.connectivity_screen.ids.connectivity_use_i2p.bind(active=save_connectivity) self.connectivity_screen.ids.connectivity_i2p_b32.bind(focus=focus_save) self.connectivity_screen.ids.connectivity_i2p_ifac_netname.bind(focus=focus_save) self.connectivity_screen.ids.connectivity_i2p_ifac_passphrase.bind(focus=focus_save) - + self.connectivity_screen.ids.connectivity_use_rnode.bind(active=serial_connectivity_save) self.connectivity_screen.ids.connectivity_rnode_ifac_netname.bind(focus=focus_save) self.connectivity_screen.ids.connectivity_rnode_ifac_passphrase.bind(focus=focus_save) @@ -3341,7 +3341,7 @@ class SidebandApp(MDApp): def close_connectivity_action(self, sender=None): self.open_conversations(direction="right") - + def rpc_copy_action(self, sender=None): c_yes_button = MDRectangleFlatButton(text="Yes",font_size=dp(18), theme_text_color="Custom", line_color=self.color_reject, text_color=self.color_reject) c_no_button = MDRectangleFlatButton(text="No, go back",font_size=dp(18)) @@ -3359,7 +3359,7 @@ class SidebandApp(MDApp): rpc_string = f"rpc_key = {RNS.hexrep(self.sideband.reticulum.rpc_key, delimit=False)}" Clipboard.copy(rpc_string) dialog.open() - + c_yes_button.bind(on_release=c_dl_yes) c_no_button.bind(on_release=c_dl_no) @@ -3405,7 +3405,7 @@ class SidebandApp(MDApp): info += "If you want to share the Sideband application itself via the repository server, you must first download it into the local repository, using the \"Update Content\" button below.\n\n" info += "To make the repository available on your local network, simply start it below, and it will become browsable on a local IP address for anyone connected to the same WiFi or wired network.\n\n" if self.sideband.webshare_server != None: - if RNS.vendor.platformutils.is_android(): + if RNS.vendor.platformutils.is_android(): def getIP(): adrs = [] try: @@ -3462,7 +3462,7 @@ class SidebandApp(MDApp): def repository_stop_action(self, sender=None): self.reposository_url = None - self.sideband.stop_webshare() + self.sideband.stop_webshare() Clock.schedule_once(self.repository_update_info, 0.75) def repository_download_action(self, sender=None): @@ -3518,7 +3518,7 @@ class SidebandApp(MDApp): self.root.ids.screen_manager.add_widget(self.repository_screen) self.repository_screen.ids.repository_scrollview.effect_cls = ScrollEffect - + self.repository_update_info() if not RNS.vendor.platformutils.is_android(): @@ -3564,7 +3564,7 @@ class SidebandApp(MDApp): def close_sub_hardware_action(self, sender=None): self.hardware_action(direction="right") - + def hardware_init(self, sender=None): if not self.hardware_ready: if not self.root.ids.screen_manager.has_screen("hardware_screen"): @@ -3661,12 +3661,12 @@ class SidebandApp(MDApp): self.sideband.config["hw_rnode_spreading_factor"] = int(self.hardware_rnode_screen.ids.hardware_rnode_spreadingfactor.text) except: pass - + try: self.sideband.config["hw_rnode_coding_rate"] = int(self.hardware_rnode_screen.ids.hardware_rnode_codingrate.text) except: pass - + try: self.sideband.config["hw_rnode_atl_short"] = float(self.hardware_rnode_screen.ids.hardware_rnode_atl_short.text) except: @@ -3676,7 +3676,7 @@ class SidebandApp(MDApp): self.sideband.config["hw_rnode_atl_long"] = float(self.hardware_rnode_screen.ids.hardware_rnode_atl_long.text) except: self.sideband.config["hw_rnode_atl_long"] = None - + if self.hardware_rnode_screen.ids.hardware_rnode_beaconinterval.text == "": self.sideband.config["hw_rnode_beaconinterval"] = None else: @@ -3747,7 +3747,7 @@ class SidebandApp(MDApp): self.sideband.config["hw_rnode_bluetooth"] = False self.sideband.save_configuration() - + def hardware_rnode_ble_toggle_action(self, sender=None, event=None): if sender.active: self.sideband.config["hw_rnode_ble"] = True @@ -3756,7 +3756,7 @@ class SidebandApp(MDApp): self.sideband.config["hw_rnode_ble"] = False self.sideband.save_configuration() - + def hardware_rnode_framebuffer_toggle_action(self, sender=None, event=None): if sender.active: self.sideband.config["hw_rnode_enable_framebuffer"] = True @@ -3764,7 +3764,7 @@ class SidebandApp(MDApp): self.sideband.config["hw_rnode_enable_framebuffer"] = False self.sideband.save_configuration() - + def hardware_rnode_init(self, sender=None): if not self.hardware_rnode_ready: if not self.root.ids.screen_manager.has_screen("hardware_rnode_screen"): @@ -3860,7 +3860,7 @@ class SidebandApp(MDApp): self.hardware_rnode_ready = True def hardware_rnode_validate(self, sender=None): - valid = True + valid = True try: val = float(self.hardware_rnode_screen.ids.hardware_rnode_frequency.text) if not val > 0: @@ -3870,7 +3870,7 @@ class SidebandApp(MDApp): except: self.hardware_rnode_screen.ids.hardware_rnode_frequency.error = True valid = False - + try: valid_vals = [7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250, 500] val = float(self.hardware_rnode_screen.ids.hardware_rnode_bandwidth.text) @@ -3881,7 +3881,7 @@ class SidebandApp(MDApp): except: self.hardware_rnode_screen.ids.hardware_rnode_bandwidth.error = True valid = False - + try: val = int(self.hardware_rnode_screen.ids.hardware_rnode_txpower.text) if not val >= 0: @@ -3891,7 +3891,7 @@ class SidebandApp(MDApp): except: self.hardware_rnode_screen.ids.hardware_rnode_txpower.error = True valid = False - + try: val = int(self.hardware_rnode_screen.ids.hardware_rnode_spreadingfactor.text) if val < 7 or val > 12: @@ -3901,7 +3901,7 @@ class SidebandApp(MDApp): except: self.hardware_rnode_screen.ids.hardware_rnode_spreadingfactor.error = True valid = False - + try: val = int(self.hardware_rnode_screen.ids.hardware_rnode_codingrate.text) if val < 5 or val > 8: @@ -3911,7 +3911,7 @@ class SidebandApp(MDApp): except: self.hardware_rnode_screen.ids.hardware_rnode_codingrate.error = True valid = False - + try: if self.hardware_rnode_screen.ids.hardware_rnode_beaconinterval.text != "": val = int(self.hardware_rnode_screen.ids.hardware_rnode_beaconinterval.text) @@ -3923,7 +3923,7 @@ class SidebandApp(MDApp): except: self.hardware_rnode_screen.ids.hardware_rnode_beaconinterval.text = "" valid = False - + return valid def hardware_rnode_import(self, sender=None): @@ -3950,7 +3950,7 @@ class SidebandApp(MDApp): self.hardware_rnode_screen.ids.hardware_rnode_txpower.text = str(config["t"]) self.hardware_rnode_screen.ids.hardware_rnode_spreadingfactor.text = str(config["s"]) self.hardware_rnode_screen.ids.hardware_rnode_codingrate.text = str(config["c"]) - + if "n" in config and config["n"] != None: ifn = str(config["n"]) else: @@ -4047,9 +4047,9 @@ class SidebandApp(MDApp): dialog.dismiss() yes_button.bind(on_release=dl_yes) dialog.open() - + ## Modem hardware screen - + def hardware_modem_action(self, sender=None, direction="left"): if self.hardware_modem_ready: self.hardware_modem_open(direction=direction) @@ -4109,22 +4109,22 @@ class SidebandApp(MDApp): t_p = str(self.sideband.config["hw_modem_parity"]) else: t_p = "" - + if self.sideband.config["hw_modem_stopbits"] != None: t_sb = str(self.sideband.config["hw_modem_stopbits"]) else: t_sb = "" - + if self.sideband.config["hw_modem_preamble"] != None: t_pa = str(self.sideband.config["hw_modem_preamble"]) else: t_pa = "" - + if self.sideband.config["hw_modem_tail"] != None: t_t = str(self.sideband.config["hw_modem_tail"]) else: t_t = "" - + if self.sideband.config["hw_modem_persistence"] != None: t_ps = str(self.sideband.config["hw_modem_persistence"]) else: @@ -4143,7 +4143,7 @@ class SidebandApp(MDApp): t_bd = str(self.sideband.config["hw_modem_beacondata"]) else: t_bd = "" - + self.hardware_modem_screen.ids.hardware_modem_baudrate.text = t_b self.hardware_modem_screen.ids.hardware_modem_databits.text = t_db self.hardware_modem_screen.ids.hardware_modem_parity.text = t_p @@ -4176,7 +4176,7 @@ class SidebandApp(MDApp): self.hardware_modem_screen.ids.hardware_modem_slottime.bind(on_text_validate=save_connectivity) self.hardware_modem_ready = True - + def hardware_modem_save(self): self.sideband.config["hw_modem_baudrate"] = int(self.hardware_modem_screen.ids.hardware_modem_baudrate.text) self.sideband.config["hw_modem_databits"] = int(self.hardware_modem_screen.ids.hardware_modem_databits.text) @@ -4200,7 +4200,7 @@ class SidebandApp(MDApp): self.sideband.save_configuration() def hardware_modem_validate(self, sender=None): - valid = True + valid = True try: val = int(self.hardware_modem_screen.ids.hardware_modem_baudrate.text) if not val > 0: @@ -4210,7 +4210,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_baudrate.error = True valid = False - + try: val = int(self.hardware_modem_screen.ids.hardware_modem_databits.text) if not val > 0: @@ -4220,7 +4220,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_databits.error = True valid = False - + try: val = int(self.hardware_modem_screen.ids.hardware_modem_stopbits.text) if not val > 0: @@ -4230,7 +4230,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_stopbits.error = True valid = False - + try: val = int(self.hardware_modem_screen.ids.hardware_modem_preamble.text) if not (val >= 0 and val <= 1000): @@ -4240,7 +4240,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_preamble.error = True valid = False - + try: val = int(self.hardware_modem_screen.ids.hardware_modem_tail.text) if not (val > 0 and val <= 500): @@ -4250,7 +4250,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_tail.error = True valid = False - + try: val = int(self.hardware_modem_screen.ids.hardware_modem_slottime.text) if not (val > 0 and val <= 500): @@ -4260,7 +4260,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_slottime.error = True valid = False - + try: val = int(self.hardware_modem_screen.ids.hardware_modem_persistence.text) if not (val > 0 and val <= 255): @@ -4270,7 +4270,7 @@ class SidebandApp(MDApp): except: self.hardware_modem_screen.ids.hardware_modem_persistence.error = True valid = False - + try: val = self.hardware_modem_screen.ids.hardware_modem_parity.text nval = val.lower() @@ -4301,7 +4301,7 @@ class SidebandApp(MDApp): valid = False return valid - + ## Serial hardware screen def hardware_serial_action(self, sender=None, direction="left"): if self.hardware_serial_ready: @@ -4361,12 +4361,12 @@ class SidebandApp(MDApp): t_p = str(self.sideband.config["hw_serial_parity"]) else: t_p = "" - + if self.sideband.config["hw_serial_stopbits"] != None: t_sb = str(self.sideband.config["hw_serial_stopbits"]) else: t_sb = "" - + self.hardware_serial_screen.ids.hardware_serial_baudrate.text = t_b self.hardware_serial_screen.ids.hardware_serial_databits.text = t_db self.hardware_serial_screen.ids.hardware_serial_parity.text = t_p @@ -4383,7 +4383,7 @@ class SidebandApp(MDApp): self.hardware_serial_ready = True def hardware_serial_validate(self, sender=None): - valid = True + valid = True try: val = int(self.hardware_serial_screen.ids.hardware_serial_baudrate.text) if not val > 0: @@ -4393,7 +4393,7 @@ class SidebandApp(MDApp): except: self.hardware_serial_screen.ids.hardware_serial_baudrate.error = True valid = False - + try: val = int(self.hardware_serial_screen.ids.hardware_serial_databits.text) if not val > 0: @@ -4403,7 +4403,7 @@ class SidebandApp(MDApp): except: self.hardware_serial_screen.ids.hardware_serial_databits.error = True valid = False - + try: val = int(self.hardware_serial_screen.ids.hardware_serial_stopbits.text) if not val > 0: @@ -4413,7 +4413,7 @@ class SidebandApp(MDApp): except: self.hardware_serial_screen.ids.hardware_serial_stopbits.error = True valid = False - + try: val = self.hardware_serial_screen.ids.hardware_serial_parity.text nval = val.lower() @@ -4476,7 +4476,7 @@ class SidebandApp(MDApp): self.root.ids.screen_manager.transition.direction = direction self.root.ids.nav_drawer.set_state("closed") - + if self.sideband.getstate("app.flags.new_announces"): self.announces_view.update() @@ -4500,7 +4500,7 @@ class SidebandApp(MDApp): ### Keys screen ###################################### - + def keys_action(self, sender=None, direction="left"): if self.root.ids.screen_manager.has_screen("keys_screen"): self.keys_open(direction=direction) @@ -4556,7 +4556,7 @@ class SidebandApp(MDApp): ) def dl_yes(s): dialog.dismiss() - + yes_button.bind(on_release=dl_yes) dialog.open() @@ -4576,7 +4576,7 @@ class SidebandApp(MDApp): Clipboard.copy(str(base64.b32encode(self.sideband.identity.get_private_key()).decode("utf-8"))) dialog.open() - + c_yes_button.bind(on_release=c_dl_yes) c_no_button.bind(on_release=c_dl_no) @@ -4595,7 +4595,7 @@ class SidebandApp(MDApp): def c_dl_yes(s): c_dialog.dismiss() b32_text = self.keys_screen.ids.key_restore_text.text - + try: key_bytes = base64.b32decode(b32_text) new_id = RNS.Identity.from_bytes(key_bytes) @@ -4618,8 +4618,8 @@ class SidebandApp(MDApp): dialog.dismiss() yes_button.bind(on_release=dl_yes) dialog.open() - - + + c_yes_button.bind(on_release=c_dl_yes) c_no_button.bind(on_release=c_dl_no) @@ -4627,7 +4627,7 @@ class SidebandApp(MDApp): ### Plugins & Services screen ###################################### - + def plugins_action(self, sender=None, direction="left"): if self.root.ids.screen_manager.has_screen("plugins_screen"): self.plugins_open(direction=direction) @@ -4695,7 +4695,7 @@ class SidebandApp(MDApp): if os.path.isdir(path): self.sideband.config["command_plugins_path"] = path self.sideband.save_configuration() - + if RNS.vendor.platformutils.is_android(): toast(f"Using \"{path)}\" as plugin directory") else: @@ -4707,7 +4707,7 @@ class SidebandApp(MDApp): ) ok_button.bind(on_release=ate_dialog.dismiss) ate_dialog.open() - + except Exception as e: RNS.log(f"Error while setting plugins directory to \"{path}\": {e)}", RNS.LOG_ERROR) if RNS.vendor.platformutils.get_platform() == "android": @@ -4730,7 +4730,7 @@ class SidebandApp(MDApp): perm_ok = False if self.sideband.config["command_plugins_path"] == None: if RNS.vendor.platformutils.is_android(): - perm_ok = self.check_storage_permission() + perm_ok = self.check_storage_permission() path = primary_external_storage_path() else: @@ -4747,13 +4747,13 @@ class SidebandApp(MDApp): exit_manager=self.plugins_fm_exited, select_path=self.plugins_fm_got_path, ) - + self.file_manager.show(path) except Exception as e: self.sideband.config["command_plugins_path"] = None self.sideband.save_configuration() - + if RNS.vendor.platformutils.is_android(): toast("Error reading directory, check permissions!") else: @@ -4765,7 +4765,7 @@ class SidebandApp(MDApp): ) ok_button.bind(on_release=ate_dialog.dismiss) ate_dialog.open() - + else: self.sideband.config["command_plugins_path"] = None self.sideband.save_configuration() @@ -4789,7 +4789,7 @@ class SidebandApp(MDApp): if not self.telemetry_ready: self.telemetry_screen = Telemetry(self) self.telemetry_ready = True - + def telemetry_open(self, sender=None, direction="left", no_transition=False): if no_transition: self.root.ids.screen_manager.transition = self.no_transition @@ -4830,7 +4830,7 @@ class SidebandApp(MDApp): self.sideband.setstate("app.flags.new_conversations", True) self.open_conversation(context_dest) - + def telemetry_send_update(self, sender=None): if not hasattr(self, "telemetry_info_dialog") or self.telemetry_info_dialog == None: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) @@ -4976,7 +4976,7 @@ class SidebandApp(MDApp): if self.sideband.config["map_storage_external"]: path = secondary_external_storage_path() if path == None: path = primary_external_storage_path() - else: + else: path = primary_external_storage_path() else: @@ -5012,7 +5012,7 @@ class SidebandApp(MDApp): ) ok_button.bind(on_release=ate_dialog.dismiss) ate_dialog.open() - + else: self.sideband.config["map_storage_path"] = None self.sideband.save_configuration() @@ -5039,7 +5039,7 @@ class SidebandApp(MDApp): source = MBTilesMapSource(current_map_path, cache_dir=self.map_cache) self.offline_source = source return self.offline_source - + except Exception as e: RNS.log(f"Error while loading map from \"{current_map_path}\": {e)}") self.sideband.config["map_storage_file"] = None @@ -5054,7 +5054,7 @@ class SidebandApp(MDApp): source = None if self.sideband.config["map_use_offline"]: source = self.map_get_offline_source() - + if source == None: source = MapSource.from_provider("osm", cache_dir=self.map_cache, quad_key=False) @@ -5063,13 +5063,13 @@ class SidebandApp(MDApp): def map_update_source(self, source=None): ns = source or self.map_get_source() if self.map != None: - + if source != None: maxz = source.max_zoom minz = source.min_zoom if self.map.zoom > maxz: mz = maxz; px, py = self.map_get_zoom_center(); self.map.set_zoom_at(mz, px, py) - + if self.map.zoom < minz: mz = minz; px, py = self.map_get_zoom_center(); self.map.set_zoom_at(mz, px, py) @@ -5156,7 +5156,7 @@ class SidebandApp(MDApp): def map_get_zoom_center(self): bb = self.map.get_bbox() - slat = (bb[2]-bb[0])/2; slon = (bb[3]-bb[1])/2 + slat = (bb[2]-bb[0])/2; slon = (bb[3]-bb[1])/2 zlat = bb[0]+slat; zlon = bb[1]+slon return self.map.get_window_xy_from(zlat, zlon, self.map.zoom) @@ -5515,7 +5515,7 @@ class SidebandApp(MDApp): 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"]["longitude"] != None: retain_own = True - + if not own_address in self.map_markers: marker = self.map_create_marker(own_address, own_telemetry, own_appearance) if marker != None: @@ -5554,7 +5554,7 @@ class SidebandApp(MDApp): changes = True except Exception as e: RNS.log(f"Error while removing map marker: {e)}", RNS.LOG_ERROR) - + except Exception as e: RNS.log(f"Error while updating own map marker: {e)}", RNS.LOG_ERROR) @@ -5657,13 +5657,13 @@ This short guide will give you a basic introduction to the concepts that underpi [size=18dp][b]Communication Without Subjection[/b][/size][size=5dp]\n \n[/size]Sideband is completely free, permission-less, anonymous and infrastructure-less. Sideband uses the peer-to-peer and distributed messaging system LXMF. There is no sign-up, no service providers, no "end-user license agreements", no data theft and no surveillance. You own the system. This also means that Sideband operates differently than what you might be used to. It does not need a connection to a server on the Internet to function, and you do not have an account anywhere.""" - + guide_text3 = """ [size=18dp][b]Operating Principles[/b][/size][size=5dp]\n \n[/size]When Sideband is started on your device for the first time, it randomly generates a 512-bit Reticulum Identity Key. This cryptographic key is then used to create an LXMF address for your use, and in turn to secure any communication to your address. Any other endpoint in [i]any[/i] Reticulum network will be able to send data to your address, as long as there is [i]some sort of physical connection[/i] between your device and the remote endpoint. You can also move around to other Reticulum networks with this address, even ones that were never connected to the network the address was created on, or that didn't exist when the address was created.\n\nYour LXMF address is yours to keep and control for as long (or short) a time you need it, and you can always delete it and create a new one. You identity keys and corresponding addresses are never registered on or controlled by any external servers or services, and will never leave your device, unless you manually export them for backup.""" - + guide_text10 = """ [size=18dp][b]Getting Connected[/b][/size][size=5dp]\n \n[/size]If you already have Reticulum connectivity set up on the device you are running Sideband on, no further configuration should be necessary, and Sideband will simply use the available Reticulum connectivity.\n\nIf you are running Sideband on a computer, you can configure interfaces in the Reticulum configuration file ([b]~/.reticulum/config[/b] by default). If you are running Sideband on an Android device, you can configure various interface types in the [b]Connectivity[/b] section. By default, only an [i]AutoInterface[/i] is enabled, which will connect you automatically with any other local devices on the same WiFi and/or Ethernet networks. This may or may not include Reticulum Transport Nodes, which can route your traffic to wider networks.\n\nYou can enable any or all of the other available interface types to gain wider connectivity. For more specific information on interface types, configuration options, and how to effectively build your own Reticulum networks, see the [b]Reticulum Manual[b].""" - + guide_text4 = """ [size=18dp][b]Becoming Reachable[/b][/size][size=5dp]\n \n[/size]To establish reachability for any Reticulum destination on a network, an [i]announce[/i] must be sent. By default, Sideband will announce automatically when necessary, but if you want to stay silent, automatic announces can be disabled in [b]Preferences[/b].\n\nTo send an announce manually, press the [i]Announce[/i] button in the [i]Conversations[/i] section of the program. When you send an announce, you make your LXMF address reachable for real-time messaging to the entire network you are connected to. Even in very large networks, you can expect global reachability for your address to be established in under a minute. @@ -5681,7 +5681,7 @@ The Propagation Nodes also distribute copies of messages between each other, suc [size=18dp][b]Be Yourself, Be Unknown, Stay Free[/b][/size][size=5dp]\n \n[/size]Even with the above characteristics in mind, you [b]must remember[/b] that LXMF and Reticulum is not a technology that can guarantee anonymising connections that are already de-anonymised! If you use Sideband to connect to TCP Reticulum hubs over the clear Internet, from a network that can be tied to your personal identity, an adversary may learn that you are generating LXMF traffic.\n\nIf you want to avoid this, it is recommended to use I2P to connect to Reticulum hubs on the Internet. Or only connecting from within pure Reticulum networks, that take one or more hops to reach connections that span the Internet. This is a complex topic, with many more nuances than can be covered here. You are encouraged to ask on the various Reticulum discussion forums if you are in doubt. If you use Reticulum and LXMF on hardware that does not carry any identifiers tied to you, it is possible to establish a completely free and identification-less communication system with Reticulum and LXMF clients.""" - + guide_text8 = """ [size=18dp][b]Keyboard Shortcuts[/b][/size][size=5dp]\n \n[/size]To ease navigation and operation of the program, Sideband has keyboard shortcuts mapped to the most common actions. A reference is included below. @@ -5690,7 +5690,7 @@ If you use Reticulum and LXMF on hardware that does not carry any identifiers ti - [b]Ctrl+Q[/b] Shut down Sideband - [b]Ctrl-R[/b] Start LXMF sync (from Conversations screen) - [b]Ctrl-N[/b] Create new conversation - + [b]Message Actions[/b] - [b]Ctrl-Shift-A[/b] add message attachment - [b]Ctrl-Shift-V[/b] add high-quality voice diff --git a/sbapp/mapview/downloader.py b/sbapp/mapview/downloader.py index 80c423b..c9fd327 100644 --- a/sbapp/mapview/downloader.py +++ b/sbapp/mapview/downloader.py @@ -58,7 +58,7 @@ class Downloader: logging.getLogger("urllib3.connection").setLevel(logging.WARNING) logging.getLogger("urllib3.connectionpool").setLevel(logging.WARNING) logging.getLogger("requests").setLevel(logging.WARNING) - + logging.getLogger("urllib3").propagate = True logging.getLogger("requests").propagate = True logging.getLogger("urllib3.response").propagate = True diff --git a/sbapp/mapview/view.py b/sbapp/mapview/view.py index 10cab3a..0f60c66 100644 --- a/sbapp/mapview/view.py +++ b/sbapp/mapview/view.py @@ -721,7 +721,7 @@ class MapView(Widget): if int_diff < 0.08: target = scatter.scale-diff factor = target/scatter.scale - + scatter.apply_transform( Matrix().scale(factor, factor, factor), post_multiply=True, @@ -746,7 +746,7 @@ class MapView(Widget): d = 1 if touch.button == "scrolldown" else -1 else: d = 0.1 if touch.button == "scrolldown" else -0.1 - + self.animated_diff_scale_at(d, *touch.pos) return True elif touch.is_double_tap and self.double_tap_zoom: @@ -793,7 +793,7 @@ class MapView(Widget): zoom = self._zoom scatter = self._scatter scale = scatter.scale - + if self.high_res: if self.high_res_mode == 2: # Double resolution mode diff --git a/sbapp/patches/AndroidManifest.tmpl.xml b/sbapp/patches/AndroidManifest.tmpl.xml index c6cdd64..ce6a5a8 100644 --- a/sbapp/patches/AndroidManifest.tmpl.xml +++ b/sbapp/patches/AndroidManifest.tmpl.xml @@ -75,7 +75,7 @@ > - {% if args.launcher %} + {% if args.launcher %} @@ -146,7 +146,7 @@ + android:resource="@xml/file_paths"> diff --git a/sbapp/patches/PythonService.java b/sbapp/patches/PythonService.java index ad7142c..d395886 100644 --- a/sbapp/patches/PythonService.java +++ b/sbapp/patches/PythonService.java @@ -132,9 +132,9 @@ public class PythonService extends Service implements Runnable { // https://stackoverflow.com/questions/47531742/startforeground-fail-after-upgrade-to-android-8-1 String NOTIFICATION_CHANNEL_ID = "io.unsigned.sideband.reticulum"; String channelName = "Background Service"; - NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, + NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE); - + chan.setLightColor(Color.BLUE); chan.setLockscreenVisibility(Notification.VISIBILITY_SECRET); chan.setShowBadge(false); diff --git a/sbapp/plyer/platforms/android/audio.py b/sbapp/plyer/platforms/android/audio.py index 58cd9c5..2d2f870 100644 --- a/sbapp/plyer/platforms/android/audio.py +++ b/sbapp/plyer/platforms/android/audio.py @@ -37,7 +37,7 @@ class AndroidAudio(Audio): time.sleep(0.25) self.is_playing = False - + if self._finished_callback and callable(self._finished_callback): self._check_thread = None self._finished_callback(self) diff --git a/sbapp/plyer/platforms/linux/audio.py b/sbapp/plyer/platforms/linux/audio.py index 091e9e5..80acd10 100644 --- a/sbapp/plyer/platforms/linux/audio.py +++ b/sbapp/plyer/platforms/linux/audio.py @@ -34,7 +34,7 @@ class LinuxAudio(Audio): run = False self.is_playing = False - + if self._finished_callback and callable(self._finished_callback): self._check_thread = None self._finished_callback(self) @@ -52,7 +52,7 @@ class LinuxAudio(Audio): frame_duration = frame_duration_ms/1000 frame_size = int(frame_duration * samples_per_second) bytes_per_frame = frame_size*bytes_per_sample - + read_bytes = 0 pcm_buf = b"" should_continue = True diff --git a/sbapp/plyer/platforms/macosx/audio.py b/sbapp/plyer/platforms/macosx/audio.py index 1f2069e..e11968d 100644 --- a/sbapp/plyer/platforms/macosx/audio.py +++ b/sbapp/plyer/platforms/macosx/audio.py @@ -41,7 +41,7 @@ class OSXAudio(Audio): def _check_playback(self): while self._player and self._player.isPlaying: time.sleep(0.25) - + if self._finished_callback and callable(self._finished_callback): self._check_thread = None self._finished_callback(self) diff --git a/sbapp/pydub/effects.py b/sbapp/pydub/effects.py index 99bed5c..6ff6659 100644 --- a/sbapp/pydub/effects.py +++ b/sbapp/pydub/effects.py @@ -37,11 +37,11 @@ def normalize(seg, headroom=0.1): headroom is how close to the maximum volume to boost the signal up to (specified in dB) """ peak_sample_val = seg.max - + # if the max is 0, this audio segment is silent, and can't be normalized if peak_sample_val == 0: return seg - + target_peak = seg.max_possible_amplitude * db_to_float(-headroom) needed_boost = ratio_to_db(target_peak / peak_sample_val) @@ -91,7 +91,7 @@ def speedup(seg, playback_speed=1.5, chunk_size=150, crossfade=25): out += last_chunk return out - + @register_pydub_effect def strip_silence(seg, silence_len=1000, silence_thresh=-16, padding=100): @@ -115,17 +115,17 @@ def strip_silence(seg, silence_len=1000, silence_thresh=-16, padding=100): def compress_dynamic_range(seg, threshold=-20.0, ratio=4.0, attack=5.0, release=50.0): """ Keyword Arguments: - + threshold - default: -20.0 Threshold in dBFS. default of -20.0 means -20dB relative to the maximum possible volume. 0dBFS is the maximum possible value so all values for this argument sould be negative. ratio - default: 4.0 - Compression ratio. Audio louder than the threshold will be + Compression ratio. Audio louder than the threshold will be reduced to 1/ratio the volume. A ratio of 4.0 is equivalent to a setting of 4:1 in a pro-audio compressor like the Waves C1. - + attack - default: 5.0 Attack in milliseconds. How long it should take for the compressor to kick in once the audio has exceeded the threshold. @@ -134,15 +134,15 @@ def compress_dynamic_range(seg, threshold=-20.0, ratio=4.0, attack=5.0, release= Release in milliseconds. How long it should take for the compressor to stop compressing after the audio has falled below the threshold. - + For an overview of Dynamic Range Compression, and more detailed explanation - of the related terminology, see: + of the related terminology, see: http://en.wikipedia.org/wiki/Dynamic_range_compression """ thresh_rms = seg.max_possible_amplitude * db_to_float(threshold) - + look_frames = int(seg.frame_count(ms=attack)) def rms_at(frame_i): return seg.get_sample_slice(frame_i - look_frames, frame_i).rms @@ -155,34 +155,34 @@ def compress_dynamic_range(seg, threshold=-20.0, ratio=4.0, attack=5.0, release= # amount to reduce the volume of the audio by (in dB) attenuation = 0.0 - + attack_frames = seg.frame_count(ms=attack) release_frames = seg.frame_count(ms=release) for i in xrange(int(seg.frame_count())): rms_now = rms_at(i) - + # with a ratio of 4.0 this means the volume will exceed the threshold by # 1/4 the amount (of dB) that it would otherwise max_attenuation = (1 - (1.0 / ratio)) * db_over_threshold(rms_now) - + attenuation_inc = max_attenuation / attack_frames attenuation_dec = max_attenuation / release_frames - + if rms_now > thresh_rms and attenuation <= max_attenuation: attenuation += attenuation_inc attenuation = min(attenuation, max_attenuation) else: attenuation -= attenuation_dec attenuation = max(attenuation, 0) - + frame = seg.get_frame(i) if attenuation != 0.0: frame = audioop.mul(frame, seg.sample_width, db_to_float(-attenuation)) - + output.append(frame) - + return seg._spawn(data=b''.join(output)) @@ -196,22 +196,22 @@ def invert_phase(seg, channels=(1, 1)): Note that mono AudioSegments will become stereo. """ if channels == (1, 1): - inverted = audioop.mul(seg._data, seg.sample_width, -1.0) + inverted = audioop.mul(seg._data, seg.sample_width, -1.0) return seg._spawn(data=inverted) - + else: if seg.channels == 2: left, right = seg.split_to_mono() else: raise Exception(f"Can't implicitly convert an AudioSegment with {seg.channels)} channels to stereo.") - - if channels == (1, 0): + + if channels == (1, 0): left = left.invert_phase() else: right = right.invert_phase() - + return seg.from_mono_audiosegments(left, right) - + # High and low pass filters based on implementation found on Stack Overflow: @@ -227,10 +227,10 @@ def low_pass_filter(seg, cutoff): dt = 1.0 / seg.frame_rate alpha = dt / (RC + dt) - + original = seg.get_array_of_samples() filteredArray = array.array(seg.array_type, original) - + frame_count = int(seg.frame_count()) last_val = [0] * seg.channels @@ -258,10 +258,10 @@ def high_pass_filter(seg, cutoff): alpha = RC / (RC + dt) minval, maxval = get_min_max_value(seg.sample_width * 8) - + original = seg.get_array_of_samples() filteredArray = array.array(seg.array_type, original) - + frame_count = int(seg.frame_count()) last_val = [0] * seg.channels @@ -277,64 +277,64 @@ def high_pass_filter(seg, cutoff): filteredArray[offset] = int(min(max(last_val[j], minval), maxval)) return seg._spawn(data=filteredArray) - - + + @register_pydub_effect def pan(seg, pan_amount): """ pan_amount should be between -1.0 (100% left) and +1.0 (100% right) - + When pan_amount == 0.0 the left/right balance is not changed. - + Panning does not alter the *perceived* loundness, but since loudness is decreasing on one side, the other side needs to get louder to compensate. When panned hard left, the left channel will be 3dB louder. """ if not -1.0 <= pan_amount <= 1.0: raise ValueError("pan_amount should be between -1.0 (100% left) and +1.0 (100% right)") - + max_boost_db = ratio_to_db(2.0) boost_db = abs(pan_amount) * max_boost_db - + boost_factor = db_to_float(boost_db) reduce_factor = db_to_float(max_boost_db) - boost_factor - + reduce_db = ratio_to_db(reduce_factor) - + # Cut boost in half (max boost== 3dB) - in reality 2 speakers # do not sum to a full 6 dB. boost_db = boost_db / 2.0 - + if pan_amount < 0: return seg.apply_gain_stereo(boost_db, reduce_db) else: return seg.apply_gain_stereo(reduce_db, boost_db) - - + + @register_pydub_effect def apply_gain_stereo(seg, left_gain=0.0, right_gain=0.0): """ left_gain - amount of gain to apply to the left channel (in dB) right_gain - amount of gain to apply to the right channel (in dB) - + note: mono audio segments will be converted to stereo """ if seg.channels == 1: left = right = seg elif seg.channels == 2: left, right = seg.split_to_mono() - + l_mult_factor = db_to_float(left_gain) r_mult_factor = db_to_float(right_gain) - + left_data = audioop.mul(left._data, left.sample_width, l_mult_factor) left_data = audioop.tostereo(left_data, left.sample_width, 1, 0) - + right_data = audioop.mul(right._data, right.sample_width, r_mult_factor) right_data = audioop.tostereo(right_data, right.sample_width, 0, 1) - + output = audioop.add(left_data, right_data, seg.sample_width) - + return seg._spawn(data=output, overrides={'channels': 2, 'frame_width': 2 * seg.sample_width}) diff --git a/sbapp/pydub/generators.py b/sbapp/pydub/generators.py index a5ecfbe..eb3dfef 100644 --- a/sbapp/pydub/generators.py +++ b/sbapp/pydub/generators.py @@ -1,9 +1,9 @@ """ -Each generator will return float samples from -1.0 to 1.0, which can be +Each generator will return float samples from -1.0 to 1.0, which can be converted to actual audio with 8, 16, 24, or 32 bit depth using the SiganlGenerator.to_audio_segment() method (on any of it's subclasses). -See Wikipedia's "waveform" page for info on some of the generators included +See Wikipedia's "waveform" page for info on some of the generators included here: http://en.wikipedia.org/wiki/Waveform """ @@ -44,7 +44,7 @@ class SignalGenerator: sample_data = itertools.islice(sample_data, 0, sample_count) data = array.array(array_type, sample_data) - + try: data = data.tobytes() except: diff --git a/sbapp/pydub/scipy_effects.py b/sbapp/pydub/scipy_effects.py index abab2b4..3544ab7 100644 --- a/sbapp/pydub/scipy_effects.py +++ b/sbapp/pydub/scipy_effects.py @@ -72,30 +72,30 @@ def _eq(seg, focus_freq, bandwidth=100, mode="peak", gain_dB=0, order=2): bandwidth - range of the equalizer band mode - Mode of Equalization(Peak/Notch(Bell Curve),High Shelf, Low Shelf) order - Rolloff factor(1 - 6dB/Octave 2 - 12dB/Octave) - + Returns: Equalized/Filtered AudioSegment """ filt_mode = ["peak", "low_shelf", "high_shelf"] if mode not in filt_mode: raise ValueError("Incorrect Mode Selection") - + if gain_dB >= 0: if mode == "peak": sec = band_pass_filter(seg, focus_freq - bandwidth/2, focus_freq + bandwidth/2, order = order) seg = seg.overlay(sec - (3 - gain_dB)) return seg - + if mode == "low_shelf": sec = low_pass_filter(seg, focus_freq, order=order) seg = seg.overlay(sec - (3 - gain_dB)) return seg - + if mode == "high_shelf": sec = high_pass_filter(seg, focus_freq, order=order) seg = seg.overlay(sec - (3 - gain_dB)) return seg - + if gain_dB < 0: if mode == "peak": sec = high_pass_filter(seg, focus_freq - bandwidth/2, order=order) @@ -103,17 +103,17 @@ def _eq(seg, focus_freq, bandwidth=100, mode="peak", gain_dB=0, order=2): sec = low_pass_filter(seg, focus_freq + bandwidth/2, order=order) seg = seg.overlay(sec - (3 + gain_dB)) + gain_dB return seg - + if mode == "low_shelf": sec = high_pass_filter(seg, focus_freq, order=order) seg = seg.overlay(sec - (3 + gain_dB)) + gain_dB return seg - + if mode=="high_shelf": sec=low_pass_filter(seg, focus_freq, order=order) seg=seg.overlay(sec - (3 + gain_dB)) +gain_dB return seg - + @register_pydub_effect def eq(seg, focus_freq, bandwidth=100, channel_mode="L+R", filter_mode="peak", gain_dB=0, order=2): @@ -131,41 +131,41 @@ def eq(seg, focus_freq, bandwidth=100, channel_mode="L+R", filter_mode="peak", g Mono Audio Segments are completely filtered. filter_mode - Mode of Equalization(Peak/Notch(Bell Curve),High Shelf, Low Shelf) order - Rolloff factor(1 - 6dB/Octave 2 - 12dB/Octave) - + Returns: Equalized/Filtered AudioSegment """ channel_modes = ["L+R", "M+S", "L", "R", "M", "S"] if channel_mode not in channel_modes: raise ValueError("Incorrect Channel Mode Selection") - + if seg.channels == 1: return _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order) - + if channel_mode == "L+R": return _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order) - + if channel_mode == "L": seg = seg.split_to_mono() seg = [_eq(seg[0], focus_freq, bandwidth, filter_mode, gain_dB, order), seg[1]] return AudioSegment.from_mono_audio_segements(seg[0], seg[1]) - + if channel_mode == "R": seg = seg.split_to_mono() seg = [seg[0], _eq(seg[1], focus_freq, bandwidth, filter_mode, gain_dB, order)] return AudioSegment.from_mono_audio_segements(seg[0], seg[1]) - + if channel_mode == "M+S": seg = stereo_to_ms(seg) seg = _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order) return ms_to_stereo(seg) - + if channel_mode == "M": seg = stereo_to_ms(seg).split_to_mono() seg = [_eq(seg[0], focus_freq, bandwidth, filter_mode, gain_dB, order), seg[1]] seg = AudioSegment.from_mono_audio_segements(seg[0], seg[1]) return ms_to_stereo(seg) - + if channel_mode == "S": seg = stereo_to_ms(seg).split_to_mono() seg = [seg[0], _eq(seg[1], focus_freq, bandwidth, filter_mode, gain_dB, order)] diff --git a/sbapp/pyogg/__init__.py b/sbapp/pyogg/__init__.py index a97b0d2..10c6a28 100644 --- a/sbapp/pyogg/__init__.py +++ b/sbapp/pyogg/__init__.py @@ -76,22 +76,22 @@ else: class OpusBufferedEncoder: # type: ignore def __init__(*args, **kw): raise PyOggError("The Opus library wasn't found or couldn't be loaded (maybe you're trying to use 64bit libraries with 32bit Python?)") - + class OpusDecoder: # type: ignore def __init__(*args, **kw): raise PyOggError("The Opus library wasn't found or couldn't be loaded (maybe you're trying to use 64bit libraries with 32bit Python?)") -if (PYOGG_OGG_AVAIL and PYOGG_OPUS_AVAIL): +if (PYOGG_OGG_AVAIL and PYOGG_OPUS_AVAIL): # OggOpusWriter from .ogg_opus_writer import OggOpusWriter - + else: class OggOpusWriter: # type: ignore def __init__(*args, **kw): if not PYOGG_OGG_AVAIL: raise PyOggError("The Ogg library wasn't found or couldn't be loaded (maybe you're trying to use 64bit libraries with 32bit Python?)") raise PyOggError("The Opus library was't found or couldn't be loaded (maybe you're trying to use 64bit libraries with 32bit Python?)") - + if PYOGG_FLAC_AVAIL: # FlacFile diff --git a/sbapp/pyogg/audio_file.py b/sbapp/pyogg/audio_file.py index 4fb77a2..b4d70c1 100644 --- a/sbapp/pyogg/audio_file.py +++ b/sbapp/pyogg/audio_file.py @@ -9,8 +9,8 @@ class AudioFile: def __init__(self): raise PyOggError("AudioFile is an Abstract Base Class "+ - "and should not be instantiated") - + "and should not be instantiated") + def as_array(self): """Returns the buffer as a NumPy array. @@ -26,9 +26,9 @@ class AudioFile: """ # Assumes that self.buffer is a one-dimensional array of # bytes and that channels are interleaved. - + import numpy # type: ignore - + assert self.buffer is not None assert self.channels is not None @@ -43,7 +43,7 @@ class AudioFile: 1: numpy.int8, 2: numpy.int16 } - + # Convert the ctypes buffer to a NumPy array array = numpy.frombuffer( self.buffer, diff --git a/sbapp/pyogg/flac.py b/sbapp/pyogg/flac.py index d44509e..910ecd1 100644 --- a/sbapp/pyogg/flac.py +++ b/sbapp/pyogg/flac.py @@ -64,7 +64,7 @@ if libflac: PYOGG_FLAC_AVAIL = True else: PYOGG_FLAC_AVAIL = False - + # ctypes c_ubyte_p = POINTER(c_ubyte) c_uchar_p = c_ubyte_p @@ -76,7 +76,7 @@ c_off_t = c_int32 if PYOGG_FLAC_AVAIL: # Sanity check also satisfies mypy type checking assert libflac is not None - + # ordinals FLAC__int8 = c_int8 @@ -170,7 +170,7 @@ if PYOGG_FLAC_AVAIL: FLAC__EntropyCodingMethodType = c_int FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0 - + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 @@ -272,10 +272,10 @@ if PYOGG_FLAC_AVAIL: _fields_ = [("type", FLAC__SubframeType), ("data", FLAC__Subframe_data), ("wasted_bits", c_uint)] - + FLAC__SUBFRAME_ZERO_PAD_LEN = c_uint.in_dll(libflac, "FLAC__SUBFRAME_ZERO_PAD_LEN") - + FLAC__SUBFRAME_TYPE_LEN = c_uint.in_dll(libflac, "FLAC__SUBFRAME_TYPE_LEN") FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = c_uint.in_dll(libflac, "FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN") @@ -327,7 +327,7 @@ if PYOGG_FLAC_AVAIL: ("number_type", FLAC__FrameNumberType), ("number", FLAC__FrameHeader_number), ("crc", FLAC__uint8)] - + FLAC__FRAME_HEADER_SYNC = c_uint.in_dll(libflac, "FLAC__FRAME_HEADER_SYNC") @@ -360,7 +360,7 @@ if PYOGG_FLAC_AVAIL: _fields_ = [("header", FLAC__FrameHeader), ("subframes", FLAC__Subframe * FLAC__MAX_CHANNELS), ("footer", FLAC__FrameFooter)] - + FLAC__MetadataType = c_int @@ -435,7 +435,7 @@ if PYOGG_FLAC_AVAIL: ("data", FLAC__byte_p)] FLAC__STREAM_METADATA_APPLICATION_ID_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_APPLICATION_ID_LEN") - + class FLAC__StreamMetadata_SeekPoint(Structure): _fields_ = [("sample_number", FLAC__uint64), @@ -475,10 +475,10 @@ if PYOGG_FLAC_AVAIL: class FLAC__StreamMetadata_CueSheet_Index(Structure): _fields_ = [("offset", FLAC__uint64), ("number", FLAC__byte)] - + FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN") - + FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN") FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN") @@ -494,7 +494,7 @@ if PYOGG_FLAC_AVAIL: ("indices", POINTER(FLAC__StreamMetadata_CueSheet_Index))] FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN") - + FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN") FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN") @@ -516,7 +516,7 @@ if PYOGG_FLAC_AVAIL: ("tracks", POINTER(FLAC__StreamMetadata_CueSheet_Track))] FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN") - + FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN") @@ -584,7 +584,7 @@ if PYOGG_FLAC_AVAIL: FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_PICTURE_COLORS_LEN") - FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN") + FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN") class FLAC__StreamMetadata_Unknown(Structure): @@ -608,7 +608,7 @@ if PYOGG_FLAC_AVAIL: ("data", FLAC__StreamMetadata_data)] FLAC__STREAM_METADATA_IS_LAST_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_IS_LAST_LEN") - + FLAC__STREAM_METADATA_TYPE_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_TYPE_LEN") FLAC__STREAM_METADATA_LENGTH_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_LENGTH_LEN") @@ -798,7 +798,7 @@ if PYOGG_FLAC_AVAIL: def FLAC__metadata_simple_iterator_get_block(iterator): return libflac.FLAC__metadata_simple_iterator_get_block(iterator) - + libflac.FLAC__metadata_simple_iterator_set_block.restype = FLAC__bool libflac.FLAC__metadata_simple_iterator_set_block.argtypes = [POINTER(FLAC__Metadata_SimpleIterator), POINTER(FLAC__StreamMetadata), FLAC__bool] @@ -819,7 +819,7 @@ if PYOGG_FLAC_AVAIL: class FLAC__Metadata_Chain(Structure): _fields_ = [("dummy", c_int)] - + class FLAC__Metadata_Iterator(Structure): _fields_ = [("dummy", c_int)] @@ -1261,13 +1261,13 @@ if PYOGG_FLAC_AVAIL: FLAC__StreamDecoderStateEnum = ["FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", "FLAC__STREAM_DECODER_READ_METADATA", "FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", - "FLAC__STREAM_DECODER_READ_FRAME", + "FLAC__STREAM_DECODER_READ_FRAME", "FLAC__STREAM_DECODER_END_OF_STREAM", "FLAC__STREAM_DECODER_OGG_ERROR", "FLAC__STREAM_DECODER_SEEK_ERROR", - "FLAC__STREAM_DECODER_ABORTED", + "FLAC__STREAM_DECODER_ABORTED", "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR", - "FLAC__STREAM_DECODER_UNINITIALIZED"] + "FLAC__STREAM_DECODER_UNINITIALIZED"] libflac.FLAC__StreamDecoderStateString.restype = c_char_p libflac.FLAC__StreamDecoderStateString.argtypes = [] @@ -1280,7 +1280,7 @@ if PYOGG_FLAC_AVAIL: FLAC__StreamDecoderInitStatusEnum = ["FLAC__STREAM_DECODER_INIT_STATUS_OK", "FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER", "FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS", - "FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR", + "FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR", "FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE", "FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED"] diff --git a/sbapp/pyogg/flac_file.py b/sbapp/pyogg/flac_file.py index 132f6a7..337bdd7 100644 --- a/sbapp/pyogg/flac_file.py +++ b/sbapp/pyogg/flac_file.py @@ -107,7 +107,7 @@ class FlacFile(AudioFile): ctypes.c_byte * (self.bytes_per_sample * len(self.buffer)) ) - self.buffer = CharBuffer.from_buffer(self.buffer) + self.buffer = CharBuffer.from_buffer(self.buffer) # FLAC audio is always signed. See # https://xiph.org/flac/api/group__flac__stream__decoder.html#gaf98a4f9e2cac5747da6018c3dfc8dde1 diff --git a/sbapp/pyogg/library_loader.py b/sbapp/pyogg/library_loader.py index 0ccf60f..ca62c3e 100644 --- a/sbapp/pyogg/library_loader.py +++ b/sbapp/pyogg/library_loader.py @@ -24,7 +24,7 @@ if architecture == "32bit": for arch_style in ["32bit", "32" "86", "win32", "x86", "_x86", "_32", "_win32", "_32bit"]: for style in ["{}", "lib{}"]: _windows_styles.append(style.format(f"{{}}{arch_style}")) - + elif architecture == "64bit": for arch_style in ["64bit", "64" "86_64", "amd64", "win_amd64", "x86_64", "_x86_64", "_64", "_amd64", "_64bit"]: for style in ["{}", "lib{}"]: @@ -33,7 +33,7 @@ elif architecture == "64bit": run_tests = lambda lib, tests: [f(lib) for f in tests] -# Get the appropriate directory for the shared libraries depending +# Get the appropriate directory for the shared libraries depending # on the current platform and architecture platform_ = platform.system() lib_dir = None @@ -53,7 +53,7 @@ class Library: if lib is None: lib = ExternalLibrary.load(names["external"], paths, tests) return lib - + class InternalLibrary: @staticmethod @@ -61,7 +61,7 @@ class InternalLibrary: # If we do not have a library directory, give up immediately if lib_dir is None: return None - + # Get the appropriate library filename given the platform try: name = names[platform_] @@ -69,7 +69,7 @@ class InternalLibrary: return None # Attempt to load the library from here - path = f"{_here}/{lib_dir}/{name}" + path = f"{_here}/{lib_dir}/{name}" try: lib = ctypes.CDLL(path) except OSError as e: @@ -81,7 +81,7 @@ class InternalLibrary: # Library failed tests return None - + # Cache of libraries that have already been loaded _loaded_libraries: Dict[str, ctypes.CDLL] = {} @@ -119,7 +119,7 @@ class ExternalLibrary: def load_windows(name, paths = None, tests = []): os.environ["PATH"] += f";{f"{os.getcwd()};{_here}"}" if paths: os.environ["PATH"] += f";{';'.join(paths)}" - + not_supported = [] # libraries that were found, but are not supported for style in _windows_styles: candidate = style.format(name) @@ -134,7 +134,7 @@ class ExternalLibrary: pass except OSError: not_supported.append(library) - + if not_supported: raise ExternalLibraryError(f"library '{name}' couldn't be loaded, because the following candidates were not supported:" @@ -142,6 +142,6 @@ class ExternalLibrary: raise ExternalLibraryError(f"library '{name}' couldn't be loaded") - - + + diff --git a/sbapp/pyogg/ogg.py b/sbapp/pyogg/ogg.py index 08a944b..e5b43c1 100644 --- a/sbapp/pyogg/ogg.py +++ b/sbapp/pyogg/ogg.py @@ -212,7 +212,7 @@ if PYOGG_OGG_AVAIL: og_p = POINTER(ogg_page) os_p = POINTER(ogg_stream_state) iov_p = POINTER(ogg_iovec_t) - + libogg.oggpack_writeinit.restype = None libogg.oggpack_writeinit.argtypes = [b_p] @@ -330,13 +330,13 @@ if PYOGG_OGG_AVAIL: def oggpackB_writeinit(b): libogg.oggpackB_writeinit(b) - + try: libogg.oggpackB_writecheck.restype = c_int libogg.oggpackB_writecheck.argtypes = [b_p] def oggpackB_writecheck(b): - return libogg.oggpackB_writecheck(b) + return libogg.oggpackB_writecheck(b) except: pass diff --git a/sbapp/pyogg/ogg_opus_writer.py b/sbapp/pyogg/ogg_opus_writer.py index feebc0a..eb89bf0 100644 --- a/sbapp/pyogg/ogg_opus_writer.py +++ b/sbapp/pyogg/ogg_opus_writer.py @@ -18,7 +18,7 @@ from .pyogg_error import PyOggError class OggOpusWriter(): """Encodes PCM data into an OggOpus file.""" - def __init__(self, + def __init__(self, f: Union[BinaryIO, str], encoder: OpusBufferedEncoder, custom_pre_skip: Optional[int] = None) -> None: @@ -29,7 +29,7 @@ class OggOpusWriter(): If f is an already-opened file handle, then it is the user's responsibility to close the file when they are - finished with it. The file should be opened for writing + finished with it. The file should be opened for writing in binary (not text) mode. The encoder should be a @@ -123,7 +123,7 @@ class OggOpusWriter(): def _write_to_oggopus(self, pcm: memoryview, flush: bool = False) -> None: assert self._encoder is not None - + def handle_encoded_packet(encoded_packet: memoryview, samples: int, end_of_stream: bool) -> None: @@ -132,7 +132,7 @@ class OggOpusWriter(): encoded_packet_ctypes = Buffer.from_buffer(encoded_packet) # Obtain a pointer to the encoded packet - encoded_packet_ptr = ctypes.cast( + encoded_packet_ptr = ctypes.cast( encoded_packet_ctypes, ctypes.POINTER(ctypes.c_ubyte) ) diff --git a/sbapp/pyogg/opus.py b/sbapp/pyogg/opus.py index 446d0ab..56ee347 100644 --- a/sbapp/pyogg/opus.py +++ b/sbapp/pyogg/opus.py @@ -232,7 +232,7 @@ if libopus: PYOGG_OPUS_AVAIL = True else: PYOGG_OPUS_AVAIL = False - + if libopusfile: PYOGG_OPUS_FILE_AVAIL = True else: @@ -345,22 +345,22 @@ OPUS_APPLICATION_AUDIO = 2049 OPUS_APPLICATION_RESTRICTED_LOWDELAY =2051 OPUS_SIGNAL_VOICE =3001 -OPUS_SIGNAL_MUSIC =3002 -OPUS_BANDWIDTH_NARROWBAND =1101 -OPUS_BANDWIDTH_MEDIUMBAND =1102 -OPUS_BANDWIDTH_WIDEBAND =1103 -OPUS_BANDWIDTH_SUPERWIDEBAND =1104 -OPUS_BANDWIDTH_FULLBAND =1105 +OPUS_SIGNAL_MUSIC =3002 +OPUS_BANDWIDTH_NARROWBAND =1101 +OPUS_BANDWIDTH_MEDIUMBAND =1102 +OPUS_BANDWIDTH_WIDEBAND =1103 +OPUS_BANDWIDTH_SUPERWIDEBAND =1104 +OPUS_BANDWIDTH_FULLBAND =1105 -OPUS_FRAMESIZE_ARG =5000 -OPUS_FRAMESIZE_2_5_MS =5001 -OPUS_FRAMESIZE_5_MS =5002 +OPUS_FRAMESIZE_ARG =5000 +OPUS_FRAMESIZE_2_5_MS =5001 +OPUS_FRAMESIZE_5_MS =5002 OPUS_FRAMESIZE_10_MS =5003 -OPUS_FRAMESIZE_20_MS =5004 -OPUS_FRAMESIZE_40_MS =5005 -OPUS_FRAMESIZE_60_MS =5006 -OPUS_FRAMESIZE_80_MS =5007 -OPUS_FRAMESIZE_100_MS =5008 +OPUS_FRAMESIZE_20_MS =5004 +OPUS_FRAMESIZE_40_MS =5005 +OPUS_FRAMESIZE_60_MS =5006 +OPUS_FRAMESIZE_80_MS =5007 +OPUS_FRAMESIZE_100_MS =5008 OPUS_FRAMESIZE_120_MS =5009 OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST =5120 @@ -405,7 +405,7 @@ opus_int32 = c_int32 opus_int32_p = POINTER(opus_int32) opus_uint32 = c_uint32 -opus_int = c_int +opus_int = c_int opus_int64= c_longlong opus_int8= c_int8 @@ -640,7 +640,7 @@ if PYOGG_OPUS_AVAIL: def opus_multistream_packet_unpad(data, len, nb_streams): return libopus.opus_multistream_packet_unpad(data, len, nb_streams) - + libopus.opus_strerror.restype = c_char_p libopus.opus_strerror.argtypes = [c_int] @@ -770,7 +770,7 @@ if PYOGG_OPUS_AVAIL: if PYOGG_OPUS_FILE_AVAIL: assert libopusfile is not None - + # opusfile class OggOpusFile(ctypes.Structure): @@ -1212,7 +1212,7 @@ if PYOGG_OPUS_AVAIL: if PYOGG_OPUS_ENC_AVAIL: # Sanity check also satisfies mypy type checking assert libopusenc is not None - + ope_write_func = ctypes.CFUNCTYPE(c_int, c_void_p, c_uchar_p, diff --git a/sbapp/pyogg/opus_buffered_encoder.py b/sbapp/pyogg/opus_buffered_encoder.py index 16f784d..6b9a6e8 100644 --- a/sbapp/pyogg/opus_buffered_encoder.py +++ b/sbapp/pyogg/opus_buffered_encoder.py @@ -105,7 +105,7 @@ class OpusBufferedEncoder(OpusEncoder): "rather than bytes)." ) pcm_ctypes = Buffer.from_buffer(pcm_bytes) - + # Either store the encoded packet to return at the end of the # method or immediately call the callback with the encoded # packet. @@ -135,7 +135,7 @@ class OpusBufferedEncoder(OpusEncoder): assert self._buffer_index is not None assert self._channels is not None assert self._buffer is not None - + # If the buffer is already empty, we have no work to do if self._buffer_index == 0: return @@ -156,7 +156,7 @@ class OpusBufferedEncoder(OpusEncoder): # count len(self._buffer) - self._buffer_index ) - + # Encode the PCM # As at 2020-11-05, mypy is unaware that ctype Arrays # support the buffer protocol. @@ -166,16 +166,16 @@ class OpusBufferedEncoder(OpusEncoder): # callback store_or_callback(encoded_packet, samples, True) - + # Copy the data remaining from the provided PCM into the # buffer. Flush if required. def copy_insufficient_data() -> None: # Sanity checks to satisfy mypy assert self._buffer is not None - + # Calculate remaining data remaining_data = len(pcm_bytes) - pcm_index - + # Copy the data into the buffer. ctypes.memmove( # destination @@ -191,7 +191,7 @@ class OpusBufferedEncoder(OpusEncoder): # If we've been asked to flush the buffer then do so if flush: flush_buffer() - + # Loop through the provided PCM and the current buffer, # encoding as we have full packets. while True: @@ -227,7 +227,7 @@ class OpusBufferedEncoder(OpusEncoder): // self._channels // ctypes.sizeof(opus.opus_int16) ) - + # Encode the PCM encoded_packet = super().encode(frame_data) @@ -266,7 +266,7 @@ class OpusBufferedEncoder(OpusEncoder): pcm_index += remaining self._buffer_index += remaining assert self._buffer_index == len(self._buffer) - + # Encode the PCM encoded_packet = super().encode( # Memoryviews of ctypes do work, even though @@ -284,7 +284,7 @@ class OpusBufferedEncoder(OpusEncoder): # We've now processed the buffer self._buffer_index = 0 - + # Either store the encoded packet or call the # callback store_or_callback(encoded_packet, samples) diff --git a/sbapp/pyogg/opus_decoder.py b/sbapp/pyogg/opus_decoder.py index 00688d2..6ef4ec2 100644 --- a/sbapp/pyogg/opus_decoder.py +++ b/sbapp/pyogg/opus_decoder.py @@ -87,7 +87,7 @@ class OpusDecoder: # data) Buffer = ctypes.c_char * len(encoded_bytes) encoded_bytes_ctypes = Buffer.from_buffer(encoded_bytes) - + # Create pointer to encoded bytes encoded_bytes_ptr = ctypes.cast( encoded_bytes_ctypes, @@ -127,16 +127,16 @@ class OpusDecoder: * ctypes.sizeof(opus.opus_int16) * self._channels ) - + # Create memoryview of PCM buffer to avoid copying data during slice. mv = memoryview(self._pcm_buffer) - + # Cast memoryview to chars mv = mv.cast('c') - + # Slice memoryview to extract only valid data mv = mv[:end_valid_data] - + return mv diff --git a/sbapp/pyogg/opus_encoder.py b/sbapp/pyogg/opus_encoder.py index b1d5390..8443cec 100644 --- a/sbapp/pyogg/opus_encoder.py +++ b/sbapp/pyogg/opus_encoder.py @@ -131,8 +131,8 @@ class OpusEncoder: ctypes.cast(ctypes.pointer(self._output_buffer), ctypes.POINTER(ctypes.c_ubyte)) ) - - + + def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview: """Encodes PCM data into an Opus frame. @@ -146,7 +146,7 @@ class OpusEncoder: # If we haven't already created an encoder, do so now if self._encoder is None: self._encoder = self._create_encoder() - + # Sanity checks also satisfy mypy type checking assert self._channels is not None assert self._samples_per_second is not None @@ -177,7 +177,7 @@ class OpusEncoder: PcmCtypes = ctypes.c_ubyte * len(pcm) try: # Attempt to share the PCM memory - + # Unfortunately, as at 2020-09-27, the type hinting for # read-only and writeable buffer protocols was a # work-in-progress. The following only works for writable @@ -225,27 +225,27 @@ class OpusEncoder: # * https://github.com/python/typing/issues/593 # * https://github.com/python/typeshed/pull/4232 mv = memoryview(self._output_buffer) # type: ignore - + # Cast the memoryview to char mv = mv.cast('c') # Slice just the valid data from the memoryview valid_data_as_bytes = mv[:result] - + # DEBUG # Convert memoryview back to ctypes instance Buffer = ctypes.c_ubyte * len(valid_data_as_bytes) buf = Buffer.from_buffer( valid_data_as_bytes ) - + # Convert PCM back to pointer and dump 4,000-byte buffer ptr = ctypes.cast( buf, ctypes.POINTER(ctypes.c_ubyte) ) - + return valid_data_as_bytes - + def get_algorithmic_delay(self): """Gets the total samples of delay added by the entire codec. @@ -266,9 +266,9 @@ class OpusEncoder: # If we haven't already created an encoder, do so now if self._encoder is None: self._encoder = self._create_encoder() - + # Obtain the algorithmic delay of the Opus encoder. See - # https://tools.ietf.org/html/rfc7845#page-27 + # https://tools.ietf.org/html/rfc7845#page-27 delay = opus.opus_int32() result = opus.opus_encoder_ctl( @@ -285,7 +285,7 @@ class OpusEncoder: delay_samples = delay.value return delay_samples - + # # Internal methods # diff --git a/sbapp/pyogg/opus_file.py b/sbapp/pyogg/opus_file.py index 123d98b..5fea830 100644 --- a/sbapp/pyogg/opus_file.py +++ b/sbapp/pyogg/opus_file.py @@ -14,7 +14,7 @@ class OpusFile(AudioFile): ctypes.pointer(error) ) - # Check for errors + # Check for errors if error.value != 0: raise PyOggError( ("File '{}' couldn't be opened or doesn't exist. "+ diff --git a/sbapp/pyogg/opus_file_stream.py b/sbapp/pyogg/opus_file_stream.py index c464fca..a012608 100644 --- a/sbapp/pyogg/opus_file_stream.py +++ b/sbapp/pyogg/opus_file_stream.py @@ -14,7 +14,7 @@ class OpusFileStream: An exception will be raised if the file cannot be opened correctly. - """ + """ error = ctypes.c_int() self.of = opus.op_open_file(ogg.to_char_p(path), ctypes.pointer(error)) diff --git a/sbapp/pyogg/vorbis.py b/sbapp/pyogg/vorbis.py index a8432ba..c57a648 100644 --- a/sbapp/pyogg/vorbis.py +++ b/sbapp/pyogg/vorbis.py @@ -180,7 +180,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: ("res_bits", ogg_int64_t), ("backend_state", c_void_p)] - + class alloc_chain(ctypes.Structure): """ Wrapper for: @@ -232,7 +232,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: ("comments", c_int), ("vendor", c_char_p)] - + vi_p = POINTER(vorbis_info) vc_p = POINTER(vorbis_comment) @@ -285,7 +285,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_comment_clear(vc) - + libvorbis.vorbis_block_init.restype = c_int libvorbis.vorbis_block_init.argtypes = [vd_p, vb_p] def vorbis_block_init(v,vb): @@ -307,7 +307,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: return libvorbis.vorbis_granule_time(v, granulepos) - + libvorbis.vorbis_version_string.restype = c_char_p libvorbis.vorbis_version_string.argtypes = [] def vorbis_version_string(): @@ -326,7 +326,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_commentheader_out.argtypes = [vc_p, op_p] def vorbis_commentheader_out(vc, op): return libvorbis.vorbis_commentheader_out(vc, op) - + libvorbis.vorbis_analysis_headerout.restype = c_int libvorbis.vorbis_analysis_headerout.argtypes = [vd_p, vc_p, op_p, op_p, op_p] def vorbis_analysis_headerout(v,vc, op, op_comm, op_code): @@ -346,7 +346,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_analysis_blockout.argtypes = [vd_p, vb_p] def vorbis_analysis_blockout(v, vb): return libvorbis.vorbis_analysis_blockout(v, vb) - + libvorbis.vorbis_analysis.restype = c_int libvorbis.vorbis_analysis.argtypes = [vb_p, op_p] def vorbis_analysis(vb, op): @@ -359,7 +359,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_bitrate_addblock.argtypes = [vb_p] def vorbis_bitrate_addblock(vb): return libvorbis.vorbis_bitrate_addblock(vb) - + libvorbis.vorbis_bitrate_flushpacket.restype = c_int libvorbis.vorbis_bitrate_flushpacket.argtypes = [vd_p, op_p] def vorbis_bitrate_flushpacket(vd, op): @@ -372,7 +372,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_synthesis_idheader.argtypes = [op_p] def vorbis_synthesis_idheader(op): return libvorbis.vorbis_synthesis_idheader(op) - + libvorbis.vorbis_synthesis_headerin.restype = c_int libvorbis.vorbis_synthesis_headerin.argtypes = [vi_p, vc_p, op_p] def vorbis_synthesis_headerin(vi, vc, op): @@ -400,7 +400,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_synthesis_trackonly.argtypes = [vb_p, op_p] def vorbis_synthesis_trackonly(vb, op): return libvorbis.vorbis_synthesis_trackonly(vb, op) - + libvorbis.vorbis_synthesis_blockin.restype = c_int libvorbis.vorbis_synthesis_blockin.argtypes = [vd_p, vb_p] def vorbis_synthesis_blockin(v, vb): @@ -410,7 +410,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_synthesis_pcmout.argtypes = [vd_p, c_float_p_p_p] def vorbis_synthesis_pcmout(v, pcm): return libvorbis.vorbis_synthesis_pcmout(v, pcm) - + libvorbis.vorbis_synthesis_lapout.restype = c_int libvorbis.vorbis_synthesis_lapout.argtypes = [vd_p, c_float_p_p_p] def vorbis_synthesis_lapout(v, pcm): @@ -420,7 +420,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_synthesis_read.argtypes = [vd_p, c_int] def vorbis_synthesis_read(v, samples): return libvorbis.vorbis_synthesis_read(v, samples) - + libvorbis.vorbis_packet_blocksize.restype = c_long libvorbis.vorbis_packet_blocksize.argtypes = [vi_p, op_p] def vorbis_packet_blocksize(vi, op): @@ -432,7 +432,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: libvorbis.vorbis_synthesis_halfrate.argtypes = [vi_p, c_int] def vorbis_synthesis_halfrate(v, flag): return libvorbis.vorbis_synthesis_halfrate(v, flag) - + libvorbis.vorbis_synthesis_halfrate_p.restype = c_int libvorbis.vorbis_synthesis_halfrate_p.argtypes = [vi_p] def vorbis_synthesis_halfrate_p(vi): @@ -483,7 +483,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: ("seek_func", seek_func), ("close_func", close_func), ("tell_func", tell_func)] - + NOTOPEN = 0 PARTOPEN = 1 OPENED = 2 @@ -768,10 +768,10 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL: try: # vorbisenc - + # Sanity check also satisfies mypy type checking assert libvorbisenc is not None - + libvorbisenc.vorbis_encode_init.restype = c_int libvorbisenc.vorbis_encode_init.argtypes = [vi_p, c_long, c_long, c_long, c_long, c_long] diff --git a/sbapp/pyogg/vorbis_file.py b/sbapp/pyogg/vorbis_file.py index dcb1d23..29a9ac7 100644 --- a/sbapp/pyogg/vorbis_file.py +++ b/sbapp/pyogg/vorbis_file.py @@ -22,7 +22,7 @@ class VorbisFile(AudioFile): bytes_per_sample: int = 2, signed:bool = True) -> None: """Load an OggVorbis File. - + path specifies the location of the Vorbis file. Unicode filenames may not work correctly under Windows. @@ -40,7 +40,7 @@ class VorbisFile(AudioFile): # Sanity check that the vorbis library is available (for mypy) assert vorbis.libvorbisfile is not None - + #: Bytes per sample self.bytes_per_sample = bytes_per_sample @@ -104,7 +104,7 @@ class VorbisFile(AudioFile): ) # Storage for the index of the logical bitstream - bitstream_previous = None + bitstream_previous = None bitstream = ctypes.c_int() # Set bytes remaining to read into PCM @@ -142,9 +142,9 @@ class VorbisFile(AudioFile): if bitstream_previous != bitstream: raise PyOggError( "PyOgg currently supports Vorbis files "+ - "with only one logical stream" + "with only one logical stream" ) - + # Check for end of file if result == 0: break @@ -154,7 +154,7 @@ class VorbisFile(AudioFile): # Update the pointer into the buffer buf_ptr.value += result - + # Close the file and clean up memory vorbis.libvorbisfile.ov_clear(ctypes.byref(vf)) diff --git a/sbapp/pyogg/vorbis_file_stream.py b/sbapp/pyogg/vorbis_file_stream.py index 61e50ee..5750e52 100644 --- a/sbapp/pyogg/vorbis_file_stream.py +++ b/sbapp/pyogg/vorbis_file_stream.py @@ -7,7 +7,7 @@ class VorbisFileStream: def __init__(self, path, buffer_size=8192): self.exists = False self._buffer_size = buffer_size - + self.vf = vorbis.OggVorbis_File() error = vorbis.ov_fopen(path, ctypes.byref(self.vf)) if error != 0: diff --git a/sbapp/services/sidebandservice.py b/sbapp/services/sidebandservice.py index 05203aa..d31e855 100644 --- a/sbapp/services/sidebandservice.py +++ b/sbapp/services/sidebandservice.py @@ -30,7 +30,7 @@ if RNS.vendor.platformutils.get_platform() == "android": from android import python_act android_api_version = autoclass('android.os.Build$VERSION').SDK_INT - + Intent = autoclass('android.content.Intent') BitmapFactory = autoclass('android.graphics.BitmapFactory') Icon = autoclass("android.graphics.drawable.Icon") @@ -63,7 +63,7 @@ class SidebandService(): 0x239A: [0x8029], # Adafruit (RAK4631) 0x303A: [0x1001], # ESP-32S3 } - + def android_notification(self, title="", content="", ticker="", group=None, context_id=None): if android_api_version < 26: return @@ -99,7 +99,7 @@ class SidebandService(): notification.setContentTitle(title) notification.setContentText(AndroidString(content)) notification.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) - + # if group != None: # notification.setGroup(group_id) @@ -140,9 +140,9 @@ class SidebandService(): except Exception as e: RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) - + return False - + else: return False @@ -184,7 +184,7 @@ class SidebandService(): if self.should_update_location(): if not self._gps_started: RNS.log("Starting service location provider", RNS.LOG_DEBUG) - + if self.gps == None: from plyer import gps self.gps = gps @@ -232,7 +232,7 @@ class SidebandService(): if RNS.vendor.platformutils.is_android(): self.android_service = autoclass('org.kivy.android.PythonService').mService self.app_context = self.android_service.getApplication().getApplicationContext() - + try: self.wifi_manager = self.app_context.getSystemService(Context.WIFI_SERVICE) except Exception as e: @@ -248,7 +248,7 @@ class SidebandService(): RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) self.discover_usb_devices() - + self.sideband = SidebandCore(self, is_service=True, android_app_dir=self.app_dir, verbose=__debug_build__, owner_service=self, service_context=self.android_service) if self.sideband.config["debug"]: @@ -257,7 +257,7 @@ class SidebandService(): self.sideband.start() self.update_connectivity_type() self.update_power_restrictions() - + if RNS.vendor.platformutils.is_android(): RNS.log(f"Discovered USB devices: {self.usb_devices)}", RNS.LOG_EXTREME) self.update_location_provider() @@ -282,7 +282,7 @@ class SidebandService(): except Exception as e: RNS.log(f"Could not list USB devices. The contained exception was: {e)}", RNS.LOG_ERROR) - + def start(self): self.should_run = True self.take_locks() @@ -334,7 +334,7 @@ class SidebandService(): is_controlling = True self.sideband.setpersistent("service.is_controlling_connectivity", is_controlling) - + def get_connectivity_status(self): if self.sideband.reticulum.is_connected_to_shared_instance: return "[size=22dp][b]Connectivity Status[/b][/size]\n\nSideband is connected via a shared Reticulum instance running on this system. Use the rnstatus utility to obtain full connectivity info." @@ -425,23 +425,23 @@ class SidebandService(): if self.sideband.interface_local != None: total_rxb += self.sideband.interface_local.rxb total_txb += self.sideband.interface_local.txb - + if self.sideband.interface_rnode != None: total_rxb += self.sideband.interface_rnode.rxb total_txb += self.sideband.interface_rnode.txb - + if self.sideband.interface_modem != None: total_rxb += self.sideband.interface_modem.rxb total_txb += self.sideband.interface_modem.txb - + if self.sideband.interface_serial != None: total_rxb += self.sideband.interface_serial.rxb total_txb += self.sideband.interface_serial.txb - + if self.sideband.interface_tcp != None: total_rxb += self.sideband.interface_tcp.rxb total_txb += self.sideband.interface_tcp.txb - + if self.sideband.interface_i2p != None: total_rxb += self.sideband.interface_i2p.rxb total_txb += self.sideband.interface_i2p.txb diff --git a/sbapp/share/pkgs.html b/sbapp/share/pkgs.html index 0ed8470..80d9710 100644 --- a/sbapp/share/pkgs.html +++ b/sbapp/share/pkgs.html @@ -42,7 +42,7 @@ var got_data = function(err, data) { for (e in data) { url = "/pkg/"+data[e]; name = data[e]; - + // create a new div element const listitem = document.createElement("li"); const anc = document.createElement("a") diff --git a/sbapp/sideband/audioproc.py b/sbapp/sideband/audioproc.py index 542773a..a46d6a7 100644 --- a/sbapp/sideband/audioproc.py +++ b/sbapp/sideband/audioproc.py @@ -37,14 +37,14 @@ def samples_from_ogg(file_path=None, output_rate=8000): audio = AudioSegment( bytes(opus_file.as_array()), frame_rate=opus_file.frequency, - sample_width=opus_file.bytes_per_sample, + sample_width=opus_file.bytes_per_sample, channels=opus_file.channels) audio = audio.split_to_mono()[0] audio = audio.apply_gain(-audio.max_dBFS) audio = audio.set_frame_rate(output_rate) audio = audio.set_sample_width(2) - + return audio.get_array_of_samples() def resample(samples, width, channels, input_rate, output_rate, normalize): @@ -80,12 +80,12 @@ def samples_to_ogg(samples=None, file_path=None, normalize=False, input_channels frame_duration = frame_duration_ms/1000.0 frame_size = int(frame_duration * samples_per_second) bytes_per_frame = frame_size*bytes_per_sample - + ogg_opus_writer.write(memoryview(bytearray(samples))) ogg_opus_writer.close() - + return True - + except Exception as e: RNS.trace_exception(e) return False @@ -153,7 +153,7 @@ def encode_codec2(samples, mode): N_FRAMES = math.floor(len(samples)/SPF) # TODO: Add padding to align to whole frames frames = np.array(samples[0:N_FRAMES*SPF], dtype=np.int16) - + encoded = b"" for pi in range(0, N_FRAMES): pstart = pi*SPF diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py index 237b649..a66e5ae 100644 --- a/sbapp/sideband/core.py +++ b/sbapp/sideband/core.py @@ -168,7 +168,7 @@ class SidebandCore(): self.app_dir = config_path self.cache_dir = f"{self.app_dir}/cache" - + self.rns_configdir = None if RNS.vendor.platformutils.is_android(): self.app_dir = f"{android_app_dir}/io.unsigned.sideband/files/" @@ -215,7 +215,7 @@ class SidebandCore(): self.tmp_dir = f"{self.app_dir}/app_storage/tmp" self.exports_dir = f"{self.app_dir}/exports" self.webshare_dir = "./share/" - + self.first_run = True self.saving_configuration = False self.last_lxmf_announce = 0 @@ -246,7 +246,7 @@ class SidebandCore(): if os.path.isdir(self.exports_dir): self.clear_exports_dir() - + except Exception as e: RNS.log(f"Error while configuring Sideband: {e)}", RNS.LOG_ERROR) @@ -275,7 +275,7 @@ class SidebandCore(): except Exception as e: RNS.log(f"Error while configuring Reticulum instance: {e)}", RNS.LOG_ERROR) - + else: pass @@ -423,7 +423,7 @@ class SidebandCore(): self.config["connect_ifmode_modem"] = "full" self.config["connect_ifmode_serial"] = "full" self.config["connect_ifmode_bluetooth"] = "full" - + # Hardware self.config["hw_rnode_frequency"] = None self.config["hw_rnode_modulation"] = "LoRa" @@ -470,7 +470,7 @@ class SidebandCore(): def clear_map_cache(self): for entry in os.scandir(self.map_cache): os.unlink(entry.path) - + def get_map_cache_size(self): total = 0 for entry in os.scandir(self.map_cache): @@ -624,7 +624,7 @@ class SidebandCore(): self.config["hw_modem_beaconinterval"] = None if not "hw_modem_beacondata" in self.config: self.config["hw_modem_beacondata"] = None - + if not "hw_serial_baudrate" in self.config: self.config["hw_serial_baudrate"] = 57600 if not "hw_serial_databits" in self.config: @@ -735,7 +735,7 @@ class SidebandCore(): self.config["map_use_online"] = True if not "map_layer" in self.config: self.config["map_layer"] = None - + if not "map_storage_path" in self.config: self.config["map_storage_path"] = None if not "map_storage_file" in self.config: @@ -791,7 +791,7 @@ class SidebandCore(): command_plugins_enabled = self.config["command_plugins_enabled"] == True service_plugins_enabled = self.config["service_plugins_enabled"] == True plugins_enabled = service_plugins_enabled - + if plugins_enabled: if plugins_path != None: RNS.log("Loading Sideband plugins...", RNS.LOG_DEBUG) @@ -806,7 +806,7 @@ class SidebandCore(): plugin_path = os.path.join(plugins_path, file) exec(open(plugin_path).read(), plugin_globals) plugin_class = plugin_globals["plugin_class"] - + if plugin_class != None: plugin = plugin_class(self) plugin.start() @@ -819,7 +819,7 @@ class SidebandCore(): RNS.log(f"Registered {plugin)} as handler for command \"{command_name)}\"", RNS.LOG_NOTICE) else: RNS.log(f"Could not register {plugin)} as handler for command \"{command_name)}\". Command name was already registered", RNS.LOG_ERROR) - + elif issubclass(type(plugin), SidebandServicePlugin): service_name = plugin.service_name if not service_name in self.active_service_plugins: @@ -874,7 +874,7 @@ class SidebandCore(): self.active_propagation_node = dest self.config["last_lxmf_propagation_node"] = dest self.message_router.set_outbound_propagation_node(dest) - + RNS.log(f"Active propagation node set to: {RNS.prettyhexrep(dest)}") self.__save_config() except Exception as e: @@ -887,7 +887,7 @@ class SidebandCore(): title = strip_emojis(title) content = strip_emojis(content) - + if self.config["notifications_on"]: if RNS.vendor.platformutils.is_android(): if self.getpersistent("permissions.notifications"): @@ -1033,7 +1033,7 @@ class SidebandCore(): return existing_conv["trust"] == 1 return self.requests_allowed_from(context_dest) - + except Exception as e: RNS.log(f"Error while checking request permissions for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False @@ -1226,7 +1226,7 @@ class SidebandCore(): if self.is_client: try: return self.service_rpc_request({"request_latest_telemetry": {"from_addr": from_addr}}) - + except Exception as e: RNS.log(f"Error while requesting latest telemetry over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) @@ -1244,7 +1244,7 @@ class SidebandCore(): RNS.trace_exception(e) return "not_sent" - else: + else: if from_addr == None or from_addr == self.lxmf_destination.hash: return "no_address" else: @@ -1254,7 +1254,7 @@ class SidebandCore(): if from_addr != None: dest_identity = RNS.Identity.recall(from_addr) - + if dest_identity == None: RNS.log(f"The identity for {RNS.prettyhexrep(from_addr)} could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG) RNS.Transport.request_path(from_addr) @@ -1264,7 +1264,7 @@ class SidebandCore(): now = time.time() dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") source = self.lxmf_destination - + if self.config["telemetry_use_propagation_only"] == True: desired_method = LXMF.LXMessage.PROPAGATED else: @@ -1335,7 +1335,7 @@ class SidebandCore(): if (self.latest_packed_telemetry != None and self.latest_telemetry != None) or stream != None: dest_identity = RNS.Identity.recall(to_addr) - + if dest_identity == None: RNS.log(f"The identity for {RNS.prettyhexrep(to_addr)} could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG) RNS.Transport.request_path(to_addr) @@ -1344,7 +1344,7 @@ class SidebandCore(): else: dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") source = self.lxmf_destination - + if self.config["telemetry_use_propagation_only"] == True: desired_method = LXMF.LXMessage.PROPAGATED else: @@ -1385,7 +1385,7 @@ class SidebandCore(): self.setstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending", True) self.message_router.handle_outbound(lxm) return "sent" - + else: RNS.log(f"Telemetry update with timebase {telemetry_timebase} was already successfully sent", RNS.LOG_DEBUG) return "already_sent" @@ -1695,7 +1695,7 @@ class SidebandCore(): RNS.log("Ready for next RPC client", RNS.LOG_DEBUG) rpc_connection = self.rpc_listener.accept() RNS.log("Accepted RPC client", RNS.LOG_DEBUG) - + def job_factory(connection): def rpc_client_job(): try: @@ -1876,7 +1876,7 @@ class SidebandCore(): try: db = self.__db_connect() dbc = db.cursor() - + query = "select * from persistent where property=:uprop" dbc.execute(query, {"uprop": prop.encode("utf-8")}) result = dbc.fetchall() @@ -1896,7 +1896,7 @@ class SidebandCore(): except Exception as e: RNS.log(f"Could not unpack persistent value from database for property \"{prop)}\". The contained exception was: {e)}", RNS.LOG_ERROR) return None - + except Exception as e: RNS.log(f"An error occurred during persistent getstate database operation: {e)}", RNS.LOG_ERROR) self.db = None @@ -1917,7 +1917,7 @@ class SidebandCore(): data = (uprop, bval) dbc.execute(query, data) db.commit() - + except Exception as e: RNS.log(f"Error while setting persistent state property {prop)} in DB: {e)}", RNS.LOG_ERROR) RNS.log("Retrying as update query...") @@ -1929,7 +1929,7 @@ class SidebandCore(): query = "UPDATE persistent set value=:bval where property=:uprop;" dbc.execute(query, {"bval": bval, "uprop": uprop}) db.commit() - + except Exception as e: RNS.log(f"An error occurred during persistent setstate database operation: {e)}", RNS.LOG_ERROR) self.db = None @@ -1958,7 +1958,7 @@ class SidebandCore(): try: db = self.__db_connect() dbc = db.cursor() - + if unread: if tx: query = "UPDATE conv set unread = ?, last_tx = ? where dest_context = ?" @@ -2003,7 +2003,7 @@ class SidebandCore(): query = query = "select * from telemetry" dbc.execute(query, {}) - else: + else: if after != None and before == None: query = f"select * from telemetry where dest_context=:context_dest and ts>:after_ts{order_part}" dbc.execute(query, {"context_dest": context_dest, "after_ts": after}) @@ -2027,12 +2027,12 @@ class SidebandCore(): telemetry_source = entry[1] telemetry_timestamp = entry[2] telemetry_data = entry[3] - + if not telemetry_source in results: results[telemetry_source] = [] results[telemetry_source].append([telemetry_timestamp, telemetry_data]) - + return results def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, source_dest = None, via = None, is_retry = False): @@ -2096,7 +2096,7 @@ class SidebandCore(): remote_telemeter.sensors["received"].via = via remote_telemeter.sensors["received"].update_data() telemetry = remote_telemeter.packed() - + query = "INSERT INTO telemetry (dest_context, ts, data) values (?, ?, ?)" data = (context_dest, telemetry_timestamp, telemetry) dbc.execute(query, data) @@ -2130,7 +2130,7 @@ class SidebandCore(): # TODO: Clean out these temporary values at some interval. # Probably expire after 14 days or so. self.setpersistent(f"temp.peer_appearance.{RNS.hexrep(context_dest, delimit=False)}", ae) - + else: with self.db_lock: data_dict = conv["data"] @@ -2147,10 +2147,10 @@ class SidebandCore(): if data_dict["appearance"] != appearance: data_dict["appearance"] = appearance packed_dict = msgpack.packb(data_dict) - + db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set data = ? where dest_context = ?" data = (packed_dict, context_dest) dbc.execute(query, data) @@ -2195,7 +2195,7 @@ class SidebandCore(): appearance = data_dict["appearance"] else: appearance = [data_dict["appearance"][0], htf(data_dict["appearance"][1]), htf(data_dict["appearance"][2])] - + return appearance except Exception as e: RNS.log(f"Could not retrieve appearance for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) @@ -2211,11 +2211,11 @@ class SidebandCore(): data_dict["telemetry"] = send_telemetry packed_dict = msgpack.packb(data_dict) - + with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set data = ? where dest_context = ?" data = (packed_dict, context_dest) dbc.execute(query, data) @@ -2238,11 +2238,11 @@ class SidebandCore(): data_dict["allow_requests"] = allow_requests packed_dict = msgpack.packb(data_dict) - + with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set data = ? where dest_context = ?" data = (packed_dict, context_dest) dbc.execute(query, data) @@ -2265,11 +2265,11 @@ class SidebandCore(): data_dict["is_object"] = is_object packed_dict = msgpack.packb(data_dict) - + with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set data = ? where dest_context = ?" data = (packed_dict, context_dest) dbc.execute(query, data) @@ -2292,11 +2292,11 @@ class SidebandCore(): data_dict["ptt_enabled"] = ptt_enabled packed_dict = msgpack.packb(data_dict) - + with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set data = ? where dest_context = ?" data = (packed_dict, context_dest) dbc.execute(query, data) @@ -2315,7 +2315,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set trust = ? where dest_context = ?" data = (trusted, context_dest) dbc.execute(query, data) @@ -2334,11 +2334,11 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE conv set name=:name_data where dest_context=:ctx;" dbc.execute(query, {"ctx": context_dest, "name_data": name.encode("utf-8")}) result = dbc.fetchall() - + try: db.commit() except Exception as e: @@ -2352,7 +2352,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + dbc.execute("select * from conv") result = dbc.fetchall() @@ -2397,7 +2397,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + dbc.execute("select * from announce order by received desc") result = dbc.fetchall() @@ -2429,7 +2429,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "select * from conv where dest_context=:ctx" dbc.execute(query, {"ctx": context_dest}) result = dbc.fetchall() @@ -2562,7 +2562,7 @@ class SidebandCore(): extras = msgpack.packb(msg_extras) query = "UPDATE lxm set state = ?, extra = ? where lxm_hash = ?" data = (state, extras, lxm_hash) - + else: query = "UPDATE lxm set state = ? where lxm_hash = ?" data = (state, lxm_hash) @@ -2583,7 +2583,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "UPDATE lxm set method = ? where lxm_hash = ?" data = (method, lxm_hash) dbc.execute(query, data) @@ -2605,7 +2605,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "select * from lxm where lxm_hash=:mhash" dbc.execute(query, {"mhash": msg_hash}) result = dbc.fetchall() @@ -2653,7 +2653,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + query = "select count(*) from lxm where dest=:context_dest or source=:context_dest" dbc.execute(query, {"context_dest": context_dest}) @@ -2668,7 +2668,7 @@ class SidebandCore(): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + if after != None and before == None: query = "select * from lxm where (dest=:context_dest or source=:context_dest) and rx_ts>:after_ts" dbc.execute(query, {"context_dest": context_dest, "after_ts": after}) @@ -2698,7 +2698,7 @@ class SidebandCore(): packed_lxm = entry[10] lxm = LXMF.LXMessage.unpack_from_bytes(packed_lxm, original_method = lxm_method) - + if lxm.desired_method == LXMF.LXMessage.PAPER: lxm.paper_packed = paper_packed_lxm @@ -2707,7 +2707,7 @@ class SidebandCore(): extras = msgpack.unpackb(entry[11]) except: pass - + message = { "hash": lxm.hash, "dest": lxm.destination_hash, @@ -2868,13 +2868,13 @@ class SidebandCore(): self.next_auto_announce = time.time() + 60*(random.random()*(SidebandCore.AUTO_ANNOUNCE_RANDOM_MAX-SidebandCore.AUTO_ANNOUNCE_RANDOM_MIN)+SidebandCore.AUTO_ANNOUNCE_RANDOM_MIN) RNS.log(f"Next auto announce in {RNS.prettytime(self.next_auto_announce - time.time())}", RNS.LOG_DEBUG) self.setstate("wants.announce", False) - + else: if self.config["lxmf_require_stamps"]: self.message_router.set_inbound_stamp_cost(self.lxmf_destination.hash, self.config["lxmf_inbound_stamp_cost"]) else: self.message_router.set_inbound_stamp_cost(self.lxmf_destination.hash, None) - + self.setstate("wants.announce", True) def run_telemetry(self): @@ -3000,7 +3000,7 @@ class SidebandCore(): except Exception as e: RNS.log(f"An error occurred while {telemetry_plugin)} was handling telemetry. The contained exception was: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) - + if self.config["telemetry_s_fixed_location"]: self.telemeter.synthesize("location") self.telemeter.sensors["location"].latitude = self.config["telemetry_s_fixed_latlon"][0] @@ -3071,7 +3071,7 @@ class SidebandCore(): if self.message_router.delivery_per_transfer_limit != lxm_limit: self.message_router.delivery_per_transfer_limit = lxm_limit RNS.log(f"Updated delivery limit to {RNS.prettysize(self.message_router.delivery_per_transfer_limit * 1000)}", RNS.LOG_DEBUG) - + except Exception as e: RNS.log(f"Error while updating LXMF router delivery limit: {e)}", RNS.LOG_ERROR) @@ -3213,7 +3213,7 @@ class SidebandCore(): else: RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR) self.setstate("executing.bt_on", False) - + if self.getstate("wants.bt_off"): self.setstate("wants.bt_off", False) self.owner_app.discover_usb_devices() @@ -3228,7 +3228,7 @@ class SidebandCore(): else: RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR) self.setstate("executing.bt_off", False) - + if self.getstate("wants.bt_pair"): self.setstate("wants.bt_pair", False) self.owner_app.discover_usb_devices() @@ -3379,7 +3379,7 @@ class SidebandCore(): self.service_thread = threading.Thread(target=self._service_jobs, daemon=True) self.service_thread.start() - if self.is_standalone or self.is_service: + if self.is_standalone or self.is_service: if self.config["start_announce"]: def da(): time.sleep(8) @@ -3437,7 +3437,7 @@ class SidebandCore(): if_mode = Interface.Interface.MODE_BOUNDARY else: if_mode = None - + self.reticulum._add_interface(autointerface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.interface_local = autointerface self.interface_local_adding = False @@ -3464,7 +3464,7 @@ class SidebandCore(): target_port = target_device["port"] else: target_port = None - + bt_device_name = None rnode_allow_bluetooth = False rnode_allow_ble = False @@ -3563,7 +3563,7 @@ class SidebandCore(): if_mode = Interface.Interface.MODE_BOUNDARY else: if_mode = None - + self.reticulum._add_interface(rnodeinterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.interface_rnode = rnodeinterface self.interface_rnode_adding = False @@ -3622,7 +3622,7 @@ class SidebandCore(): if not self.reticulum.is_connected_to_shared_instance: RNS.log("Running as master or standalone instance, adding interfaces") - + self.interface_local = None self.interface_tcp = None self.interface_i2p = None @@ -3682,7 +3682,7 @@ class SidebandCore(): if_mode = Interface.Interface.MODE_BOUNDARY else: if_mode = None - + self.reticulum._add_interface(tcpinterface, mode=if_mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, ifac_size=ifac_size) self.interface_tcp = tcpinterface @@ -3733,9 +3733,9 @@ class SidebandCore(): if_mode = Interface.Interface.MODE_BOUNDARY else: if_mode = None - + self.reticulum._add_interface(i2pinterface, mode = if_mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, ifac_size=ifac_size) - + for si in RNS.Transport.interfaces: if type(si) == RNS.Interfaces.I2PInterface.I2PInterfacePeer: self.interface_i2p = si @@ -3794,7 +3794,7 @@ class SidebandCore(): if_mode = Interface.Interface.MODE_BOUNDARY else: if_mode = None - + self.reticulum._add_interface(serialinterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.interface_serial = serialinterface @@ -3854,7 +3854,7 @@ class SidebandCore(): if_mode = Interface.Interface.MODE_BOUNDARY else: if_mode = None - + self.reticulum._add_interface(modeminterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.interface_modem = modeminterface @@ -3864,7 +3864,7 @@ class SidebandCore(): RNS.log("Reticulum started, activating LXMF...") self.setstate("init.loadingstate", "Activating LXMF Router") - + if self.config["lxm_limit_1mb"]: lxm_limit = 1000 else: @@ -3882,7 +3882,7 @@ class SidebandCore(): self.message_router.enforce_stamps() else: self.message_router.ignore_stamps() - + # TODO: Update to announce call in LXMF when full 0.5.0 support is added (get app data from LXMRouter instead) # Currently overrides the LXMF routers auto-generated announce data so that Sideband will announce old-format # LXMF announces if require_stamps is disabled. @@ -3990,7 +3990,7 @@ class SidebandCore(): dest_identity = RNS.Identity.recall(destination_hash) dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") source = self.lxmf_destination - + desired_method = LXMF.LXMessage.PAPER # TODO: Should paper messages also include a ticket to trusted peers? lxm = LXMF.LXMessage(dest, source, content, title="", desired_method=desired_method, fields = self.get_message_fields(destination_hash), include_ticket=self.is_trusted(destination_hash)) @@ -4010,7 +4010,7 @@ class SidebandCore(): if self.is_client: try: return self.service_rpc_request({"get_lxm_progress": {"lxm_hash": lxm_hash}}) - + except Exception as e: RNS.log(f"Error while getting LXM progress over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) @@ -4053,7 +4053,7 @@ class SidebandCore(): "image": image, "audio": audio} }) - + except Exception as e: RNS.log(f"Error while sending message over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) @@ -4098,7 +4098,7 @@ class SidebandCore(): dest_identity = RNS.Identity.recall(destination_hash) dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") source = self.lxmf_destination - + if propagation: desired_method = LXMF.LXMessage.PROPAGATED else: @@ -4121,7 +4121,7 @@ class SidebandCore(): fields[LXMF.FIELD_AUDIO] = audio lxm = LXMF.LXMessage(dest, source, content, title="", desired_method=desired_method, fields = fields, include_ticket=self.is_trusted(destination_hash)) - + if not no_display: lxm.register_delivery_callback(self.message_notification) lxm.register_failed_callback(self.message_notification) @@ -4178,7 +4178,7 @@ class SidebandCore(): dest_identity = RNS.Identity.recall(destination_hash) dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") source = self.lxmf_destination - + if propagation: desired_method = LXMF.LXMessage.PROPAGATED else: @@ -4240,13 +4240,13 @@ class SidebandCore(): if ingest_result == False: response = "The URI contained no decodable messages" - + elif ingest_result == local_delivery_signal: response = "Message was decoded, decrypted successfully, and added to your conversation list." elif ingest_result == duplicate_signal: response = "The decoded message has already been processed by the LXMF Router, and will not be ingested again." - + else: # TODO: Add message to sneakernet queues response = "The decoded message was not addressed to your LXMF address, and has been discarded." @@ -4382,7 +4382,7 @@ class SidebandCore(): elif audio_field[0] >= LXMF.AM_CODEC2_700C and audio_field[0] <= LXMF.AM_CODEC2_3200: temp_path = f"{self.rec_cache}/msg.ogg" from sideband.audioproc import samples_to_ogg, decode_codec2, detect_codec2 - + target_rate = 8000 if RNS.vendor.platformutils.is_linux(): target_rate = 48000 @@ -4395,7 +4395,7 @@ class SidebandCore(): else: self.last_msg_audio = None return - + else: # Unimplemented audio type pass @@ -4598,16 +4598,16 @@ class SidebandCore(): else: RNS.log("Responding with own latest telemetry", RNS.LOG_DEBUG) self.send_latest_telemetry(to_addr=context_dest) - + elif Commands.PING in command: RNS.log("Handling ping request", RNS.LOG_DEBUG) self.send_message("Ping reply", context_dest, False, skip_fields=True, no_display=True) - + elif Commands.ECHO in command: msg_content = f"Echo reply: {command[Commands.ECHO].decode('utf-8')}" RNS.log("Handling echo request", RNS.LOG_DEBUG) self.send_message(msg_content, context_dest, False, skip_fields=True, no_display=True) - + elif Commands.SIGNAL_REPORT in command: RNS.log("Handling signal report", RNS.LOG_DEBUG) phy_str = "" diff --git a/sbapp/sideband/geo.py b/sbapp/sideband/geo.py index 3c423e1..2992439 100644 --- a/sbapp/sideband/geo.py +++ b/sbapp/sideband/geo.py @@ -139,12 +139,12 @@ def ellipsoid_distance(c1, c2): sin_sigma = t**0.5 cos_sigma = sin(U1)*sin(U2) + cos(U1)*cos(U2)*cos(lambda_old) sigma = atan2(sin_sigma, cos_sigma) - + sin_alpha = cos(U1)*cos(U2)*sin(lambda_old) / sin_sigma cos_sq_alpha = 1 - sin_alpha**2 cos_2sigma_m = cos_sigma - 2*sin(U1)*sin(U2)/cos_sq_alpha C = f*cos_sq_alpha*(4 + f*(4-3*cos_sq_alpha))/16 - + t = sigma + C*sin_sigma*(cos_2sigma_m + C*cos_sigma*(-1 + 2*cos_2sigma_m**2)) lambda_new = L + (1 - C)*f*sin_alpha*t if abs(lambda_new - lambda_old) <= tolerance: @@ -155,7 +155,7 @@ def ellipsoid_distance(c1, c2): if iteration%1000 == 0: if iteration >= max_iterations: return None - + if time.time() > st+timeout: return None @@ -171,7 +171,7 @@ def ellipsoid_distance(c1, c2): except Exception as e: return None -def azalt(c1, c2, ellipsoid=True): +def azalt(c1, c2, ellipsoid=True): c2rp = rotate_globe(c1, c2, ellipsoid=ellipsoid) altitude = None azimuth = None @@ -280,7 +280,7 @@ def radio_horizon(h, rh=0, ellipsoid=False): def shared_radio_horizon(c1, c2,): lat1 = c1[0]; lon1 = c1[1]; h1 = c1[2] lat2 = c2[0]; lon2 = c2[1]; h2 = c2[2] - + geodesic_distance = orthodromic_distance((lat1, lon1, 0.0), (lat2, lon2, 0.0) , ellipsoid=False) antenna_distance = euclidian_distance(c1,c2,ellipsoid=False) rh1 = radio_horizon(h1) @@ -532,7 +532,7 @@ class GeoidHeight: # us = time.time() # ld = c1+c2; g = geod.Inverse(c1[0], c1[1], c2[0], c2[1]) # print("Lib computed in "+str(round((time.time()-us)*1e6, 3))+"us") -# us = time.time() +# us = time.time() # eld = orthodromic_distance(c1,c2,ellipsoid=True) # if eld: # print("Own computed in "+str(round((time.time()-us)*1e6, 3))+"us") diff --git a/sbapp/sideband/res.py b/sbapp/sideband/res.py index 5c52855..fbc1404 100644 --- a/sbapp/sideband/res.py +++ b/sbapp/sideband/res.py @@ -1,34 +1,34 @@ sideband_fb_data = [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x07, 0xfc, 0x00, - 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x03, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0x00, - 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x80, - 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xc0, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, - 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, - 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x1f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xf8, - 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xf8, - 0x3f, 0xff, 0xff, 0xc0, 0x20, 0x03, 0xff, 0xfc, 0x3f, 0xf8, 0x3f, 0x80, 0xf0, 0x07, 0xff, 0xfc, - 0x3f, 0xe0, 0x0f, 0x01, 0xfc, 0x1f, 0xff, 0xfc, 0x7f, 0xc0, 0x04, 0x07, 0xfe, 0x3f, 0xff, 0xfe, - 0x7f, 0x80, 0x00, 0x0f, 0xfe, 0x3f, 0xff, 0xfe, 0x7f, 0x00, 0x00, 0x3f, 0xfe, 0x3f, 0xff, 0xfe, - 0x7f, 0x00, 0x00, 0x7f, 0xfe, 0x3f, 0xff, 0xfe, 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, - 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, - 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, - 0x7f, 0x00, 0x01, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7f, 0x00, 0x01, 0xff, 0xfe, 0x3f, 0xff, 0xfe, - 0x7f, 0x80, 0x03, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7f, 0xc0, 0x07, 0xff, 0xfe, 0x3f, 0xff, 0xfe, - 0x7f, 0xe0, 0x0f, 0xff, 0xfc, 0x1f, 0xff, 0xfe, 0x3f, 0xf8, 0x3f, 0xff, 0xf0, 0x07, 0xff, 0xfc, - 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xfc, - 0x3f, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xf8, - 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, - 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, - 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xc0, - 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x07, 0xfe, 0x00, - 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x1f, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, - 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, + 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x07, 0xfc, 0x00, + 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x03, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0x00, + 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x80, + 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xc0, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, + 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, + 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x1f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xf8, + 0x3f, 0xff, 0xff, 0xc0, 0x20, 0x03, 0xff, 0xfc, 0x3f, 0xf8, 0x3f, 0x80, 0xf0, 0x07, 0xff, 0xfc, + 0x3f, 0xe0, 0x0f, 0x01, 0xfc, 0x1f, 0xff, 0xfc, 0x7f, 0xc0, 0x04, 0x07, 0xfe, 0x3f, 0xff, 0xfe, + 0x7f, 0x80, 0x00, 0x0f, 0xfe, 0x3f, 0xff, 0xfe, 0x7f, 0x00, 0x00, 0x3f, 0xfe, 0x3f, 0xff, 0xfe, + 0x7f, 0x00, 0x00, 0x7f, 0xfe, 0x3f, 0xff, 0xfe, 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, + 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, + 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7e, 0x00, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xfe, + 0x7f, 0x00, 0x01, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7f, 0x00, 0x01, 0xff, 0xfe, 0x3f, 0xff, 0xfe, + 0x7f, 0x80, 0x03, 0xff, 0xfe, 0x3f, 0xff, 0xfe, 0x7f, 0xc0, 0x07, 0xff, 0xfe, 0x3f, 0xff, 0xfe, + 0x7f, 0xe0, 0x0f, 0xff, 0xfc, 0x1f, 0xff, 0xfe, 0x3f, 0xf8, 0x3f, 0xff, 0xf0, 0x07, 0xff, 0xfc, + 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xfc, + 0x3f, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, + 0x0f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xf0, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, + 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xe0, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xc0, + 0x01, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x07, 0xfe, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x1f, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, + 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] \ No newline at end of file diff --git a/sbapp/sideband/sense.py b/sbapp/sideband/sense.py index 6c567e6..78ea57f 100644 --- a/sbapp/sideband/sense.py +++ b/sbapp/sideband/sense.py @@ -93,7 +93,7 @@ class Telemeter(): self.sensors[sensor]._telemeter = self if not self.sensors[sensor].active: self.sensors[sensor].start() - + def disable(self, sensor): if not self.from_packed: if sensor in self.available: @@ -159,9 +159,9 @@ class Telemeter(): except Exception as e: RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) - + return False - + else: from android.permissions import check_permission return check_permission(f"android.permission.{permission}") @@ -440,7 +440,7 @@ class Battery(Sensor): if RNS.vendor.platformutils.is_android(): from plyer import battery self.battery = battery - + elif RNS.vendor.platformutils.is_linux(): node_exists = False bn = 0 @@ -467,7 +467,7 @@ class Battery(Sensor): self.battery.get_state() b = self.battery.status self.data = {"charge_percent": b["percentage"], "charging": b["isCharging"], "temperature": None} - + elif RNS.vendor.platformutils.is_linux(): if self.battery_node_name: status = {"isCharging": None, "percentage": None} @@ -486,7 +486,7 @@ class Battery(Sensor): is_charging = output['POWER_SUPPLY_STATUS'] == 'Charging' charge_percent = float(output['POWER_SUPPLY_CAPACITY']) self.data = {"charge_percent": round(charge_percent, 1), "charging": is_charging, "temperature": None} - + except: self.data = None @@ -515,7 +515,7 @@ class Battery(Sensor): def render(self, relative_to=None): if self.data == None: return None - + d = self.data p = d["charge_percent"] t = d["temperature"] @@ -580,7 +580,7 @@ class Pressure(Sensor): try: if RNS.vendor.platformutils.is_android(): self.data = {"mbar": round(self.android_sensor.pressure, 2)} - + except: self.data = None @@ -623,7 +623,7 @@ class Pressure(Sensor): class Location(Sensor): SID = Sensor.SID_LOCATION - + STALE_TIME = 15 MIN_DISTANCE = 4 ACCURACY_TARGET = 250 @@ -679,11 +679,11 @@ class Location(Sensor): self._location_provider = self self.update_data() - + def teardown_sensor(self): if RNS.vendor.platformutils.is_android(): self.gps.stop() - + self.latitude = None self.longitude = None self.altitude = None @@ -764,7 +764,7 @@ class Location(Sensor): "accuracy": round(self.accuracy, 2), "last_update": int(self._last_update), } - + except: self.data = None @@ -816,7 +816,7 @@ class Location(Sensor): coords = (self.data["latitude"], self.data["longitude"], aamsl) obj_ath = angle_to_horizon(coords) obj_rh = radio_horizon(aamsl) - + rendered = { "icon": "map-marker", "name": "Location", @@ -856,7 +856,7 @@ class Location(Sensor): above_horizon = True else: above_horizon = False - + srh = shared_radio_horizon(cs, cr) if salt != None and alt != None: dalt = salt-alt @@ -917,7 +917,7 @@ class PhysicalLink(Sensor): def render(self, relative_to=None): if self.data == None: return None - + q = self.data["q"] rendered = { "icon": "network-strength-outline", @@ -956,7 +956,7 @@ class Temperature(Sensor): try: if RNS.vendor.platformutils.is_android(): self.data = {"c": round(self.android_sensor.temperature, 2)} - + except: self.data = None @@ -1012,7 +1012,7 @@ class Humidity(Sensor): try: if RNS.vendor.platformutils.is_android(): self.data = {"percent_relative": round(self.android_sensor.tell, 2)} - + except: self.data = None @@ -1035,7 +1035,7 @@ class Humidity(Sensor): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "water-percent", "name": "Relative Humidity", @@ -1069,7 +1069,7 @@ class MagneticField(Sensor): if RNS.vendor.platformutils.is_android(): vectors = self.android_sensor.field self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} - + except: self.data = None @@ -1092,7 +1092,7 @@ class MagneticField(Sensor): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "magnet", "name": "Magnetic Field", @@ -1125,7 +1125,7 @@ class AmbientLight(Sensor): try: if RNS.vendor.platformutils.is_android(): self.data = {"lux": round(self.android_sensor.illumination, 2)} - + except: self.data = None @@ -1155,7 +1155,7 @@ class AmbientLight(Sensor): if rs.data != None and "lux" in rs.data and rs.data["lux"] != None: if self.data["lux"] != None: delta = round(rs.data["lux"] - self.data["lux"], 2) - + rendered = { "icon": "white-balance-sunny", "name": "Ambient Light", @@ -1192,7 +1192,7 @@ class Gravity(Sensor): if RNS.vendor.platformutils.is_android(): vectors = self.android_sensor.gravity self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} - + except: self.data = None @@ -1215,7 +1215,7 @@ class Gravity(Sensor): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "arrow-down-thin-circle-outline", "name": "Gravity", @@ -1249,7 +1249,7 @@ class AngularVelocity(Sensor): if RNS.vendor.platformutils.is_android(): vectors = self.android_sensor.rotation self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} - + except: self.data = None @@ -1272,7 +1272,7 @@ class AngularVelocity(Sensor): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "orbit", "name": "Angular Velocity", @@ -1306,7 +1306,7 @@ class Acceleration(Sensor): if RNS.vendor.platformutils.is_android(): vectors = self.android_sensor.acceleration self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} - + except: self.data = None @@ -1351,7 +1351,7 @@ class Proximity(Sensor): try: if RNS.vendor.platformutils.is_android(): self.data = self.android_sensor.proximity - + except: self.data = None @@ -1374,7 +1374,7 @@ class Proximity(Sensor): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "signal-distance-variant", "name": "Proximity", @@ -1439,7 +1439,7 @@ class PowerConsumption(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1454,7 +1454,7 @@ class PowerConsumption(Sensor): else: label = type_label consumers.append({"label": label, "w": self.data[type_label][0], "custom_icon": self.data[type_label][1]}) - + rendered = { "icon": "power-plug-outline", "name": "Power Consumption", @@ -1520,7 +1520,7 @@ class PowerProduction(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1535,7 +1535,7 @@ class PowerProduction(Sensor): else: label = type_label producers.append({"label": label, "w": self.data[type_label][0], "custom_icon": self.data[type_label][1]}) - + rendered = { "icon": "lightning-bolt", "name": "Power Production", @@ -1601,7 +1601,7 @@ class Processor(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1621,7 +1621,7 @@ class Processor(Sensor): "load_avgs": self.data[type_label][1], "clock": self.data[type_label][2], }) - + rendered = { "icon": "chip", "name": "Processor", @@ -1687,7 +1687,7 @@ class RandomAccessMemory(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1708,7 +1708,7 @@ class RandomAccessMemory(Sensor): "free": self.data[type_label][0]-self.data[type_label][1], "percent": (self.data[type_label][1]/self.data[type_label][0])*100, }) - + rendered = { "icon": "memory", "name": "Random Access Memory", @@ -1774,7 +1774,7 @@ class NonVolatileMemory(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1795,7 +1795,7 @@ class NonVolatileMemory(Sensor): "free": self.data[type_label][0]-self.data[type_label][1], "percent": (self.data[type_label][1]/self.data[type_label][0])*100, }) - + rendered = { "icon": "harddisk", "name": "Non-Volatile Memory", @@ -1861,7 +1861,7 @@ class Custom(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1880,7 +1880,7 @@ class Custom(Sensor): "value": self.data[type_label][0], "custom_icon": self.data[type_label][1], }) - + rendered = { "icon": "ruler", "name": "Custom", @@ -1950,7 +1950,7 @@ class Tank(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1974,7 +1974,7 @@ class Tank(Sensor): "percent": (self.data[type_label][1]/self.data[type_label][0])*100, "custom_icon": self.data[type_label][3], }) - + rendered = { "icon": "storage-tank", "name": "Tank", @@ -2043,7 +2043,7 @@ class Fuel(Sensor): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -2067,7 +2067,7 @@ class Fuel(Sensor): "percent": (self.data[type_label][1]/self.data[type_label][0])*100, "custom_icon": self.data[type_label][3], }) - + rendered = { "icon": "fuel", "name": "Fuel", diff --git a/sbapp/ui/announces.py b/sbapp/ui/announces.py index b021988..c9fc458 100644 --- a/sbapp/ui/announces.py +++ b/sbapp/ui/announces.py @@ -73,7 +73,7 @@ class Announces(): for item in self.list.children: if not item.sb_uid in (a["dest"] for a in self.announces): remove_widgets.append(item) - + else: for announce in self.announces: if announce["dest"] == item.sb_uid: @@ -103,7 +103,7 @@ class Announces(): name = multilingual_markup(escape_markup(str(name)).encode("utf-8")).decode("utf-8") cost = str(cost) def x(sender): - yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) + yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) if dtype == "lxmf.delivery": ad_text = f"[size=22dp]LXMF Peer[/size]\n\n[b]Received[/b] {ts}\n[b]Address[/b] {RNS.prettyhexrep(dest)}\n[b]Name[/b] {name}\n[b]Stamp Cost[/b] {cost}" @@ -235,7 +235,7 @@ class Announces(): dm_items = [] item.iconr = IconRightWidget(icon="dots-vertical"); - + item.dmenu = MDDropdownMenu( caller=item.iconr, items=dm_items, @@ -253,7 +253,7 @@ class Announces(): item.iconr.bind(on_release=callback_factory(item)) item.add_widget(item.iconr) - + self.added_item_dests.append(context_dest) self.list.add_widget(item, index=len(self.list.children)) @@ -263,7 +263,7 @@ class Announces(): layout_announces_screen = """ MDScreen: name: "announces_screen" - + BoxLayout: orientation: "vertical" diff --git a/sbapp/ui/conversations.py b/sbapp/ui/conversations.py index 0f38b62..e568646 100644 --- a/sbapp/ui/conversations.py +++ b/sbapp/ui/conversations.py @@ -51,7 +51,7 @@ class Conversations(): self.screen.app = self.app self.ids = self.screen.ids self.app.root.ids.screen_manager.add_widget(self.screen) - + self.conversation_dropdown = None self.delete_dialog = None self.clear_dialog = None @@ -73,9 +73,9 @@ class Conversations(): def update(self): # if self.app.sideband.getstate("app.flags.unread_conversations"): # self.clear_list() - + self.context_dests = self.app.sideband.list_conversations(conversations=self.app.include_conversations, objects=self.app.include_objects) - + view_title = "Conversations" if self.app.include_conversations: if self.app.include_objects: @@ -104,7 +104,7 @@ class Conversations(): trust_icon = "email" else: trust_icon = appearance[0] or da[0]; - + else: if self.app.sideband.requests_allowed_from(context_dest): if unread: @@ -183,7 +183,7 @@ class Conversations(): for w in remove_widgets: self.list.remove_widget(w) - + for conv in self.context_dests: context_dest = conv["dest"] unread = conv["unread"] @@ -447,7 +447,7 @@ class Conversations(): item.add_widget(item.iconr) item.trusted = self.app.sideband.is_trusted(context_dest, conv_data=existing_conv) - + self.added_item_dests.append(context_dest) self.list.add_widget(item) @@ -487,7 +487,7 @@ class Conversations(): conv_screen_kv = """ MDScreen: name: "conversations_screen" - + BoxLayout: orientation: "vertical" diff --git a/sbapp/ui/helpers.py b/sbapp/ui/helpers.py index 93cc6ce..2e6553d 100644 --- a/sbapp/ui/helpers.py +++ b/sbapp/ui/helpers.py @@ -72,7 +72,7 @@ def multilingual_markup(data): match = True if rfont != mapped_font: rfont = mapped_font - switch = True + switch = True break if (not match) and rfont != "default": diff --git a/sbapp/ui/layouts.py b/sbapp/ui/layouts.py index 6a466f0..1b8108b 100644 --- a/sbapp/ui/layouts.py +++ b/sbapp/ui/layouts.py @@ -12,7 +12,7 @@ MDNavigationLayout: MDScreen: name: "starting_screen" - + AnchorLayout: padding: [dp(0), dp(72), dp(0), dp(0)] anchor_x: "center" @@ -49,141 +49,141 @@ MDNavigationLayout: id: nav_scrollview DrawerList: id: md_list - + MDList: OneLineIconListItem: text: "Conversations" on_release: root.ids.screen_manager.app.conversations_action(self) # _no_ripple_effect: True - + IconLeftWidget: icon: "comment-text-multiple" on_release: root.ids.screen_manager.app.conversations_action(self) - + OneLineIconListItem: text: "Objects & Devices" on_release: root.ids.screen_manager.app.objects_action(self) # _no_ripple_effect: True - + IconLeftWidget: icon: "devices" on_release: root.ids.screen_manager.app.objects_action(self) - + OneLineIconListItem: text: "Situation Map" on_release: root.ids.screen_manager.app.map_action(self) - + IconLeftWidget: icon: "map" on_release: root.ids.screen_manager.app.map_action(self) - + OneLineIconListItem: text: "Announce Stream" on_release: root.ids.screen_manager.app.announces_action(self) - + IconLeftWidget: icon: "account-voice" on_release: root.ids.screen_manager.app.announces_action(self) - + # OneLineIconListItem: # text: "Local Broadcasts" # on_release: root.ids.screen_manager.app.broadcasts_action(self) - + # IconLeftWidget: # icon: "radio-tower" # on_release: root.ids.screen_manager.app.broadcasts_action(self) - + OneLineIconListItem: text: "Telemetry" on_release: root.ids.screen_manager.app.telemetry_action(self) - + IconLeftWidget: icon: "map-marker-path" on_release: root.ids.screen_manager.app.telemetry_action(self) - + OneLineIconListItem: text: "Preferences" on_release: root.ids.screen_manager.app.settings_action(self) - + IconLeftWidget: icon: "cog" on_release: root.ids.screen_manager.app.settings_action(self) - + OneLineIconListItem: text: "Connectivity" on_release: root.ids.screen_manager.app.connectivity_action(self) - + IconLeftWidget: icon: "wifi" on_release: root.ids.screen_manager.app.connectivity_action(self) - + OneLineIconListItem: text: "Hardware" on_release: root.ids.screen_manager.app.hardware_action(self) - + IconLeftWidget: icon: "router-wireless" on_release: root.ids.screen_manager.app.hardware_action(self) - + OneLineIconListItem: text: "Encryption Keys" on_release: root.ids.screen_manager.app.keys_action(self) - + IconLeftWidget: icon: "key-chain" on_release: root.ids.screen_manager.app.keys_action(self) - + OneLineIconListItem: text: "Plugins" on_release: root.ids.screen_manager.app.plugins_action(self) - + IconLeftWidget: icon: "google-circles-extended" on_release: root.ids.screen_manager.app.keys_action(self) - + OneLineIconListItem: text: "Guide" on_release: root.ids.screen_manager.app.guide_action(self) - + IconLeftWidget: icon: "book-open" on_release: root.ids.screen_manager.app.guide_action(self) - + OneLineIconListItem: text: "Repository" on_release: root.ids.screen_manager.app.repository_action(self) - + IconLeftWidget: icon: "book-multiple" on_release: root.ids.screen_manager.app.guide_action(self) - + OneLineIconListItem: id: app_version_info text: "" on_release: root.ids.screen_manager.app.information_action(self) - + IconLeftWidget: icon: "information" on_release: root.ids.screen_manager.app.information_action(self) - + OneLineIconListItem: text: "Shutdown" on_release: root.ids.screen_manager.app.quit_action(self) - + IconLeftWidget: icon: "power" on_release: root.ids.screen_manager.app.quit_action(self) @@ -193,7 +193,7 @@ MDNavigationLayout: layout_broadcasts_screen = """ MDScreen: name: "broadcasts_screen" - + BoxLayout: orientation: "vertical" @@ -230,7 +230,7 @@ MDScreen: layout_exit_screen = """ MDScreen: name: "exit_screen" - + AnchorLayout: padding: [dp(0), dp(72), dp(0), dp(0)] anchor_x: "center" @@ -262,7 +262,7 @@ MDScreen: layout_loader_screen = """ MDScreen: name: "loader_screen" - + BoxLayout: orientation: "vertical" @@ -295,7 +295,7 @@ MDScreen: layout_connectivity_screen = """ MDScreen: name: "connectivity_screen" - + BoxLayout: orientation: "vertical" @@ -337,7 +337,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_local_label text: "Connect via local WiFi/Ethernet" @@ -380,7 +380,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_tcp_label text: "Connect via TCP" @@ -429,7 +429,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_i2p_label text: "Connect via I2P" @@ -472,7 +472,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_rnode_label text: "Connect via RNode" @@ -510,7 +510,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_modem_label text: "Connect via Radio Modem" @@ -548,7 +548,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_serial_label text: "Connect via Serial Port" @@ -586,7 +586,7 @@ MDScreen: # padding: [0,0,dp(24),0] # size_hint_y: None # height: dp(24) - + # MDLabel: # id: connectivity_bluetooth_label # text: "Connect via Bluetooth" @@ -648,7 +648,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(24) - + MDLabel: id: connectivity_transport_label text: "Enable Reticulum Transport" @@ -751,7 +751,7 @@ MDScreen: layout_guide_screen = """ MDScreen: name: "guide_screen" - + BoxLayout: orientation: "vertical" @@ -859,7 +859,7 @@ MDScreen: layout_information_screen = """ MDScreen: name: "information_screen" - + BoxLayout: orientation: "vertical" @@ -913,7 +913,7 @@ MDScreen: layout_map_settings_screen = """ MDScreen: name: "map_settings_screen" - + BoxLayout: orientation: "vertical" @@ -961,7 +961,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(48) - + MDLabel: text: "Use online map sources" font_style: "H6" @@ -976,7 +976,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(48) - + MDLabel: text: "Use offline map source" font_style: "H6" @@ -991,7 +991,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(48) - + MDLabel: id: map_storage_external_label text: "Use external storage path" @@ -1035,7 +1035,7 @@ MDScreen: layout_map_screen = """ MDScreen: name: "map_screen" - + BoxLayout: orientation: "vertical" @@ -1063,7 +1063,7 @@ MDScreen: layout_keys_screen = """ MDScreen: name: "keys_screen" - + BoxLayout: orientation: "vertical" @@ -1155,7 +1155,7 @@ MDScreen: layout_plugins_screen = """ MDScreen: name: "plugins_screen" - + BoxLayout: orientation: "vertical" @@ -1200,7 +1200,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(26),dp(0)] height: dp(24) - + MDLabel: text: "Enable Plugins" font_style: "H6" @@ -1215,7 +1215,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(26),dp(0)] height: dp(24) - + MDLabel: text: "Enable Command Plugins" font_style: "H6" @@ -1262,7 +1262,7 @@ MDScreen: layout_settings_screen = """ MDScreen: name: "settings_screen" - + BoxLayout: orientation: "vertical" @@ -1404,7 +1404,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Notifications" font_style: "H6" @@ -1419,7 +1419,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Dark Mode" font_style: "H6" @@ -1434,7 +1434,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "E-Ink Mode" font_style: "H6" @@ -1449,7 +1449,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Show user icons in conversation list" font_style: "H6" @@ -1464,7 +1464,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Only show user icons from trusted" font_style: "H6" @@ -1479,7 +1479,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Advanced Metrics" font_style: "H6" @@ -1516,7 +1516,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Announce Automatically" font_style: "H6" @@ -1531,7 +1531,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Try propagation on direct delivery failure" font_style: "H6" @@ -1547,7 +1547,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Send via Propagation Node by default" font_style: "H6" @@ -1563,7 +1563,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Ignore unknown senders" font_style: "H6" @@ -1579,7 +1579,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Limit incoming messages to 1MB" font_style: "H6" @@ -1595,7 +1595,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Limit each sync to 3 messages" font_style: "H6" @@ -1611,7 +1611,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: id: settings_lxmf_sync_periodic text: "Sync with Propagation Node periodically" @@ -1643,7 +1643,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: id: settings_lxmf_require_stamps_label text: "Require stamps for incoming" @@ -1675,7 +1675,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Ignore messages with invalid stamps" font_style: "H6" @@ -1691,7 +1691,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Use high-quality voice for PTT" font_style: "H6" @@ -1707,7 +1707,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Use Home Node as Broadcast Repeater" font_style: "H6" @@ -1723,7 +1723,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(24)] height: dp(48+24) - + MDLabel: text: "Debug Logging" font_style: "H6" @@ -1761,7 +1761,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Latin, Greek, Cyrillic" font_style: "H6" @@ -1776,7 +1776,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Chinese" font_style: "H6" @@ -1791,7 +1791,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Japanese" font_style: "H6" @@ -1806,7 +1806,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Korean" font_style: "H6" @@ -1821,7 +1821,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Devanagari" font_style: "H6" @@ -1836,7 +1836,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Hebrew (incomplete)" font_style: "H6" @@ -1851,7 +1851,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Block Predictive Text" font_style: "H6" @@ -1882,7 +1882,7 @@ MDScreen: layout_repository_screen = """ MDScreen: name: "repository_screen" - + BoxLayout: orientation: "vertical" @@ -1971,7 +1971,7 @@ MDScreen: layout_hardware_screen = """ MDScreen: name: "hardware_screen" - + BoxLayout: orientation: "vertical" @@ -2052,7 +2052,7 @@ MDScreen: layout_hardware_modem_screen = """ MDScreen: name: "hardware_modem_screen" - + BoxLayout: orientation: "vertical" @@ -2200,7 +2200,7 @@ MDScreen: layout_hardware_rnode_screen = """ MDScreen: name: "hardware_rnode_screen" - + BoxLayout: orientation: "vertical" @@ -2366,7 +2366,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Control RNode Display" font_style: "H6" @@ -2381,7 +2381,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Connect using Bluetooth" font_style: "H6" @@ -2396,7 +2396,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Device requires BLE" font_style: "H6" @@ -2463,7 +2463,7 @@ MDScreen: layout_hardware_serial_screen = """ MDScreen: name: "hardware_serial_screen" - + BoxLayout: orientation: "vertical" diff --git a/sbapp/ui/messages.py b/sbapp/ui/messages.py index 5c2f441..d647567 100644 --- a/sbapp/ui/messages.py +++ b/sbapp/ui/messages.py @@ -104,7 +104,7 @@ class Messages(): def message_details_dialog(self, lxm_hash): ss = int(dp(16)) ms = int(dp(14)) - + msg = self.app.sideband.message(lxm_hash) if msg: close_button = MDRectangleFlatButton(text="Close", font_size=dp(18)) @@ -144,7 +144,7 @@ class Messages(): d_text += f"[size={ss}][b]Encrypted[/b] with destination identity key[/size]\n" else: d_text += f"[size={ss}][b]Encryption[/b] status unknown[/size]\n" - + if msg["extras"] != None and "stamp_checked" in msg["extras"]: valid_str = " is not valid" if msg["extras"]["stamp_valid"] == True: @@ -294,7 +294,7 @@ class Messages(): sphrase = "Link established" elif prg >= 0.05: sphrase = "Sending" - + if msg["title"]: titlestr = f"[b]Title[/b] {msg['title'].decode('utf-8')}\n" w.heading = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] {sphrase}{prgstr} " @@ -481,7 +481,7 @@ class Messages(): pass rcvd_d_str = "" - + trcvd = telemeter.read("received") if telemeter else None if trcvd and "distance" in trcvd: d = trcvd["distance"] @@ -725,7 +725,7 @@ class Messages(): image_field = item.image_field extension = str(image_field[0]).replace(".", "") filename = f"{time.strftime('LXM_%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))}.{extension)}" - + self.app.share_image(image_field[1], filename) item.dmenu.dismiss() return x @@ -755,7 +755,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -770,7 +770,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -824,7 +824,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -839,7 +839,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -858,7 +858,7 @@ class Messages(): if "snr" in physical_link: telemeter.sensors["physical_link"].snr = physical_link["snr"] if "quality" in physical_link: telemeter.sensors["physical_link"].q = physical_link["quality"] telemeter.sensors["physical_link"].update_data() - + tlm = telemeter.read_all() Clipboard.copy(str(tlm)) item.dmenu.dismiss() @@ -909,7 +909,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -924,7 +924,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -935,7 +935,7 @@ class Messages(): def x(): item.dmenu.dismiss() return x - + else: def x(): try: @@ -961,7 +961,7 @@ class Messages(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -1166,7 +1166,7 @@ class Messages(): messages_screen_kv = """ MDScreen: name: "messages_screen" - + BoxLayout: orientation: "vertical" @@ -1227,7 +1227,7 @@ MDScreen: on_release: root.app.message_ptt_up_action(self) _no_ripple_effect: True background_normal: "" - background_down: "" + background_down: "" BoxLayout: id: message_input_part diff --git a/sbapp/ui/objectdetails.py b/sbapp/ui/objectdetails.py index 1f0f446..fc931a1 100644 --- a/sbapp/ui/objectdetails.py +++ b/sbapp/ui/objectdetails.py @@ -115,7 +115,7 @@ class ObjectDetails(): yes_button.bind(on_release=dl_yes) no_button.bind(on_release=dl_no) - + self.delete_dialog.open() def reload_telemetry(self, sender=None, notoast=False): @@ -195,7 +195,7 @@ class ObjectDetails(): def job(dt): self.screen.ids.coordinates_button.disabled = False Clock.schedule_once(job, 0.01) - + self.telemetry_list.update_source(rendered_telemetry) def job(dt): self.screen.ids.telemetry_button.disabled = False @@ -239,7 +239,7 @@ class ObjectDetails(): else: title_str = "Unknown Status" info_str = "The status of the telemetry update is unknown." - + self.info_dialog.title = title_str self.info_dialog.text = info_str self.info_dialog.open() @@ -263,7 +263,7 @@ class ObjectDetails(): else: title_str = "Unknown Status" info_str = "The status of the telemetry request is unknown." - + self.info_dialog.title = title_str self.info_dialog.text = info_str self.info_dialog.open() @@ -273,7 +273,7 @@ class ObjectDetails(): def update(self): us = time.time() - self.update_widget() + self.update_widget() RNS.log(f"Updated object details in {RNS.prettytime(time.time() - us)}", RNS.LOG_DEBUG) def update_widget(self): @@ -303,7 +303,7 @@ class RVDetails(MDRecycleView): try: if not rendered_telemetry: rendered_telemetry = [] - + sort = { "Information": 5, "Physical Link": 10, @@ -329,7 +329,7 @@ class RVDetails(MDRecycleView): "Timestamp": 190, "Received": 200, } - + def pass_job(sender=None): pass @@ -341,7 +341,7 @@ class RVDetails(MDRecycleView): release_function = pass_job formatted_values = None name = s["name"] - + if name == "Timestamp": ts = s["values"]["UTC"] if ts != None: @@ -351,7 +351,7 @@ class RVDetails(MDRecycleView): Clipboard.copy(ts_str) toast("Copied to clipboard") release_function = copy_info - + elif name == "Information": info = s["values"]["contents"] if info != None: @@ -362,7 +362,7 @@ class RVDetails(MDRecycleView): release_function = copy_info external_text = multilingual_markup(escape_markup(istr).encode("utf-8")).decode("utf-8") formatted_values = f"[b]Information[/b]: {external_text}" - + elif name == "Received": formatted_values = "" by = s["values"]["by"]; @@ -380,14 +380,14 @@ class RVDetails(MDRecycleView): if via != None and via == by: vstr = self.app.sideband.peer_display_name(via) formatted_values = f"Received from, and collected by [b]{vstr}[/b]" - + else: if via != None: vstr = self.app.sideband.peer_display_name(via) via_str = f"Received from [b]{vstr}[/b]" else: via_str = "Received from an [b]unknown peer[/b]" - + if by != None: dstr = self.app.sideband.peer_display_name(by) by_str = f", collected by [b]{dstr}[/b]" @@ -401,7 +401,7 @@ class RVDetails(MDRecycleView): if not by == self.app.sideband.lxmf_destination.hash and not self.app.sideband.is_trusted(by): extra_entries.append({"icon": "alert", "text": "Collected by a [b]non-trusted[/b] peer"}) - + elif name == "Battery": p = s["values"]["percent"] cs = s["values"]["_meta"] @@ -415,7 +415,7 @@ class RVDetails(MDRecycleView): cs_str = f" ({cs})" if p != None: formatted_values = f"{name} [b]{p}%[/b]{cs_str}" - + elif name == "Ambient Pressure": p = s["values"]["mbar"] if p != None: formatted_values = f"{name} [b]{p} mbar[/b]" @@ -423,7 +423,7 @@ class RVDetails(MDRecycleView): if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: d = s["deltas"][dt] formatted_values += f" (Δ = {d} mbar)" - + elif name == "Ambient Temperature": c = s["values"]["c"] if c != None: formatted_values = f"{name} [b]{c}° C[/b]" @@ -431,7 +431,7 @@ class RVDetails(MDRecycleView): if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: d = s["deltas"][dt] formatted_values += f" (Δ = {d}° C)" - + elif name == "Relative Humidity": r = s["values"]["percent"] if r != None: formatted_values = f"{name} [b]{r}%[/b]" @@ -439,7 +439,7 @@ class RVDetails(MDRecycleView): if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: d = s["deltas"][dt] formatted_values += f" (Δ = {d}%)" - + elif name == "Physical Link": rssi = s["values"]["rssi"]; rssi_str = None snr = s["values"]["snr"]; snr_str = None @@ -453,7 +453,7 @@ class RVDetails(MDRecycleView): if q != None or rssi != None: snr_str = f", {snr_str}" if q_str or rssi_str or snr_str: formatted_values = q_str+rssi_str+snr_str - + elif name == "Power Consumption": cs = s["values"] if cs != None: @@ -664,13 +664,13 @@ class RVDetails(MDRecycleView): if od != None: od_text = f"Geodesic distance [b]{RNS.prettydistance(od)}[/b]" extra_entries.append({"icon": "earth", "text": od_text}) - + if "euclidian" in s["distance"]: ed = s["distance"]["euclidian"] if ed != None: ed_text = f"Euclidian distance [b]{RNS.prettydistance(ed)}[/b]" extra_entries.append({"icon": "axis-arrow", "text": ed_text}) - + if "vertical" in s["distance"]: vd = s["distance"]["vertical"] if vd != None: @@ -710,7 +710,7 @@ class RVDetails(MDRecycleView): az = s["azalt"]["azimuth"] az_text = f"Azimuth [b]{round(az,3)}°[/b]" azalt_formatted_text += az_text - + if "altitude" in s["azalt"]: al = s["azalt"]["altitude"] al_text = f"altitude [b]{round(al,3)}°[/b]" @@ -740,7 +740,7 @@ class RVDetails(MDRecycleView): rh_icon = "set-none" else: rh_formatted_text = f"[b]Outside[/b] shared radio horizon of [b]{crange_text}[/b]" - + extra_entries.append({"icon": rh_icon, "text": rh_formatted_text}) def select(e=None): @@ -763,7 +763,7 @@ class RVDetails(MDRecycleView): formatted_values += ", " formatted_values = formatted_values[:-2] - + data = None if formatted_values != None: if release_function: @@ -775,7 +775,7 @@ class RVDetails(MDRecycleView): self.entries.append(data) for extra in extra_entries: self.entries.append(extra) - + except Exception as e: RNS.log("An error ocurred while displaying telemetry for object", RNS.LOG_ERROR) RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) @@ -860,7 +860,7 @@ layout_object_details = """ MDScreen: name: "object_details_screen" - + BoxLayout: orientation: "vertical" @@ -930,7 +930,7 @@ MDScreen: size_hint: [1.0, None] on_release: root.delegate.copy_coordinates(self) disabled: False - + MDSeparator: orientation: "horizontal" height: dp(1) @@ -938,7 +938,7 @@ MDScreen: MDBoxLayout: orientation: "vertical" id: object_details_container - + MDSeparator: orientation: "horizontal" height: dp(1) @@ -989,5 +989,5 @@ MDScreen: # size_hint: [1.0, None] # on_release: root.delegate.copy_telemetry(self) # disabled: False - + """ \ No newline at end of file diff --git a/sbapp/ui/telemetry.py b/sbapp/ui/telemetry.py index 60ab64f..7b2fa0a 100644 --- a/sbapp/ui/telemetry.py +++ b/sbapp/ui/telemetry.py @@ -30,7 +30,7 @@ class Telemetry(): self.sensors_screen = None self.icons_screen = None self.color_picker = None - + if not self.app.root.ids.screen_manager.has_screen("telemetry_screen"): self.screen = Builder.load_string(layout_telemetry_screen) self.screen.app = self.app @@ -74,17 +74,17 @@ class Telemetry(): self.screen.ids.telemetry_try_propagation_on_fail.active = self.app.sideband.config["telemetry_try_propagation_on_fail"] self.screen.ids.telemetry_try_propagation_on_fail.bind(active=self.telemetry_save) - + self.screen.ids.telemetry_requests_only_send_latest.active = self.app.sideband.config["telemetry_requests_only_send_latest"] self.screen.ids.telemetry_requests_only_send_latest.bind(active=self.telemetry_save) - + self.screen.ids.telemetry_allow_requests_from_trusted.active = self.app.sideband.config["telemetry_allow_requests_from_trusted"] self.screen.ids.telemetry_allow_requests_from_trusted.bind(active=self.telemetry_save) - + self.screen.ids.telemetry_allow_requests_from_anyone.active = self.app.sideband.config["telemetry_allow_requests_from_anyone"] self.screen.ids.telemetry_allow_requests_from_anyone.bind(active=self.telemetry_save) - - + + self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect info = "\nSideband allows you to securely share telemetry, such as location and sensor data, with people, custom programs, " info += "machines or other systems over LXMF. You have complete control over what kind of telemetry to send, and who you share " @@ -100,7 +100,7 @@ class Telemetry(): if self.app.theme_cls.theme_style == "Dark": info = f"[color=#{self.app.dark_theme_text_color}]{info}[/color]" - + self.screen.ids.telemetry_info.text = info def send_interval_change(sender=None, event=None, save=True): @@ -229,7 +229,7 @@ class Telemetry(): self.app.sideband.run_telemetry() else: self.app.sideband.stop_telemetry() - + def telemetry_save(self, sender=None, event=None): run_telemetry_update = False if len(self.screen.ids.telemetry_collector.text) != 32: @@ -259,7 +259,7 @@ class Telemetry(): self.app.sideband.config["telemetry_allow_requests_from_trusted"] = self.screen.ids.telemetry_allow_requests_from_trusted.active self.app.sideband.config["telemetry_allow_requests_from_anyone"] = self.screen.ids.telemetry_allow_requests_from_anyone.active self.app.sideband.config["telemetry_collector_enabled"] = self.screen.ids.telemetry_collector_enabled.active - + self.app.sideband.save_configuration() if run_telemetry_update: self.app.sideband.update_telemetry() @@ -276,14 +276,14 @@ class Telemetry(): def telemetry_fg_color(self, sender=None): if self.color_picker == None: self.color_picker = MDColorPicker(size_hint=(0.85, 0.85)) - + self.color_picker.open() self.color_picker.bind(on_release=self.telemetry_fg_select) def job(sender=None): self.color_picker._rgb = self.app.sideband.config["telemetry_fg"][0:3] self.color_picker.ids.view_headline.on_tab_press() Clock.schedule_once(job, 0) - + def telemetry_fg_select(self, instance_color_picker: MDColorPicker, type_color: str, selected_color: Union[list, str]): s = selected_color; color = [s[0], s[1], s[2], 1] self.screen.ids.telemetry_icon_preview.icon_color = color @@ -304,7 +304,7 @@ class Telemetry(): self.color_picker._rgb = self.app.sideband.config["telemetry_bg"][0:3] self.color_picker.ids.view_headline.on_tab_press() Clock.schedule_once(job, 0) - + def telemetry_bg_select(self, instance_color_picker: MDColorPicker, type_color: str, selected_color: Union[list, str]): s = selected_color; color = [s[0], s[1], s[2], 1] self.screen.ids.telemetry_icon_preview.md_bg_color = color @@ -329,7 +329,7 @@ class Telemetry(): info3 = "\nTo include a specific type of telemetry data while sending, it must be enabled below. Please note that some sensor types are not supported on all devices. Sideband will only be able to read a specific type of sensor if your device actually includes hardware for it.\n" if self.app.theme_cls.theme_style == "Dark": - info3 = f"[color=#{self.app.dark_theme_text_color}]{info3}[/color]" + info3 = f"[color=#{self.app.dark_theme_text_color}]{info3}[/color]" self.sensors_screen.ids.telemetry_info3.text = info3 self.sensors_screen.ids.sensors_scrollview.effect_cls = ScrollEffect @@ -491,7 +491,7 @@ class Telemetry(): self.app.root.ids.screen_manager.transition.direction = "left" self.app.root.ids.screen_manager.current = "icons_screen" self.app.sideband.setstate("app.displaying", self.app.root.ids.screen_manager.current) - + # sf = self.icons_screen.ids.icons_search_field.text # self.icons_filter(sf, len(sf)>0) @@ -541,7 +541,7 @@ class Telemetry(): layout_telemetry_screen = """ MDScreen: name: "telemetry_screen" - + BoxLayout: orientation: "vertical" @@ -582,7 +582,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(48) - + MDLabel: id: telemetry_enabled_label text: "Enable telemetry" @@ -598,7 +598,7 @@ MDScreen: padding: [0,0,dp(24),0] size_hint_y: None height: dp(48) - + MDLabel: text: "Enable collector" font_style: "H6" @@ -613,7 +613,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Send display style to everyone" font_style: "H6" @@ -628,7 +628,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Only display trusted on map" font_style: "H6" @@ -643,7 +643,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Only receive from trusted" font_style: "H6" @@ -658,7 +658,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: id: telemetry_send_to_collector_label text: "Auto sync to collector" @@ -689,7 +689,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: id: telemetry_request_from_collector_label text: "Auto sync from collector" @@ -730,7 +730,7 @@ MDScreen: text: "" font_size: dp(24) - + # MDRectangleFlatIconButton: # id: telemetry_copy_button # icon: "content-copy" @@ -799,7 +799,7 @@ MDScreen: on_release: root.app.map_display_own_telemetry(self) disabled: False - + MDLabel: text: "Display Options" @@ -897,7 +897,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Embed telemetry to all trusted" font_style: "H6" @@ -912,7 +912,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Sync all known telemetry to collector" font_style: "H6" @@ -927,7 +927,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Always use propagation for telemetry" font_style: "H6" @@ -942,7 +942,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Try propagation if direct delivery fails" font_style: "H6" @@ -957,7 +957,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Requests receive only latest" font_style: "H6" @@ -972,7 +972,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Allow requests from all trusted" font_style: "H6" @@ -987,7 +987,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Allow requests from anyone" font_style: "H6" @@ -997,13 +997,13 @@ MDScreen: pos_hint: {"center_y": 0.3} active: False - + """ layout_sensors_screen = """ MDScreen: name: "sensors_screen" - + BoxLayout: orientation: "vertical" @@ -1051,7 +1051,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Location" font_style: "H6" @@ -1066,7 +1066,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Battery State" font_style: "H6" @@ -1081,7 +1081,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Pressure" font_style: "H6" @@ -1096,7 +1096,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Temperature" font_style: "H6" @@ -1111,7 +1111,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Humidity" font_style: "H6" @@ -1126,7 +1126,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Magnetic Field" font_style: "H6" @@ -1141,7 +1141,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Ambient Light" font_style: "H6" @@ -1156,7 +1156,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Gravity" font_style: "H6" @@ -1171,7 +1171,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Angular Velocity" font_style: "H6" @@ -1186,7 +1186,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Acceleration" font_style: "H6" @@ -1201,7 +1201,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Proximity" font_style: "H6" @@ -1216,7 +1216,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Information" font_style: "H6" @@ -1247,7 +1247,7 @@ MDScreen: size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Fixed Location" font_style: "H6" @@ -1285,7 +1285,7 @@ MDScreen: layout_icons_screen = """ MDScreen: name: "icons_screen" - + BoxLayout: orientation: "vertical"