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 @@ def update_telemetry(self, telemeter): 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 @@ def get_image_field(self, preset="default"): 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 @@ def read_frames(self): 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 @@ def update(self): 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 @@ def release_camera(self): try: self.camera.release() except: - pass - + pass + self.camera = None self.camera_ready = False @@ -185,14 +185,14 @@ def read_frames(self): 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 @@ def release_stream(self): try: self.stream.release() except: - pass - + pass + self.stream = None self.stream_ready = False @@ -306,7 +306,7 @@ def handle_command(self, arguments, lxm): 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 @@ def link_dirs_flags(self, arch): # 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/ffpyplayer/setup.py.patch b/recipes/ffpyplayer/setup.py.patch index 6a7d42f..262b8ba 100644 --- a/recipes/ffpyplayer/setup.py.patch +++ b/recipes/ffpyplayer/setup.py.patch @@ -3,13 +3,13 @@ @@ -27,12 +27,6 @@ # This sets whether or not Cython gets added to setup_requires. declare_cython = False - + -if platform in ('ios', 'android'): - # NEVER use or declare cython on these platforms - print('Not using cython on %s' % platform) - can_use_cython = False -else: - declare_cython = True - + src_path = build_path = dirname(__file__) print(f'Source/build path: {src_path}') \ No newline at end of file diff --git a/recipes/numpy/patches/add_libm_explicitly_to_build.patch b/recipes/numpy/patches/add_libm_explicitly_to_build.patch index f9ba9e9..3eff436 100644 --- a/recipes/numpy/patches/add_libm_explicitly_to_build.patch +++ b/recipes/numpy/patches/add_libm_explicitly_to_build.patch @@ -8,7 +8,7 @@ index 66c07c9..d34bd93 100644 extra_info=lapack_info, + libraries=['m'], ) - + # umath_linalg module @@ -54,7 +54,7 @@ def configuration(parent_package='', top_path=None): sources=['umath_linalg.c.src', get_lapack_lite_sources], diff --git a/recipes/numpy/patches/remove-default-paths.patch b/recipes/numpy/patches/remove-default-paths.patch index 3581f0f..c77800c 100644 --- a/recipes/numpy/patches/remove-default-paths.patch +++ b/recipes/numpy/patches/remove-default-paths.patch @@ -5,7 +5,7 @@ index fc7018a..7b514bc 100644 @@ -340,10 +340,10 @@ if os.path.join(sys.prefix, 'lib') not in default_lib_dirs: default_include_dirs.append(os.path.join(sys.prefix, 'include')) default_src_dirs.append(os.path.join(sys.prefix, 'src')) - + -default_lib_dirs = [_m for _m in default_lib_dirs if os.path.isdir(_m)] -default_runtime_dirs = [_m for _m in default_runtime_dirs if os.path.isdir(_m)] -default_include_dirs = [_m for _m in default_include_dirs if os.path.isdir(_m)] @@ -14,15 +14,15 @@ index fc7018a..7b514bc 100644 +default_runtime_dirs =[] # [_m for _m in default_runtime_dirs if os.path.isdir(_m)] +default_include_dirs =[] # [_m for _m in default_include_dirs if os.path.isdir(_m)] +default_src_dirs =[] # [_m for _m in default_src_dirs if os.path.isdir(_m)] - + so_ext = get_shared_lib_extension() - + @@ -814,7 +814,7 @@ class system_info(object): path = self.get_paths(self.section, key) if path == ['']: path = [] - return path + return [] - + def get_include_dirs(self, key='include_dirs'): return self.get_paths(self.section, key) 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 @@ def build_arch(self, arch): # 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 @@ def get_recipe_env(self, arch, with_flags_in_cc=True): 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 @@ def build_arch(self, arch): # 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 @@ def build(self): 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 @@ async def set_filter_chips(): ) 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 @@ def start_core(self, dt): 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 @@ def sjob(dt): 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 @@ def start_final(self): # 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 @@ def update_input_language(self): 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 @@ def update_ui_colors(self): 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 @@ def share_image(self, image, filename): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -695,7 +695,7 @@ def on_resume(self): 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 @@ def check_bluetooth_permissions(self): 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 @@ def request_notifications_permission(self): 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 @@ def check_storage_permission(self): def dl_ok(s): dialog.dismiss() self.request_storage_permission() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -815,7 +815,7 @@ def request_storage_permission(self): 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 @@ def cb(dt): 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 @@ def handle_action(self, action, data): 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 @@ def jobs(self, delta_time): 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 @@ def cb(d): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -1055,7 +1055,7 @@ def dl_ok(s): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -1165,7 +1165,7 @@ def clear_att(): 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 @@ def clear_att(): 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 @@ def clear_att(): 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 @@ def clear_att(): 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 @@ def clear_att(): 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 @@ def announce_now_action(self, sender=None): ) def dl_yes(s): dialog.dismiss() - + yes_button.bind(on_release=dl_yes) dialog.open() @@ -1441,7 +1441,7 @@ def open_conversation(self, context_dest, direction="left"): 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 @@ def cb(dt): 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 @@ def cb(dt): 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 @@ def message_fm_got_path(self, path): 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 @@ def message_select_file_action(self, sender=None): ) 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 @@ def cb(sender): 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 @@ def cb(sender): self.last_msg_audio = None self.display_codec2_error() return - + else: raise NotImplementedError(audio_field[0]) @@ -1822,7 +1822,7 @@ def cb(sender): 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 @@ def message_ptt_down_action(self, sender=None): 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 @@ def message_process_audio(self): 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 @@ def a_finished(sender): 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 @@ def a_save(sender): self.update_message_widgets() toast("Added recorded audio to message") - + except Exception as e: RNS.trace_exception(e) @@ -2085,7 +2085,7 @@ def message_record_audio_action(self): 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 @@ def a_audio_lb(sender): 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 @@ def update_message_widgets(self): 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 @@ def message_area_detect(self): ### 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 @@ def objects_action(self, sender=None, direction="left", no_transition=False): 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 @@ def get_connectivity_text(self): 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 @@ def open_ingest_lxm_dialog(self, sender=None): 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 @@ def lxmf_sync_request(self, sender): ) def dl_yes(s): dialog.dismiss() - + yes_button.bind(on_release=dl_yes) dialog.open() else: @@ -2413,7 +2413,7 @@ def dl_yes(s): # 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 @@ def dl_close(s): # 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 @@ def cb(dt): 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 @@ def new_conversation_request(self, sender=None): 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 @@ def save_input_lang(sender=None, event=None): 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 @@ def con_hide_settings(): 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 @@ def ifmode_validate(sender=None, event=None): 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 @@ def ifmode_validate(sender=None, event=None): 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 @@ def dl_yes(s): 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 @@ def repository_update_info(self, sender=None): 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 @@ def repository_start_action(self, sender=None): 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 @@ def repository_init(self, sender=None): 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 @@ def hardware_open(self, sender=None, direction="left", no_transition=False): 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 @@ def hardware_rnode_save(self): 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 @@ def hardware_rnode_save(self): 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 @@ def hardware_rnode_bt_toggle_action(self, sender=None, event=None): 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 @@ def hardware_rnode_ble_toggle_action(self, sender=None, event=None): 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 @@ def hardware_rnode_framebuffer_toggle_action(self, sender=None, event=None): 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 @@ def focus_save(sender=None, event=None): 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 @@ def hardware_rnode_validate(self, sender=None): 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 @@ def hardware_rnode_validate(self, sender=None): 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 @@ def hardware_rnode_validate(self, sender=None): 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 @@ def hardware_rnode_validate(self, sender=None): 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 @@ def hardware_rnode_validate(self, sender=None): 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 @@ def hardware_rnode_validate(self, sender=None): 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 @@ def dl_yes(s): 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 @@ def dl_yes(s): 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 @@ def focus_save(sender=None, event=None): 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 @@ def focus_save(sender=None, event=None): 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 @@ def focus_save(sender=None, event=None): 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 @@ def hardware_modem_save(self): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def hardware_modem_validate(self, sender=None): 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 @@ def focus_save(sender=None, event=None): 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 @@ def focus_save(sender=None, event=None): 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 @@ def hardware_serial_validate(self, sender=None): 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 @@ def hardware_serial_validate(self, sender=None): 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 @@ def hardware_serial_validate(self, sender=None): 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 @@ def announces_open(self, sender=None, direction="left", no_transition=False): 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 @@ def screen_transition_complete(self, sender): ### 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 @@ def identity_display_action(self, sender=None): ) def dl_yes(s): dialog.dismiss() - + yes_button.bind(on_release=dl_yes) dialog.open() @@ -4576,7 +4576,7 @@ def dl_yes(s): 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 @@ def c_dl_no(s): 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 @@ def dl_yes(s): 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 @@ def dl_yes(s): ### 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 @@ def plugins_fm_got_path(self, path): 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 @@ def plugins_fm_got_path(self, path): ) 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 @@ def plugins_select_directory_action(self, sender=None): 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 @@ def plugins_select_directory_action(self, sender=None): 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 @@ def plugins_select_directory_action(self, sender=None): ) 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 @@ def telemetry_init(self): 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 @@ def converse_from_telemetry(self, sender=None): 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 @@ def map_select_file_action(self, sender=None): 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 @@ def map_select_file_action(self, sender=None): ) 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 @@ def map_get_offline_source(self): 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 @@ def map_get_source(self): 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 @@ def map_get_source(self): 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 @@ def map_nav_down(self, sender=None, modifier=1.0): 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 @@ def map_update_markers(self, sender=None): 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 @@ def map_update_markers(self, sender=None): 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 @@ def lj(): [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 @@ def lj(): [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 @@ def lj(): - [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 @@ def __init__(self, max_workers=None, cap_time=None, **kwargs): 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 @@ def scale_at(self, scale, x, y, final = False): 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 @@ def on_touch_down(self, touch): 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 @@ def on_transform(self, *args): 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 @@ protected void doStartForeground(Bundle extras) { // 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 @@ def _check_playback(self): 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 @@ def _check_playback(self): 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 @@ def _record_job(self): 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 @@ def __init__(self, file_path=None): 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 db_over_threshold(rms): # 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 @@ def to_audio_segment(self, duration=1000.0, volume=0.0): 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 @@ def __init__(*args, **kw): 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 @@ def as_array(self): """ # 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 @@ def as_array(self): 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 @@ 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 @@ 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 @@ class FLAC__IOCallbacks(Structure): FLAC__EntropyCodingMethodType = c_int FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0 - + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 @@ -272,10 +272,10 @@ class FLAC__Subframe(Structure): _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 @@ class FLAC__FrameHeader(Structure): ("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 @@ class FLAC__Frame(Structure): _fields_ = [("header", FLAC__FrameHeader), ("subframes", FLAC__Subframe * FLAC__MAX_CHANNELS), ("footer", FLAC__FrameFooter)] - + FLAC__MetadataType = c_int @@ -435,7 +435,7 @@ class FLAC__StreamMetadata_Application(Structure): ("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 @@ class FLAC__StreamMetadata_VorbisComment(Structure): 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 @@ class FLAC__StreamMetadata_CueSheet_Track(Structure): ("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 @@ class FLAC__StreamMetadata_CueSheet(Structure): ("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 @@ class FLAC__StreamMetadata_Picture(Structure): 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 @@ class FLAC__StreamMetadata(Structure): ("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 @@ def FLAC__metadata_simple_iterator_get_application_id(iterator, id): 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 @@ def FLAC__metadata_simple_iterator_delete_block(iterator, use_padding): class FLAC__Metadata_Chain(Structure): _fields_ = [("dummy", c_int)] - + class FLAC__Metadata_Iterator(Structure): _fields_ = [("dummy", c_int)] @@ -1261,13 +1261,13 @@ def FLAC__metadata_object_picture_is_legal(object, violation): 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 @@ def FLAC__StreamDecoderStateString(): 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 @@ def __init__(self, path): 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 @@ class ExternalLibraryError(Exception): 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 @@ class ExternalLibraryError(Exception): 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 @@ def load(names: Dict[str, str], paths: Optional[List[str]] = None, tests = []) - if lib is None: lib = ExternalLibrary.load(names["external"], paths, tests) return lib - + class InternalLibrary: @staticmethod @@ -61,7 +61,7 @@ def load(names: Dict[str, str], tests) -> Optional[ctypes.CDLL]: # 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 @@ def load(names: Dict[str, str], tests) -> Optional[ctypes.CDLL]: 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 @@ def load(names: Dict[str, str], tests) -> Optional[ctypes.CDLL]: # Library failed tests return None - + # Cache of libraries that have already been loaded _loaded_libraries: Dict[str, ctypes.CDLL] = {} @@ -119,7 +119,7 @@ def load_other(name, paths = None, tests = []): 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 @@ def load_windows(name, paths = None, tests = []): 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 @@ def load_windows(name, paths = None, tests = []): 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 @@ class ogg_sync_state(ctypes.Structure): 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 @@ def oggpack_get_buffer(b): 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 @@ 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 @@ def __init__(self, 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 @@ def write(self, pcm: memoryview) -> None: 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 @@ def handle_encoded_packet(encoded_packet: memoryview, 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 @@ PYOGG_OPUS_AVAIL = True else: PYOGG_OPUS_AVAIL = False - + if libopusfile: PYOGG_OPUS_FILE_AVAIL = True else: @@ -345,22 +345,22 @@ 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_FRAMESIZE_ARG =5000 -OPUS_FRAMESIZE_2_5_MS =5001 -OPUS_FRAMESIZE_5_MS =5002 +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_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_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 @@ def opus_multistream_packet_pad(data, len, new_len, nb_streams): 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 @@ def opus_multistream_decoder_destroy(st): if PYOGG_OPUS_FILE_AVAIL: assert libopusfile is not None - + # opusfile class OggOpusFile(ctypes.Structure): @@ -1212,7 +1212,7 @@ def op_read_float_stereo(_of, _pcm, _buf_size): 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 @@ def buffered_encode(self, "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 @@ def flush_buffer() -> None: 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 @@ def flush_buffer() -> None: # 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 @@ def flush_buffer() -> None: # 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 @@ def copy_insufficient_data() -> None: # 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 @@ def copy_insufficient_data() -> None: // self._channels // ctypes.sizeof(opus.opus_int16) ) - + # Encode the PCM encoded_packet = super().encode(frame_data) @@ -266,7 +266,7 @@ def copy_insufficient_data() -> None: 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 @@ def copy_insufficient_data() -> None: # 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 @@ def decode(self, encoded_bytes: memoryview): # 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 @@ def decode(self, encoded_bytes: memoryview): * 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 @@ def set_max_bytes_per_frame(self, max_bytes: int) -> None: 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 @@ def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview: # 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 @@ def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview: 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 @@ def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview: # * 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 @@ def get_algorithmic_delay(self): # 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 @@ def get_algorithmic_delay(self): 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 @@ def __init__(self, path: str) -> None: 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 @@ def __init__(self, path): 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 @@ class vorbis_dsp_state(ctypes.Structure): ("res_bits", ogg_int64_t), ("backend_state", c_void_p)] - + class alloc_chain(ctypes.Structure): """ Wrapper for: @@ -232,7 +232,7 @@ class vorbis_comment(ctypes.Structure): ("comments", c_int), ("vendor", c_char_p)] - + vi_p = POINTER(vorbis_info) vc_p = POINTER(vorbis_comment) @@ -285,7 +285,7 @@ def vorbis_comment_clear(vc): 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 @@ def vorbis_granule_time(v, granulepos): 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 @@ def vorbis_analysis_init(v, vi): 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 @@ def vorbis_analysis_wrote(v, vals): 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 @@ def vorbis_analysis(vb, op): 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 @@ def vorbis_bitrate_flushpacket(vd, op): 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 @@ def vorbis_synthesis(vb, op): 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 @@ def vorbis_synthesis_blockin(v, vb): 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 @@ def vorbis_synthesis_lapout(v, pcm): 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 @@ def vorbis_packet_blocksize(vi, op): 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 @@ class ov_callbacks(ctypes.Structure): ("seek_func", seek_func), ("close_func", close_func), ("tell_func", tell_func)] - + NOTOPEN = 0 PARTOPEN = 1 OPENED = 2 @@ -768,10 +768,10 @@ def ov_halfrate_p(vf): 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 @@ def __init__(self, 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 @@ def __init__(self, # 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 @@ def __init__(self, ) # 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 @@ def __init__(self, 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 @@ def __init__(self, # 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 @@ def mod(method, name, signature): 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 @@ def android_notification(self, title="", content="", ticker="", group=None, cont 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 @@ def check_permission(self, permission): except Exception as e: RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) - + return False - + else: return False @@ -184,7 +184,7 @@ def update_location_provider(self): 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 @@ def __init__(self): 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 @@ def __init__(self): 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 @@ def __init__(self): 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 @@ def discover_usb_devices(self): 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 @@ def update_connectivity_type(self): 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 @@ def get_connectivity_status(self): 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 @@ 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 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa 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 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa 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 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa 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 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa except Exception as e: RNS.log(f"Error while configuring Reticulum instance: {e)}", RNS.LOG_ERROR) - + else: pass @@ -423,7 +423,7 @@ def __init_config(self): 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 @@ def __init_config(self): 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 @@ def __load_config(self): 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 @@ def __load_config(self): 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 @@ def __load_plugins(self): 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 @@ def __load_plugins(self): 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 @@ def __load_plugins(self): 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 @@ def set_active_propagation_node(self, dest): 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 @@ def notify(self, title, content, group=None, context_id=None): 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 @@ def allow_request_from(self, context_dest): 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 @@ def _service_request_latest_telemetry(self, from_addr=None): 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 @@ def request_latest_telemetry(self, from_addr=None): 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 @@ def request_latest_telemetry(self, from_addr=None): 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 @@ def request_latest_telemetry(self, from_addr=None): 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 @@ def send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemet 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 @@ def send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemet 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 @@ def send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemet 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 @@ def __rpc_loop(self): 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 @@ def _db_getpersistent(self, prop): 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 @@ def _db_getpersistent(self, prop): 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 @@ def _db_setpersistent(self, prop, val): 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 @@ def _db_setpersistent(self, prop, val): 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 @@ def _db_conversation_set_unread(self, context_dest, unread, tx = False, is_retry 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 @@ def _db_telemetry(self, context_dest = None, after = None, before = None, limit 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 @@ def _db_telemetry(self, context_dest = None, after = None, before = None, limit 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 @@ def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, sour 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 @@ def _db_update_appearance(self, context_dest, timestamp, appearance, from_bulk_t # 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 @@ def _db_update_appearance(self, context_dest, timestamp, appearance, from_bulk_t 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 @@ def htf(cbytes): 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 @@ def _db_conversation_set_telemetry(self, context_dest, send_telemetry=False, is_ 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 @@ def _db_conversation_set_requests(self, context_dest, allow_requests=False, is_r 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 @@ def _db_conversation_set_object(self, context_dest, is_object=False): 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 @@ def _db_conversation_set_ptt_enabled(self, context_dest, ptt_enabled=False): 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 @@ def _db_conversation_set_trusted(self, context_dest, trusted): 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 @@ def _db_conversation_set_name(self, context_dest, name): 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 @@ def _db_conversations(self, conversations=True, objects=False): with self.db_lock: db = self.__db_connect() dbc = db.cursor() - + dbc.execute("select * from conv") result = dbc.fetchall() @@ -2397,7 +2397,7 @@ def _db_announces(self): 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 @@ def _db_conversation(self, context_dest): 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 @@ def _db_message_set_state(self, lxm_hash, state, is_retry=False, ratchet_id=None 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 @@ def _db_message_set_method(self, lxm_hash, method): 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 @@ def _db_message(self, msg_hash): 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 @@ def _db_message_count(self, context_dest): 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 @@ def _db_messages(self, context_dest, after = None, before = None, limit = None): 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 @@ def _db_messages(self, context_dest, after = None, before = None, limit = None): 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 @@ def _db_messages(self, context_dest, after = None, before = None, limit = None): extras = msgpack.unpackb(entry[11]) except: pass - + message = { "hash": lxm.hash, "dest": lxm.destination_hash, @@ -2868,13 +2868,13 @@ def lxmf_announce(self, attached_interface=None): 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 @@ def update_telemeter_config(self): 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 @@ def _update_delivery_limits(self): 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 @@ def x(): 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 @@ def x(): 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 @@ def __start_jobs_deferred(self): 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 @@ def __add_localinterface(self, delay=None): 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 @@ def __add_rnodeinterface(self, delay=None): 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 @@ def __add_rnodeinterface(self, delay=None): 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 @@ def __start_jobs_immediate(self): 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 @@ def __start_jobs_immediate(self): 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 @@ def __start_jobs_immediate(self): 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 @@ def __start_jobs_immediate(self): 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 @@ def __start_jobs_immediate(self): 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 @@ def __start_jobs_immediate(self): 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 @@ def __start_jobs_immediate(self): 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 @@ def paper_message(self, content, destination_hash): 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 @@ def _service_get_lxm_progress(self, lxm_hash): 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 @@ def _service_send_message(self, content, destination_hash, propagation, skip_fie "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 @@ def send_message(self, content, destination_hash, propagation, skip_fields=False 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 @@ def send_message(self, content, destination_hash, propagation, skip_fields=False 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 @@ def send_command(self, content, destination_hash, propagation): 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 @@ def lxm_ingest_uri(self, uri): 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 @@ def ptt_playback(self, message): 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 @@ def ptt_playback(self, message): else: self.last_msg_audio = None return - + else: # Unimplemented audio type pass @@ -4598,16 +4598,16 @@ def handle_commands(self, commands, message): 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 @@ def get(self, lat, lon, cubic=True): # 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 @@ def enable(self, sensor): 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 @@ def check_permission(self, permission): 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 @@ def __init__(self): 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 @@ def update_data(self): 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 @@ def update_data(self): 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 @@ def unpack(self, packed): 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 @@ def update_data(self): try: if RNS.vendor.platformutils.is_android(): self.data = {"mbar": round(self.android_sensor.pressure, 2)} - + except: self.data = None @@ -623,7 +623,7 @@ def render(self, relative_to=None): class Location(Sensor): SID = Sensor.SID_LOCATION - + STALE_TIME = 15 MIN_DISTANCE = 4 ACCURACY_TARGET = 250 @@ -679,11 +679,11 @@ def setup_sensor(self): 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 @@ def update_data(self): "accuracy": round(self.accuracy, 2), "last_update": int(self._last_update), } - + except: self.data = None @@ -816,7 +816,7 @@ def render(self, relative_to=None): 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 @@ def render(self, relative_to=None): 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 @@ def unpack(self, packed): 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 @@ def update_data(self): try: if RNS.vendor.platformutils.is_android(): self.data = {"c": round(self.android_sensor.temperature, 2)} - + except: self.data = None @@ -1012,7 +1012,7 @@ def update_data(self): 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 @@ def unpack(self, packed): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "water-percent", "name": "Relative Humidity", @@ -1069,7 +1069,7 @@ def update_data(self): 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 @@ def unpack(self, packed): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "magnet", "name": "Magnetic Field", @@ -1125,7 +1125,7 @@ def update_data(self): try: if RNS.vendor.platformutils.is_android(): self.data = {"lux": round(self.android_sensor.illumination, 2)} - + except: self.data = None @@ -1155,7 +1155,7 @@ def render(self, relative_to=None): 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 @@ def update_data(self): 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 @@ def unpack(self, packed): 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 @@ def update_data(self): 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 @@ def unpack(self, packed): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "orbit", "name": "Angular Velocity", @@ -1306,7 +1306,7 @@ def update_data(self): 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 @@ def update_data(self): try: if RNS.vendor.platformutils.is_android(): self.data = self.android_sensor.proximity - + except: self.data = None @@ -1374,7 +1374,7 @@ def unpack(self, packed): def render(self, relative_to=None): if self.data == None: return None - + rendered = { "icon": "signal-distance-variant", "name": "Proximity", @@ -1439,7 +1439,7 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1454,7 +1454,7 @@ def render(self, relative_to=None): 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 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1535,7 +1535,7 @@ def render(self, relative_to=None): 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 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1621,7 +1621,7 @@ def render(self, relative_to=None): "load_avgs": self.data[type_label][1], "clock": self.data[type_label][2], }) - + rendered = { "icon": "chip", "name": "Processor", @@ -1687,7 +1687,7 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1708,7 +1708,7 @@ def render(self, relative_to=None): "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 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1795,7 +1795,7 @@ def render(self, relative_to=None): "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 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1880,7 +1880,7 @@ def render(self, relative_to=None): "value": self.data[type_label][0], "custom_icon": self.data[type_label][1], }) - + rendered = { "icon": "ruler", "name": "Custom", @@ -1950,7 +1950,7 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -1974,7 +1974,7 @@ def render(self, relative_to=None): "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 @@ def unpack(self, packed): for entry in packed: unpacked[entry[0]] = entry[1] return unpacked - + except: return None @@ -2067,7 +2067,7 @@ def render(self, relative_to=None): "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 @@ def update_widget(self): 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 @@ def gen_info(ts, dest, name, cost, dtype): 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 @@ def x(): dm_items = [] item.iconr = IconRightWidget(icon="dots-vertical"); - + item.dmenu = MDDropdownMenu( caller=item.iconr, items=dm_items, @@ -253,7 +253,7 @@ def x(sender): 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 @@ def get_widget(self): 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 @@ def __init__(self, app): 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 @@ def clear_list(self): 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 @@ def trust_icon(self, conv): 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 @@ def update_widget(self): 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 @@ def x(sender): 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 @@ def get_widget(self): 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 @@ MDScreen: name: "starting_screen" - + AnchorLayout: padding: [dp(0), dp(72), dp(0), dp(0)] anchor_x: "center" @@ -49,141 +49,141 @@ 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 @@ layout_broadcasts_screen = """ MDScreen: name: "broadcasts_screen" - + BoxLayout: orientation: "vertical" @@ -230,7 +230,7 @@ layout_exit_screen = """ MDScreen: name: "exit_screen" - + AnchorLayout: padding: [dp(0), dp(72), dp(0), dp(0)] anchor_x: "center" @@ -262,7 +262,7 @@ layout_loader_screen = """ MDScreen: name: "loader_screen" - + BoxLayout: orientation: "vertical" @@ -295,7 +295,7 @@ layout_connectivity_screen = """ MDScreen: name: "connectivity_screen" - + BoxLayout: orientation: "vertical" @@ -337,7 +337,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ # 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 @@ 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 @@ layout_guide_screen = """ MDScreen: name: "guide_screen" - + BoxLayout: orientation: "vertical" @@ -859,7 +859,7 @@ layout_information_screen = """ MDScreen: name: "information_screen" - + BoxLayout: orientation: "vertical" @@ -913,7 +913,7 @@ layout_map_settings_screen = """ MDScreen: name: "map_settings_screen" - + BoxLayout: orientation: "vertical" @@ -961,7 +961,7 @@ 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 @@ 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 @@ 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 @@ layout_map_screen = """ MDScreen: name: "map_screen" - + BoxLayout: orientation: "vertical" @@ -1063,7 +1063,7 @@ layout_keys_screen = """ MDScreen: name: "keys_screen" - + BoxLayout: orientation: "vertical" @@ -1155,7 +1155,7 @@ layout_plugins_screen = """ MDScreen: name: "plugins_screen" - + BoxLayout: orientation: "vertical" @@ -1200,7 +1200,7 @@ 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 @@ 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 @@ layout_settings_screen = """ MDScreen: name: "settings_screen" - + BoxLayout: orientation: "vertical" @@ -1404,7 +1404,7 @@ size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Notifications" font_style: "H6" @@ -1419,7 +1419,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Chinese" font_style: "H6" @@ -1791,7 +1791,7 @@ size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Japanese" font_style: "H6" @@ -1806,7 +1806,7 @@ size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Korean" font_style: "H6" @@ -1821,7 +1821,7 @@ size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Devanagari" font_style: "H6" @@ -1836,7 +1836,7 @@ 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 @@ 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 @@ layout_repository_screen = """ MDScreen: name: "repository_screen" - + BoxLayout: orientation: "vertical" @@ -1971,7 +1971,7 @@ layout_hardware_screen = """ MDScreen: name: "hardware_screen" - + BoxLayout: orientation: "vertical" @@ -2052,7 +2052,7 @@ layout_hardware_modem_screen = """ MDScreen: name: "hardware_modem_screen" - + BoxLayout: orientation: "vertical" @@ -2200,7 +2200,7 @@ layout_hardware_rnode_screen = """ MDScreen: name: "hardware_rnode_screen" - + BoxLayout: orientation: "vertical" @@ -2366,7 +2366,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ def load_more(self, dt): 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 @@ def message_details_dialog(self, lxm_hash): 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 @@ def lmcb(sender): 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 @@ def update_widget(self): 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 @@ def x(): 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 @@ def x(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -770,7 +770,7 @@ def dl_ok(s): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -824,7 +824,7 @@ def x(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -839,7 +839,7 @@ def dl_ok(s): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -858,7 +858,7 @@ def x(): 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 @@ def x(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -924,7 +924,7 @@ def dl_ok(s): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -935,7 +935,7 @@ def gen_print_qr(lxm, item): def x(): item.dmenu.dismiss() return x - + else: def x(): try: @@ -961,7 +961,7 @@ def x(): ) def dl_ok(s): dialog.dismiss() - + ok_button.bind(on_release=dl_ok) dialog.open() @@ -1166,7 +1166,7 @@ def close_send_error_dialog(self, sender=None): messages_screen_kv = """ MDScreen: name: "messages_screen" - + BoxLayout: orientation: "vertical" @@ -1227,7 +1227,7 @@ def close_send_error_dialog(self, sender=None): 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 @@ def dl_no(s): 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 @@ def djob(dt): 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 @@ def send_update(self): 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 @@ def request_update(self): 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 @@ def clear_widget(self): 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 @@ def update_source(self, rendered_telemetry=None): try: if not rendered_telemetry: rendered_telemetry = [] - + sort = { "Information": 5, "Physical Link": 10, @@ -329,7 +329,7 @@ def update_source(self, rendered_telemetry=None): "Timestamp": 190, "Received": 200, } - + def pass_job(sender=None): pass @@ -341,7 +341,7 @@ def pass_job(sender=None): release_function = pass_job formatted_values = None name = s["name"] - + if name == "Timestamp": ts = s["values"]["UTC"] if ts != None: @@ -351,7 +351,7 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def copy_info(e=None): 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 @@ def lj(): formatted_values += ", " formatted_values = formatted_values[:-2] - + data = None if formatted_values != None: if release_function: @@ -775,7 +775,7 @@ def lj(): 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 @@ def lj(): MDScreen: name: "object_details_screen" - + BoxLayout: orientation: "vertical" @@ -930,7 +930,7 @@ def lj(): size_hint: [1.0, None] on_release: root.delegate.copy_coordinates(self) disabled: False - + MDSeparator: orientation: "horizontal" height: dp(1) @@ -938,7 +938,7 @@ def lj(): MDBoxLayout: orientation: "vertical" id: object_details_container - + MDSeparator: orientation: "horizontal" height: dp(1) @@ -989,5 +989,5 @@ def lj(): # 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 @@ def __init__(self, app): 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 @@ def __init__(self, app): 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 @@ def __init__(self, app): 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 @@ def telemetry_enabled_toggle(self, sender=None, event=None): 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 @@ def telemetry_save(self, sender=None, event=None): 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 @@ def telemetry_copy(self, sender=None): 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 @@ def job(sender=None): 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 @@ def sensors_init(self): 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 @@ def icons_action(self, sender=None): 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 @@ def f(): layout_telemetry_screen = """ MDScreen: name: "telemetry_screen" - + BoxLayout: orientation: "vertical" @@ -582,7 +582,7 @@ def f(): 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 @@ def f(): padding: [0,0,dp(24),0] size_hint_y: None height: dp(48) - + MDLabel: text: "Enable collector" font_style: "H6" @@ -613,7 +613,7 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): text: "" font_size: dp(24) - + # MDRectangleFlatIconButton: # id: telemetry_copy_button # icon: "content-copy" @@ -799,7 +799,7 @@ def f(): on_release: root.app.map_display_own_telemetry(self) disabled: False - + MDLabel: text: "Display Options" @@ -897,7 +897,7 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): 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 @@ def f(): pos_hint: {"center_y": 0.3} active: False - + """ layout_sensors_screen = """ MDScreen: name: "sensors_screen" - + BoxLayout: orientation: "vertical" @@ -1051,7 +1051,7 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Location" font_style: "H6" @@ -1066,7 +1066,7 @@ def f(): 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 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Pressure" font_style: "H6" @@ -1096,7 +1096,7 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Temperature" font_style: "H6" @@ -1111,7 +1111,7 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Humidity" font_style: "H6" @@ -1126,7 +1126,7 @@ def f(): 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 @@ def f(): 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 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Gravity" font_style: "H6" @@ -1171,7 +1171,7 @@ def f(): 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 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Acceleration" font_style: "H6" @@ -1201,7 +1201,7 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Proximity" font_style: "H6" @@ -1216,7 +1216,7 @@ def f(): size_hint_y: None padding: [0,0,dp(24),dp(0)] height: dp(48) - + MDLabel: text: "Information" font_style: "H6" @@ -1247,7 +1247,7 @@ def f(): 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 @@ def f(): layout_icons_screen = """ MDScreen: name: "icons_screen" - + BoxLayout: orientation: "vertical"