From 2a13ed0921f159df1e7161d0480835289ffd736f Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Mon, 7 Oct 2024 11:15:03 +0200 Subject: [PATCH 1/2] modernize --- docs/example_plugins/basic.py | 4 +- docs/example_plugins/comic.py | 2 +- docs/example_plugins/service.py | 4 +- docs/example_plugins/view.py | 10 +- docs/utilities/rns_audio_call_calc.py | 2 +- recipes/codec2/__init__.py | 4 +- recipes/ffpyplayer/__init__.py | 143 +++--- recipes/libopus/__init__.py | 2 +- recipes/mffmpeg/__init__.py | 30 +- recipes/numpy/__init__.py | 4 +- recipes/opusfile/__init__.py | 2 +- recipes/pycodec2/__init__.py | 6 +- sbapp/__init__.py | 2 +- sbapp/assets/icons_macos.py | 10 +- sbapp/freeze.py | 8 +- sbapp/gv.py | 2 +- sbapp/kivymd/font_definitions.py | 26 +- sbapp/kivymd/tools/hotreload/app.py | 26 +- sbapp/kivymd/tools/patterns/create_project.py | 2 +- sbapp/kivymd/tools/release/make_release.py | 12 +- sbapp/kivymd/tools/release/update_icons.py | 6 +- sbapp/kivymd/uix/behaviors/hover_behavior.py | 4 +- sbapp/kivymd/uix/button/button.py | 4 +- sbapp/kivymd/uix/datatables/datatables.py | 2 - sbapp/kivymd/uix/filemanager/filemanager.py | 2 +- sbapp/kivymd/uix/label/label.py | 6 +- .../uix/pickers/colorpicker/colorpicker.py | 4 +- .../uix/pickers/datepicker/datepicker.py | 6 +- .../uix/pickers/timepicker/timepicker.py | 2 +- sbapp/kivymd/uix/textfield/textfield.py | 4 +- sbapp/kivymd/uix/toolbar/toolbar.py | 16 +- sbapp/kivymd/utils/fpsmonitor.py | 2 +- sbapp/main.py | 242 +++++----- sbapp/mapview/__init__.py | 1 - sbapp/mapview/clustered_marker_layer.py | 5 +- sbapp/mapview/downloader.py | 6 +- sbapp/mapview/geojson.py | 1 - sbapp/mapview/mbtsource.py | 3 +- sbapp/mapview/source.py | 2 - sbapp/mapview/types.py | 2 - sbapp/mapview/utils.py | 2 - sbapp/mapview/view.py | 10 +- sbapp/patches/p4a_build.py | 8 +- sbapp/plyer/facades/audio.py | 2 +- sbapp/plyer/facades/flash.py | 1 - sbapp/plyer/facades/spatialorientation.py | 3 - sbapp/plyer/facades/temperature.py | 3 - sbapp/plyer/platforms/android/__init__.py | 4 +- sbapp/plyer/platforms/android/audio.py | 4 +- sbapp/plyer/platforms/android/call.py | 2 +- sbapp/plyer/platforms/android/camera.py | 4 +- sbapp/plyer/platforms/android/filechooser.py | 3 +- sbapp/plyer/platforms/android/flash.py | 1 - sbapp/plyer/platforms/android/gps.py | 3 +- sbapp/plyer/platforms/android/stt.py | 2 +- sbapp/plyer/platforms/ios/call.py | 2 +- sbapp/plyer/platforms/ios/flash.py | 1 - sbapp/plyer/platforms/ios/gps.py | 5 +- sbapp/plyer/platforms/ios/maps.py | 12 +- sbapp/plyer/platforms/linux/accelerometer.py | 2 +- sbapp/plyer/platforms/linux/cpu.py | 4 +- sbapp/plyer/platforms/linux/filechooser.py | 4 +- sbapp/plyer/platforms/linux/notification.py | 2 +- sbapp/plyer/platforms/linux/storagepath.py | 6 +- sbapp/plyer/platforms/linux/uniqueid.py | 4 +- sbapp/plyer/platforms/linux/wifi.py | 5 +- sbapp/plyer/platforms/macosx/maps.py | 12 +- sbapp/plyer/platforms/win/email.py | 2 +- sbapp/plyer/platforms/win/filechooser.py | 4 +- sbapp/plyer/platforms/win/libs/balloontip.py | 5 +- .../plyer/platforms/win/libs/batterystatus.py | 6 +- sbapp/plyer/tools/pep8checker/pep8.py | 137 +++--- sbapp/plyer/tools/pep8checker/pep8kivy.py | 12 +- sbapp/plyer/utils.py | 11 +- sbapp/pydub/audio_segment.py | 36 +- sbapp/pydub/effects.py | 5 +- sbapp/pydub/generators.py | 12 +- sbapp/pydub/utils.py | 17 +- sbapp/pyogg/flac_file.py | 8 +- sbapp/pyogg/flac_file_stream.py | 8 +- sbapp/pyogg/library_loader.py | 20 +- sbapp/pyogg/ogg_opus_writer.py | 3 +- sbapp/pyogg/opus_buffered_encoder.py | 5 +- sbapp/pyogg/opus_decoder.py | 7 +- sbapp/pyogg/opus_encoder.py | 10 +- sbapp/pyogg/opus_file.py | 3 +- sbapp/pyogg/opus_file_stream.py | 4 +- sbapp/pyogg/vorbis_file.py | 3 +- sbapp/pyogg/vorbis_file_stream.py | 2 +- sbapp/services/sidebandservice.py | 42 +- sbapp/sideband/__init__.py | 2 +- sbapp/sideband/audioproc.py | 10 +- sbapp/sideband/core.py | 434 +++++++++--------- sbapp/sideband/geo.py | 2 +- sbapp/sideband/sense.py | 16 +- sbapp/ui/__init__.py | 2 +- sbapp/ui/announces.py | 8 +- sbapp/ui/conversations.py | 10 +- sbapp/ui/helpers.py | 2 +- sbapp/ui/messages.py | 104 ++--- sbapp/ui/objectdetails.py | 24 +- sbapp/ui/telemetry.py | 10 +- setup.py | 10 +- 103 files changed, 822 insertions(+), 906 deletions(-) diff --git a/docs/example_plugins/basic.py b/docs/example_plugins/basic.py index b80af0c..3319049 100644 --- a/docs/example_plugins/basic.py +++ b/docs/example_plugins/basic.py @@ -22,11 +22,11 @@ def stop(self): super().stop() def handle_command(self, arguments, lxm): - response_content = "Hello "+RNS.prettyhexrep(lxm.source_hash)+". " + response_content = f"Hello {RNS.prettyhexrep(lxm.source_hash)}. " response_content += "This is a response from the basic command example. It doesn't do much, but here is a list of the arguments you included:\n" for argument in arguments: - response_content += "\n"+str(argument) + response_content += f"\n{argument)}" # Let the Sideband core send a reply. self.get_sideband().send_message( diff --git a/docs/example_plugins/comic.py b/docs/example_plugins/comic.py index 3e5a3f4..3a8022e 100644 --- a/docs/example_plugins/comic.py +++ b/docs/example_plugins/comic.py @@ -61,7 +61,7 @@ def handle_command(self, arguments, lxm): except Exception as e: # Send an error message self.get_sideband().send_message( - "An error occurred while trying to fetch the specified comic:\n\n"+str(e), + f"An error occurred while trying to fetch the specified comic:\n\n{e)}", lxm.source_hash, False, # Don't use propagation by default, try direct first skip_fields = True, # Don't include any additional fields automatically diff --git a/docs/example_plugins/service.py b/docs/example_plugins/service.py index 085c265..22c5e2a 100644 --- a/docs/example_plugins/service.py +++ b/docs/example_plugins/service.py @@ -12,9 +12,9 @@ class BasicServicePlugin(SidebandServicePlugin): def service_jobs(self): while self.should_run: time.sleep(5) - RNS.log("Service ping from "+str(self)) + RNS.log(f"Service ping from {self)}") - RNS.log("Jobs stopped running for "+str(self)) + RNS.log(f"Jobs stopped running for {self)}") def start(self): # Do any initialisation work here diff --git a/docs/example_plugins/view.py b/docs/example_plugins/view.py index a30f9d1..874575f 100644 --- a/docs/example_plugins/view.py +++ b/docs/example_plugins/view.py @@ -131,7 +131,7 @@ def read_frames(self): self.frame_queue.put(frame) except Exception as e: - RNS.log("An error occurred while reading frames from the camera: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while reading frames from the camera: {e)}", RNS.LOG_ERROR) self.release_camera() @@ -195,10 +195,10 @@ def read_frames(self): self.frame_queue.put(frame) - RNS.log(str(self)+" idled", RNS.LOG_DEBUG) + RNS.log(f"{self)} idled", RNS.LOG_DEBUG) except Exception as e: - RNS.log("An error occurred while reading frames from the stream: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while reading frames from the stream: {e)}", RNS.LOG_ERROR) self.release_stream() @@ -236,7 +236,7 @@ def update(self): self.source_data = image_file.read() except Exception as e: - RNS.log("Could not read image at \"{self.path}\": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Could not read image at \"{self.path}\": {e)}", RNS.LOG_ERROR) self.source_data = None class ViewCommandPlugin(SidebandCommandPlugin): @@ -292,7 +292,7 @@ def handle_command(self, arguments, lxm): else: response = "Available Sources:\n" for source in self.sources: - response += "\n - "+str(source) + response += f"\n - {source)}" self.message_response(response, requestor) return diff --git a/docs/utilities/rns_audio_call_calc.py b/docs/utilities/rns_audio_call_calc.py index 61bbfff..238aa45 100644 --- a/docs/utilities/rns_audio_call_calc.py +++ b/docs/utilities/rns_audio_call_calc.py @@ -100,7 +100,7 @@ def simulate(link_speed=9600, audio_slot_ms=70, codec_rate=1200, method="msgpack print(f" On-air length : {PACKET_LEN} bytes") print(f" Packet airtime : {PACKET_AIRTIME}ms") - print( "\n===== Results for "+RNS.prettyspeed(LINK_SPEED)+" Link Speed ===\n") + print( f"\n===== Results for {RNS.prettyspeed(LINK_SPEED)} Link Speed ===\n") print(f" Final latency : {TOTAL_LATENCY}ms") print(f" Recording latency : contributes {TARGET_MS}ms") print(f" Packet transport : contributes {PACKET_LATENCY}ms") diff --git a/recipes/codec2/__init__.py b/recipes/codec2/__init__.py index 81aa527..44219bc 100644 --- a/recipes/codec2/__init__.py +++ b/recipes/codec2/__init__.py @@ -13,13 +13,13 @@ class Codec2Recipe(Recipe): def include_flags(self, arch): '''Returns a string with the include folders''' codec2_includes = join(self.get_build_dir(arch.arch), 'build_android') - return (' -I' + codec2_includes) + return (f" -I{codec2_includes}") def link_dirs_flags(self, arch): '''Returns a string with the appropriate `-L` to link with the libs. This string is usually added to the environment variable `LDFLAGS`''' - return ' -L' + self.get_build_dir(arch.arch) + return f" -L{self.get_build_dir(arch.arch)}" # def link_libs_flags(self): # '''Returns a string with the appropriate `-l` flags to link with diff --git a/recipes/ffpyplayer/__init__.py b/recipes/ffpyplayer/__init__.py index 03960b7..9f8fb9a 100644 --- a/recipes/ffpyplayer/__init__.py +++ b/recipes/ffpyplayer/__init__.py @@ -146,12 +146,12 @@ class Recipe(metaclass=RecipeMeta): def get_stl_library(self, arch): return join( arch.ndk_lib_dir, - 'lib{name}.so'.format(name=self.stl_lib_name), + f'lib{self.stl_lib_name}.so', ) def install_stl_lib(self, arch): if not self.ctx.has_lib( - arch.arch, 'lib{name}.so'.format(name=self.stl_lib_name) + arch.arch, f'lib{self.stl_lib_name}.so' ): self.install_libs(arch, self.get_stl_library(arch)) @@ -181,7 +181,7 @@ def download_file(self, url, target, cwd=None): if not url: return - info('Downloading {} from {}'.format(self.name, url)) + info(f'Downloading {self.name} from {url}') if cwd: target = join(cwd, target) @@ -190,12 +190,11 @@ def download_file(self, url, target, cwd=None): if parsed_url.scheme in ('http', 'https'): def report_hook(index, blksize, size): if size <= 0: - progression = '{0} bytes'.format(index * blksize) + progression = f'{index * blksize} bytes' else: - progression = '{0:.2f}%'.format( - index * blksize * 100. / float(size)) + progression = f'{index * blksize * 100.0 / float(size):.2f}%' if "CI" not in environ: - stdout.write('- Download {}\r'.format(progression)) + stdout.write(f'- Download {progression}\r') stdout.flush() if exists(target): @@ -214,7 +213,7 @@ def report_hook(index, blksize, size): attempts += 1 if attempts >= 5: raise - stdout.write('Download failed: {}; retrying in {} second(s)...'.format(e, seconds)) + stdout.write(f'Download failed: {e}; retrying in {seconds} second(s)...') time.sleep(seconds) seconds *= 2 continue @@ -253,20 +252,20 @@ def apply_patch(self, filename, arch, build_dir=None): .. versionchanged:: 0.6.0 Add ability to apply patch from any dir via kwarg `build_dir`''' """ - info("Applying patch {}".format(filename)) + info(f"Applying patch {filename}") build_dir = build_dir if build_dir else self.get_build_dir(arch) filename = join(self.get_recipe_dir(), filename) shprint(sh.patch, "-t", "-d", build_dir, "-p1", "-i", filename, _tail=10) def copy_file(self, filename, dest): - info("Copy {} to {}".format(filename, dest)) + info(f"Copy {filename} to {dest}") filename = join(self.get_recipe_dir(), filename) dest = join(self.build_dir, dest) shutil.copy(filename, dest) def append_file(self, filename, dest): - info("Append {} to {}".format(filename, dest)) + info(f"Append {filename} to {dest}") filename = join(self.get_recipe_dir(), filename) dest = join(self.build_dir, dest) with open(filename, "rb") as fd: @@ -322,7 +321,7 @@ def get_build_container_dir(self, arch): ''' dir_name = self.get_dir_name() return join(self.ctx.build_dir, 'other_builds', - dir_name, '{}__ndk_target_{}'.format(arch, self.ctx.ndk_api)) + dir_name, f'{arch}__ndk_target_{self.ctx.ndk_api}') def get_dir_name(self): choices = self.check_recipe_choices() @@ -349,24 +348,23 @@ def get_recipe_dir(self): # Public Recipe API to be subclassed if needed def download_if_necessary(self): - info_main('Downloading {}'.format(self.name)) - user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower())) + info_main(f'Downloading {self.name}') + user_dir = environ.get(f'P4A_{self.name.lower()}_DIR') if user_dir is not None: - info('P4A_{}_DIR is set, skipping download for {}'.format( - self.name, self.name)) + info(f'P4A_{self.name}_DIR is set, skipping download for {self.name}') return self.download() def download(self): if self.url is None: - info('Skipping {} download as no URL is set'.format(self.name)) + info(f'Skipping {self.name} download as no URL is set') return url = self.versioned_url expected_digests = {} - for alg in set(hashlib.algorithms_guaranteed) | set(('md5', 'sha512', 'blake2b')): + for alg in set(hashlib.algorithms_guaranteed) | {'md5', 'sha512', 'blake2b'}: expected_digest = getattr(self, alg + 'sum') if hasattr(self, alg + 'sum') else None - ma = match(u'^(.+)#' + alg + u'=([0-9a-f]{32,})$', url) + ma = match('^(.+)#' + alg + '=([0-9a-f]{32,})$', url) if ma: # fragmented URL? if expected_digest: raise ValueError( @@ -383,7 +381,7 @@ def download(self): filename = shprint(sh.basename, url).stdout[:-1].decode('utf-8') do_download = True - marker_filename = '.mark-{}'.format(filename) + marker_filename = f'.mark-{filename}' if exists(filename) and isfile(filename): if not exists(marker_filename): shprint(sh.rm, filename) @@ -391,10 +389,8 @@ def download(self): for alg, expected_digest in expected_digests.items(): current_digest = algsum(alg, filename) if current_digest != expected_digest: - debug('* Generated {}sum: {}'.format(alg, - current_digest)) - debug('* Expected {}sum: {}'.format(alg, - expected_digest)) + debug(f'* Generated {alg}sum: {current_digest}') + debug(f'* Expected {alg}sum: {expected_digest}') raise ValueError( ('Generated {0}sum does not match expected {0}sum ' 'for {1} recipe').format(alg, self.name)) @@ -402,7 +398,7 @@ def download(self): # If we got this far, we will download if do_download: - debug('Downloading {} from {}'.format(self.name, url)) + debug(f'Downloading {self.name} from {url}') shprint(sh.rm, '-f', marker_filename) self.download_file(self.versioned_url, filename) @@ -412,25 +408,22 @@ def download(self): for alg, expected_digest in expected_digests.items(): current_digest = algsum(alg, filename) if current_digest != expected_digest: - debug('* Generated {}sum: {}'.format(alg, - current_digest)) - debug('* Expected {}sum: {}'.format(alg, - expected_digest)) + debug(f'* Generated {alg}sum: {current_digest}') + debug(f'* Expected {alg}sum: {expected_digest}') raise ValueError( ('Generated {0}sum does not match expected {0}sum ' 'for {1} recipe').format(alg, self.name)) else: - info('{} download already cached, skipping'.format(self.name)) + info(f'{self.name} download already cached, skipping') def unpack(self, arch): - info_main('Unpacking {} for {}'.format(self.name, arch)) + info_main(f'Unpacking {self.name} for {arch}') build_dir = self.get_build_container_dir(arch) - user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower())) + user_dir = environ.get(f'P4A_{self.name.lower()}_DIR') if user_dir is not None: - info('P4A_{}_DIR exists, symlinking instead'.format( - self.name.lower())) + info(f'P4A_{self.name.lower()}_DIR exists, symlinking instead') if exists(self.get_build_dir(arch)): return rmdir(build_dir) @@ -439,12 +432,12 @@ def unpack(self, arch): return if self.url is None: - info('Skipping {} unpack as no URL is set'.format(self.name)) + info(f'Skipping {self.name} unpack as no URL is set') return filename = shprint( sh.basename, self.versioned_url).stdout[:-1].decode('utf-8') - ma = match(u'^(.+)#[a-z0-9_]{3,}=([0-9a-f]{32,})$', filename) + ma = match('^(.+)#[a-z0-9_]{3,}=([0-9a-f]{32,})$', filename) if ma: # fragmented URL? filename = ma.group(1) @@ -493,7 +486,7 @@ def unpack(self, arch): .format(extraction_filename)) else: - info('{} is already unpacked, skipping'.format(self.name)) + info(f'{self.name} is already unpacked, skipping') def get_recipe_env(self, arch=None, with_flags_in_cc=True): """Return the env specialized for the recipe @@ -507,11 +500,11 @@ def prebuild_arch(self, arch): '''Run any pre-build tasks for the Recipe. By default, this checks if any prebuild_archname methods exist for the archname of the current architecture, and runs them if so.''' - prebuild = "prebuild_{}".format(arch.arch.replace('-', '_')) + prebuild = f"prebuild_{arch.arch.replace('-', '_')}" if hasattr(self, prebuild): getattr(self, prebuild)() else: - info('{} has no {}, skipping'.format(self.name, prebuild)) + info(f'{self.name} has no {prebuild}, skipping') def is_patched(self, arch): build_dir = self.get_build_dir(arch.arch) @@ -523,11 +516,10 @@ def apply_patches(self, arch, build_dir=None): .. versionchanged:: 0.6.0 Add ability to apply patches from any dir via kwarg `build_dir`''' if self.patches: - info_main('Applying patches for {}[{}]' - .format(self.name, arch.arch)) + info_main(f'Applying patches for {self.name}[{arch.arch}]') if self.is_patched(arch): - info_main('{} already patched, skipping'.format(self.name)) + info_main(f'{self.name} already patched, skipping') return build_dir = build_dir if build_dir else self.get_build_dir(arch.arch) @@ -559,7 +551,7 @@ def build_arch(self, arch): '''Run any build tasks for the Recipe. By default, this checks if any build_archname methods exist for the archname of the current architecture, and runs them if so.''' - build = "build_{}".format(arch.arch) + build = f"build_{arch.arch}" if hasattr(self, build): getattr(self, build)() @@ -581,7 +573,7 @@ def postbuild_arch(self, arch): any postbuild_archname methods exist for the archname of the current architecture, and runs them if so. ''' - postbuild = "postbuild_{}".format(arch.arch) + postbuild = f"postbuild_{arch.arch}" if hasattr(self, postbuild): getattr(self, postbuild)() @@ -707,9 +699,9 @@ def get_recipe(cls, name, ctx): break else: - raise ValueError('Recipe does not exist: {}'.format(name)) + raise ValueError(f'Recipe does not exist: {name}') - mod = import_recipe('pythonforandroid.recipes.{}'.format(name), recipe_file) + mod = import_recipe(f'pythonforandroid.recipes.{name}', recipe_file) if len(logger.handlers) > 1: logger.removeHandler(logger.handlers[1]) recipe = mod.recipe @@ -718,7 +710,7 @@ def get_recipe(cls, name, ctx): return recipe -class IncludedFilesBehaviour(object): +class IncludedFilesBehaviour: '''Recipe mixin class that will automatically unpack files included in the recipe directory.''' src_filename = None @@ -765,8 +757,7 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True, with_python=False): env['PYTHON_INCLUDE_ROOT'] = self.ctx.python_recipe.include_root(arch.arch) env['PYTHON_LINK_ROOT'] = self.ctx.python_recipe.link_root(arch.arch) - env['EXTRA_LDLIBS'] = ' -lpython{}'.format( - self.ctx.python_recipe.link_version) + env['EXTRA_LDLIBS'] = f' -lpython{self.ctx.python_recipe.link_version}' return env @@ -868,18 +859,18 @@ def clean_build(self, arch=None): if site_packages_dir: build_dir = join(site_packages_dir[0], name) if exists(build_dir): - info('Deleted {}'.format(build_dir)) + info(f'Deleted {build_dir}') rmdir(build_dir) @property def real_hostpython_location(self): - host_name = 'host{}'.format(self.ctx.python_recipe.name) + host_name = f'host{self.ctx.python_recipe.name}' if host_name == 'hostpython3': python_recipe = Recipe.get_recipe(host_name, self.ctx) return python_recipe.python_exe else: python_recipe = self.ctx.python_recipe - return 'python{}'.format(python_recipe.version) + return f'python{python_recipe.version}' @property def hostpython_location(self): @@ -905,9 +896,7 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True): env["PATH"] = join(self.hostpython_site_dir, "bin") + ":" + env["PATH"] if not self.call_hostpython_via_targetpython: - env['CFLAGS'] += ' -I{}'.format( - self.ctx.python_recipe.include_root(arch.arch) - ) + env['CFLAGS'] += f' -I{self.ctx.python_recipe.include_root(arch.arch)}' env['LDFLAGS'] += ' -L{} -lpython{}'.format( self.ctx.python_recipe.link_root(arch.arch), self.ctx.python_recipe.link_version, @@ -932,7 +921,7 @@ def should_build(self, arch): if self.ctx.has_package(name, arch): info('Python package already exists in site-packages') return False - info('{} apparently isn\'t already in site-packages'.format(name)) + info(f'{name} apparently isn\'t already in site-packages') return True def build_arch(self, arch): @@ -951,13 +940,13 @@ def install_python_package(self, arch, name=None, env=None, is_dir=True): if env is None: env = self.get_recipe_env(arch) - info('Installing {} into site-packages'.format(self.name)) + info(f'Installing {self.name} into site-packages') hostpython = sh.Command(self.hostpython_location) hpenv = env.copy() with current_directory(self.get_build_dir(arch.arch)): shprint(hostpython, 'setup.py', 'install', '-O2', - '--root={}'.format(self.ctx.get_python_install_dir(arch.arch)), + f'--root={self.ctx.get_python_install_dir(arch.arch)}', '--install-lib=.', _env=hpenv, *self.setup_extra_args) @@ -978,7 +967,7 @@ def install_hostpython_package(self, arch): env = self.get_hostrecipe_env(arch) real_hostpython = sh.Command(self.real_hostpython_location) shprint(real_hostpython, 'setup.py', 'install', '-O2', - '--root={}'.format(dirname(self.real_hostpython_location)), + f'--root={dirname(self.real_hostpython_location)}', '--install-lib=Lib/site-packages', _env=env, *self.setup_extra_args) @@ -1030,7 +1019,7 @@ def build_arch(self, arch): self.install_python_package(arch) def build_compiled_components(self, arch): - info('Building compiled components in {}'.format(self.name)) + info(f'Building compiled components in {self.name}') env = self.get_recipe_env(arch) hostpython = sh.Command(self.hostpython_location) @@ -1049,7 +1038,7 @@ def install_hostpython_package(self, arch): super().install_hostpython_package(arch) def rebuild_compiled_components(self, arch, env): - info('Rebuilding compiled components in {}'.format(self.name)) + info(f'Rebuilding compiled components in {self.name}') hostpython = sh.Command(self.real_hostpython_location) shprint(hostpython, 'setup.py', 'clean', '--all', _env=env) @@ -1078,14 +1067,14 @@ def build_arch(self, arch): self.install_python_package(arch) def build_cython_components(self, arch): - info('Cythonizing anything necessary in {}'.format(self.name)) + info(f'Cythonizing anything necessary in {self.name}') env = self.get_recipe_env(arch) with current_directory(self.get_build_dir(arch.arch)): hostpython = sh.Command(self.ctx.hostpython) shprint(hostpython, '-c', 'import sys; print(sys.path)', _env=env) - debug('cwd is {}'.format(realpath(curdir))) + debug(f'cwd is {realpath(curdir)}') info('Trying first build of {} to get cython files: this is ' 'expected to fail'.format(self.name)) @@ -1095,7 +1084,7 @@ def build_cython_components(self, arch): *self.setup_extra_args) except sh.ErrorReturnCode_1: print() - info('{} first build failed (as expected)'.format(self.name)) + info(f'{self.name} first build failed (as expected)') manually_cythonise = True if manually_cythonise: @@ -1125,7 +1114,7 @@ def cythonize_file(self, env, build_dir, filename): short_filename = filename if filename.startswith(build_dir): short_filename = filename[len(build_dir) + 1:] - info(u"Cythonize {}".format(short_filename)) + info(f"Cythonize {short_filename}") cyenv = env.copy() if 'CYTHONPATH' in cyenv: cyenv['PYTHONPATH'] = cyenv['CYTHONPATH'] @@ -1166,7 +1155,7 @@ def get_recipe_env(self, arch, with_flags_in_cc=True): # Every recipe uses its own liblink path, object files are # collected and biglinked later liblink_path = join(self.get_build_container_dir(arch.arch), - 'objects_{}'.format(self.name)) + f'objects_{self.name}') env['LIBLINK_PATH'] = liblink_path ensure_dir(liblink_path) @@ -1190,9 +1179,7 @@ def get_recipe_env(self, arch, **kwargs): build_opts = join(build_dir, "build-opts.cfg") with open(build_opts, "w") as file: - file.write("[bdist_wheel]\nplat-name={}".format( - self.get_wheel_platform_tag(arch) - )) + file.write(f"[bdist_wheel]\nplat-name={self.get_wheel_platform_tag(arch)}") file.close() env["DIST_EXTRA_CONFIG"] = build_opts @@ -1246,7 +1233,7 @@ def build_arch(self, arch): "build", "--wheel", "--config-setting", - "builddir={}".format(sub_build_dir), + f"builddir={sub_build_dir}", ] + self.extra_build_args built_wheels = [] @@ -1309,13 +1296,13 @@ def write_build_options(self, arch): option_data = "" build_options = self.get_recipe_meson_options(arch) for key in build_options.keys(): - data_chunk = "[{}]".format(key) + data_chunk = f"[{key}]" for subkey in build_options[key].keys(): value = build_options[key][subkey] if isinstance(value, int): value = str(value) elif isinstance(value, str): - value = "'{}'".format(value) + value = f"'{value}'" elif isinstance(value, bool): value = "true" if value else "false" elif isinstance(value, list): @@ -1331,17 +1318,17 @@ def ensure_args(self, *args): def build_arch(self, arch): cross_file = join("/tmp", "android.meson.cross") - info("Writing cross file at: {}".format(cross_file)) + info(f"Writing cross file at: {cross_file}") # write cross config file with open(cross_file, "w") as file: file.write(self.write_build_options(arch)) file.close() # set cross file - self.ensure_args('-Csetup-args=--cross-file', '-Csetup-args={}'.format(cross_file)) + self.ensure_args('-Csetup-args=--cross-file', f'-Csetup-args={cross_file}') # ensure ninja and meson for dep in [ - "ninja=={}".format(self.ninja_version), - "meson=={}".format(self.meson_version), + f"ninja=={self.ninja_version}", + f"meson=={self.meson_version}", ]: if dep not in self.hostpython_prerequisites: self.hostpython_prerequisites.append(dep) @@ -1388,7 +1375,7 @@ def get_recipe_env(self, arch, **kwargs): env["PYO3_CROSS_LIB_DIR"] = realpath(glob.glob(join( realpython_dir, "android-build", "build", - "lib.linux-*-{}/".format(self.python_major_minor_version), + f"lib.linux-*-{self.python_major_minor_version}/", ))[0]) info_main("Ensuring rust build toolchain") @@ -1447,7 +1434,7 @@ def create_python_bundle(self, dirn, arch): copying all the modules and standard library to the right place. """ - raise NotImplementedError('{} does not implement create_python_bundle'.format(self)) + raise NotImplementedError(f'{self} does not implement create_python_bundle') def reduce_object_file_names(self, dirn): """Recursively renames all files named XXX.cpython-...-linux-gnu.so" diff --git a/recipes/libopus/__init__.py b/recipes/libopus/__init__.py index 1eb4977..c698809 100644 --- a/recipes/libopus/__init__.py +++ b/recipes/libopus/__init__.py @@ -12,7 +12,7 @@ def build_arch(self, arch): with current_directory(self.get_build_dir(arch.arch)): env = self.get_recipe_env(arch) flags = [ - '--host=' + arch.command_prefix, + f"--host={arch.command_prefix}", ] configure = sh.Command('./configure') shprint(configure, *flags, _env=env) diff --git a/recipes/mffmpeg/__init__.py b/recipes/mffmpeg/__init__.py index a51a246..c11ea81 100644 --- a/recipes/mffmpeg/__init__.py +++ b/recipes/mffmpeg/__init__.py @@ -40,9 +40,9 @@ def build_arch(self, arch): ] build_dir = Recipe.get_recipe( 'openssl', self.ctx).get_build_dir(arch.arch) - cflags += ['-I' + build_dir + '/include/', + cflags += [f"-I{build_dir}/include/", '-DOPENSSL_API_COMPAT=0x10002000L'] - ldflags += ['-L' + build_dir] + ldflags += [f"-L{build_dir}"] if 'ffpyplayer_codecs' in self.ctx.recipe_build_order: # Enable GPL @@ -52,22 +52,22 @@ def build_arch(self, arch): flags += ['--enable-libx264'] build_dir = Recipe.get_recipe( 'libx264', self.ctx).get_build_dir(arch.arch) - cflags += ['-I' + build_dir + '/include/'] - ldflags += ['-lx264', '-L' + build_dir + '/lib/'] + cflags += [f"-I{build_dir}/include/"] + ldflags += ['-lx264', f"-L{build_dir}/lib/"] # libshine flags += ['--enable-libshine'] build_dir = Recipe.get_recipe('libshine', self.ctx).get_build_dir(arch.arch) - cflags += ['-I' + build_dir + '/include/'] - ldflags += ['-lshine', '-L' + build_dir + '/lib/'] + cflags += [f"-I{build_dir}/include/"] + ldflags += ['-lshine', f"-L{build_dir}/lib/"] ldflags += ['-lm'] # libvpx flags += ['--enable-libvpx'] build_dir = Recipe.get_recipe( 'libvpx', self.ctx).get_build_dir(arch.arch) - cflags += ['-I' + build_dir + '/include/'] - ldflags += ['-lvpx', '-L' + build_dir + '/lib/'] + cflags += [f"-I{build_dir}/include/"] + ldflags += ['-lvpx', f"-L{build_dir}/lib/"] # Enable all codecs: flags += [ @@ -122,12 +122,12 @@ def build_arch(self, arch): flags += [ '--target-os=android', '--enable-cross-compile', - '--cross-prefix={}-'.format(arch.target), - '--arch={}'.format(arch_flag), - '--strip={}'.format(self.ctx.ndk.llvm_strip), - '--sysroot={}'.format(self.ctx.ndk.sysroot), + f'--cross-prefix={arch.target}-', + f'--arch={arch_flag}', + f'--strip={self.ctx.ndk.llvm_strip}', + f'--sysroot={self.ctx.ndk.sysroot}', '--enable-neon', - '--prefix={}'.format(realpath('.')), + f"--prefix={realpath('.')}", ] if arch_flag == 'arm': @@ -137,8 +137,8 @@ def build_arch(self, arch): '-fPIC', ] - env['CFLAGS'] += ' ' + ' '.join(cflags) - env['LDFLAGS'] += ' ' + ' '.join(ldflags) + env['CFLAGS'] += f" {' '.join(cflags)}" + env['LDFLAGS'] += f" {' '.join(ldflags)}" configure = sh.Command('./configure') shprint(configure, *flags, _env=env) diff --git a/recipes/numpy/__init__.py b/recipes/numpy/__init__.py index 55a0279..2f845d8 100644 --- a/recipes/numpy/__init__.py +++ b/recipes/numpy/__init__.py @@ -37,7 +37,7 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True): return env def _build_compiled_components(self, arch): - info('Building compiled components in {}'.format(self.name)) + info(f'Building compiled components in {self.name}') env = self.get_recipe_env(arch) with current_directory(self.get_build_dir(arch.arch)): @@ -49,7 +49,7 @@ def _build_compiled_components(self, arch): env['STRIP'], '{}', ';', _env=env) def _rebuild_compiled_components(self, arch, env): - info('Rebuilding compiled components in {}'.format(self.name)) + info(f'Rebuilding compiled components in {self.name}') hostpython = sh.Command(self.real_hostpython_location) shprint(hostpython, 'setup.py', 'clean', '--all', '--force', _env=env) diff --git a/recipes/opusfile/__init__.py b/recipes/opusfile/__init__.py index 27d0f29..e82282b 100644 --- a/recipes/opusfile/__init__.py +++ b/recipes/opusfile/__init__.py @@ -15,7 +15,7 @@ def build_arch(self, arch): with current_directory(self.get_build_dir(arch.arch)): env = self.get_recipe_env(arch) flags = [ - "--host=" + arch.command_prefix, + f"--host={arch.command_prefix}", "--disable-http", "--disable-examples", "--disable-doc", diff --git a/recipes/pycodec2/__init__.py b/recipes/pycodec2/__init__.py index 6ad05bd..cb4918b 100644 --- a/recipes/pycodec2/__init__.py +++ b/recipes/pycodec2/__init__.py @@ -17,9 +17,9 @@ def get_recipe_env(self, arch, with_flags_in_cc=True): env = super().get_recipe_env(arch, with_flags_in_cc) codec2_recipe = self.get_recipe('codec2', self.ctx) - env['CFLAGS'] += codec2_recipe.include_flags(arch) +" -l:libcodec2.so" - env['LDFLAGS'] += ' -L{}'.format(self.ctx.get_libs_dir(arch.arch)) - env['LDFLAGS'] += ' -L{}'.format(self.ctx.libs_dir) + env['CFLAGS'] += f"{codec2_recipe.include_flags(arch)} -l:libcodec2.so" + 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 diff --git a/sbapp/__init__.py b/sbapp/__init__.py index f49e360..1d03710 100644 --- a/sbapp/__init__.py +++ b/sbapp/__init__.py @@ -1,5 +1,5 @@ import os import glob -modules = glob.glob(os.path.dirname(__file__)+"/*.py") +modules = glob.glob(f"{os.path.dirname(__file__)}/*.py") __all__ = [ os.path.basename(f)[:-3] for f in modules if not f.endswith('__init__.py')] \ No newline at end of file diff --git a/sbapp/assets/icons_macos.py b/sbapp/assets/icons_macos.py index cbab2cb..fa57537 100644 --- a/sbapp/assets/icons_macos.py +++ b/sbapp/assets/icons_macos.py @@ -222,10 +222,7 @@ def main(): iconsetDir.mkdir() except Exception as ex: raise SystemExit( - " ".join(( - "[ERROR] Could not create temporary", - f"iconset folder: {iconsetDir}" - )) + f"[ERROR] Could not create temporary iconset folder: {iconsetDir}" ) else: if False: # cliArgs.delete_tmp_iconset: @@ -303,10 +300,7 @@ def main(): ) else: print( - " ".join(( - "[SUCCESS] An iconset was successfully", - f"generated to {resultingIconset}" - )) + f"[SUCCESS] An iconset was successfully generated to {resultingIconset}" ) raise SystemExit(0) diff --git a/sbapp/freeze.py b/sbapp/freeze.py index 81f5ad8..bdbe0f0 100644 --- a/sbapp/freeze.py +++ b/sbapp/freeze.py @@ -11,7 +11,7 @@ def get_version() -> str: os.path.dirname(__file__), "main.py" ) - version_file_data = open(version_file, "rt", encoding="utf-8").read() + version_file_data = open(version_file, encoding="utf-8").read() version_regex = r"(?<=^__version__ = ['\"])[^'\"]+(?=['\"]$)" try: version = re.findall(version_regex, version_file_data, re.M)[0] @@ -24,7 +24,7 @@ def get_variant() -> str: os.path.dirname(__file__), "main.py" ) - version_file_data = open(version_file, "rt", encoding="utf-8").read() + version_file_data = open(version_file, encoding="utf-8").read() version_regex = r"(?<=^__variant__ = ['\"])[^'\"]+(?=['\"]$)" try: version = re.findall(version_regex, version_file_data, re.M)[0] @@ -60,14 +60,14 @@ def glob_paths(pattern): ] } -print("Freezing Sideband "+__version__+" "+__variant__) +print(f"Freezing Sideband {__version__} {__variant__}") if build_appimage: global_excludes = [".buildozer", "build", "dist"] # Dependencies are automatically detected, but they might need fine-tuning. appimage_options = { "target_name": "Sideband", - "target_version": __version__+" "+__variant__, + "target_version": f"{__version__} {__variant__}", "include_files": [], "excludes": [], "packages": ["kivy"], diff --git a/sbapp/gv.py b/sbapp/gv.py index 6d07c8c..350e6d2 100644 --- a/sbapp/gv.py +++ b/sbapp/gv.py @@ -5,7 +5,7 @@ def gv() -> str: os.path.dirname(__file__), "main.py" ) - version_file_data = open(version_file, "rt", encoding="utf-8").read() + version_file_data = open(version_file, encoding="utf-8").read() version_regex = r"(?<=^__version__ = ['\"])[^'\"]+(?=['\"]$)" try: version = re.findall(version_regex, version_file_data, re.M)[0] diff --git a/sbapp/kivymd/font_definitions.py b/sbapp/kivymd/font_definitions.py index e7cc8e2..84c45a5 100755 --- a/sbapp/kivymd/font_definitions.py +++ b/sbapp/kivymd/font_definitions.py @@ -14,34 +14,34 @@ fonts = [ { "name": "Roboto", - "fn_regular": fonts_path + "Roboto-Regular.ttf", - "fn_bold": fonts_path + "Roboto-Bold.ttf", - "fn_italic": fonts_path + "Roboto-Italic.ttf", - "fn_bolditalic": fonts_path + "Roboto-BoldItalic.ttf", + "fn_regular": f"{fonts_path}Roboto-Regular.ttf", + "fn_bold": f"{fonts_path}Roboto-Bold.ttf", + "fn_italic": f"{fonts_path}Roboto-Italic.ttf", + "fn_bolditalic": f"{fonts_path}Roboto-BoldItalic.ttf", }, { "name": "RobotoThin", - "fn_regular": fonts_path + "Roboto-Thin.ttf", - "fn_italic": fonts_path + "Roboto-ThinItalic.ttf", + "fn_regular": f"{fonts_path}Roboto-Thin.ttf", + "fn_italic": f"{fonts_path}Roboto-ThinItalic.ttf", }, { "name": "RobotoLight", - "fn_regular": fonts_path + "Roboto-Light.ttf", - "fn_italic": fonts_path + "Roboto-LightItalic.ttf", + "fn_regular": f"{fonts_path}Roboto-Light.ttf", + "fn_italic": f"{fonts_path}Roboto-LightItalic.ttf", }, { "name": "RobotoMedium", - "fn_regular": fonts_path + "Roboto-Medium.ttf", - "fn_italic": fonts_path + "Roboto-MediumItalic.ttf", + "fn_regular": f"{fonts_path}Roboto-Medium.ttf", + "fn_italic": f"{fonts_path}Roboto-MediumItalic.ttf", }, { "name": "RobotoBlack", - "fn_regular": fonts_path + "Roboto-Black.ttf", - "fn_italic": fonts_path + "Roboto-BlackItalic.ttf", + "fn_regular": f"{fonts_path}Roboto-Black.ttf", + "fn_italic": f"{fonts_path}Roboto-BlackItalic.ttf", }, { "name": "Icons", - "fn_regular": fonts_path + "materialdesignicons-webfont.ttf", + "fn_regular": f"{fonts_path}materialdesignicons-webfont.ttf", }, ] diff --git a/sbapp/kivymd/tools/hotreload/app.py b/sbapp/kivymd/tools/hotreload/app.py index d3ef77f..47d7c28 100644 --- a/sbapp/kivymd/tools/hotreload/app.py +++ b/sbapp/kivymd/tools/hotreload/app.py @@ -182,7 +182,7 @@ class MDApp(BaseApp): def build(self): if self.DEBUG: - Logger.info("{}: Debug mode activated".format(self.appname)) + Logger.info(f"{self.appname}: Debug mode activated") self.enable_autoreload() self.patch_builder() self.bind_key(32, self.rebuild) @@ -267,7 +267,7 @@ def load_app_dependencies(self): Builder.load_file(path_to_kv_file) def rebuild(self, *args, **kwargs): - print("{}: Rebuild the application".format(self.appname)) + print(f"{self.appname}: Rebuild the application") first = kwargs.get("first", False) try: if not first: @@ -287,7 +287,7 @@ def rebuild(self, *args, **kwargs): except Exception as exc: import traceback - Logger.exception("{}: Error when building app".format(self.appname)) + Logger.exception(f"{self.appname}: Error when building app") self.set_error(repr(exc), traceback.format_exc()) if not self.DEBUG and self.RAISE_ERROR: raise @@ -304,7 +304,7 @@ def set_error(self, exc, tb=None): lbl = Factory.Label( text_size=(Window.width - 100, None), size_hint_y=None, - text="{}\n\n{}".format(exc, tb or ""), + text=f"{exc}\n\n{tb or ''}", ) lbl.bind(texture_size=lbl.setter("size")) scroll.add_widget(lbl) @@ -338,10 +338,10 @@ def enable_autoreload(self): from watchdog.observers import Observer except ImportError: Logger.warn( - "{}: Autoreloader is missing watchdog".format(self.appname) + f"{self.appname}: Autoreloader is missing watchdog" ) return - Logger.info("{}: Autoreloader activated".format(self.appname)) + Logger.info(f"{self.appname}: Autoreloader activated") rootpath = self.get_root_path() self.w_handler = handler = FileSystemEventHandler() handler.dispatch = self._reload_from_watchdog @@ -402,16 +402,12 @@ def install_idle(self, timeout=60): if monotonic is None: Logger.exception( - "{}: Cannot use idle detector, monotonic is missing".format( - self.appname - ) + f"{self.appname}: Cannot use idle detector, monotonic is missing" ) self.idle_timer = None self.idle_timeout = timeout Logger.info( - "{}: Install idle detector, {} seconds".format( - self.appname, timeout - ) + f"{self.appname}: Install idle detector, {timeout} seconds" ) Clock.schedule_interval(self._check_idle, 1) self.root.bind( @@ -498,7 +494,7 @@ def _reload_py(self, filename): module = self._filename_to_module(filename) if module in sys.modules: - Logger.debug("{}: Module exist, reload it".format(self.appname)) + Logger.debug(f"{self.appname}: Module exist, reload it") Factory.unregister_from_filename(filename) self._unregister_factory_from_module(module) reload(sys.modules[module]) @@ -528,9 +524,7 @@ def _filename_to_module(self, filename): filename = filename[1:] module = filename[:-3].replace("/", ".") Logger.debug( - "{}: Translated {} to {}".format( - self.appname, orig_filename, module - ) + f"{self.appname}: Translated {orig_filename} to {module}" ) return module diff --git a/sbapp/kivymd/tools/patterns/create_project.py b/sbapp/kivymd/tools/patterns/create_project.py index 864ed55..c1aaa0d 100644 --- a/sbapp/kivymd/tools/patterns/create_project.py +++ b/sbapp/kivymd/tools/patterns/create_project.py @@ -982,7 +982,7 @@ def create_module_screens() -> None: path_to_module_screens = os.path.join(path_to_project, "View", "screens.py") with open(path_to_module_screens, "w", encoding="utf-8") as module_screens: module_screens.write( - "%s\nscreens = {%s}" % (temp_screens_imports, temp_screens_data) + f"{temp_screens_imports}\nscreens = {{{temp_screens_data}}}" ) diff --git a/sbapp/kivymd/tools/release/make_release.py b/sbapp/kivymd/tools/release/make_release.py index f321a2d..eb24bc6 100644 --- a/sbapp/kivymd/tools/release/make_release.py +++ b/sbapp/kivymd/tools/release/make_release.py @@ -53,9 +53,9 @@ def run_pre_commit(): def replace_in_file(pattern, repl, file): """Replace one `pattern` match to `repl` in file `file`.""" - file_content = open(file, "rt", encoding="utf-8").read() + file_content = open(file, encoding="utf-8").read() new_file_content = re.sub(pattern, repl, file_content, 1, re.M) - open(file, "wt", encoding="utf-8").write(new_file_content) + open(file, "w", encoding="utf-8").write(new_file_content) return not file_content == new_file_content @@ -116,7 +116,7 @@ def move_changelog( """Edit unreleased.rst and rename to .rst.""" # Read unreleased changelog - changelog = open(unreleased_file, "rt", encoding="utf-8").read() + changelog = open(unreleased_file, encoding="utf-8").read() # Edit changelog changelog = re.sub( @@ -157,7 +157,7 @@ def move_changelog( ) # Write changelog - open(version_file, "wt", encoding="utf-8").write(changelog) + open(version_file, "w", encoding="utf-8").write(changelog) # Remove unreleased changelog os.remove(unreleased_file) # Update index file @@ -200,7 +200,7 @@ def create_unreleased_changelog( * Bug fixes and other minor improvements. """ # Create unreleased file - open(unreleased_file, "wt", encoding="utf-8").write(changelog) + open(unreleased_file, "w", encoding="utf-8").write(changelog) # Update index file success = replace_in_file( r"(?<=Changelog\n=========\n\n)", @@ -218,7 +218,7 @@ def main(): release = args.command == "release" version = args.version or "0.0.0" next_version = args.next_version or ( - (version[:-1] + str(int(version[-1]) + 1) + ".dev0") + f"{version[:-1] + str(int(version[-1]) + 1)}.dev0" if "rc" not in version else version ) diff --git a/sbapp/kivymd/tools/release/update_icons.py b/sbapp/kivymd/tools/release/update_icons.py index 13fd43d..96627db 100644 --- a/sbapp/kivymd/tools/release/update_icons.py +++ b/sbapp/kivymd/tools/release/update_icons.py @@ -74,7 +74,7 @@ def unzip_archive(archive_path, dir_path): def get_icons_list(): # There is js array with icons in file preview.html - with open(temp_preview_path, "r") as f: + with open(temp_preview_path) as f: preview_file = f.read() # Find version version = re_version.findall(preview_file)[0] @@ -101,13 +101,13 @@ def make_icon_definitions(icons): icon_definitions += f'"{i["name"]}": "\\U{i["hex"].upper()}",\n' else: icon_definitions += f'"{i["name"]}": "\\u{i["hex"].upper()}",\n' - icon_definitions += " " * 4 + '"blank": " ",\n' # Add blank icon (space) + icon_definitions += f"{' ' * 4}\"blank\": \" \",\n" # Add blank icon (space) icon_definitions += "}" return icon_definitions def export_icon_definitions(icon_definitions, version): - with open(icon_definitions_path, "r") as f: + with open(icon_definitions_path) as f: icon_definitions_file = f.read() # Change md_icons list new_icon_definitions = re_icon_definitions.sub( diff --git a/sbapp/kivymd/uix/behaviors/hover_behavior.py b/sbapp/kivymd/uix/behaviors/hover_behavior.py index dbe1ce2..07e6fa8 100644 --- a/sbapp/kivymd/uix/behaviors/hover_behavior.py +++ b/sbapp/kivymd/uix/behaviors/hover_behavior.py @@ -88,7 +88,7 @@ def build(self): from kivy.uix.widget import Widget -class HoverBehavior(object): +class HoverBehavior: """ :Events: :attr:`on_enter` @@ -136,7 +136,7 @@ def __init__(self, **kwargs): self.register_event_type("on_enter") self.register_event_type("on_leave") Window.bind(mouse_pos=self.on_mouse_update) - super(HoverBehavior, self).__init__(**kwargs) + super().__init__(**kwargs) def on_mouse_update(self, *args): # If the Widget currently has no parent, do nothing diff --git a/sbapp/kivymd/uix/button/button.py b/sbapp/kivymd/uix/button/button.py index 5750a33..cd7ccb9 100755 --- a/sbapp/kivymd/uix/button/button.py +++ b/sbapp/kivymd/uix/button/button.py @@ -1477,7 +1477,7 @@ def __init__(self, *args, **kwargs): self.line_width = 0.001 Clock.schedule_once(self.set_size) - def set_size(self, interval: Union[int, float]) -> None: + def set_size(self, interval: int | float) -> None: """ Sets the icon width/height based on the current `icon_size` attribute, or the default value if it is zero. The icon size @@ -1637,7 +1637,7 @@ class BaseFloatingBottomButton(MDFloatingActionButton, MDTooltip): _padding_right = NumericProperty(0) _bg_color = ColorProperty(None) - def set_size(self, interval: Union[int, float]) -> None: + def set_size(self, interval: int | float) -> None: self.width = "46dp" self.height = "46dp" diff --git a/sbapp/kivymd/uix/datatables/datatables.py b/sbapp/kivymd/uix/datatables/datatables.py index 44748a5..52ceb12 100644 --- a/sbapp/kivymd/uix/datatables/datatables.py +++ b/sbapp/kivymd/uix/datatables/datatables.py @@ -339,7 +339,6 @@ def __init__(self, **kwargs): self._col_headings.append(col_heading[0]) if i: self.ids.header.add_widget( - ( CellHeader( text=col_heading[0], sort_action=col_heading[2], @@ -362,7 +361,6 @@ def __init__(self, **kwargs): width=self.cols_minimum[i], table_data=self.table_data, ) - ) ) else: # Sets the text in the first cell. diff --git a/sbapp/kivymd/uix/filemanager/filemanager.py b/sbapp/kivymd/uix/filemanager/filemanager.py index 728c796..217afe4 100755 --- a/sbapp/kivymd/uix/filemanager/filemanager.py +++ b/sbapp/kivymd/uix/filemanager/filemanager.py @@ -650,7 +650,7 @@ def get_content( return dirs, files except OSError as e: - print("Filemanager OSError: "+str(e)) + print(f"Filemanager OSError: {e)}") return None, None def close(self) -> None: diff --git a/sbapp/kivymd/uix/label/label.py b/sbapp/kivymd/uix/label/label.py index 73bd46b..4358361 100755 --- a/sbapp/kivymd/uix/label/label.py +++ b/sbapp/kivymd/uix/label/label.py @@ -711,7 +711,7 @@ def __init__(self, *args, **kwargs): self.on_opposite_colors(None, self.opposite_colors) Clock.schedule_once(self.check_font_styles) - def check_font_styles(self, interval: Union[int, float] = 0) -> bool: + def check_font_styles(self, interval: int | float = 0) -> bool: if self.font_style not in list(self.theme_cls.font_styles.keys()): raise ValueError( f"MDLabel.font_style is set to an invalid option '{self.font_style}'." @@ -828,7 +828,7 @@ def on_theme_text_color( else: self.color = color - def on_text_color(self, instance_label, color: Union[list, str]) -> None: + def on_text_color(self, instance_label, color: list | str) -> None: if self.theme_text_color == "Custom": if self.theme_cls.theme_style_switch_animation: Animation( @@ -842,7 +842,7 @@ def on_text_color(self, instance_label, color: Union[list, str]) -> None: def on_opposite_colors(self, *args) -> None: self.on_theme_text_color(self, self.theme_text_color) - def on_md_bg_color(self, instance_label, color: Union[list, str]) -> None: + def on_md_bg_color(self, instance_label, color: list | str) -> None: self.canvas.remove_group("Background_instruction") self.canvas.before.clear() with self.canvas.before: diff --git a/sbapp/kivymd/uix/pickers/colorpicker/colorpicker.py b/sbapp/kivymd/uix/pickers/colorpicker/colorpicker.py index c289dd4..0905bcc 100644 --- a/sbapp/kivymd/uix/pickers/colorpicker/colorpicker.py +++ b/sbapp/kivymd/uix/pickers/colorpicker/colorpicker.py @@ -229,10 +229,10 @@ def create_gradient_texture( else self.color_picker.get_rgb(self.theme_cls.primary_color) ) else: - r, g, b = [ + r, g, b = ( int(value * 255) for value in self.color_picker.default_color[:-1] - ] + ) self.color_picker._rgb = [r, g, b] ( r_adjacent_color_constant, diff --git a/sbapp/kivymd/uix/pickers/datepicker/datepicker.py b/sbapp/kivymd/uix/pickers/datepicker/datepicker.py index 3b24f9e..0d2731d 100644 --- a/sbapp/kivymd/uix/pickers/datepicker/datepicker.py +++ b/sbapp/kivymd/uix/pickers/datepicker/datepicker.py @@ -678,7 +678,7 @@ def set_error(self): self.error = True - def input_filter(self, value: str, boolean: bool) -> Union[str, None]: + def input_filter(self, value: str, boolean: bool) -> str | None: """Filters the input according to the specified mode.""" if self.is_numeric(value): @@ -1077,7 +1077,7 @@ def transformation_to_dialog_input_date(self) -> None: self._update_date_label_text() def transformation_from_dialog_input_date( - self, interval: Union[int, float] + self, interval: int | float ) -> None: if not self._try_apply_input(): return @@ -1299,7 +1299,7 @@ def set_text_full_date(self, year, month, day, orientation): horizontal = orientation == "portrait" or self._input_date_dialog_open def date_repr(date): - return date.strftime("%b").capitalize() + " " + str(date.day) + return f"{date.strftime('%b').capitalize()} {date.day)}" input_dates = self._get_dates_from_fields() if self.mode == "picker": diff --git a/sbapp/kivymd/uix/pickers/timepicker/timepicker.py b/sbapp/kivymd/uix/pickers/timepicker/timepicker.py index e45a784..8a55a32 100644 --- a/sbapp/kivymd/uix/pickers/timepicker/timepicker.py +++ b/sbapp/kivymd/uix/pickers/timepicker/timepicker.py @@ -243,7 +243,7 @@ def validate_time(self, text) -> Union[None, re.Match]: def insert_text(self, text, from_undo=False): strip_text = self.text.strip() - current_string = "".join([strip_text, text]) + current_string = f"{strip_text}{text}" if not self.validate_time(current_string): text = "" return super().insert_text(text, from_undo=from_undo) diff --git a/sbapp/kivymd/uix/textfield/textfield.py b/sbapp/kivymd/uix/textfield/textfield.py index a351580..b2802ab 100755 --- a/sbapp/kivymd/uix/textfield/textfield.py +++ b/sbapp/kivymd/uix/textfield/textfield.py @@ -356,7 +356,7 @@ def format(self, value): elif len(value) == 4: start = self.text[:-1] end = self.text[-1] - self.text = "%s) %s" % (start, end) + self.text = f"{start}) {end}" self._check_cursor() elif len(value) == 8: self.text += "-" @@ -364,7 +364,7 @@ def format(self, value): elif len(value) in [12, 16]: start = self.text[:-1] end = self.text[-1] - self.text = "%s-%s" % (start, end) + self.text = f"{start}-{end}" self._check_cursor() def _check_cursor(self): diff --git a/sbapp/kivymd/uix/toolbar/toolbar.py b/sbapp/kivymd/uix/toolbar/toolbar.py index 091b040..e215c6a 100755 --- a/sbapp/kivymd/uix/toolbar/toolbar.py +++ b/sbapp/kivymd/uix/toolbar/toolbar.py @@ -1371,7 +1371,7 @@ def __init__(self, **kwargs): Clock.schedule_once(self.update_floating_radius) Clock.schedule_once(self.check_overflow_cls) - def set_headline_font_style(self, interval: Union[int, float]) -> None: + def set_headline_font_style(self, interval: int | float) -> None: if self.type_height in ("medium", "large"): self.ids.label_headline.font_style = { "medium": "H6", @@ -1470,7 +1470,7 @@ def add_action_button_to_overflow(self): self.overflow_cls.items = self._overflow_menu_items self.overflow_cls.caller = self.ids.right_actions.children[0] - def check_overflow_cls(self, interval: Union[int, float]) -> None: + def check_overflow_cls(self, interval: int | float) -> None: """ If the user does not set the :attr:`overflow_cls` attribute but uses overflows, the :attr:`overflow_cls` attribute will use the default @@ -1537,7 +1537,7 @@ def on_md_bg_color(self, instance_toolbar, color_value: list) -> None: Called when the value of the :attr:`md_bg_color` attribute changes. """ - def on_md_bg_color(interval: Union[int, float]): + def on_md_bg_color(interval: int | float): if self.type == "bottom": self.md_bg_color = [0, 0, 0, 0] else: @@ -1554,7 +1554,7 @@ def on_left_action_items(self, instance_toolbar, items_value: list) -> None: changes. """ - def on_left_action_items(interval: Union[int, float]): + def on_left_action_items(interval: int | float): self.update_action_bar(self.ids.left_actions, items_value) Clock.schedule_once(on_left_action_items) @@ -1567,7 +1567,7 @@ def on_right_action_items( changes. """ - def on_right_actions(interval: Union[int, float]): + def on_right_actions(interval: int | float): self.update_action_bar(self.ids.right_actions, items_value) Clock.schedule_once(on_right_actions) @@ -1599,7 +1599,7 @@ def on_anchor_title(self, instance_toolbar, anchor_value: str) -> None: Called when the value of the :attr:`anchor_title` attribute changes. """ - def on_anchor_title(interval: Union[int, float]): + def on_anchor_title(interval: int | float): self.ids.label_title.halign = anchor_value Clock.schedule_once(on_anchor_title) @@ -1610,7 +1610,7 @@ def on_mode(self, instance_toolbar, mode_value: str) -> None: if self.type == "top": return - def on_mode(interval: Union[int, float]): + def on_mode(interval: int | float): def set_button_pos(*args): self.action_button.x = x self.action_button.y = y - self._rounded_rectangle_height / 2 @@ -1685,7 +1685,7 @@ def update_bar_height( self.on_type_height(self, self.type_height) self.update_anchor_title(material_style_value) - def update_floating_radius(self, interval: Union[int, float]) -> None: + def update_floating_radius(self, interval: int | float) -> None: self.action_button.radius = self.action_button.width / 2 def update_anchor_title(self, material_style_value: str) -> str: diff --git a/sbapp/kivymd/utils/fpsmonitor.py b/sbapp/kivymd/utils/fpsmonitor.py index 4fbc2fc..7756474 100644 --- a/sbapp/kivymd/utils/fpsmonitor.py +++ b/sbapp/kivymd/utils/fpsmonitor.py @@ -45,4 +45,4 @@ def start(self): Clock.schedule_interval(self.update_fps, self.updated_interval) def update_fps(self, *args): - self._fsp_value = "FPS: %f" % Clock.get_fps() + self._fsp_value = f"FPS: {Clock.get_fps():f}" diff --git a/sbapp/main.py b/sbapp/main.py index 4a222e9..b695e7c 100644 --- a/sbapp/main.py +++ b/sbapp/main.py @@ -11,7 +11,7 @@ parser.add_argument("-d", "--daemon", action='store_true', default=False, help="run as a daemon, without user interface") parser.add_argument("--export-settings", action='store', default=None, help="export application settings to file") parser.add_argument("--import-settings", action='store', default=None, help="import application settings from file") -parser.add_argument("--version", action="version", version="sideband {version}".format(version=__version__)) +parser.add_argument("--version", action="version", version=f"sideband {__version__}") args = parser.parse_args() sys.argv = [sys.argv[0]] @@ -35,7 +35,7 @@ load_config_only=True, ) - sideband.version_str = "v"+__version__+" "+__variant__ + sideband.version_str = f"v{__version__} {__variant__}" import json export = sideband.config.copy() @@ -64,7 +64,7 @@ load_config_only=True, ) - sideband.version_str = "v"+__version__+" "+__variant__ + sideband.version_str = f"v{__version__} {__variant__}" import json addr_fields = ["lxmf_propagation_node", "last_lxmf_propagation_node", "nn_home_node", "telemetry_collector"] @@ -106,9 +106,9 @@ def debug(self, arg): def trace(self, arg): pass def warning(self, arg): - RNS.log("Kivy error: "+str(arg), RNS.LOG_WARNING) + RNS.log(f"Kivy error: {arg)}", RNS.LOG_WARNING) def critical(self, arg): - RNS.log("Kivy error: "+str(arg), RNS.LOG_ERROR) + RNS.log(f"Kivy error: {arg)}", RNS.LOG_ERROR) if RNS.vendor.platformutils.get_platform() == "android": import jnius.reflect @@ -272,7 +272,7 @@ def __init__(self, **kwargs): else: self.sideband = SidebandCore(self, config_path=self.config_path, is_client=False, verbose=(args.verbose or __debug_build__)) - self.sideband.version_str = "v"+__version__+" "+__variant__ + self.sideband.version_str = f"v{__version__} {__variant__}" self.set_ui_theme() self.font_config() @@ -318,8 +318,8 @@ def __init__(self, **kwargs): self.key_ptt_down = False Window.softinput_mode = "below_target" - self.icon = self.sideband.asset_dir+"/icon.png" - self.notification_icon = self.sideband.asset_dir+"/notification_icon.png" + self.icon = f"{self.sideband.asset_dir}/icon.png" + self.notification_icon = f"{self.sideband.asset_dir}/notification_icon.png" self.connectivity_updater = None self.last_map_update = 0 @@ -370,7 +370,7 @@ def sjob(dt): def start_service(self): if RNS.vendor.platformutils.is_android(): - RNS.log("Running on Android API level "+str(android_api_version)) + RNS.log(f"Running on Android API level {android_api_version)}") RNS.log("Launching platform-specific service for RNS and LXMF") if RNS.vendor.platformutils.get_platform() == "android": @@ -442,7 +442,7 @@ def check_errors(dt): ) self.hw_error_dialog = MDDialog( title="Hardware Error", - text="When starting a connected RNode, Reticulum reported the following error:\n\n[i]"+str(description)+"[/i]", + text=f"When starting a connected RNode, Reticulum reported the following error:\n\n[i]{description)}[/i]", buttons=[ yes_button ], # elevation=0, ) @@ -479,31 +479,31 @@ def set_ui_theme(self): def font_config(self): from kivy.core.text import LabelBase, DEFAULT_FONT - fb_path = self.sideband.asset_dir+"/fonts/" + fb_path = f"{self.sideband.asset_dir}/fonts/" LabelBase.register(name="hebrew", - fn_regular=fb_path+"NotoSansHebrew-Regular.ttf", - fn_bold=fb_path+"NotoSansHebrew-Bold.ttf",) + fn_regular=f"{fb_path}NotoSansHebrew-Regular.ttf", + fn_bold=f"{fb_path}NotoSansHebrew-Bold.ttf",) LabelBase.register(name="japanese", - fn_regular=fb_path+"NotoSansJP-Regular.ttf") + fn_regular=f"{fb_path}NotoSansJP-Regular.ttf") LabelBase.register(name="chinese", - fn_regular=fb_path+"NotoSansSC-Regular.ttf") + fn_regular=f"{fb_path}NotoSansSC-Regular.ttf") LabelBase.register(name="korean", - fn_regular=fb_path+"NotoSansKR-Regular.ttf") + fn_regular=f"{fb_path}NotoSansKR-Regular.ttf") LabelBase.register(name="emoji", - fn_regular=fb_path+"NotoEmoji-Regular.ttf") + fn_regular=f"{fb_path}NotoEmoji-Regular.ttf") LabelBase.register(name="defaultinput", - fn_regular=fb_path+"DefaultInput.ttf") + fn_regular=f"{fb_path}DefaultInput.ttf") LabelBase.register(name="combined", - fn_regular=fb_path+"NotoSans-Regular.ttf", - fn_bold=fb_path+"NotoSans-Bold.ttf", - fn_italic=fb_path+"NotoSans-Italic.ttf", - fn_bolditalic=fb_path+"NotoSans-BoldItalic.ttf") + fn_regular=f"{fb_path}NotoSans-Regular.ttf", + fn_bold=f"{fb_path}NotoSans-Bold.ttf", + fn_italic=f"{fb_path}NotoSans-Italic.ttf", + fn_bolditalic=f"{fb_path}NotoSans-BoldItalic.ttf") def update_input_language(self): language = self.sideband.config["input_language"] @@ -512,7 +512,7 @@ def update_input_language(self): else: self.input_font = language - RNS.log("Setting input language to "+str(self.input_font), RNS.LOG_DEBUG) + RNS.log(f"Setting input language to {self.input_font)}", RNS.LOG_DEBUG) # def modify_input_font(self, ids): # BIND_CLASSES = ["kivymd.uix.textfield.textfield.MDTextField",] @@ -629,11 +629,11 @@ def share_text(self, text): def share_image(self, image, filename): if RNS.vendor.platformutils.get_platform() == "android": save_path = self.sideband.exports_dir - file_path = save_path+"/"+filename + file_path = f"{save_path}/{filename}" try: if not os.path.isdir(save_path): - RNS.log("Creating directory: "+str(save_path)) + RNS.log(f"Creating directory: {save_path)}") os.makedirs(save_path) Intent = autoclass("android.content.Intent") @@ -660,7 +660,7 @@ def share_image(self, image, filename): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Export Error", - text="The resource could not be exported and shared:\n\n"+str(e), + text=f"The resource could not be exported and shared:\n\n{e)}", buttons=[ ok_button ], ) def dl_ok(s): @@ -878,15 +878,15 @@ def handle_action(self, action, data): self.ingest_lxm_uri(data) def ingest_lxm_uri(self, lxm_uri): - RNS.log("Ingesting LXMF paper message from URI: "+str(lxm_uri), RNS.LOG_DEBUG) + 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 = self.sideband.asset_dir+"/fonts" + FONT_PATH = f"{self.sideband.asset_dir}/fonts" if RNS.vendor.platformutils.is_darwin(): - self.icon = self.sideband.asset_dir+"/icon_macos_formed.png" + self.icon = f"{self.sideband.asset_dir}/icon_macos_formed.png" else: - self.icon = self.sideband.asset_dir+"/icon.png" + self.icon = f"{self.sideband.asset_dir}/icon.png" self.announces_view = None @@ -949,7 +949,7 @@ def dl_ok(s): ) self.hw_error_dialog = MDDialog( title="Hardware Error", - text="While communicating with an RNode, Reticulum reported the following error:\n\n[i]"+str(description)+"[/i]", + text=f"While communicating with an RNode, Reticulum reported the following error:\n\n[i]{description)}[/i]", buttons=[ yes_button ], # elevation=0, ) @@ -1076,12 +1076,12 @@ def on_start(self): Window.bind(on_request_close=self.close_requested) if __variant__ != "": - variant_str = " "+__variant__ + variant_str = f" {__variant__}" else: variant_str = "" self.root.ids.screen_manager.app = self - self.root.ids.app_version_info.text = "Sideband v"+__version__+variant_str + self.root.ids.app_version_info.text = f"Sideband v{__version__}{variant_str}" self.root.ids.nav_scrollview.effect_cls = ScrollEffect Clock.schedule_once(self.start_core, 0.25) @@ -1300,7 +1300,7 @@ def ui_clipboard_action(self, sender=None, event=None): action = "tap" if RNS.vendor.platformutils.is_android() else "click" toast(f"Field copied, double-{action} any empty field to paste") except Exception as e: - RNS.log("An error occurred while handling clipboard action: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while handling clipboard action: {e)}", RNS.LOG_ERROR) def loader_init(self, sender=None): if not self.root.ids.screen_manager.has_screen("loader_screen"): @@ -1501,7 +1501,7 @@ def cb(dt): if not self.outbound_mode_command and not self.outbound_mode_paper: if self.attach_type != None and self.attach_path != None: try: - RNS.log("Processing "+str(self.attach_type)+" attachment \""+str(self.attach_path)+"\"", RNS.LOG_DEBUG) + 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": @@ -1543,7 +1543,7 @@ def cb(dt): except Exception as e: self.messages_view.send_error_dialog = MDDialog( title="Attachment Error", - text="An error occurred while processing the attachment:\n\n[i]"+str(e)+"[/i]", + text=f"An error occurred while processing the attachment:\n\n[i]{e)}[/i]", buttons=[ MDRectangleFlatButton( text="OK", @@ -1649,26 +1649,26 @@ def message_fm_got_path(self, path): self.attach_path = path if RNS.vendor.platformutils.is_android(): - toast("Attached \""+str(fbn)+"\"") + toast(f"Attached \"{fbn)}\"") else: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) ate_dialog = MDDialog( title="File Attached", - text="The file \""+str(fbn)+"\" was attached, and will be included with the next message sent.", + text=f"The file \"{fbn)}\" was attached, and will be included with the next message sent.", buttons=[ ok_button ], ) ok_button.bind(on_release=ate_dialog.dismiss) ate_dialog.open() except Exception as e: - RNS.log(f"Error while attaching \"{fbn}\": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while attaching \"{fbn}\": {e)}", RNS.LOG_ERROR) if RNS.vendor.platformutils.get_platform() == "android": - toast("Could not attach \""+str(fbn)+"\"") + toast(f"Could not attach \"{fbn)}\"") else: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) ate_dialog = MDDialog( title="Attachment Error", - text="The specified file could not be attached:\n\n[i]"+str(e)+"[/i]", + text=f"The specified file could not be attached:\n\n[i]{e)}[/i]", buttons=[ ok_button ], ) ok_button.bind(on_release=ate_dialog.dismiss) @@ -1791,12 +1791,12 @@ def cb(sender): return if audio_field[0] == LXMF.AM_OPUS_OGG: - temp_path = self.sideband.rec_cache+"/msg.ogg" + temp_path = f"{self.sideband.rec_cache}/msg.ogg" with open(temp_path, "wb") as af: af.write(self.last_msg_audio) elif audio_field[0] >= LXMF.AM_CODEC2_700C and audio_field[0] <= LXMF.AM_CODEC2_3200: - temp_path = self.sideband.rec_cache+"/msg.ogg" + temp_path = f"{self.sideband.rec_cache}/msg.ogg" from sideband.audioproc import samples_to_ogg, decode_codec2, detect_codec2 target_rate = 8000 @@ -1805,7 +1805,7 @@ def cb(sender): if detect_codec2(): if samples_to_ogg(decode_codec2(audio_field[1], audio_field[0]), temp_path, input_rate=8000, output_rate=target_rate): - RNS.log("Wrote OGG file to: "+temp_path, RNS.LOG_DEBUG) + RNS.log(f"Wrote OGG file to: {temp_path}", RNS.LOG_DEBUG) else: RNS.log("OGG write failed", RNS.LOG_DEBUG) else: @@ -1839,7 +1839,7 @@ def cb(sender): RNS.log("Playback was requested, but no audio data was loaded for playback", RNS.LOG_ERROR) except Exception as e: - RNS.log("Error while playing message audio:"+str(e)) + RNS.log(f"Error while playing message audio:{e)}") RNS.trace_exception(e) def message_ptt_down_action(self, sender=None): @@ -1884,7 +1884,7 @@ def cb_s(dt): try: self.msg_audio.stop() except Exception as e: - RNS.log("An error occurred while stopping recording: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while stopping recording: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) self.sideband.ui_stopped_recording() @@ -1936,9 +1936,9 @@ def message_process_audio(self): encoded = encode_codec2(samples, self.audio_msg_mode) ap_duration = time.time() - ap_start - RNS.log("Audio processing complete in "+RNS.prettytime(ap_duration), RNS.LOG_DEBUG) + RNS.log(f"Audio processing complete in {RNS.prettytime(ap_duration)}", RNS.LOG_DEBUG) - export_path = self.sideband.rec_cache+"/recording.enc" + export_path = f"{self.sideband.rec_cache}/recording.enc" with open(export_path, "wb") as export_file: export_file.write(encoded) self.attach_path = export_path @@ -1958,7 +1958,7 @@ def message_init_rec_dialog(self): from sbapp.plyer import audio self.msg_audio = audio - self.msg_audio._file_path = self.sideband.rec_cache+"/recording.ogg" + self.msg_audio._file_path = f"{self.sideband.rec_cache}/recording.ogg" def a_rec_action(sender): if not self.rec_dialog.recording: @@ -1970,7 +1970,7 @@ def a_rec_action(sender): el.theme_text_color="Custom" el.text_color=mdc("Red","400") el.icon = "stop-circle" - self.rec_dialog.rec_item.text = "[size="+str(ss)+"]Stop Recording[/size]" + self.rec_dialog.rec_item.text = f"[size={ss)}]Stop Recording[/size]" def cb(dt): self.msg_audio.start() Clock.schedule_once(cb, 0.10) @@ -1979,7 +1979,7 @@ def cb(dt): self.sideband.ui_stopped_recording() RNS.log("Stopping recording...") # TODO: Remove self.rec_dialog.recording = False - self.rec_dialog.rec_item.text = "[size="+str(ss)+"]Start Recording[/size]" + self.rec_dialog.rec_item.text = f"[size={ss)}]Start Recording[/size]" el = self.rec_dialog.rec_item.children[0].children[0] el.icon = "record" el.text_color = self.theme_cls._get_text_color() @@ -1997,13 +1997,13 @@ def a_play(sender): RNS.log("Playing recording...", RNS.LOG_DEBUG) self.rec_dialog.playing = True self.rec_dialog.play_item.children[0].children[0].icon = "stop" - self.rec_dialog.play_item.text = "[size="+str(ss)+"]Stop[/size]" + self.rec_dialog.play_item.text = f"[size={ss)}]Stop[/size]" self.msg_audio.play() else: RNS.log("Stopping playback...", RNS.LOG_DEBUG) self.rec_dialog.playing = False self.rec_dialog.play_item.children[0].children[0].icon = "play" - self.rec_dialog.play_item.text = "[size="+str(ss)+"]Play[/size]" + self.rec_dialog.play_item.text = f"[size={ss)}]Play[/size]" self.msg_audio.stop() self.msg_rec_a_play = a_play @@ -2012,7 +2012,7 @@ def a_finished(sender): RNS.log("Playback finished", RNS.LOG_DEBUG) self.rec_dialog.playing = False self.rec_dialog.play_item.children[0].children[0].icon = "play" - self.rec_dialog.play_item.text = "[size="+str(ss)+"]Play[/size]" + self.rec_dialog.play_item.text = f"[size={ss)}]Play[/size]" self.msg_audio._finished_callback = a_finished @@ -2045,9 +2045,9 @@ def a_save(sender): self.msg_rec_a_save = a_save cancel_button = MDRectangleFlatButton(text="Cancel", font_size=dp(18)) - rec_item = DialogItem(IconLeftWidget(icon="record", on_release=a_rec_action), text="[size="+str(ss)+"]Start Recording[/size]", on_release=a_rec_action) - play_item = DialogItem(IconLeftWidget(icon="play", on_release=a_play), text="[size="+str(ss)+"]Play[/size]", on_release=a_play, disabled=True) - save_item = DialogItem(IconLeftWidget(icon="content-save-move-outline", on_release=a_save), text="[size="+str(ss)+"]Save to message[/size]", on_release=a_save, disabled=True) + rec_item = DialogItem(IconLeftWidget(icon="record", on_release=a_rec_action), text=f"[size={ss)}]Start Recording[/size]", on_release=a_rec_action) + play_item = DialogItem(IconLeftWidget(icon="play", on_release=a_play), text=f"[size={ss)}]Play[/size]", on_release=a_play, disabled=True) + save_item = DialogItem(IconLeftWidget(icon="content-save-move-outline", on_release=a_save), text=f"[size={ss)}]Save to message[/size]", on_release=a_save, disabled=True) self.rec_dialog = MDDialog( title="Record Audio", type="simple", @@ -2076,7 +2076,7 @@ def message_record_audio_action(self): self.rec_dialog.play_item.disabled = True self.rec_dialog.save_item.disabled = True self.rec_dialog.recording = False - self.rec_dialog.rec_item.text = "[size="+str(ss)+"]Start Recording[/size]" + self.rec_dialog.rec_item.text = f"[size={ss)}]Start Recording[/size]" self.rec_dialog.rec_item.children[0].children[0].icon = "record" self.rec_dialog.open() @@ -2125,12 +2125,12 @@ def a_audio_lb(sender): ss = int(dp(18)) cancel_button = MDRectangleFlatButton(text="Cancel", font_size=dp(18)) ad_items = [ - DialogItem(IconLeftWidget(icon="message-image-outline", on_release=a_img_lb), text="[size="+str(ss)+"]Low-bandwidth Image[/size]", on_release=a_img_lb), - DialogItem(IconLeftWidget(icon="file-image", on_release=a_img_def), text="[size="+str(ss)+"]Medium Image[/size]", on_release=a_img_def), - DialogItem(IconLeftWidget(icon="image-outline", on_release=a_img_hq), text="[size="+str(ss)+"]High-res Image[/size]", on_release=a_img_hq), - DialogItem(IconLeftWidget(icon="account-voice", on_release=a_audio_lb), text="[size="+str(ss)+"]Low-bandwidth Voice[/size]", on_release=a_audio_lb), - DialogItem(IconLeftWidget(icon="microphone-message", on_release=a_audio_hq), text="[size="+str(ss)+"]High-quality Voice[/size]", on_release=a_audio_hq), - DialogItem(IconLeftWidget(icon="file-outline", on_release=a_file), text="[size="+str(ss)+"]File Attachment[/size]", on_release=a_file)] + DialogItem(IconLeftWidget(icon="message-image-outline", on_release=a_img_lb), text=f"[size={ss)}]Low-bandwidth Image[/size]", on_release=a_img_lb), + DialogItem(IconLeftWidget(icon="file-image", on_release=a_img_def), text=f"[size={ss)}]Medium Image[/size]", on_release=a_img_def), + DialogItem(IconLeftWidget(icon="image-outline", on_release=a_img_hq), text=f"[size={ss)}]High-res Image[/size]", on_release=a_img_hq), + 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) @@ -2204,7 +2204,7 @@ def update_message_widgets(self): def key_query_action(self, sender): context_dest = self.messages_view.ids.messages_scrollview.active_conversation if self.sideband.request_key(context_dest): - keys_str = "Public key information for "+RNS.prettyhexrep(context_dest)+" was requested from the network. Waiting for request to be answered." + keys_str = f"Public key information for {RNS.prettyhexrep(context_dest)} was requested from the network. Waiting for request to be answered." self.messages_view.ids.nokeys_text.text = keys_str else: keys_str = "Could not send request. Check your connectivity and addresses." @@ -2299,7 +2299,7 @@ def get_connectivity_text(self): return connectivity_status except Exception as e: - RNS.log("An error occurred while retrieving connectivity status: "+str(e), RNS.LOG_ERROR) + 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): @@ -2346,14 +2346,14 @@ def open_ingest_lxm_dialog(self, sender=None): def dl_yes(s): try: lxm_uri = Clipboard.paste() - if not lxm_uri.lower().startswith(LXMF.LXMessage.URI_SCHEMA+"://"): - lxm_uri = LXMF.LXMessage.URI_SCHEMA+"://"+lxm_uri + if not lxm_uri.lower().startswith(f"{LXMF.LXMessage.URI_SCHEMA}://"): + lxm_uri = f"{LXMF.LXMessage.URI_SCHEMA}://{lxm_uri}" self.ingest_lxm_uri(lxm_uri) dialog.dismiss() except Exception as e: - response = "Error ingesting message from URI: "+str(e) + response = f"Error ingesting message from URI: {e)}" RNS.log(response, RNS.LOG_ERROR) self.sideband.setstate("lxm_uri_ingest.result", response) dialog.dismiss() @@ -2372,7 +2372,7 @@ def dl_ds(s): self.dialog_open = True except Exception as e: - RNS.log("Error while creating ingest LXM dialog: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating ingest LXM dialog: {e)}", RNS.LOG_ERROR) def lxmf_sync_action(self, sender): def cb(dt): @@ -2406,7 +2406,7 @@ def dl_yes(s): dialog_content = MsgSync() dialog = MDDialog( - title="LXMF Sync via "+RNS.prettyhexrep(self.sideband.message_router.get_outbound_propagation_node()), + title=f"LXMF Sync via {RNS.prettyhexrep(self.sideband.message_router.get_outbound_propagation_node())}", type="custom", content_cls=dialog_content, buttons=[ stop_button, close_button ], @@ -2443,7 +2443,7 @@ def cb(dt): dsp = 0 self.sideband.setstate("app.flags.lxmf_sync_dialog_open", True) - self.message_sync_dialog.title = f"LXMF Sync via "+RNS.prettyhexrep(self.sideband.message_router.get_outbound_propagation_node()) + self.message_sync_dialog.title = f"LXMF Sync via {RNS.prettyhexrep(self.sideband.message_router.get_outbound_propagation_node())}" self.message_sync_dialog.d_content.ids.sync_status.text = self.sideband.get_sync_status() self.message_sync_dialog.d_content.ids.sync_progress.value = dsp self.message_sync_dialog.d_content.ids.sync_progress.start() @@ -2484,7 +2484,7 @@ def dl_yes(s): new_result = self.sideband.new_conversation(n_address, n_name, n_trusted) except Exception as e: - RNS.log("Error while creating conversation: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating conversation: {e)}", RNS.LOG_ERROR) if new_result: dialog.d_content.ids["n_address_field"].error = False @@ -2509,7 +2509,7 @@ def dl_ds(s): self.dialog_open = True except Exception as e: - RNS.log("Error while creating new conversation dialog: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating new conversation dialog: {e)}", RNS.LOG_ERROR) ### Information/version screen ###################################### @@ -2537,14 +2537,14 @@ def lj(): threading.Thread(target=lj, daemon=True).start() self.information_screen.ids.information_scrollview.effect_cls = ScrollEffect - self.information_screen.ids.information_logo.icon = self.sideband.asset_dir+"/rns_256.png" + self.information_screen.ids.information_logo.icon = f"{self.sideband.asset_dir}/rns_256.png" str_comps = " - [b]Reticulum[/b] (MIT License)\n - [b]LXMF[/b] (MIT License)\n - [b]KivyMD[/b] (MIT License)" str_comps += "\n - [b]Kivy[/b] (MIT License)\n - [b]Codec2[/b] (LGPL License)\n - [b]PyCodec2[/b] (BSD-3 License)" str_comps += "\n - [b]PyDub[/b] (MIT License)\n - [b]PyOgg[/b] (Public Domain)" str_comps += "\n - [b]GeoidHeight[/b] (LGPL License)\n - [b]Python[/b] (PSF License)" - str_comps += "\n\nGo to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project.\n\nThe Sideband app is Copyright (c) 2024 Mark Qvist / unsigned.io\n\nPermission is granted to freely share and distribute binary copies of "+self.root.ids.app_version_info.text+", so long as no payment or compensation is charged for said distribution or sharing.\n\nIf you were charged or paid anything for this copy of Sideband, please report it to [b]license@unsigned.io[/b].\n\nTHIS IS EXPERIMENTAL SOFTWARE - SIDEBAND COMES WITH ABSOLUTELY NO WARRANTY - USE AT YOUR OWN RISK AND RESPONSIBILITY" - info = "This is "+self.root.ids.app_version_info.text+", on RNS v"+RNS.__version__+" and LXMF v"+LXMF.__version__+".\n\nHumbly build using the following open components:\n\n"+str_comps + str_comps += f"\n\nGo to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project.\n\nThe Sideband app is Copyright (c) 2024 Mark Qvist / unsigned.io\n\nPermission is granted to freely share and distribute binary copies of {self.root.ids.app_version_info.text}, so long as no payment or compensation is charged for said distribution or sharing.\n\nIf you were charged or paid anything for this copy of Sideband, please report it to [b]license@unsigned.io[/b].\n\nTHIS IS EXPERIMENTAL SOFTWARE - SIDEBAND COMES WITH ABSOLUTELY NO WARRANTY - USE AT YOUR OWN RISK AND RESPONSIBILITY" + info = f"This is {self.root.ids.app_version_info.text}, on RNS v{RNS.__version__} and LXMF v{LXMF.__version__}.\n\nHumbly build using the following open components:\n\n{str_comps}" self.information_screen.ids.information_info.text = info self.information_screen.ids.information_info.bind(on_ref_press=link_exec) @@ -2846,7 +2846,7 @@ def sync_interval_change(sender=None, event=None, save=True): interval_text = RNS.prettytime(interval) pre = self.settings_screen.ids.settings_lxmf_sync_periodic.text - self.settings_screen.ids.settings_lxmf_sync_periodic.text = "Auto sync every "+interval_text + self.settings_screen.ids.settings_lxmf_sync_periodic.text = f"Auto sync every {interval_text}" if save: if (event == None or not hasattr(event, "button") or not event.button) or not "scroll" in event.button: self.sideband.config["lxmf_sync_interval"] = interval @@ -3201,7 +3201,7 @@ def ifmode_validate(sender=None, event=None): all_valid = True iftypes = ["local", "tcp", "i2p", "rnode", "modem", "serial"] for iftype in iftypes: - element = self.connectivity_screen.ids["connectivity_"+iftype+"_ifmode"] + element = self.connectivity_screen.ids[f"connectivity_{iftype}_ifmode"] modes = ["full", "gateway", "access point", "roaming", "boundary"] value = element.text.lower() if value in ["", "f"] or value.startswith("fu"): @@ -3356,7 +3356,7 @@ def dl_yes(s): dialog.dismiss() yes_button.bind(on_release=dl_yes) - rpc_string = "rpc_key = "+RNS.hexrep(self.sideband.reticulum.rpc_key, delimit=False) + rpc_string = f"rpc_key = {RNS.hexrep(self.sideband.reticulum.rpc_key, delimit=False)}" Clipboard.copy(rpc_string) dialog.open() @@ -3427,7 +3427,7 @@ def getIP(): adrs.append(ha) except Exception as e: - RNS.log("Error while getting repository IP address: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while getting repository IP address: {e)}", RNS.LOG_ERROR) return None return adrs @@ -3439,11 +3439,11 @@ def getIP(): else: ipstr = "" for ip in ips: - ipstr += "http://"+str(ip)+":4444/\n" + ipstr += f"http://{ip)}:4444/\n" self.reposository_url = ipstr ms = "" if len(ips) == 1 else "es" - info += "The repository server is running at the following address"+ms+":\n [u][ref=link]"+ipstr+"[/ref][u]" + info += f"The repository server is running at the following address{ms}:\n [u][ref=link]{ipstr}[/ref][u]" self.repository_screen.ids.repository_info.bind(on_ref_press=self.repository_link_action) self.repository_screen.ids.repository_enable_button.disabled = True @@ -3487,10 +3487,10 @@ def update_job(sender=None): apk_version = release["tag_name"] RNS.log(f"Found version {apk_version} artefact {pkgname} at {apk_url}") except Exception as e: - self.repository_screen.ids.repository_update.text = f"Downloading release info failed with the error:\n"+str(e) + self.repository_screen.ids.repository_update.text = f"Downloading release info failed with the error:\n{e)}" return - self.repository_screen.ids.repository_update.text = "Downloading: "+str(apk_url) + self.repository_screen.ids.repository_update.text = f"Downloading: {apk_url)}" with requests.get(apk_url, stream=True) as response: with open("./dl_tmp", "wb") as tmp_file: cs = 32*1024 @@ -3498,12 +3498,12 @@ def update_job(sender=None): for chunk in response.iter_content(chunk_size=cs): tmp_file.write(chunk) tds += cs - self.repository_screen.ids.repository_update.text = "Downloaded "+RNS.prettysize(tds)+" of "+str(pkgname) + self.repository_screen.ids.repository_update.text = f"Downloaded {RNS.prettysize(tds)} of {pkgname)}" os.rename("./dl_tmp", f"./share/pkg/{pkgname}") self.repository_screen.ids.repository_update.text = f"Added {pkgname} to the repository!" except Exception as e: - self.repository_screen.ids.repository_update.text = f"Downloading contents failed with the error:\n"+str(e) + self.repository_screen.ids.repository_update.text = f"Downloading contents failed with the error:\n{e)}" self.repository_screen.ids.repository_update.text = "Starting package download..." def start_update_job(sender=None): @@ -3996,7 +3996,7 @@ def dl_yes(s): yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Import Failed", - text="The read data did not contain a valid config mote. If any data was decoded, you may try to correct it by editing the relevant fields. The reported error was:\n\n"+str(e), + text=f"The read data did not contain a valid config mote. If any data was decoded, you may try to correct it by editing the relevant fields. The reported error was:\n\n{e)}", buttons=[ yes_button ], # elevation=0, ) @@ -4550,7 +4550,7 @@ def identity_display_action(self, sender=None): yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( - text="Your Identity key, in base32 format is as follows:\n\n[b]"+str(base64.b32encode(self.sideband.identity.get_private_key()).decode("utf-8"))+"[/b]", + text=f"Your Identity key, in base32 format is as follows:\n\n[b]{base64.b32encode(self.sideband.identity.get_private_key()).decode('utf-8'))}[/b]", buttons=[ yes_button ], # elevation=0, ) @@ -4613,7 +4613,7 @@ def dl_yes(s): except Exception as e: yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) - dialog = MDDialog(text="[b]The provided Identity key data was not valid[/b]\n\nThe error reported by Reticulum was:\n\n[i]"+str(e)+"[/i]\n\nNo Identity was imported into Sideband.", buttons=[ yes_button ]) + dialog = MDDialog(text=f"[b]The provided Identity key data was not valid[/b]\n\nThe error reported by Reticulum was:\n\n[i]{e)}[/i]\n\nNo Identity was imported into Sideband.", buttons=[ yes_button ]) def dl_yes(s): dialog.dismiss() yes_button.bind(on_release=dl_yes) @@ -4697,26 +4697,26 @@ def plugins_fm_got_path(self, path): self.sideband.save_configuration() if RNS.vendor.platformutils.is_android(): - toast("Using \""+str(path)+"\" as plugin directory") + toast(f"Using \"{path)}\" as plugin directory") else: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) ate_dialog = MDDialog( title="Directory Set", - text="Using \""+str(path)+"\" as plugin directory", + text=f"Using \"{path)}\" as plugin directory", buttons=[ ok_button ], ) 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}\": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while setting plugins directory to \"{path}\": {e)}", RNS.LOG_ERROR) if RNS.vendor.platformutils.get_platform() == "android": - toast("Could not set plugins directory to \""+str(path)+"\"") + toast(f"Could not set plugins directory to \"{path)}\"") else: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) e_dialog = MDDialog( title="Error", - text="Could not set plugins directory to \""+str(path)+"\"", + text=f"Could not set plugins directory to \"{path)}\"", buttons=[ ok_button ], ) ok_button.bind(on_release=e_dialog.dismiss) @@ -4875,7 +4875,7 @@ def dl_ok(s): info_str = "There was no new data to send." else: title_str = "Unknown Status" - info_str = "The status of the telemetry update is unknown: "+str(result) + info_str = f"The status of the telemetry update is unknown: {result)}" self.telemetry_info_dialog.title = title_str self.telemetry_info_dialog.text = info_str @@ -4913,7 +4913,7 @@ def dl_ok(s): info_str = "A telemetry request could not be sent." else: title_str = "Unknown Status" - info_str = "The status of the telemetry request is unknown: "+str(result) + info_str = f"The status of the telemetry request is unknown: {result)}" self.telemetry_info_dialog.title = title_str self.telemetry_info_dialog.text = info_str @@ -4932,21 +4932,21 @@ def map_fm_got_path(self, path): self.sideband.save_configuration() if RNS.vendor.platformutils.is_android(): - toast("Using \""+os.path.basename(path)+"\" as offline map") + toast(f"Using \"{os.path.basename(path)}\" as offline map") else: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) ate_dialog = MDDialog( title="Map Set", - text="Using \""+os.path.basename(path)+"\" as offline map", + text=f"Using \"{os.path.basename(path)}\" as offline map", buttons=[ ok_button ], ) ok_button.bind(on_release=ate_dialog.dismiss) ate_dialog.open() except Exception as e: - RNS.log(f"Error while loading map \"{path}\": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while loading map \"{path}\": {e)}", RNS.LOG_ERROR) if RNS.vendor.platformutils.get_platform() == "android": - toast("Could not load map \""+os.path.basename(path)+"\"") + toast(f"Could not load map \"{os.path.basename(path)}\"") else: ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) map_dialog = MDDialog( @@ -5041,7 +5041,7 @@ def map_get_offline_source(self): return self.offline_source except Exception as e: - RNS.log(f"Error while loading map from \"{current_map_path}\": "+str(e)) + RNS.log(f"Error while loading map from \"{current_map_path}\": {e)}") self.sideband.config["map_storage_file"] = None self.sideband.config["map_use_offline"] = False self.sideband.config["map_use_online"] = True @@ -5114,7 +5114,7 @@ def map_layers_action(self, sender=None): self.map_layer = ml self.map_update_source(source) except Exception as e: - RNS.log("Error while switching map layer: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while switching map layer: {e)}", RNS.LOG_ERROR) map_nav_divisor = 12 map_nav_zoom = 0.25 @@ -5479,7 +5479,7 @@ def map_create_marker(self, source, telemetry, appearance): return marker except Exception as e: - RNS.log("Could not create map marker for "+RNS.prettyhexrep(source)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Could not create map marker for {RNS.prettyhexrep(source)}: {e)}", RNS.LOG_ERROR) return None def map_update_markers(self, sender=None): @@ -5546,17 +5546,17 @@ def map_update_markers(self, sender=None): stale_markers.append(marker) for marker in stale_markers: - RNS.log("Removing stale marker: "+str(marker), RNS.LOG_DEBUG) + RNS.log(f"Removing stale marker: {marker)}", RNS.LOG_DEBUG) try: to_remove = self.map_markers[marker] self.map_screen.ids.map_layout.map.remove_marker(to_remove) self.map_markers.pop(marker) changes = True except Exception as e: - RNS.log("Error while removing map marker: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while removing map marker: {e)}", RNS.LOG_ERROR) except Exception as e: - RNS.log("Error while updating own map marker: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while updating own map marker: {e)}", RNS.LOG_ERROR) for telemetry_source in telemetry_entries: try: @@ -5601,7 +5601,7 @@ def map_update_markers(self, sender=None): changes = True except Exception as e: - RNS.log("Error while updating map entry for "+RNS.prettyhexrep(telemetry_source)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while updating map entry for {RNS.prettyhexrep(telemetry_source)}: {e)}", RNS.LOG_ERROR) self.last_map_update = time.time() if changes: @@ -5740,16 +5740,16 @@ def lj(): info9 = guide_text9 if self.theme_cls.theme_style == "Dark": - info1 = "[color=#"+dark_theme_text_color+"]"+info1+"[/color]" - info2 = "[color=#"+dark_theme_text_color+"]"+info2+"[/color]" - info3 = "[color=#"+dark_theme_text_color+"]"+info3+"[/color]" - info4 = "[color=#"+dark_theme_text_color+"]"+info4+"[/color]" - info5 = "[color=#"+dark_theme_text_color+"]"+info5+"[/color]" - info6 = "[color=#"+dark_theme_text_color+"]"+info6+"[/color]" - info7 = "[color=#"+dark_theme_text_color+"]"+info7+"[/color]" - info8 = "[color=#"+dark_theme_text_color+"]"+info8+"[/color]" - info9 = "[color=#"+dark_theme_text_color+"]"+info9+"[/color]" - info10 = "[color=#"+dark_theme_text_color+"]"+info10+"[/color]" + info1 = f"[color=#{dark_theme_text_color}]{info1}[/color]" + info2 = f"[color=#{dark_theme_text_color}]{info2}[/color]" + info3 = f"[color=#{dark_theme_text_color}]{info3}[/color]" + info4 = f"[color=#{dark_theme_text_color}]{info4}[/color]" + info5 = f"[color=#{dark_theme_text_color}]{info5}[/color]" + info6 = f"[color=#{dark_theme_text_color}]{info6}[/color]" + info7 = f"[color=#{dark_theme_text_color}]{info7}[/color]" + info8 = f"[color=#{dark_theme_text_color}]{info8}[/color]" + info9 = f"[color=#{dark_theme_text_color}]{info9}[/color]" + info10 = f"[color=#{dark_theme_text_color}]{info10}[/color]" self.guide_screen.ids.guide_info1.text = info1 self.guide_screen.ids.guide_info2.text = info2 self.guide_screen.ids.guide_info3.text = info3 @@ -5788,7 +5788,7 @@ def broadcasts_open(self, sender=None, direction="left", no_transition=False): info = "The [b]Local Broadcasts[/b] feature will allow you to send and listen for local broadcast transmissions on all connected interfaces.\n\n[b]Local Broadcasts[/b] makes it easy to establish public information exchange with anyone in direct radio range, or even with large areas far away using the [i]Remote Broadcast Repeater[/i] feature.\n\nThese features are not yet implemented in Sideband.\n\nWant it faster? Go to [u][ref=link]https://unsigned.io/donate[/ref][/u] to support the project." if self.theme_cls.theme_style == "Dark": - info = "[color=#"+dark_theme_text_color+"]"+info+"[/color]" + info = f"[color=#{dark_theme_text_color}]{info}[/color]" self.broadcasts_screen.ids.broadcasts_info.text = info self.root.ids.screen_manager.current = "broadcasts_screen" @@ -5830,7 +5830,7 @@ def handle_exception(self, e): if etype != SystemExit: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"An unhandled {str(type(e))} exception occurred: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"An unhandled {type(e))} exception occurred: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) return ExceptionManager.PASS else: @@ -5847,7 +5847,7 @@ def run(): is_daemon=True ) - sideband.version_str = "v"+__version__+" "+__variant__ + sideband.version_str = f"v{__version__} {__variant__}" sideband.start() while True: time.sleep(5) diff --git a/sbapp/mapview/__init__.py b/sbapp/mapview/__init__.py index 3fc9a97..cfdd85f 100644 --- a/sbapp/mapview/__init__.py +++ b/sbapp/mapview/__init__.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ MapView ======= diff --git a/sbapp/mapview/clustered_marker_layer.py b/sbapp/mapview/clustered_marker_layer.py index c114e58..b3876a9 100644 --- a/sbapp/mapview/clustered_marker_layer.py +++ b/sbapp/mapview/clustered_marker_layer.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ Layer that support point clustering =================================== @@ -265,9 +264,7 @@ def __init__(self, lon, lat, cls=MapMarker, options=None): self.widget = None def __repr__(self): - return "".format( - self.lon, self.lat, self.source - ) + return f"" class SuperCluster: diff --git a/sbapp/mapview/downloader.py b/sbapp/mapview/downloader.py index e888227..80c423b 100644 --- a/sbapp/mapview/downloader.py +++ b/sbapp/mapview/downloader.py @@ -1,5 +1,3 @@ -# coding=utf-8 - __all__ = ["Downloader"] import logging @@ -52,7 +50,7 @@ def __init__(self, max_workers=None, cap_time=None, **kwargs): self._futures = [] Clock.schedule_interval(self._check_executor, 1 / 60.0) if not exists(self.cache_dir): - RNS.log("Creating cache dir "+str(self.cache_dir), RNS.LOG_WARNING) + RNS.log(f"Creating cache dir {self.cache_dir)}", RNS.LOG_WARNING) makedirs(self.cache_dir) logging.getLogger("urllib3").setLevel(logging.WARNING) @@ -134,7 +132,7 @@ def _load_tile(self, tile): # Logger.debug("Downloaded {} bytes: {}".format(len(data), uri)) return tile.set_source, (cache_fn,) except Exception as e: - print("Downloader error: {!r}".format(e)) + print(f"Downloader error: {e!r}") def _check_executor(self, dt): start = time() diff --git a/sbapp/mapview/geojson.py b/sbapp/mapview/geojson.py index 0c5f4c7..2a383d4 100644 --- a/sbapp/mapview/geojson.py +++ b/sbapp/mapview/geojson.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ Geojson layer ============= diff --git a/sbapp/mapview/mbtsource.py b/sbapp/mapview/mbtsource.py index 2a2f69c..da02b8e 100644 --- a/sbapp/mapview/mbtsource.py +++ b/sbapp/mapview/mbtsource.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ MBTiles provider for MapView ============================ @@ -87,7 +86,7 @@ def _load_tile(self, tile): im = CoreImage( data, ext='png', - filename="{}.{}.{}.png".format(tile.zoom, tile.tile_x, tile.tile_y), + filename=f"{tile.zoom}.{tile.tile_x}.{tile.tile_y}.png", ) if im is None: diff --git a/sbapp/mapview/source.py b/sbapp/mapview/source.py index db1e1c1..dd0b5bb 100644 --- a/sbapp/mapview/source.py +++ b/sbapp/mapview/source.py @@ -1,5 +1,3 @@ -# coding=utf-8 - __all__ = ["MapSource"] import hashlib diff --git a/sbapp/mapview/types.py b/sbapp/mapview/types.py index 622d8a9..75d8c16 100644 --- a/sbapp/mapview/types.py +++ b/sbapp/mapview/types.py @@ -1,5 +1,3 @@ -# coding=utf-8 - __all__ = ["Coordinate", "Bbox"] from collections import namedtuple diff --git a/sbapp/mapview/utils.py b/sbapp/mapview/utils.py index 1ecc84f..d65b688 100644 --- a/sbapp/mapview/utils.py +++ b/sbapp/mapview/utils.py @@ -1,5 +1,3 @@ -# coding=utf-8 - __all__ = ["clamp", "haversine", "get_zoom_for_radius"] from math import asin, cos, pi, radians, sin, sqrt diff --git a/sbapp/mapview/view.py b/sbapp/mapview/view.py index 38bc67b..10cab3a 100644 --- a/sbapp/mapview/view.py +++ b/sbapp/mapview/view.py @@ -1,5 +1,3 @@ -# coding=utf-8 - __all__ = ["MapView", "MapMarker", "MapMarkerPopup", "MapLayer", "MarkerMapLayer"] import webbrowser @@ -174,7 +172,7 @@ def __init__(self, **kwargs): else: self.source = join(dirname(__file__), "icons", "marker_dark.png") - super(CustomMapMarker, self).__init__(**kwargs) + super().__init__(**kwargs) self.texture_update() def detach(self): @@ -212,7 +210,7 @@ class MapMarker(ButtonBehavior, Image): _layer = None def __init__(self, **kwargs): - super(MapMarker, self).__init__(**kwargs) + super().__init__(**kwargs) self.texture_update() def detach(self): @@ -312,7 +310,7 @@ def reposition(self): bbox = None # reposition the markers depending the latitude markers = sorted(self.markers, key=lambda x: -x.lat) - margin = max((max(marker.size) for marker in markers)) + margin = max(max(marker.size) for marker in markers) bbox = mapview.get_bbox(margin) for marker in markers: if bbox.collide(marker.lat, marker.lon): @@ -783,7 +781,7 @@ def on_touch_up(self, touch): # self.animated_diff_scale_at(2.0 - cur_scale, *touch.pos) self._pause = False return True - return super(MapView, self).on_touch_up(touch) + return super().on_touch_up(touch) def on_transform(self, *args): self._invalid_scale = True diff --git a/sbapp/patches/p4a_build.py b/sbapp/patches/p4a_build.py index 66f1d9c..27b5482 100644 --- a/sbapp/patches/p4a_build.py +++ b/sbapp/patches/p4a_build.py @@ -24,7 +24,7 @@ def get_dist_info_for(key, error_if_missing=True): try: - with open(join(dirname(__file__), 'dist_info.json'), 'r') as fileh: + with open(join(dirname(__file__), 'dist_info.json')) as fileh: info = json.load(fileh) value = info[key] except (OSError, KeyError) as e: @@ -496,7 +496,7 @@ def make_package(args): ) # Find the SDK directory and target API - with open('project.properties', 'r') as fileh: + with open('project.properties') as fileh: target = fileh.read().strip() android_api = target.split('-')[1] @@ -509,7 +509,7 @@ def make_package(args): str(android_api) + "'" ) - with open('local.properties', 'r') as fileh: + with open('local.properties') as fileh: sdk_dir = fileh.read().strip() sdk_dir = sdk_dir[8:] @@ -730,7 +730,7 @@ def get_manifest_orientation(orientations, manifest_orientation=None): def get_dist_ndk_min_api_level(): # Get the default minsdk, equal to the NDK API that this dist is built against try: - with open('dist_info.json', 'r') as fileh: + with open('dist_info.json') as fileh: info = json.load(fileh) ndk_api = int(info['ndk_api']) except (OSError, KeyError, ValueError, TypeError): diff --git a/sbapp/plyer/facades/audio.py b/sbapp/plyer/facades/audio.py index 0394037..51ed1b9 100644 --- a/sbapp/plyer/facades/audio.py +++ b/sbapp/plyer/facades/audio.py @@ -94,7 +94,7 @@ def file_path(self, location): # private def _start(self): - raise IOError("JUICE") + raise OSError("JUICE") raise NotImplementedError() def _stop(self): diff --git a/sbapp/plyer/facades/flash.py b/sbapp/plyer/facades/flash.py index ac70b2e..ba01faa 100644 --- a/sbapp/plyer/facades/flash.py +++ b/sbapp/plyer/facades/flash.py @@ -1,4 +1,3 @@ -# coding=utf-8 ''' Flash ===== diff --git a/sbapp/plyer/facades/spatialorientation.py b/sbapp/plyer/facades/spatialorientation.py index 9fe400b..f9e3681 100644 --- a/sbapp/plyer/facades/spatialorientation.py +++ b/sbapp/plyer/facades/spatialorientation.py @@ -1,6 +1,3 @@ -# coding=utf-8 - - class SpatialOrientation: '''Spatial Orientation facade. diff --git a/sbapp/plyer/facades/temperature.py b/sbapp/plyer/facades/temperature.py index baaae2a..7baa392 100644 --- a/sbapp/plyer/facades/temperature.py +++ b/sbapp/plyer/facades/temperature.py @@ -1,6 +1,3 @@ -# coding=utf-8 - - class Temperature: '''Temperature facade. diff --git a/sbapp/plyer/platforms/android/__init__.py b/sbapp/plyer/platforms/android/__init__.py index 8fe1263..3285ee6 100644 --- a/sbapp/plyer/platforms/android/__init__.py +++ b/sbapp/plyer/platforms/android/__init__.py @@ -11,8 +11,8 @@ ns = 'org.renpy.android' if 'PYTHON_SERVICE_ARGUMENT' in environ: - PythonService = autoclass(ns + '.PythonService') + PythonService = autoclass(f"{ns}.PythonService") activity = PythonService.mService else: - PythonActivity = autoclass(ns + '.PythonActivity') + PythonActivity = autoclass(f"{ns}.PythonActivity") activity = PythonActivity.mActivity diff --git a/sbapp/plyer/platforms/android/audio.py b/sbapp/plyer/platforms/android/audio.py index 33a0a0d..58cd9c5 100644 --- a/sbapp/plyer/platforms/android/audio.py +++ b/sbapp/plyer/platforms/android/audio.py @@ -72,7 +72,7 @@ def _stop(self): self._recorder.stop() self._recorder.release() except Exception as e: - print("Could not stop recording: "+str(e)) + print(f"Could not stop recording: {e)}") self._recorder = None @@ -81,7 +81,7 @@ def _stop(self): self._player.stop() self._player.release() except Exception as e: - print("Could not stop playback: "+str(e)) + print(f"Could not stop playback: {e)}") self._player = None diff --git a/sbapp/plyer/platforms/android/call.py b/sbapp/plyer/platforms/android/call.py index 2a1388c..a5d14cf 100644 --- a/sbapp/plyer/platforms/android/call.py +++ b/sbapp/plyer/platforms/android/call.py @@ -17,7 +17,7 @@ def _makecall(self, **kwargs): intent = Intent(Intent.ACTION_CALL) tel = kwargs.get('tel') - intent.setData(uri.parse("tel:{}".format(tel))) + intent.setData(uri.parse(f"tel:{tel}")) activity.startActivity(intent) def _dialcall(self, **kwargs): diff --git a/sbapp/plyer/platforms/android/camera.py b/sbapp/plyer/platforms/android/camera.py index 3384a66..d3ed04c 100644 --- a/sbapp/plyer/platforms/android/camera.py +++ b/sbapp/plyer/platforms/android/camera.py @@ -20,7 +20,7 @@ def _take_picture(self, on_complete, filename=None): android.activity.unbind(on_activity_result=self._on_activity_result) android.activity.bind(on_activity_result=self._on_activity_result) intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) - uri = Uri.parse('file://' + filename) + uri = Uri.parse(f"file://{filename}") parcelable = cast('android.os.Parcelable', uri) intent.putExtra(MediaStore.EXTRA_OUTPUT, parcelable) activity.startActivityForResult(intent, 0x123) @@ -32,7 +32,7 @@ def _take_video(self, on_complete, filename=None): android.activity.unbind(on_activity_result=self._on_activity_result) android.activity.bind(on_activity_result=self._on_activity_result) intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE) - uri = Uri.parse('file://' + filename) + uri = Uri.parse(f"file://{filename}") parcelable = cast('android.os.Parcelable', uri) intent.putExtra(MediaStore.EXTRA_OUTPUT, parcelable) diff --git a/sbapp/plyer/platforms/android/filechooser.py b/sbapp/plyer/platforms/android/filechooser.py index b8c943c..dea9791 100644 --- a/sbapp/plyer/platforms/android/filechooser.py +++ b/sbapp/plyer/platforms/android/filechooser.py @@ -93,8 +93,7 @@ class AndroidFileChooser(FileChooser): "pptx": "application/vnd.openxmlformats-officedocument." + "presentationml.presentation", "xls": "application/vnd.ms-excel", - "xlsx": "application/vnd.openxmlformats-officedocument." + - "spreadsheetml.sheet", + "xlsx": f"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "text": "text/*", "pdf": "application/pdf", "zip": "application/zip", diff --git a/sbapp/plyer/platforms/android/flash.py b/sbapp/plyer/platforms/android/flash.py index eec1ae3..0eb8c20 100644 --- a/sbapp/plyer/platforms/android/flash.py +++ b/sbapp/plyer/platforms/android/flash.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ Flash ----- diff --git a/sbapp/plyer/platforms/android/gps.py b/sbapp/plyer/platforms/android/gps.py index 740b636..5a8a784 100644 --- a/sbapp/plyer/platforms/android/gps.py +++ b/sbapp/plyer/platforms/android/gps.py @@ -55,8 +55,7 @@ def onStatusChanged(self, provider, status, extras): s_status = 'temporarily-unavailable' elif status == 0x02: s_status = 'available' - self.root.on_status('provider-status', '{}: {}'.format( - provider, s_status)) + self.root.on_status('provider-status', f'{provider}: {s_status}') class AndroidGPS(GPS): diff --git a/sbapp/plyer/platforms/android/stt.py b/sbapp/plyer/platforms/android/stt.py index 51681e0..40caf33 100644 --- a/sbapp/plyer/platforms/android/stt.py +++ b/sbapp/plyer/platforms/android/stt.py @@ -134,7 +134,7 @@ def onError(self, error): msg = 'speech_timeout' if msg and self.error_callback: - self.error_callback('error:' + msg) + self.error_callback(f"error:{msg}") @java_method('(ILandroid/os/Bundle;)V') def onEvent(self, event_type, params): diff --git a/sbapp/plyer/platforms/ios/call.py b/sbapp/plyer/platforms/ios/call.py index 9999d6a..9bac868 100644 --- a/sbapp/plyer/platforms/ios/call.py +++ b/sbapp/plyer/platforms/ios/call.py @@ -15,7 +15,7 @@ class IOSCall(Call): def _makecall(self, **kwargs): tel = kwargs.get('tel') - url = "tel://" + tel + url = f"tel://{tel}" nsurl = NSURL.alloc().initWithString_(objc_str(url)) UIApplication.sharedApplication().openURL_(nsurl) diff --git a/sbapp/plyer/platforms/ios/flash.py b/sbapp/plyer/platforms/ios/flash.py index 17f59f1..897806d 100644 --- a/sbapp/plyer/platforms/ios/flash.py +++ b/sbapp/plyer/platforms/ios/flash.py @@ -1,4 +1,3 @@ -# coding=utf-8 """ Flash ----- diff --git a/sbapp/plyer/platforms/ios/gps.py b/sbapp/plyer/platforms/ios/gps.py index d7ee0a7..42e2539 100644 --- a/sbapp/plyer/platforms/ios/gps.py +++ b/sbapp/plyer/platforms/ios/gps.py @@ -50,8 +50,7 @@ def locationManager_didChangeAuthorizationStatus_(self, manager, status): elif status == 4: provider_status = 'provider-enabled' s_status = 'authorizedWhenInUse' - self.on_status(provider_status, '{}: {}'.format( - provider, s_status)) + self.on_status(provider_status, f'{provider}: {s_status}') @protocol('CLLocationManagerDelegate') def locationManager_didUpdateLocations_(self, manager, locations): @@ -60,7 +59,7 @@ def locationManager_didUpdateLocations_(self, manager, locations): description = location.description.UTF8String() split_description = description.split('<')[-1].split('>')[0].split(',') - lat, lon = [float(coord) for coord in split_description] + lat, lon = (float(coord) for coord in split_description) acc = float(description.split(' +/- ')[-1].split('m ')[0]) speed = location.speed diff --git a/sbapp/plyer/platforms/ios/maps.py b/sbapp/plyer/platforms/ios/maps.py index dac01d5..efeb606 100644 --- a/sbapp/plyer/platforms/ios/maps.py +++ b/sbapp/plyer/platforms/ios/maps.py @@ -18,7 +18,7 @@ def _open_by_address(self, address, **kwargs): ''' address = quote_plus(address, safe=',') - maps_address = 'http://maps.apple.com/?address=' + address + maps_address = f"http://maps.apple.com/?address={address}" webbrowser.open(maps_address) @@ -31,8 +31,7 @@ def _open_by_lat_long(self, latitude, longitude, **kwargs): ''' name = kwargs.get("name", "Selected Location") - maps_address = 'http://maps.apple.com/?ll={},{}&q={}'.format( - latitude, longitude, name) + maps_address = f'http://maps.apple.com/?ll={latitude},{longitude}&q={name}' webbrowser.open(maps_address) @@ -51,10 +50,10 @@ def _search(self, query, **kwargs): longitude = kwargs.get('longitude') query = quote_plus(query, safe=',') - maps_address = 'http://maps.apple.com/?q=' + query + maps_address = f"http://maps.apple.com/?q={query}" if latitude is not None and longitude is not None: - maps_address += '&sll={},{}'.format(latitude, longitude) + maps_address += f'&sll={latitude},{longitude}' webbrowser.open(maps_address) @@ -66,8 +65,7 @@ def _route(self, saddr, daddr, **kwargs): saddr = quote_plus(saddr, safe=',') daddr = quote_plus(daddr, safe=',') - maps_address = 'http://maps.apple.com/?saddr={}&daddr={}'.format( - saddr, daddr) + maps_address = f'http://maps.apple.com/?saddr={saddr}&daddr={daddr}' webbrowser.open(maps_address) diff --git a/sbapp/plyer/platforms/linux/accelerometer.py b/sbapp/plyer/platforms/linux/accelerometer.py index 889de15..d0d15de 100644 --- a/sbapp/plyer/platforms/linux/accelerometer.py +++ b/sbapp/plyer/platforms/linux/accelerometer.py @@ -22,7 +22,7 @@ def _get_acceleration(self): except IndexError: raise Exception('Could not enable accelerometer!') - with open(pos, "r") as p: + with open(pos) as p: t = p.read() coords = re.findall(r"[-]?\d+\.?\d*", t) # Apparently the acceleration on sysfs goes from -1000 to 1000. diff --git a/sbapp/plyer/platforms/linux/cpu.py b/sbapp/plyer/platforms/linux/cpu.py index 66a532f..c07d6ce 100644 --- a/sbapp/plyer/platforms/linux/cpu.py +++ b/sbapp/plyer/platforms/linux/cpu.py @@ -83,7 +83,7 @@ def _cache(self): else: present = [present[0]] - cores = ['cpu{}'.format(i) for i in present] + cores = [f'cpu{i}' for i in present] for core in cores: indicies = [ # get 'indexN' files from 'cache' folder assuming @@ -97,7 +97,7 @@ def _cache(self): index_type = join(cpu_path, core, 'cache', index, 'level') with open(index_type, 'rb') as fle: cache_level = fle.read().decode('utf-8').strip() - values['L{}'.format(cache_level)] += 1 + values[f'L{cache_level}'] += 1 return values @staticmethod diff --git a/sbapp/plyer/platforms/linux/filechooser.py b/sbapp/plyer/platforms/linux/filechooser.py index a8e2ef2..8a945cd 100644 --- a/sbapp/plyer/platforms/linux/filechooser.py +++ b/sbapp/plyer/platforms/linux/filechooser.py @@ -127,7 +127,7 @@ def _gen_cmdline(self): else: cmdline += [ "--file-filter", - "{name} | {flt}".format(name=f[0], flt=" ".join(f[1:])) + f"{f[0]} | {' '.join(f[1:])}" ] return cmdline @@ -220,7 +220,7 @@ def _gen_cmdline(self): else: cmdline += [ "--file-filter", - "{name} | {flt}".format(name=f[0], flt=" ".join(f[1:])) + f"{f[0]} | {' '.join(f[1:])}" ] return cmdline diff --git a/sbapp/plyer/platforms/linux/notification.py b/sbapp/plyer/platforms/linux/notification.py index 552519e..409b608 100644 --- a/sbapp/plyer/platforms/linux/notification.py +++ b/sbapp/plyer/platforms/linux/notification.py @@ -23,7 +23,7 @@ def _notify(self, **kwargs): "org.freedesktop.portal.Desktop", "--object-path", "/org/freedesktop/portal/desktop", "--method", "org.freedesktop.portal.Notification.AddNotification", "", - "{'title': <'" + title + "'>, 'body': <'" + body + "'>}" + f"{{'title': <'{title}'>, 'body': <'{body}'>}}" ], stdout=subprocess.DEVNULL) diff --git a/sbapp/plyer/platforms/linux/storagepath.py b/sbapp/plyer/platforms/linux/storagepath.py index b32a5fe..b18be2b 100755 --- a/sbapp/plyer/platforms/linux/storagepath.py +++ b/sbapp/plyer/platforms/linux/storagepath.py @@ -28,9 +28,9 @@ def _get_from_user_dirs(self, name): if not exists(user_dirs): return default - with open(user_dirs, "r") as f: + with open(user_dirs) as f: for line in f.readlines(): - if line.startswith("XDG_" + name): + if line.startswith(f"XDG_{name}"): return line.split('"')[1] return default @@ -39,7 +39,7 @@ def _get_home_dir(self): return expanduser('~') def _get_external_storage_dir(self): - return "/media/" + self._get_home_dir().split("/")[-1] + return f"/media/{self._get_home_dir().split('/')[-1]}" def _get_root_dir(self): return "/" diff --git a/sbapp/plyer/platforms/linux/uniqueid.py b/sbapp/plyer/platforms/linux/uniqueid.py index 30c1112..4708e31 100644 --- a/sbapp/plyer/platforms/linux/uniqueid.py +++ b/sbapp/plyer/platforms/linux/uniqueid.py @@ -21,14 +21,14 @@ def _get_uid(self): stdout=PIPE, stderr=PIPE ).communicate()[0].decode('utf-8') - output = u'' + output = '' for line in stdout.splitlines(): if 'serial:' not in line: continue output = line break - environ['LANG'] = old_lang or u'' + environ['LANG'] = old_lang or '' result = None if output: diff --git a/sbapp/plyer/platforms/linux/wifi.py b/sbapp/plyer/platforms/linux/wifi.py index 144f58a..1b3e1ed 100644 --- a/sbapp/plyer/platforms/linux/wifi.py +++ b/sbapp/plyer/platforms/linux/wifi.py @@ -13,8 +13,7 @@ import wifi except ModuleNotFoundError as err: raise ModuleNotFoundError( - "python-wifi not installed. try:" + - "`pip install --user wifi`.") from err + f"python-wifi not installed. try:`pip install --user wifi`.") from err class NMCLIWifi(Wifi): @@ -170,7 +169,7 @@ def _get_network_info(self, name): ret_list['signal'] = self.names[name]['SIGNAL'] bars = len(self.names[name]['BARS']) - ret_list['quality'] = '{}/100'.format(bars / 5.0 * 100) + ret_list['quality'] = f'{bars / 5.0 * 100}/100' ret_list['frequency'] = self.names[name]['FREQ'] ret_list['bitrates'] = self.names[name]['RATE'] diff --git a/sbapp/plyer/platforms/macosx/maps.py b/sbapp/plyer/platforms/macosx/maps.py index 7a6d998..2671dff 100644 --- a/sbapp/plyer/platforms/macosx/maps.py +++ b/sbapp/plyer/platforms/macosx/maps.py @@ -18,7 +18,7 @@ def _open_by_address(self, address, **kwargs): ''' address = quote_plus(address, safe=',') - maps_address = 'http://maps.apple.com/?address=' + address + maps_address = f"http://maps.apple.com/?address={address}" process = Popen( ['open', '-a', 'Maps', maps_address], @@ -34,8 +34,7 @@ def _open_by_lat_long(self, latitude, longitude, **kwargs): ''' name = kwargs.get("name", "Selected Location") - maps_address = 'http://maps.apple.com/?ll={},{}&q={}'.format( - latitude, longitude, name) + maps_address = f'http://maps.apple.com/?ll={latitude},{longitude}&q={name}' process = Popen( ['open', '-a', 'Maps', maps_address], @@ -57,10 +56,10 @@ def _search(self, query, **kwargs): longitude = kwargs.get('longitude') query = quote_plus(query, safe=',') - maps_address = 'http://maps.apple.com/?q=' + query + maps_address = f"http://maps.apple.com/?q={query}" if latitude is not None and longitude is not None: - maps_address += '&sll={},{}'.format(latitude, longitude) + maps_address += f'&sll={latitude},{longitude}' process = Popen( ['open', '-a', 'Maps', maps_address], @@ -75,8 +74,7 @@ def _route(self, saddr, daddr, **kwargs): saddr = quote_plus(saddr, safe=',') daddr = quote_plus(daddr, safe=',') - maps_address = 'http://maps.apple.com/?saddr={}&daddr={}'.format( - saddr, daddr) + maps_address = f'http://maps.apple.com/?saddr={saddr}&daddr={daddr}' process = Popen( ['open', '-a', 'Maps', maps_address], stdout=PIPE, stderr=PIPE) diff --git a/sbapp/plyer/platforms/win/email.py b/sbapp/plyer/platforms/win/email.py index 3c43cde..641d8c9 100644 --- a/sbapp/plyer/platforms/win/email.py +++ b/sbapp/plyer/platforms/win/email.py @@ -35,7 +35,7 @@ def _send(self, **kwargs): # WE + startfile are available only on Windows try: os.startfile(uri) - except WindowsError: + except OSError: print("Warning: unable to find a program able to send emails.") diff --git a/sbapp/plyer/platforms/win/filechooser.py b/sbapp/plyer/platforms/win/filechooser.py index 9932d9b..7a99e5c 100644 --- a/sbapp/plyer/platforms/win/filechooser.py +++ b/sbapp/plyer/platforms/win/filechooser.py @@ -85,9 +85,9 @@ def run(self): filters = "" for f in self.filters: if isinstance(f, str): - filters += (f + "\x00") * 2 + filters += f'{f}\x00' * 2 else: - filters += f[0] + "\x00" + ";".join(f[1:]) + "\x00" + filters += f"{f[0]}\x00{';'.join(f[1:])}\x00" args["Filter"] = filters flags = win32con.OFN_OVERWRITEPROMPT diff --git a/sbapp/plyer/platforms/win/libs/balloontip.py b/sbapp/plyer/platforms/win/libs/balloontip.py index 1334a99..7645bd0 100644 --- a/sbapp/plyer/platforms/win/libs/balloontip.py +++ b/sbapp/plyer/platforms/win/libs/balloontip.py @@ -1,4 +1,3 @@ -# -- coding: utf-8 -- ''' Module of Windows API for creating taskbar balloon tip notification in the taskbar's tray notification area. @@ -87,7 +86,7 @@ def __init__(self, title, message, app_name, app_icon='', atexit.register(self.__del__) wnd_class_ex = win_api_defs.get_WNDCLASSEXW() - class_name = 'PlyerTaskbar' + str(WindowsBalloonTip._get_unique_id()) + class_name = f"PlyerTaskbar{WindowsBalloonTip._get_unique_id())}" wnd_class_ex.lpszClassName = class_name @@ -127,7 +126,7 @@ def __init__(self, title, message, app_name, app_icon='', ) if hicon is None: - raise Exception('Could not load icon {}'.format(app_icon)) + raise Exception(f'Could not load icon {app_icon}') self._balloon_icon = self._hicon = hicon else: self._hicon = win_api_defs.LoadIconW( diff --git a/sbapp/plyer/platforms/win/libs/batterystatus.py b/sbapp/plyer/platforms/win/libs/batterystatus.py index 0c0c635..5925369 100644 --- a/sbapp/plyer/platforms/win/libs/batterystatus.py +++ b/sbapp/plyer/platforms/win/libs/batterystatus.py @@ -18,7 +18,7 @@ def battery_status(): if not win_api_defs.GetSystemPowerStatus(ctypes.pointer(status)): raise Exception('Could not get system power status.') - return dict( - (field, getattr(status, field)) + return { + field: getattr(status, field) for field, _ in status._fields_ - ) + } diff --git a/sbapp/plyer/tools/pep8checker/pep8.py b/sbapp/plyer/tools/pep8checker/pep8.py index a2f1f2c..3300d98 100644 --- a/sbapp/plyer/tools/pep8checker/pep8.py +++ b/sbapp/plyer/tools/pep8checker/pep8.py @@ -308,14 +308,14 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number, if blank_lines: yield 0, "E304 blank lines found after function decorator" elif blank_lines > 2 or (indent_level and blank_lines == 2): - yield 0, "E303 too many blank lines (%d)" % blank_lines + yield 0, f"E303 too many blank lines ({int(blank_lines)})" elif logical_line.startswith(('def ', 'class ', '@')): if indent_level: if not (blank_lines or previous_indent_level < indent_level or DOCSTRING_REGEX.match(previous_logical)): yield 0, "E301 expected 1 blank line, found 0" elif blank_lines != 2: - yield 0, "E302 expected 2 blank lines, found %d" % blank_lines + yield 0, f"E302 expected 2 blank lines, found {int(blank_lines)}" def extraneous_whitespace(logical_line): @@ -343,12 +343,12 @@ def extraneous_whitespace(logical_line): text = match.group() char = text.strip() found = match.start() - if text == char + ' ': + if text == f"{char} ": # assert char in '([{' - yield found + 1, "E201 whitespace after '%s'" % char + yield found + 1, f"E201 whitespace after '{char}'" elif line[found - 1] != ',': code = ('E202' if char in '}])' else 'E203') # if char in ',;:' - yield found, "%s whitespace before '%s'" % (code, char) + yield found, f"{code} whitespace before '{char}'" def whitespace_around_keywords(logical_line): @@ -397,7 +397,7 @@ def missing_whitespace(logical_line): continue # Slice syntax, no space required if char == ',' and line[index + 1] == ')': continue # Allow tuple with only one element: (3,) - yield index, "E231 missing whitespace after '%s'" % char + yield index, f"E231 missing whitespace after '{char}'" def indentation(logical_line, previous_logical, indent_char, @@ -474,7 +474,7 @@ def continuation_line_indentation(logical_line, tokens, indent_level, verbose): indent_chances = {} last_indent = (0, 0) if verbose >= 3: - print((">>> " + tokens[0][4].rstrip())) + print(f">>> {tokens[0][4].rstrip()}") for token_type, text, start, end, line in tokens: newline = row < start[0] - first_row @@ -487,7 +487,7 @@ def continuation_line_indentation(logical_line, tokens, indent_level, verbose): # this is the beginning of a continuation line. last_indent = start if verbose >= 3: - print(("... " + line.rstrip())) + print(f"... {line.rstrip()}") # record the initial indent. rel_indent[row] = start[1] - indent_level @@ -544,7 +544,7 @@ def continuation_line_indentation(logical_line, tokens, indent_level, verbose): indent[depth] = start[1] indent_chances[start[1]] = True if verbose >= 4: - print(("bracket depth %s indent to %s" % (depth, start[1]))) + print(f"bracket depth {depth} indent to {start[1]}") # deal with implicit string concatenation elif token_type == tokenize.STRING or text in ('u', 'ur', 'b', 'br'): indent_chances[start[1]] = str @@ -556,8 +556,8 @@ def continuation_line_indentation(logical_line, tokens, indent_level, verbose): indent.append(0) parens[row] += 1 if verbose >= 4: - print(("bracket depth %s seen, col %s, visual min = %s" % - (depth, start[1], indent[depth]))) + print("bracket depth %s seen, col %s, visual min = %s" % + (depth, start[1], indent[depth])) elif text in ')]}' and depth > 0: # parent indents should not be more than this one prev_indent = indent.pop() or last_indent[1] @@ -616,7 +616,7 @@ def whitespace_before_parameters(logical_line, tokens): (index < 2 or tokens[index - 2][1] != 'class') and # Allow "return (a.foo for a in range(5))" not keyword.iskeyword(prev_text)): - yield prev_end, "E211 whitespace before '%s'" % text + yield prev_end, f"E211 whitespace before '{text}'" prev_type = token_type prev_text = text prev_end = end @@ -743,9 +743,9 @@ def whitespace_around_comma(logical_line): for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): found = m.start() + 1 if '\t' in m.group(): - yield found, "E242 tab after '%s'" % m.group()[0] + yield found, f"E242 tab after '{m.group()[0]}'" else: - yield found, "E241 multiple spaces after '%s'" % m.group()[0] + yield found, f"E241 multiple spaces after '{m.group()[0]}'" def whitespace_around_named_parameter_equals(logical_line, tokens): @@ -925,16 +925,15 @@ def comparison_to_singleton(logical_line): if match: same = (match.group(1) == '==') singleton = match.group(2) - msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) + msg = f"'if cond is {('' if same else 'not ') + singleton}:'" if singleton in ('None',): code = 'E711' else: code = 'E712' nonzero = ((singleton == 'True' and same) or (singleton == 'False' and not same)) - msg += " or 'if %scond:'" % ('' if nonzero else 'not ') - yield match.start(1), ("%s comparison to %s should be %s" % - (code, singleton, msg)) + msg += f" or 'if {'' if nonzero else 'not '}cond:'" + yield match.start(1), (f"{code} comparison to {singleton} should be {msg}") def comparison_type(logical_line): @@ -1023,7 +1022,7 @@ def python_3000_backticks(logical_line): ############################################################################## -if '' == ''.encode(): +if '' == b'': # Python 2: implicit encoding. def readlines(filename): f = open(filename) @@ -1114,16 +1113,16 @@ def parse_udiff(diff, patterns=None, parent='.'): nrows -= 1 continue if line[:3] == '@@ ': - row, nrows = [int(g) for g in HUNK_REGEX.match(line).groups()] + row, nrows = (int(g) for g in HUNK_REGEX.match(line).groups()) rv[path].update(list(range(row, row + nrows))) elif line[:3] == '+++': path = line[4:].split('\t', 1)[0] if path[:2] == 'b/': path = path[2:] rv[path] = set() - return dict([(os.path.join(parent, path), rows) + return {os.path.join(parent, path): rows for (path, rows) in list(rv.items()) - if rows and filename_match(path, patterns)]) + if rows and filename_match(path, patterns)} def filename_match(filename, patterns, default=True): @@ -1178,9 +1177,9 @@ def __init__(self, filename, lines=None, elif lines is None: try: self.lines = readlines(filename) - except IOError: + except OSError: exc_type, exc = sys.exc_info()[:2] - self._io_error = '%s: %s' % (exc_type.__name__, exc) + self._io_error = f'{exc_type.__name__}: {exc}' self.lines = [] else: self.lines = lines @@ -1273,10 +1272,10 @@ def check_logical(self): self.previous_indent_level = self.indent_level self.indent_level = expand_indent(indent) if self.verbose >= 2: - print((self.logical_line[:80].rstrip())) + print(self.logical_line[:80].rstrip()) for name, check, argument_names in self._logical_checks: if self.verbose >= 4: - print((' ' + name)) + print(f" {name}") for result in self.run_check(check, argument_names): offset, text = result if isinstance(offset, tuple): @@ -1291,18 +1290,17 @@ def check_logical(self): def generate_tokens(self): if self._io_error: - self.report_error(1, 0, 'E902 %s' % self._io_error, readlines) + self.report_error(1, 0, f'E902 {self._io_error}', readlines) tokengen = tokenize.generate_tokens(self.readline_check_physical) try: - for token in tokengen: - yield token + yield from tokengen except (SyntaxError, tokenize.TokenError): exc_type, exc = sys.exc_info()[:2] offset = exc.args[1] if len(offset) > 2: offset = offset[1:3] self.report_error(offset[0], offset[1], - 'E901 %s: %s' % (exc_type.__name__, exc.args[0]), + f'E901 {exc_type.__name__}: {exc.args[0]}', self.generate_tokens) generate_tokens.__doc__ = " Check if the syntax is valid." @@ -1323,11 +1321,11 @@ def check_all(self, expected=None, line_offset=0): token_type, text = token[0:2] if self.verbose >= 3: if token[2][0] == token[3][0]: - pos = '[%s:%s]' % (token[2][1] or '', token[3][1]) + pos = f"[{token[2][1] or ''}:{token[3][1]}]" else: - pos = 'l.%s' % token[3][0] - print(('l.%s\t%s\t%s\t%r' % - (token[2][0], pos, tokenize.tok_name[token[0]], text))) + pos = f'l.{token[3][0]}' + print('l.%s\t%s\t%s\t%r' % + (token[2][0], pos, tokenize.tok_name[token[0]], text)) if token_type == tokenize.COMMENT or token_type == tokenize.STRING: for sre in re.finditer(r"[:.;,] ?[A-Za-z]", text): pos = sre.span()[0] @@ -1426,7 +1424,7 @@ def error(self, line_number, offset, text, check): if code in self.expected: return if self.print_filename and not self.file_errors: - print((self.filename)) + print(self.filename) self.file_errors += 1 self.total_errors += 1 return code @@ -1459,12 +1457,12 @@ def print_statistics(self, prefix=''): def print_benchmark(self): """Print benchmark numbers.""" - print(('%-7.2f %s' % (self.elapsed, 'seconds elapsed'))) + print(f'{self.elapsed:<7.2f} seconds elapsed') if self.elapsed: for key in self._benchmark_keys: - print(('%-7d %s per second (%d total)' % + print('%-7d %s per second (%d total)' % (self.counters[key] / self.elapsed, key, - self.counters[key]))) + self.counters[key])) class FileReport(BaseReport): @@ -1489,20 +1487,20 @@ def error(self, line_number, offset, text, check): code = super().error(line_number, offset, text, check) if code and (self.counters[code] == 1 or self._repeat): - print((self._fmt % { + print(self._fmt % { 'path': self.filename, 'row': self.line_offset + line_number, 'col': offset + 1, 'code': code, 'text': text[5:], - })) + }) if self._show_source: if line_number > len(self.lines): line = '' else: line = self.lines[line_number - 1] - print((line.rstrip())) - print((' ' * offset + '^')) + print(line.rstrip()) + print(f"{' ' * offset}^") if self._show_pep8 and check is not None: - print((check.__doc__.lstrip('\n').rstrip())) + print(check.__doc__.lstrip('\n').rstrip()) return code @@ -1529,16 +1527,15 @@ def __init__(self, options): def get_file_results(self): # Check if the expected errors were found - label = '%s:%s:1' % (self.filename, self.line_offset) + label = f'{self.filename}:{self.line_offset}:1' codes = sorted(self.expected) for code in codes: if not self.counters.get(code): self.file_errors += 1 self.total_errors += 1 - print(('%s: error %s not found' % (label, code))) + print(f'{label}: error {code} not found') if self._verbose and not self.file_errors: - print(('%s: passed (%s)' % - (label, ' '.join(codes) or 'Okay'))) + print(f"{label}: passed ({' '.join(codes) or 'Okay'})") self.counters['test cases'] += 1 if self.file_errors: self.counters['failed tests'] += 1 @@ -1552,10 +1549,10 @@ def print_results(self): results = ("%(physical lines)d lines tested: %(files)d files, " "%(test cases)d test cases%%s." % self.counters) if self.total_errors: - print((results % ", %s failures" % self.total_errors)) + print(results % ", %s failures" % self.total_errors) else: - print((results % "")) - print(("Test failed." if self.total_errors else "Test passed.")) + print(results % "") + print("Test failed." if self.total_errors else "Test passed.") class StyleGuide: @@ -1614,7 +1611,7 @@ def check_files(self, paths=None): def input_file(self, filename, lines=None, expected=None, line_offset=0): """Run all checks on a Python source file.""" if self.options.verbose: - print(('checking %s' % filename)) + print(f'checking {filename}') fchecker = Checker(filename, lines=lines, options=self.options) return fchecker.check_all(expected=expected, line_offset=line_offset) @@ -1629,15 +1626,15 @@ def input_dir(self, dirname): runner = self.runner for root, dirs, files in os.walk(dirname): if verbose: - print(('directory ' + root)) + print(f"directory {root}") counters['directories'] += 1 for subdir in sorted(dirs): if self.excluded(subdir): dirs.remove(subdir) for filename in sorted(files): # contain a pattern that matches? - if ((filename_match(filename, filepatterns) and - not self.excluded(filename))): + if (filename_match(filename, filepatterns) and + not self.excluded(filename)): runner(os.path.join(root, filename)) def excluded(self, filename): @@ -1740,16 +1737,16 @@ def selftest(options): for part in source.split(r'\n'): part = part.replace(r'\t', '\t') part = part.replace(r'\s', ' ') - checker.lines.append(part + '\n') + checker.lines.append(f"{part}\n") checker.check_all() error = None if code == 'Okay': if len(counters) > len(options.benchmark_keys): codes = [key for key in counters if key not in options.benchmark_keys] - error = "incorrectly found %s" % ', '.join(codes) + error = f"incorrectly found {', '.join(codes)}" elif not counters.get(code): - error = "failed to find %s" % code + error = f"failed to find {code}" # Keep showing errors for multiple tests for key in set(counters) - set(options.benchmark_keys): del counters[key] @@ -1757,12 +1754,12 @@ def selftest(options): count_all += 1 if not error: if options.verbose: - print(("%s: %s" % (code, source))) + print(f"{code}: {source}") else: count_failed += 1 - print(("%s: %s:" % (__file__, error))) + print(f"{__file__}: {error}:") for line in checker.lines: - print((line.rstrip())) + print(line.rstrip()) return count_failed, count_all @@ -1773,7 +1770,7 @@ def read_config(options, args, arglist, parser): user_conf = options.config if user_conf and os.path.isfile(user_conf): if options.verbose: - print(('user configuration: %s' % user_conf)) + print(f'user configuration: {user_conf}') config.read(user_conf) parent = tail = args and os.path.abspath(os.path.commonprefix(args)) @@ -1781,14 +1778,14 @@ def read_config(options, args, arglist, parser): local_conf = os.path.join(parent, '.pep8') if os.path.isfile(local_conf): if options.verbose: - print(('local configuration: %s' % local_conf)) + print(f'local configuration: {local_conf}') config.read(local_conf) break parent, tail = os.path.split(parent) if config.has_section('pep8'): - option_list = dict([(o.dest, o.type or o.action) - for o in parser.option_list]) + option_list = {o.dest: o.type or o.action + for o in parser.option_list} # First, read the default values new_options, _ = parser.parse_args([]) @@ -1796,10 +1793,10 @@ def read_config(options, args, arglist, parser): # Second, parse the configuration for opt in config.options('pep8'): if options.verbose > 1: - print((' %s = %s' % (opt, config.get('pep8', opt)))) + print(f" {opt} = {config.get('pep8', opt)}") if opt.replace('_', '-') not in parser.config_options: - print(('Unknown option: \'%s\'\n not in [%s]' % - (opt, ' '.join(parser.config_options)))) + print('Unknown option: \'%s\'\n not in [%s]' % + (opt, ' '.join(parser.config_options))) sys.exit(1) normalized_opt = opt.replace('-', '_') opt_type = option_list[normalized_opt] @@ -1930,8 +1927,8 @@ def _main(): count_failed = fail_s + fail_d if not options.quiet: count_passed = done_d + done_s - count_failed - print(("%d passed and %d failed." % (count_passed, count_failed))) - print(("Test failed." if count_failed else "Test passed.")) + print(f"{int(count_passed)} passed and {int(count_failed)} failed.") + print("Test failed." if count_failed else "Test passed.") if count_failed: sys.exit(1) if options.testsuite: @@ -1945,7 +1942,7 @@ def _main(): report.print_results() if report.total_errors: if options.count: - sys.stderr.write(str(report.total_errors) + '\n') + sys.stderr.write(f"{report.total_errors)}\n") sys.exit(1) diff --git a/sbapp/plyer/tools/pep8checker/pep8kivy.py b/sbapp/plyer/tools/pep8checker/pep8kivy.py index 60ec4e7..d709f9b 100644 --- a/sbapp/plyer/tools/pep8checker/pep8kivy.py +++ b/sbapp/plyer/tools/pep8checker/pep8kivy.py @@ -26,7 +26,7 @@ def report_error(self, line_number, offset, text, check): ) # html generation - print('{0}{1}'.format(line_number, text)) + print(f'{line_number}{text}') if __name__ == '__main__': @@ -52,7 +52,7 @@ def usage(): def check(fn): try: checker = KivyStyleChecker(fn) - except IOError: + except OSError: # File couldn't be opened, so was deleted apparently. # Don't check deleted files. return 0 @@ -68,10 +68,9 @@ def check(fn): if isdir(target): if htmlmode: path = join(dirname(abspath(__file__)), 'pep8base.html') - print(open(path, 'r').read()) + print(open(path).read()) print( - '''

Generated: %s

''' - '' % (time.strftime('%c')) + f'''

Generated: {time.strftime('%c')}

''' ) for dirpath, dirnames, filenames in walk(target): @@ -95,8 +94,7 @@ def check(fn): if htmlmode: print( - '' - '' % complete_filename + f'' ) errors += check(complete_filename) diff --git a/sbapp/plyer/utils.py b/sbapp/plyer/utils.py index 573075d..452e85c 100644 --- a/sbapp/plyer/utils.py +++ b/sbapp/plyer/utils.py @@ -32,10 +32,7 @@ def __str__(self): return self._get_platform() def __repr__(self): - return 'platform name: \'{platform}\' from: \n{instance}'.format( - platform=self._get_platform(), - instance=super().__repr__() - ) + return f'platform name: \'{self._get_platform()}\' from: \n{super().__repr__()}' def __hash__(self): return self._get_platform().__hash__() @@ -93,9 +90,9 @@ def _ensure_obj(self): try: name = object.__getattribute__(self, '_name') if RNS.vendor.platformutils.is_android(): - module = 'plyer.platforms.{}.{}'.format(platform, name) + module = f'plyer.platforms.{platform}.{name}' else: - module = 'sbapp.plyer.platforms.{}.{}'.format(platform, name) + module = f'sbapp.plyer.platforms.{platform}.{name}' mod = __import__(module, fromlist='.') obj = mod.instance() except Exception: @@ -227,7 +224,7 @@ def new_func(*args, **kwargs): ) ) - warnings.warn('[{}] {}'.format('WARNING', warning)) + warnings.warn(f'[WARNING] {warning}') # if there is a docstring present, emit docstring too if obj.__doc__: diff --git a/sbapp/pydub/audio_segment.py b/sbapp/pydub/audio_segment.py index 14ea46e..f39aee1 100644 --- a/sbapp/pydub/audio_segment.py +++ b/sbapp/pydub/audio_segment.py @@ -1,5 +1,3 @@ -from __future__ import division - import array import os import subprocess @@ -42,13 +40,12 @@ MissingAudioParameter, ) -if sys.version_info >= (3, 0): - basestring = str - xrange = range - StringIO = BytesIO +basestring = str +xrange = range +StringIO = BytesIO -class ClassPropertyDescriptor(object): +class ClassPropertyDescriptor: def __init__(self, fget, fset=None): self.fget = fget @@ -116,8 +113,7 @@ def read_wav_audio(data, headers=None): pos = fmt.position + 8 audio_format = struct.unpack_from('= (3, 0): - xrange = range +xrange = range @register_pydub_effect @@ -204,7 +203,7 @@ def invert_phase(seg, channels=(1, 1)): if seg.channels == 2: left, right = seg.split_to_mono() else: - raise Exception("Can't implicitly convert an AudioSegment with " + str(seg.channels) + " channels to stereo.") + raise Exception(f"Can't implicitly convert an AudioSegment with {seg.channels)} channels to stereo.") if channels == (1, 0): left = left.invert_phase() diff --git a/sbapp/pydub/generators.py b/sbapp/pydub/generators.py index b04cb4c..a5ecfbe 100644 --- a/sbapp/pydub/generators.py +++ b/sbapp/pydub/generators.py @@ -21,7 +21,7 @@ -class SignalGenerator(object): +class SignalGenerator: def __init__(self, sample_rate=44100, bit_depth=16): self.sample_rate = sample_rate self.bit_depth = bit_depth @@ -64,7 +64,7 @@ def generate(self): class Sine(SignalGenerator): def __init__(self, freq, **kwargs): - super(Sine, self).__init__(**kwargs) + super().__init__(**kwargs) self.freq = freq def generate(self): @@ -78,7 +78,7 @@ def generate(self): class Pulse(SignalGenerator): def __init__(self, freq, duty_cycle=0.5, **kwargs): - super(Pulse, self).__init__(**kwargs) + super().__init__(**kwargs) self.freq = freq self.duty_cycle = duty_cycle @@ -101,13 +101,13 @@ def generate(self): class Square(Pulse): def __init__(self, freq, **kwargs): kwargs['duty_cycle'] = 0.5 - super(Square, self).__init__(freq, **kwargs) + super().__init__(freq, **kwargs) class Sawtooth(SignalGenerator): def __init__(self, freq, duty_cycle=1.0, **kwargs): - super(Sawtooth, self).__init__(**kwargs) + super().__init__(**kwargs) self.freq = freq self.duty_cycle = duty_cycle @@ -133,7 +133,7 @@ def generate(self): class Triangle(Sawtooth): def __init__(self, freq, **kwargs): kwargs['duty_cycle'] = 0.5 - super(Triangle, self).__init__(freq, **kwargs) + super().__init__(freq, **kwargs) class WhiteNoise(SignalGenerator): diff --git a/sbapp/pydub/utils.py b/sbapp/pydub/utils.py index 740c500..f359995 100644 --- a/sbapp/pydub/utils.py +++ b/sbapp/pydub/utils.py @@ -1,5 +1,3 @@ -from __future__ import division - import json import os import re @@ -15,8 +13,7 @@ except ImportError: import pyaudioop as audioop -if sys.version_info >= (3, 0): - basestring = str +basestring = str FRAME_WIDTHS = { 8: 1, @@ -214,7 +211,7 @@ def fsdecode(filename): if isinstance(filename, basestring): return filename - raise TypeError("type {0} not accepted by fsdecode".format(type(filename))) + raise TypeError(f"type {type(filename)} not accepted by fsdecode") def get_extra_info(stderr): @@ -236,7 +233,7 @@ def get_extra_info(stderr): for i in re.finditer(re_stream, stderr): if i.group('space_end') is not None and len(i.group('space_start')) <= len( i.group('space_end')): - content_line = ','.join([i.group('content_0'), i.group('content_1')]) + content_line = f"{i.group('content_0')},{i.group('content_1')}" else: content_line = i.group('content_0') tokens = [x.strip() for x in re.split('[:,]', content_line) if x] @@ -297,8 +294,8 @@ def set_property(stream, prop, value): stream[prop] = value for token in extra_info[stream['index']]: - m = re.match('([su]([0-9]{1,2})p?) \(([0-9]{1,2}) bit\)$', token) - m2 = re.match('([su]([0-9]{1,2})p?)( \(default\))?$', token) + m = re.match(r'([su]([0-9]{1,2})p?) \(([0-9]{1,2}) bit\)$', token) + m2 = re.match(r'([su]([0-9]{1,2})p?)( \(default\))?$', token) if m: set_property(stream, 'sample_fmt', m.group(1)) set_property(stream, 'bits_per_sample', int(m.group(2))) @@ -307,11 +304,11 @@ def set_property(stream, prop, value): set_property(stream, 'sample_fmt', m2.group(1)) set_property(stream, 'bits_per_sample', int(m2.group(2))) set_property(stream, 'bits_per_raw_sample', int(m2.group(2))) - elif re.match('(flt)p?( \(default\))?$', token): + elif re.match(r'(flt)p?( \(default\))?$', token): set_property(stream, 'sample_fmt', token) set_property(stream, 'bits_per_sample', 32) set_property(stream, 'bits_per_raw_sample', 32) - elif re.match('(dbl)p?( \(default\))?$', token): + elif re.match(r'(dbl)p?( \(default\))?$', token): set_property(stream, 'sample_fmt', token) set_property(stream, 'bits_per_sample', 64) set_property(stream, 'bits_per_raw_sample', 64) diff --git a/sbapp/pyogg/flac_file.py b/sbapp/pyogg/flac_file.py index 7e97ca7..132f6a7 100644 --- a/sbapp/pyogg/flac_file.py +++ b/sbapp/pyogg/flac_file.py @@ -45,7 +45,7 @@ def metadata_callback(self,decoder, metadata, client_data): self.frequency = metadata.contents.data.stream_info.sample_rate def error_callback(self,decoder, status, client_data): - raise PyOggError("An error occured during the process of decoding. Status enum: {}".format(flac.FLAC__StreamDecoderErrorStatusEnum[status])) + raise PyOggError(f"An error occured during the process of decoding. Status enum: {flac.FLAC__StreamDecoderErrorStatusEnum[status]}") def __init__(self, path): self.decoder = flac.FLAC__stream_decoder_new() @@ -84,16 +84,16 @@ def __init__(self, path): if init_status: # error error = flac.FLAC__StreamDecoderInitStatusEnum[init_status] raise PyOggError( - "An error occured when trying to open '{}': {}".format(path, error) + f"An error occured when trying to open '{path}': {error}" ) metadata_status = (flac.FLAC__stream_decoder_process_until_end_of_metadata(self.decoder)) if not metadata_status: # error - raise PyOggError("An error occured when trying to decode the metadata of {}".format(path)) + raise PyOggError(f"An error occured when trying to decode the metadata of {path}") stream_status = (flac.FLAC__stream_decoder_process_until_end_of_stream(self.decoder)) if not stream_status: # error - raise PyOggError("An error occured when trying to decode the audio stream of {}".format(path)) + raise PyOggError(f"An error occured when trying to decode the audio stream of {path}") flac.FLAC__stream_decoder_finish(self.decoder) diff --git a/sbapp/pyogg/flac_file_stream.py b/sbapp/pyogg/flac_file_stream.py index f832c31..3c2650f 100644 --- a/sbapp/pyogg/flac_file_stream.py +++ b/sbapp/pyogg/flac_file_stream.py @@ -41,7 +41,7 @@ def metadata_callback(self,decoder, metadata, client_data): self.frequency = metadata.contents.data.stream_info.sample_rate def error_callback(self,decoder, status, client_data): - raise PyOggError("An error occured during the process of decoding. Status enum: {}".format(flac.FLAC__StreamDecoderErrorStatusEnum[status])) + raise PyOggError(f"An error occured during the process of decoding. Status enum: {flac.FLAC__StreamDecoderErrorStatusEnum[status]}") def __init__(self, path): self.decoder = flac.FLAC__stream_decoder_new() @@ -75,11 +75,11 @@ def __init__(self, path): self.client_data) if init_status: # error - raise PyOggError("An error occured when trying to open '{}': {}".format(path, flac.FLAC__StreamDecoderInitStatusEnum[init_status])) + raise PyOggError(f"An error occured when trying to open '{path}': {flac.FLAC__StreamDecoderInitStatusEnum[init_status]}") metadata_status = (flac.FLAC__stream_decoder_process_until_end_of_metadata(self.decoder)) if not metadata_status: # error - raise PyOggError("An error occured when trying to decode the metadata of {}".format(path)) + raise PyOggError(f"An error occured when trying to decode the metadata of {path}") #: Bytes per sample self.bytes_per_sample = 2 @@ -94,7 +94,7 @@ def get_buffer(self): # Attempt to read a single frame of audio stream_status = (flac.FLAC__stream_decoder_process_single(self.decoder)) if not stream_status: # error - raise PyOggError("An error occured when trying to decode the audio stream of {}".format(path)) + raise PyOggError(f"An error occured when trying to decode the audio stream of {path}") # Check if we encountered the end of the stream if (flac.FLAC__stream_decoder_get_state(self.decoder) == 4): # end of stream diff --git a/sbapp/pyogg/library_loader.py b/sbapp/pyogg/library_loader.py index 711b1ba..0ccf60f 100644 --- a/sbapp/pyogg/library_loader.py +++ b/sbapp/pyogg/library_loader.py @@ -23,12 +23,12 @@ class ExternalLibraryError(Exception): if architecture == "32bit": for arch_style in ["32bit", "32" "86", "win32", "x86", "_x86", "_32", "_win32", "_32bit"]: for style in ["{}", "lib{}"]: - _windows_styles.append(style.format("{}"+arch_style)) + _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{}"]: - _windows_styles.append(style.format("{}"+arch_style)) + _windows_styles.append(style.format(f"{{}}{arch_style}")) run_tests = lambda lib, tests: [f(lib) for f in tests] @@ -69,7 +69,7 @@ def load(names: Dict[str, str], tests) -> Optional[ctypes.CDLL]: return None # Attempt to load the library from here - path = _here + "/" + lib_dir + "/" + name + path = f"{_here}/{lib_dir}/{name}" try: lib = ctypes.CDLL(path) except OSError as e: @@ -101,8 +101,8 @@ def load(name, paths = None, tests = []): @staticmethod def load_other(name, paths = None, tests = []): - os.environ["PATH"] += ";" + ";".join((os.getcwd(), _here)) - if paths: os.environ["PATH"] += ";" + ";".join(paths) + os.environ["PATH"] += f";{f"{os.getcwd()};{_here}"}" + if paths: os.environ["PATH"] += f";{';'.join(paths)}" for style in _other_styles: candidate = style.format(name) @@ -117,8 +117,8 @@ def load_other(name, paths = None, tests = []): @staticmethod def load_windows(name, paths = None, tests = []): - os.environ["PATH"] += ";" + ";".join((os.getcwd(), _here)) - if paths: os.environ["PATH"] += ";" + ";".join(paths) + 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: @@ -130,17 +130,17 @@ def load_windows(name, paths = None, tests = []): if tests and all(run_tests(lib, tests)): return lib not_supported.append(library) - except WindowsError: + except OSError: pass except OSError: not_supported.append(library) if not_supported: - raise ExternalLibraryError("library '{}' couldn't be loaded, because the following candidates were not supported:".format(name) + raise ExternalLibraryError(f"library '{name}' couldn't be loaded, because the following candidates were not supported:" + ("\n{}" * len(not_supported)).format(*not_supported)) - raise ExternalLibraryError("library '{}' couldn't be loaded".format(name)) + raise ExternalLibraryError(f"library '{name}' couldn't be loaded") diff --git a/sbapp/pyogg/ogg_opus_writer.py b/sbapp/pyogg/ogg_opus_writer.py index 547d0f5..feebc0a 100644 --- a/sbapp/pyogg/ogg_opus_writer.py +++ b/sbapp/pyogg/ogg_opus_writer.py @@ -107,8 +107,7 @@ def write(self, pcm: memoryview) -> None: # Check that the stream hasn't already been finished if self._finished: raise PyOggError( - "Stream has already ended. Perhaps close() was "+ - "called too early?") + f"Stream has already ended. Perhaps close() was called too early?") # If we haven't already written out the headers, do so # now. Then, write a frame of silence to warm up the diff --git a/sbapp/pyogg/opus_buffered_encoder.py b/sbapp/pyogg/opus_buffered_encoder.py index 7179051..16f784d 100644 --- a/sbapp/pyogg/opus_buffered_encoder.py +++ b/sbapp/pyogg/opus_buffered_encoder.py @@ -38,8 +38,7 @@ def set_frame_size(self, frame_size: float) -> None: # units of 0.1ms to avoid floating point comparison if int(frame_size*10) not in [25, 50, 100, 200, 400, 600]: raise PyOggError( - "Frame size ({:f}) not one of ".format(frame_size)+ - "the acceptable values" + f"Frame size ({frame_size:f}) not one of the acceptable values" ) self._frame_size_ms = frame_size @@ -336,7 +335,7 @@ def _get_next_frame(self, add_silence=False): Returns None if insufficient data is available. """ - next_frame = bytes() + next_frame = b'' samples = 0 # Ensure frame size has been specified diff --git a/sbapp/pyogg/opus_decoder.py b/sbapp/pyogg/opus_decoder.py index 8a1f4dd..00688d2 100644 --- a/sbapp/pyogg/opus_decoder.py +++ b/sbapp/pyogg/opus_decoder.py @@ -32,8 +32,7 @@ def set_channels(self, n): if self._decoder is None: if n < 0 or n > 2: raise PyOggError( - "Invalid number of channels in call to "+ - "set_channels()" + f"Invalid number of channels in call to set_channels()" ) self._channels = n else: @@ -65,7 +64,7 @@ def set_sampling_frequency(self, samples_per_second): else: raise PyOggError( "Specified sampling frequency "+ - "({:d}) ".format(samples_per_second)+ + f"({samples_per_second:d}) "+ "was not one of the accepted values" ) else: @@ -152,7 +151,7 @@ def decode_missing_packet(self, frame_duration): # avoid floating-point comparisons. if int(frame_duration*10) not in [25, 50, 100, 200, 400, 600]: raise PyOggError( - "Frame duration ({:f}) is not one of the accepted values".format(frame_duration) + f"Frame duration ({frame_duration:f}) is not one of the accepted values" ) # Calculate frame size diff --git a/sbapp/pyogg/opus_encoder.py b/sbapp/pyogg/opus_encoder.py index 1da82da..b1d5390 100644 --- a/sbapp/pyogg/opus_encoder.py +++ b/sbapp/pyogg/opus_encoder.py @@ -32,8 +32,7 @@ def set_channels(self, n: int) -> None: if self._encoder is None: if n < 0 or n > 2: raise PyOggError( - "Invalid number of channels in call to "+ - "set_channels()" + f"Invalid number of channels in call to set_channels()" ) self._channels = n else: @@ -62,7 +61,7 @@ def set_sampling_frequency(self, samples_per_second: int) -> None: else: raise PyOggError( "Specified sampling frequency "+ - "({:d}) ".format(samples_per_second)+ + f"({samples_per_second:d}) "+ "was not one of the accepted values" ) else: @@ -111,7 +110,7 @@ def set_application(self, application: str) -> None: self._application = opus.OPUS_APPLICATION_RESTRICTED_LOWDELAY else: raise PyOggError( - "The application specification '{:s}' ".format(application)+ + f"The application specification '{application:s}' "+ "wasn't one of the accepted values." ) @@ -170,8 +169,7 @@ def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview: # Check that we have a valid frame size if int(frame_duration) not in [25, 50, 100, 200, 400, 600]: raise PyOggError( - "The effective frame duration ({:.1f} ms) " - .format(frame_duration/10)+ + f"The effective frame duration ({frame_duration / 10:.1f} ms) "+ "was not one of the acceptable values." ) diff --git a/sbapp/pyogg/opus_file.py b/sbapp/pyogg/opus_file.py index f8519f4..123d98b 100644 --- a/sbapp/pyogg/opus_file.py +++ b/sbapp/pyogg/opus_file.py @@ -72,8 +72,7 @@ def __init__(self, path: str) -> None: # Check for errors if ns<0: raise PyOggError( - "Error while reading OggOpus file. "+ - "Error code: {}".format(ns) + f"Error while reading OggOpus file. Error code: {ns}" ) # Increment the pointer diff --git a/sbapp/pyogg/opus_file_stream.py b/sbapp/pyogg/opus_file_stream.py index b3e1723..c464fca 100644 --- a/sbapp/pyogg/opus_file_stream.py +++ b/sbapp/pyogg/opus_file_stream.py @@ -21,7 +21,7 @@ def __init__(self, path): if error.value != 0: self.of = None - raise PyOggError("file couldn't be opened or doesn't exist. Error code : {}".format(error.value)) + raise PyOggError(f"file couldn't be opened or doesn't exist. Error code : {error.value}") #: Number of channels in audio file self.channels = opus.op_channel_count(self.of, -1) @@ -75,7 +75,7 @@ def get_buffer(self): # Check for errors if samples_read < 0: raise PyOggError( - "Failed to read OpusFileStream. Error {:d}".format(samples_read) + f"Failed to read OpusFileStream. Error {samples_read:d}" ) # Check if we've reached the end of the stream diff --git a/sbapp/pyogg/vorbis_file.py b/sbapp/pyogg/vorbis_file.py index 918f1e8..dcb1d23 100644 --- a/sbapp/pyogg/vorbis_file.py +++ b/sbapp/pyogg/vorbis_file.py @@ -131,8 +131,7 @@ def __init__(self, # Check for errors if result < 0: raise PyOggError( - "An error occurred decoding the Vorbis file: "+ - f"Error code: {result}" + f"An error occurred decoding the Vorbis file: Error code: {result}" ) # Check that the bitstream hasn't changed as we only diff --git a/sbapp/pyogg/vorbis_file_stream.py b/sbapp/pyogg/vorbis_file_stream.py index 57677ba..61e50ee 100644 --- a/sbapp/pyogg/vorbis_file_stream.py +++ b/sbapp/pyogg/vorbis_file_stream.py @@ -11,7 +11,7 @@ def __init__(self, path, buffer_size=8192): self.vf = vorbis.OggVorbis_File() error = vorbis.ov_fopen(path, ctypes.byref(self.vf)) if error != 0: - raise PyOggError("file couldn't be opened or doesn't exist. Error code : {}".format(error)) + raise PyOggError(f"file couldn't be opened or doesn't exist. Error code : {error}") info = vorbis.ov_info(ctypes.byref(self.vf), -1) diff --git a/sbapp/services/sidebandservice.py b/sbapp/services/sidebandservice.py index e718a6f..05203aa 100644 --- a/sbapp/services/sidebandservice.py +++ b/sbapp/services/sidebandservice.py @@ -78,11 +78,11 @@ def android_notification(self, title="", content="", ticker="", group=None, cont channel_id = package_name group_id = "" if group != None: - channel_id += "."+str(group) + channel_id += f".{group)}" group_id += str(group) if context_id != None: - channel_id += "."+str(context_id) - group_id += "."+str(context_id) + channel_id += f".{context_id)}" + group_id += f".{context_id)}" if not title or title == "": channel_name = "Sideband" @@ -134,12 +134,12 @@ def android_notification(self, title="", content="", ticker="", group=None, cont def check_permission(self, permission): if RNS.vendor.platformutils.is_android(): try: - result = self.android_service.checkSelfPermission("android.permission."+permission) + result = self.android_service.checkSelfPermission(f"android.permission.{permission}") if result == 0: return True except Exception as e: - RNS.log("Error while checking permission: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) return False @@ -238,14 +238,14 @@ def __init__(self): except Exception as e: self.wifi_manager = None RNS.log("Could not acquire Android WiFi Manager! Keeping WiFi-based interfaces up will be unavailable.", RNS.LOG_ERROR) - RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) try: self.power_manager = self.app_context.getSystemService(Context.POWER_SERVICE) except Exception as e: self.power_manager = None RNS.log("Could not acquire Android Power Manager! Taking wakelocks and keeping the CPU running will be unavailable.", RNS.LOG_ERROR) - RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) self.discover_usb_devices() @@ -259,7 +259,7 @@ def __init__(self): self.update_power_restrictions() if RNS.vendor.platformutils.is_android(): - RNS.log("Discovered USB devices: "+str(self.usb_devices), RNS.LOG_EXTREME) + RNS.log(f"Discovered USB devices: {self.usb_devices)}", RNS.LOG_EXTREME) self.update_location_provider() @@ -281,7 +281,7 @@ def discover_usb_devices(self): self.usb_devices.append(device_entry) except Exception as e: - RNS.log("Could not list USB devices. The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Could not list USB devices. The contained exception was: {e)}", RNS.LOG_ERROR) def start(self): self.should_run = True @@ -351,7 +351,7 @@ def get_connectivity_status(self): if len(netdevs) > 0: ds = "Using " for netdev in netdevs: - ds += "[i]"+str(netdev)+"[/i], " + ds += f"[i]{netdev)}[/i], " ds = ds[:-2] else: ds = "No usable network devices" @@ -360,13 +360,13 @@ def get_connectivity_status(self): if np == 1: ws = "1 reachable peer" else: - ws = str(np)+" reachable peers" + ws = f"{np)} reachable peers" - stat += "[b]Local[/b]\n{ds}\n{ws}\n\n".format(ds=ds, ws=ws) + stat += f"[b]Local[/b]\n{ds}\n{ws}\n\n" if self.sideband.interface_rnode != None: if self.sideband.interface_rnode.online: - rs = "On-air at "+str(self.sideband.interface_rnode.bitrate_kbps)+" Kbps" + rs = f"On-air at {self.sideband.interface_rnode.bitrate_kbps)} Kbps" else: rs = "Interface Down" @@ -384,23 +384,23 @@ def get_connectivity_status(self): else: rm = "Interface Down" - stat += "[b]Radio Modem[/b]\n{rm}\n\n".format(rm=rm) + stat += f"[b]Radio Modem[/b]\n{rm}\n\n" if self.sideband.interface_serial != None: if self.sideband.interface_serial.online: - rs = "Running at "+RNS.prettysize(self.sideband.interface_serial.bitrate/8, suffix="b")+"ps" + rs = f"Running at {RNS.prettysize(self.sideband.interface_serial.bitrate / 8, suffix='b')}ps" else: rs = "Interface Down" - stat += "[b]Serial Port[/b]\n{rs}\n\n".format(rs=rs) + stat += f"[b]Serial Port[/b]\n{rs}\n\n" if self.sideband.interface_tcp != None: if self.sideband.interface_tcp.online: - ts = "Connected to "+str(self.sideband.interface_tcp.target_ip)+":"+str(self.sideband.interface_tcp.target_port) + ts = f"Connected to {self.sideband.interface_tcp.target_ip)}:{self.sideband.interface_tcp.target_port)}" else: ts = "Interface Down" - stat += "[b]TCP[/b]\n{ts}\n\n".format(ts=ts) + stat += f"[b]TCP[/b]\n{ts}\n\n" if self.sideband.interface_i2p != None: i2s = "Unknown" @@ -417,7 +417,7 @@ def get_connectivity_status(self): else: i2s = "Connecting to I2P" - stat += "[b]I2P[/b]\n{i2s}\n\n".format(i2s=i2s) + stat += f"[b]I2P[/b]\n{i2s}\n\n" total_rxb = 0 total_txb = 0 @@ -449,7 +449,7 @@ def get_connectivity_status(self): if RNS.Reticulum.transport_enabled(): stat += "[b]Transport Instance[/b]\nRouting Traffic\n\n" - stat += "[b]Traffic[/b]\nIn: {inb}\nOut: {outb}\n\n".format(inb=RNS.prettysize(total_rxb), outb=RNS.prettysize(total_txb)) + stat += f"[b]Traffic[/b]\nIn: {RNS.prettysize(total_rxb)}\nOut: {RNS.prettysize(total_txb)}\n\n" if stat.endswith("\n\n"): stat = stat[:-2] @@ -492,7 +492,7 @@ def handle_exception(exc_type, exc_value, exc_traceback): import traceback exc_text = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback)) - RNS.log(f"An unhandled {str(exc_type)} exception occurred: {str(exc_value)}", RNS.LOG_ERROR) + RNS.log(f"An unhandled {exc_type)} exception occurred: {exc_value)}", RNS.LOG_ERROR) RNS.log(exc_text, RNS.LOG_ERROR) sys.excepthook = handle_exception diff --git a/sbapp/sideband/__init__.py b/sbapp/sideband/__init__.py index f49e360..1d03710 100644 --- a/sbapp/sideband/__init__.py +++ b/sbapp/sideband/__init__.py @@ -1,5 +1,5 @@ import os import glob -modules = glob.glob(os.path.dirname(__file__)+"/*.py") +modules = glob.glob(f"{os.path.dirname(__file__)}/*.py") __all__ = [ os.path.basename(f)[:-3] for f in modules if not f.endswith('__init__.py')] \ No newline at end of file diff --git a/sbapp/sideband/audioproc.py b/sbapp/sideband/audioproc.py index fcca182..542773a 100644 --- a/sbapp/sideband/audioproc.py +++ b/sbapp/sideband/audioproc.py @@ -108,7 +108,7 @@ def voice_processing(input_path): filters = "highpass=f=250, lowpass=f=3000,speechnorm=e=12.5:r=0.0001:l=1" output_bitrate = "12k" opus_apptype = "audio" - output_path = input_path.replace(".ogg","")+".p.ogg" + output_path = f"{input_path.replace('.ogg', '')}.p.ogg" args = [ "-i", input_path, "-filter:a", filters, "-c:a", "libopus", "-application", opus_apptype, @@ -148,7 +148,7 @@ def encode_codec2(samples, mode): c2 = pycodec2.Codec2(codec2_modes[mode]) SPF = c2.samples_per_frame() PACKET_SIZE = SPF * 2 # 16-bit samples - STRUCT_FORMAT = '{}h'.format(SPF) + STRUCT_FORMAT = f'{SPF}h' F_FRAMES = len(samples)/SPF N_FRAMES = math.floor(len(samples)/SPF) # TODO: Add padding to align to whole frames @@ -163,7 +163,7 @@ def encode_codec2(samples, mode): encoded += encoded_packet ap_duration = time.time() - ap_start - RNS.log("Codec2 encoding complete in "+RNS.prettytime(ap_duration)+", bytes out: "+str(len(encoded)), RNS.LOG_DEBUG) + RNS.log(f"Codec2 encoding complete in {RNS.prettytime(ap_duration)}, bytes out: {len(encoded))}", RNS.LOG_DEBUG) return encoded @@ -176,7 +176,7 @@ def decode_codec2(encoded_bytes, mode): c2 = pycodec2.Codec2(codec2_modes[mode]) SPF = c2.samples_per_frame() BPF = c2.bytes_per_frame() - STRUCT_FORMAT = '{}h'.format(SPF) + STRUCT_FORMAT = f'{SPF}h' N_FRAMES = math.floor(len(encoded_bytes)/BPF) decoded = b"" @@ -188,6 +188,6 @@ def decode_codec2(encoded_bytes, mode): decoded += struct.pack(STRUCT_FORMAT, *decoded_frame) ap_duration = time.time() - ap_start - RNS.log("Codec2 decoding complete in "+RNS.prettytime(ap_duration)+", samples out: "+str(len(decoded)), RNS.LOG_DEBUG) + RNS.log(f"Codec2 decoding complete in {RNS.prettytime(ap_duration)}, samples out: {len(decoded))}", RNS.LOG_DEBUG) return decoded \ No newline at end of file diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py index 00eaa4e..237b649 100644 --- a/sbapp/sideband/core.py +++ b/sbapp/sideband/core.py @@ -61,7 +61,7 @@ def received_announce(self, destination_hash, announced_identity, app_data): # age = 0 pass - RNS.log("Detected active propagation node "+RNS.prettyhexrep(destination_hash)+" emission "+str(age)+" seconds ago, "+str(hops)+" hops away") + RNS.log(f"Detected active propagation node {RNS.prettyhexrep(destination_hash)} emission {age)} seconds ago, {hops)} hops away") self.owner.log_announce(destination_hash, RNS.prettyhexrep(destination_hash).encode("utf-8"), dest_type=PropagationNodeDetector.aspect_filter) if self.owner.config["lxmf_propagation_node"] == None: @@ -77,7 +77,7 @@ def received_announce(self, destination_hash, announced_identity, app_data): pass except Exception as e: - RNS.log("Error while processing received propagation node announce: "+str(e)) + RNS.log(f"Error while processing received propagation node announce: {e)}") def __init__(self, owner): self.owner = owner @@ -161,20 +161,20 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa self.version_str = "" if config_path == None: - self.app_dir = plyer.storagepath.get_home_dir()+"/.config/sideband" + self.app_dir = f"{plyer.storagepath.get_home_dir()}/.config/sideband" if self.app_dir.startswith("file://"): self.app_dir = self.app_dir.replace("file://", "") else: self.app_dir = config_path - self.cache_dir = self.app_dir+"/cache" + self.cache_dir = f"{self.app_dir}/cache" self.rns_configdir = None if RNS.vendor.platformutils.is_android(): - self.app_dir = android_app_dir+"/io.unsigned.sideband/files/" - self.cache_dir = self.app_dir+"/cache" - self.rns_configdir = self.app_dir+"/app_storage/reticulum" - self.asset_dir = self.app_dir+"/app/assets" + self.app_dir = f"{android_app_dir}/io.unsigned.sideband/files/" + self.cache_dir = f"{self.app_dir}/cache" + self.rns_configdir = f"{self.app_dir}/app_storage/reticulum" + self.asset_dir = f"{self.app_dir}/app/assets" elif RNS.vendor.platformutils.is_darwin(): core_path = os.path.abspath(__file__) self.asset_dir = core_path.replace("/sideband/core.py", "/assets") @@ -185,35 +185,35 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa core_path = os.path.abspath(__file__) self.asset_dir = core_path.replace("\\sideband\\core.py", "\\assets") else: - self.asset_dir = plyer.storagepath.get_application_dir()+"/sbapp/assets" + self.asset_dir = f"{plyer.storagepath.get_application_dir()}/sbapp/assets" - self.map_cache = self.cache_dir+"/maps" + self.map_cache = f"{self.cache_dir}/maps" if not os.path.isdir(self.map_cache): os.makedirs(self.map_cache) - self.rec_cache = self.cache_dir+"/rec" + self.rec_cache = f"{self.cache_dir}/rec" if not os.path.isdir(self.rec_cache): os.makedirs(self.rec_cache) - self.icon = self.asset_dir+"/icon.png" - self.icon_48 = self.asset_dir+"/icon_48.png" - self.icon_32 = self.asset_dir+"/icon_32.png" - self.icon_macos = self.asset_dir+"/icon_macos.png" - self.notification_icon = self.asset_dir+"/notification_icon.png" - self.notif_icon_black = self.asset_dir+"/notification_icon_black.png" + self.icon = f"{self.asset_dir}/icon.png" + self.icon_48 = f"{self.asset_dir}/icon_48.png" + self.icon_32 = f"{self.asset_dir}/icon_32.png" + self.icon_macos = f"{self.asset_dir}/icon_macos.png" + self.notification_icon = f"{self.asset_dir}/notification_icon.png" + self.notif_icon_black = f"{self.asset_dir}/notification_icon_black.png" os.environ["TELEMETER_GEOID_PATH"] = os.path.join(self.asset_dir, "geoids") - if not os.path.isdir(self.app_dir+"/app_storage"): - os.makedirs(self.app_dir+"/app_storage") + if not os.path.isdir(f"{self.app_dir}/app_storage"): + os.makedirs(f"{self.app_dir}/app_storage") - self.config_path = self.app_dir+"/app_storage/sideband_config" - self.identity_path = self.app_dir+"/app_storage/primary_identity" - self.db_path = self.app_dir+"/app_storage/sideband.db" - self.lxmf_storage = self.app_dir+"/app_storage/" - self.log_dir = self.app_dir+"/app_storage/" - self.tmp_dir = self.app_dir+"/app_storage/tmp" - self.exports_dir = self.app_dir+"/exports" + self.config_path = f"{self.app_dir}/app_storage/sideband_config" + self.identity_path = f"{self.app_dir}/app_storage/primary_identity" + self.db_path = f"{self.app_dir}/app_storage/sideband.db" + self.lxmf_storage = f"{self.app_dir}/app_storage/" + self.log_dir = f"{self.app_dir}/app_storage/" + 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 @@ -248,7 +248,7 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa self.clear_exports_dir() except Exception as e: - RNS.log("Error while configuring Sideband: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while configuring Sideband: {e)}", RNS.LOG_ERROR) if load_config_only: return @@ -256,7 +256,7 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa # Initialise Reticulum configuration if RNS.vendor.platformutils.get_platform() == "android": try: - self.rns_configdir = self.app_dir+"/app_storage/reticulum" + self.rns_configdir = f"{self.app_dir}/app_storage/reticulum" if not os.path.isdir(self.rns_configdir): os.makedirs(self.rns_configdir) @@ -269,12 +269,12 @@ def __init__(self, owner_app, config_path = None, is_service=False, is_client=Fa generated_config = rns_config.replace("TRANSPORT_IS_ENABLED", "No") - config_file = open(self.rns_configdir+"/config", "wb") + config_file = open(f"{self.rns_configdir}/config", "wb") config_file.write(generated_config.encode("utf-8")) config_file.close() except Exception as e: - RNS.log("Error while configuring Reticulum instance: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while configuring Reticulum instance: {e)}", RNS.LOG_ERROR) else: pass @@ -304,10 +304,10 @@ def load_job(): app_entry_dir = os.path.expanduser("~/.local/share/applications") icon_dir = os.path.expanduser("~/.local/share/icons/hicolor/512x512/apps") de_filename = "io.unsigned.sideband.desktop" - de_source = self.asset_dir+"/"+de_filename - de_target = app_entry_dir+"/"+de_filename - icn_source = self.asset_dir+"/icon.png" - icn_target = icon_dir+"/io.unsigned.sideband.png" + de_source = f"{self.asset_dir}/{de_filename}" + de_target = f"{app_entry_dir}/{de_filename}" + icn_source = f"{self.asset_dir}/icon.png" + icn_target = f"{icon_dir}/io.unsigned.sideband.png" if os.path.isdir(local_share_dir): if not os.path.exists(app_entry_dir): os.makedirs(app_entry_dir) @@ -333,31 +333,31 @@ def load_job(): if update_de: RNS.log("Setting up desktop integration...", lde_level) import shutil - RNS.log("Installing menu entry to \""+str(de_target)+"\"...", lde_level) + RNS.log(f"Installing menu entry to \"{de_target)}\"...", lde_level) shutil.copy(de_source, de_target) if not os.path.exists(icon_dir): os.makedirs(icon_dir) - RNS.log("Installing icon to \""+str(icn_target)+"\"...", lde_level) + RNS.log(f"Installing icon to \"{icn_target)}\"...", lde_level) shutil.copy(icn_source, icn_target) else: RNS.log("Desktop integration is already set up", lde_level) except Exception as e: - RNS.log("An error occurred while setting up desktop integration: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while setting up desktop integration: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) def clear_tmp_dir(self): if os.path.isdir(self.tmp_dir): for file in os.listdir(self.tmp_dir): - fpath = self.tmp_dir+"/"+file + fpath = f"{self.tmp_dir}/{file}" os.unlink(fpath) def clear_exports_dir(self): if os.path.isdir(self.exports_dir): for file in os.listdir(self.exports_dir): - fpath = self.exports_dir+"/"+file - RNS.log("Clearing "+str(fpath)) + fpath = f"{self.exports_dir}/{file}" + RNS.log(f"Clearing {fpath)}") os.unlink(fpath) def __init_config(self): @@ -493,7 +493,7 @@ def __load_config(self): self.rpc_addr = ("127.0.0.1", 48165) self.rpc_key = RNS.Identity.full_hash(self.identity.get_private_key()) - RNS.log("Loading Sideband configuration... "+str(self.config_path), RNS.LOG_DEBUG) + RNS.log(f"Loading Sideband configuration... {self.config_path)}", RNS.LOG_DEBUG) config_file = open(self.config_path, "rb") self.config = msgpack.unpackb(config_file.read()) config_file.close() @@ -763,7 +763,7 @@ def __reload_config(self): self.update_active_lxmf_propagation_node() self.update_ignore_invalid_stamps() except Exception as e: - RNS.log("Error while reloading configuration: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while reloading configuration: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) def __save_config(self): @@ -779,7 +779,7 @@ def save_function(): self.saving_configuration = False except Exception as e: self.saving_configuration = False - RNS.log("Error while saving Sideband configuration: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while saving Sideband configuration: {e)}", RNS.LOG_ERROR) threading.Thread(target=save_function, daemon=True).start() @@ -802,7 +802,7 @@ def __load_plugins(self): plugin_globals["SidebandServicePlugin"] = SidebandServicePlugin plugin_globals["SidebandCommandPlugin"] = SidebandCommandPlugin plugin_globals["SidebandTelemetryPlugin"] = SidebandTelemetryPlugin - RNS.log("Loading plugin \""+str(file)+"\"", RNS.LOG_NOTICE) + RNS.log(f"Loading plugin \"{file)}\"", RNS.LOG_NOTICE) plugin_path = os.path.join(plugins_path, file) exec(open(plugin_path).read(), plugin_globals) plugin_class = plugin_globals["plugin_class"] @@ -816,17 +816,17 @@ def __load_plugins(self): command_name = plugin.command_name if not command_name in self.active_command_plugins: self.active_command_plugins[command_name] = plugin - RNS.log("Registered "+str(plugin)+" as handler for command \""+str(command_name)+"\"", RNS.LOG_NOTICE) + RNS.log(f"Registered {plugin)} as handler for command \"{command_name)}\"", RNS.LOG_NOTICE) else: - RNS.log("Could not register "+str(plugin)+" as handler for command \""+str(command_name)+"\". Command name was already registered", RNS.LOG_ERROR) + 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: self.active_service_plugins[service_name] = plugin - RNS.log("Registered "+str(plugin)+" for service \""+str(service_name)+"\"", RNS.LOG_NOTICE) + RNS.log(f"Registered {plugin)} for service \"{service_name)}\"", RNS.LOG_NOTICE) else: - RNS.log("Could not register "+str(plugin)+" for service \""+str(service_name)+"\". Service name was already registered", RNS.LOG_ERROR) + RNS.log(f"Could not register {plugin)} for service \"{service_name)}\". Service name was already registered", RNS.LOG_ERROR) try: plugin.stop() except Exception as e: @@ -837,9 +837,9 @@ def __load_plugins(self): plugin_name = plugin.plugin_name if not plugin_name in self.active_telemetry_plugins: self.active_telemetry_plugins[plugin_name] = plugin - RNS.log("Registered "+str(plugin)+" as telemetry plugin \""+str(plugin_name)+"\"", RNS.LOG_NOTICE) + RNS.log(f"Registered {plugin)} as telemetry plugin \"{plugin_name)}\"", RNS.LOG_NOTICE) else: - RNS.log("Could not register "+str(plugin)+" as telemetry plugin \""+str(plugin_name)+"\". Telemetry type was already registered", RNS.LOG_ERROR) + RNS.log(f"Could not register {plugin)} as telemetry plugin \"{plugin_name)}\". Telemetry type was already registered", RNS.LOG_ERROR) try: plugin.stop() except Exception as e: @@ -855,7 +855,7 @@ def __load_plugins(self): del plugin else: - RNS.log("Plugin "+str(plugin)+" failed to start, ignoring it.", RNS.LOG_ERROR) + RNS.log(f"Plugin {plugin)} failed to start, ignoring it.", RNS.LOG_ERROR) del plugin @@ -875,10 +875,10 @@ def set_active_propagation_node(self, dest): self.config["last_lxmf_propagation_node"] = dest self.message_router.set_outbound_propagation_node(dest) - RNS.log("Active propagation node set to: "+RNS.prettyhexrep(dest)) + RNS.log(f"Active propagation node set to: {RNS.prettyhexrep(dest)}") self.__save_config() except Exception as e: - RNS.log("Error while setting LXMF propagation node: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while setting LXMF propagation node: {e)}", RNS.LOG_ERROR) def notify(self, title, content, group=None, context_id=None): if not self.is_daemon: @@ -911,12 +911,12 @@ def log_announce(self, dest, app_data, dest_type, stamp_cost=None): if app_data == None: app_data = b"" app_data = msgpack.packb([app_data, stamp_cost]) - RNS.log("Received "+str(dest_type)+" announce for "+RNS.prettyhexrep(dest)+" with data: "+str(app_data), RNS.LOG_DEBUG) + RNS.log(f"Received {dest_type)} announce for {RNS.prettyhexrep(dest)} with data: {app_data)}", RNS.LOG_DEBUG) self._db_save_announce(dest, app_data, dest_type) self.setstate("app.flags.new_announces", True) except Exception as e: - RNS.log("Exception while decoding LXMF destination announce data:"+str(e)) + RNS.log(f"Exception while decoding LXMF destination announce data:{e)}") def list_conversations(self, conversations=True, objects=False): result = self._db_conversations(conversations, objects) @@ -955,7 +955,7 @@ def is_trusted(self, context_dest, conv_data = None): return False except Exception as e: - RNS.log("Error while checking trust for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking trust for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False def is_object(self, context_dest, conv_data = None): @@ -974,7 +974,7 @@ def is_object(self, context_dest, conv_data = None): return False except Exception as e: - RNS.log("Error while checking trust for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking trust for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False def ptt_enabled(self, context_dest, conv_data = None): @@ -993,7 +993,7 @@ def ptt_enabled(self, context_dest, conv_data = None): return False except Exception as e: - RNS.log("Error while checking PTT-enabled for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking PTT-enabled for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False def should_send_telemetry(self, context_dest, conv_data=None): @@ -1020,7 +1020,7 @@ def should_send_telemetry(self, context_dest, conv_data=None): return False except Exception as e: - RNS.log("Error while checking telemetry sending for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking telemetry sending for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False def allow_request_from(self, context_dest): @@ -1035,7 +1035,7 @@ def allow_request_from(self, context_dest): return self.requests_allowed_from(context_dest) except Exception as e: - RNS.log("Error while checking request permissions for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking request permissions for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False def requests_allowed_from(self, context_dest, conv_data=None): @@ -1055,7 +1055,7 @@ def requests_allowed_from(self, context_dest, conv_data=None): return False except Exception as e: - RNS.log("Error while checking request permissions for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking request permissions for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return False def raw_display_name(self, context_dest): @@ -1070,7 +1070,7 @@ def raw_display_name(self, context_dest): return "" except Exception as e: - RNS.log("Error while getting peer name: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while getting peer name: {e)}", RNS.LOG_ERROR) return "" def peer_appearance(self, context_dest, conv=None): @@ -1092,7 +1092,7 @@ def peer_display_name(self, context_dest): if existing_conv["trust"] == 1: return existing_conv["name"] else: - return existing_conv["name"]+" "+RNS.prettyhexrep(context_dest) + return f"{existing_conv['name']} {RNS.prettyhexrep(context_dest)}" else: app_data = RNS.Identity.recall_app_data(context_dest) @@ -1100,7 +1100,7 @@ def peer_display_name(self, context_dest): if existing_conv["trust"] == 1: return LXMF.display_name_from_app_data(app_data) else: - return LXMF.display_name_from_app_data(app_data)+" "+RNS.prettyhexrep(context_dest) + return f"{LXMF.display_name_from_app_data(app_data)} {RNS.prettyhexrep(context_dest)}" else: return RNS.prettyhexrep(context_dest) else: @@ -1108,13 +1108,13 @@ def peer_display_name(self, context_dest): if app_data != None: name_str = LXMF.display_name_from_app_data(app_data) addr_str = RNS.prettyhexrep(context_dest) - return name_str+" "+addr_str + return f"{name_str} {addr_str}" else: - return "Anonymous Peer "+RNS.prettyhexrep(context_dest) + return f"Anonymous Peer {RNS.prettyhexrep(context_dest)}" except Exception as e: - RNS.log("Could not decode a valid peer name from data: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Could not decode a valid peer name from data: {e)}", RNS.LOG_DEBUG) return RNS.prettyhexrep(context_dest) def clear_conversation(self, context_dest): @@ -1179,7 +1179,7 @@ def count_messages(self, context_dest): def outbound_telemetry_finished(self, message): if message.state == LXMF.LXMessage.FAILED and hasattr(message, "try_propagation_on_fail") and message.try_propagation_on_fail: - RNS.log("Direct delivery of telemetry update "+str(message)+" failed. Retrying as propagated message.", RNS.LOG_VERBOSE) + RNS.log(f"Direct delivery of telemetry update {message)} failed. Retrying as propagated message.", RNS.LOG_VERBOSE) message.try_propagation_on_fail = None message.delivery_attempts = 0 del message.next_delivery_attempt @@ -1200,7 +1200,7 @@ def outbound_telemetry_finished(self, message): def telemetry_request_finished(self, message): if message.state == LXMF.LXMessage.FAILED and hasattr(message, "try_propagation_on_fail") and message.try_propagation_on_fail: - RNS.log("Direct delivery of telemetry request "+str(message)+" failed. Retrying as propagated message.", RNS.LOG_VERBOSE) + RNS.log(f"Direct delivery of telemetry request {message)} failed. Retrying as propagated message.", RNS.LOG_VERBOSE) message.try_propagation_on_fail = None message.delivery_attempts = 0 del message.next_delivery_attempt @@ -1228,7 +1228,7 @@ def _service_request_latest_telemetry(self, from_addr=None): return self.service_rpc_request({"request_latest_telemetry": {"from_addr": from_addr}}) except Exception as e: - RNS.log("Error while requesting latest telemetry over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while requesting latest telemetry over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) return False else: @@ -1240,7 +1240,7 @@ def request_latest_telemetry(self, from_addr=None): return self._service_request_latest_telemetry(from_addr) except Exception as e: - RNS.log("Error requesting latest telemetry: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error requesting latest telemetry: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) return "not_sent" @@ -1256,7 +1256,7 @@ def request_latest_telemetry(self, from_addr=None): dest_identity = RNS.Identity.recall(from_addr) if dest_identity == None: - RNS.log("The identity for "+RNS.prettyhexrep(from_addr)+" could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG) + 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) return "destination_unknown" @@ -1306,7 +1306,7 @@ def _service_send_latest_telemetry(self, to_addr=None, stream=None, is_authorize }) except Exception as e: - RNS.log("Error while sending latest telemetry over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while sending latest telemetry over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) return False else: @@ -1318,7 +1318,7 @@ def send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemet return self._service_send_latest_telemetry(to_addr, stream, is_authorized_telemetry_request) except Exception as e: - RNS.log("Error requesting latest telemetry: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error requesting latest telemetry: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) return "not_sent" @@ -1337,7 +1337,7 @@ def send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemet dest_identity = RNS.Identity.recall(to_addr) if dest_identity == None: - RNS.log("The identity for "+RNS.prettyhexrep(to_addr)+" could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG) + 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) return "destination_unknown" @@ -1409,7 +1409,7 @@ def peer_telemetry(self, context_dest, after = None, before = None, limit = None return [] except Exception as e: - RNS.log("An error occurred while retrieving telemetry from the database: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while retrieving telemetry from the database: {e)}", RNS.LOG_ERROR) return [] try: @@ -1418,7 +1418,7 @@ def peer_telemetry(self, context_dest, after = None, before = None, limit = None if context_dest in pts: return pts[context_dest] except Exception as e: - RNS.log("An error occurred while retrieving telemetry from the database: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while retrieving telemetry from the database: {e)}", RNS.LOG_ERROR) return [] @@ -1441,7 +1441,7 @@ def peer_location(self, context_dest): return None except Exception as e: - RNS.log("Error while getting own location: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while getting own location: {e)}", RNS.LOG_ERROR) after_time = time.time()-3*30*24*60*60 pts = self.peer_telemetry(context_dest, after=after_time) @@ -1470,25 +1470,25 @@ def service_available(self): now = time.time() service_heartbeat = self.getstate("service.heartbeat") if not service_heartbeat: - RNS.log("No service heartbeat available at "+str(now), RNS.LOG_DEBUG) + RNS.log(f"No service heartbeat available at {now)}", RNS.LOG_DEBUG) return False else: try: if now - service_heartbeat > heartbeat_stale_time: - RNS.log("Stale service heartbeat at "+str(now)+", retrying...", RNS.LOG_DEBUG) + RNS.log(f"Stale service heartbeat at {now)}, retrying...", RNS.LOG_DEBUG) now = time.time() service_heartbeat = self.getstate("service.heartbeat") if now - service_heartbeat > heartbeat_stale_time: RNS.log("Service heartbeat did not recover after retry", RNS.LOG_DEBUG) return False else: - RNS.log("Service heartbeat recovered at"+str(now), RNS.LOG_DEBUG) + RNS.log(f"Service heartbeat recovered at{now)}", RNS.LOG_DEBUG) return True else: return True except Exception as e: - RNS.log("Error while getting service heartbeat: "+str(e), RNS.LOG_ERROR) - RNS.log("Response was: "+str(service_heartbeat), RNS.LOG_ERROR) + RNS.log(f"Error while getting service heartbeat: {e)}", RNS.LOG_ERROR) + RNS.log(f"Response was: {service_heartbeat)}", RNS.LOG_ERROR) return False def gui_foreground(self): @@ -1517,11 +1517,11 @@ def set(): try: set() except Exception as e: - RNS.log("Error while setting state over RPC: "+str(e)+". Retrying once.", RNS.LOG_DEBUG) + RNS.log(f"Error while setting state over RPC: {e)}. Retrying once.", RNS.LOG_DEBUG) try: set() except Exception as e: - RNS.log("Error on retry as well: "+str(e)+". Giving up.", RNS.LOG_DEBUG) + RNS.log(f"Error on retry as well: {e)}. Giving up.", RNS.LOG_DEBUG) return False def service_set_latest_telemetry(self, latest_telemetry, latest_packed_telemetry): @@ -1536,7 +1536,7 @@ def service_set_latest_telemetry(self, latest_telemetry, latest_packed_telemetry try: return self.service_rpc_request({"latest_telemetry": (latest_telemetry, latest_packed_telemetry)}) except Exception as e: - RNS.log("Error while setting telemetry over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while setting telemetry over RPC: {e)}", RNS.LOG_DEBUG) return False def service_rpc_set_debug(self, debug): @@ -1553,7 +1553,7 @@ def service_rpc_set_debug(self, debug): try: return self.service_rpc_request({"set_debug": debug}) except Exception as e: - RNS.log("Error while setting log level over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while setting log level over RPC: {e)}", RNS.LOG_DEBUG) return False def service_rpc_set_ui_recording(self, recording): @@ -1567,7 +1567,7 @@ def service_rpc_set_ui_recording(self, recording): try: return self.service_rpc_request({"set_ui_recording": recording}) except Exception as e: - RNS.log("Error while setting UI recording status over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while setting UI recording status over RPC: {e)}", RNS.LOG_DEBUG) return False def service_rpc_request(self, request): @@ -1605,7 +1605,7 @@ def getstate(self, prop, allow_cache=False): return self.service_rpc_request({"getstate": prop}) except Exception as e: - RNS.log("Error while retrieving state "+str(prop)+" over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while retrieving state {prop)} over RPC: {e)}", RNS.LOG_DEBUG) self.rpc_connection = None return None @@ -1624,9 +1624,9 @@ def _get_plugins_info(self): if np == 0: plugins_info_text = "[i]No plugins are currently loaded[/i]" elif np == 1: - plugins_info_text = "Currently, 1 plugin is loaded and active:\n" + plugins_info_text + plugins_info_text = f"Currently, 1 plugin is loaded and active:\n{plugins_info_text}" else: - plugins_info_text = f"Currently, {np} plugins are loaded and active:\n" + plugins_info_text + plugins_info_text = f"Currently, {np} plugins are loaded and active:\n{plugins_info_text}" return plugins_info_text def get_plugins_info(self): @@ -1639,7 +1639,7 @@ def get_plugins_info(self): try: return self.service_rpc_request({"get_plugins_info": True}) except Exception as e: - ed = "Error while getting plugins info over RPC: "+str(e) + ed = f"Error while getting plugins info over RPC: {e)}" RNS.log(ed, RNS.LOG_DEBUG) return ed @@ -1674,7 +1674,7 @@ def get_destination_establishment_rate(self, destination_hash): try: return self.service_rpc_request({"get_destination_establishment_rate": destination_hash}) except Exception as e: - ed = "Error while getting destination link etablishment rate over RPC: "+str(e) + ed = f"Error while getting destination link etablishment rate over RPC: {e)}" RNS.log(ed, RNS.LOG_DEBUG) return None @@ -1686,7 +1686,7 @@ def __start_rpc_listener(self): thread.daemon = True thread.start() except Exception as e: - RNS.log("Could not start RPC listener on "+str(self.rpc_addr)+". Terminating now. Clear up anything using the port and try again.", RNS.LOG_ERROR) + RNS.log(f"Could not start RPC listener on {self.rpc_addr)}. Terminating now. Clear up anything using the port and try again.", RNS.LOG_ERROR) RNS.panic() def __rpc_loop(self): @@ -1760,7 +1760,7 @@ def rpc_client_job(): connection.send(None) except Exception as e: - RNS.log("Error on client RPC connection: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error on client RPC connection: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) try: connection.close() @@ -1772,7 +1772,7 @@ def rpc_client_job(): threading.Thread(target=job_factory(rpc_connection), daemon=True).start() except Exception as e: - RNS.log("An error ocurred while handling RPC call from local client: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error ocurred while handling RPC call from local client: {e)}", RNS.LOG_ERROR) def setpersistent(self, prop, val): @@ -1894,11 +1894,11 @@ def _db_getpersistent(self, prop): return val except Exception as e: - RNS.log("Could not unpack persistent value from database for property \""+str(prop)+"\". The contained exception was: "+str(e), RNS.LOG_ERROR) + 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("An error occurred during persistent getstate database operation: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred during persistent getstate database operation: {e)}", RNS.LOG_ERROR) self.db = None def _db_setpersistent(self, prop, val): @@ -1919,7 +1919,7 @@ def _db_setpersistent(self, prop, val): db.commit() except Exception as e: - RNS.log("Error while setting persistent state property "+str(prop)+" in DB: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while setting persistent state property {prop)} in DB: {e)}", RNS.LOG_ERROR) RNS.log("Retrying as update query...") query = "UPDATE state set value=:bval where property=:uprop;" dbc.execute(query, {"bval": bval, "uprop": uprop}) @@ -1931,7 +1931,7 @@ def _db_setpersistent(self, prop, val): db.commit() except Exception as e: - RNS.log("An error occurred during persistent setstate database operation: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred during persistent setstate database operation: {e)}", RNS.LOG_ERROR) self.db = None def _db_conversation_update_txtime(self, context_dest, is_retry = False): @@ -1947,7 +1947,7 @@ def _db_conversation_update_txtime(self, context_dest, is_retry = False): result = dbc.fetchall() db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation TX time: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation TX time: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -1974,7 +1974,7 @@ def _db_conversation_set_unread(self, context_dest, unread, tx = False, is_retry result = dbc.fetchall() db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation unread flag: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation unread flag: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -1987,17 +1987,17 @@ def _db_telemetry(self, context_dest = None, after = None, before = None, limit limit_part = "" if limit: - limit_part = " LIMIT "+str(int(limit)) - order_part = " order by ts DESC"+limit_part + limit_part = f" LIMIT {int(limit))}" + order_part = f" order by ts DESC{limit_part}" if context_dest == None: if after != None and before == None: - query = "select * from telemetry where ts>:after_ts"+order_part + query = f"select * from telemetry where ts>:after_ts{order_part}" dbc.execute(query, {"after_ts": after}) elif after == None and before != None: - query = "select * from telemetry where ts<:before_ts"+order_part + query = f"select * from telemetry where ts<:before_ts{order_part}" dbc.execute(query, {"before_ts": before}) elif after != None and before != None: - query = "select * from telemetry where ts<:before_ts and ts>:after_ts"+order_part + query = f"select * from telemetry where ts<:before_ts and ts>:after_ts{order_part}" dbc.execute(query, {"before_ts": before, "after_ts": after}) else: query = query = "select * from telemetry" @@ -2005,16 +2005,16 @@ def _db_telemetry(self, context_dest = None, after = None, before = None, limit else: if after != None and before == None: - query = "select * from telemetry where dest_context=:context_dest and ts>:after_ts"+order_part + 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}) elif after == None and before != None: - query = "select * from telemetry where dest_context=:context_dest and ts<:before_ts"+order_part + query = f"select * from telemetry where dest_context=:context_dest and ts<:before_ts{order_part}" dbc.execute(query, {"context_dest": context_dest, "before_ts": before}) elif after != None and before != None: - query = "select * from telemetry where dest_context=:context_dest and ts<:before_ts and ts>:after_ts"+order_part + query = f"select * from telemetry where dest_context=:context_dest and ts<:before_ts and ts>:after_ts{order_part}" dbc.execute(query, {"context_dest": context_dest, "before_ts": before, "after_ts": after}) else: - query = query = "select * from telemetry where dest_context=:context_dest"+order_part + query = query = f"select * from telemetry where dest_context=:context_dest{order_part}" dbc.execute(query, {"context_dest": context_dest}) result = dbc.fetchall() @@ -2050,7 +2050,7 @@ def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, sour result = dbc.fetchall() if len(result) != 0: - RNS.log("Telemetry entry with source "+RNS.prettyhexrep(context_dest)+" and timestamp "+str(telemetry_timestamp)+" already exists, skipping save", RNS.LOG_DEBUG) + RNS.log(f"Telemetry entry with source {RNS.prettyhexrep(context_dest)} and timestamp {telemetry_timestamp)} already exists, skipping save", RNS.LOG_DEBUG) return None if physical_link != None and len(physical_link) != 0: @@ -2104,7 +2104,7 @@ def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, sour try: db.commit() except Exception as e: - RNS.log("An error occurred while commiting telemetry to database: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while commiting telemetry to database: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2118,7 +2118,7 @@ def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, sour except Exception as e: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"A {str(type(e))} occurred while saving telemetry to database: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"A {type(e))} occurred while saving telemetry to database: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) self.db = None @@ -2129,7 +2129,7 @@ def _db_update_appearance(self, context_dest, timestamp, appearance, from_bulk_t ae = [appearance, int(time.time())] # TODO: Clean out these temporary values at some interval. # Probably expire after 14 days or so. - self.setpersistent("temp.peer_appearance."+RNS.hexrep(context_dest, delimit=False), ae) + self.setpersistent(f"temp.peer_appearance.{RNS.hexrep(context_dest, delimit=False)}", ae) else: with self.db_lock: @@ -2141,7 +2141,7 @@ def _db_update_appearance(self, context_dest, timestamp, appearance, from_bulk_t data_dict["appearance"] = None if from_bulk_telemetry and data_dict["appearance"] != SidebandCore.DEFAULT_APPEARANCE: - RNS.log("Aborting appearance update from bulk transfer, since conversation already has appearance set: "+str(appearance)+" / "+str(data_dict["appearance"]), RNS.LOG_DEBUG) + RNS.log(f"Aborting appearance update from bulk transfer, since conversation already has appearance set: {appearance)} / {data_dict['appearance'])}", RNS.LOG_DEBUG) return if data_dict["appearance"] != appearance: @@ -2174,12 +2174,12 @@ def _db_get_appearance(self, context_dest, conv = None, raw=False): if data_dict != None: if not "appearance" in data_dict or data_dict["appearance"] == None: - apd = self.getpersistent("temp.peer_appearance."+RNS.hexrep(context_dest, delimit=False)) + apd = self.getpersistent(f"temp.peer_appearance.{RNS.hexrep(context_dest, delimit=False)}") if apd != None: try: data_dict["appearance"] = apd[0] except Exception as e: - RNS.log("Could not get appearance data from database: "+str(e),RNS.LOG_ERROR) + RNS.log(f"Could not get appearance data from database: {e)}",RNS.LOG_ERROR) data_dict = None try: @@ -2198,7 +2198,7 @@ def htf(cbytes): return appearance except Exception as e: - RNS.log("Could not retrieve appearance for "+RNS.prettyhexrep(context_dest)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Could not retrieve appearance for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) return None @@ -2224,7 +2224,7 @@ def _db_conversation_set_telemetry(self, context_dest, send_telemetry=False, is_ try: db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation telemetry options: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation telemetry options: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2251,7 +2251,7 @@ def _db_conversation_set_requests(self, context_dest, allow_requests=False, is_r try: db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation request options: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation request options: {e)}", RNS.LOG_ERROR) self.__db_reconnect() if not is_retry: RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2278,7 +2278,7 @@ def _db_conversation_set_object(self, context_dest, is_object=False): try: db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation object option: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation object option: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2305,7 +2305,7 @@ def _db_conversation_set_ptt_enabled(self, context_dest, ptt_enabled=False): try: db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation PTT option: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation PTT option: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2324,7 +2324,7 @@ def _db_conversation_set_trusted(self, context_dest, trusted): try: db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation trusted option: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation trusted option: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2342,7 +2342,7 @@ def _db_conversation_set_name(self, context_dest, name): try: db.commit() except Exception as e: - RNS.log("An error occurred while updating conversation name option: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating conversation name option: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2420,7 +2420,7 @@ def _db_announces(self): added_dests.append(entry[2]) announces.append(announce) except Exception as e: - RNS.log("Exception while fetching announce from DB: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Exception while fetching announce from DB: {e)}", RNS.LOG_ERROR) announces.reverse() return announces @@ -2451,7 +2451,7 @@ def _db_conversation(self, context_dest): return conv def _db_clear_conversation(self, context_dest): - RNS.log("Clearing conversation with "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Clearing conversation with {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) with self.db_lock: db = self.__db_connect() dbc = db.cursor() @@ -2461,7 +2461,7 @@ def _db_clear_conversation(self, context_dest): db.commit() def _db_clear_telemetry(self, context_dest): - RNS.log("Clearing telemetry for "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Clearing telemetry for {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) with self.db_lock: db = self.__db_connect() dbc = db.cursor() @@ -2473,7 +2473,7 @@ def _db_clear_telemetry(self, context_dest): self.setstate("app.flags.last_telemetry", time.time()) def _db_delete_conversation(self, context_dest): - RNS.log("Deleting conversation with "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Deleting conversation with {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) with self.db_lock: db = self.__db_connect() dbc = db.cursor() @@ -2484,7 +2484,7 @@ def _db_delete_conversation(self, context_dest): def _db_delete_announce(self, context_dest): - RNS.log("Deleting announce with "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Deleting announce with {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) with self.db_lock: db = self.__db_connect() dbc = db.cursor() @@ -2494,12 +2494,12 @@ def _db_delete_announce(self, context_dest): db.commit() def _db_create_conversation(self, context_dest, name = None, trust = False): - RNS.log("Creating conversation for "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Creating conversation for {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) with self.db_lock: db = self.__db_connect() dbc = db.cursor() - def_name = "".encode("utf-8") + def_name = b"" query = "INSERT INTO conv (dest_context, last_tx, last_rx, unread, type, trust, name, data) values (?, ?, ?, ?, ?, ?, ?, ?)" data = (context_dest, 0, time.time(), 0, SidebandCore.CONV_P2P, 0, def_name, msgpack.packb(None)) @@ -2515,7 +2515,7 @@ def _db_create_conversation(self, context_dest, name = None, trust = False): self.__event_conversations_changed() def _db_delete_message(self, msg_hash): - RNS.log("Deleting message "+RNS.prettyhexrep(msg_hash)) + RNS.log(f"Deleting message {RNS.prettyhexrep(msg_hash)}") with self.db_lock: db = self.__db_connect() dbc = db.cursor() @@ -2525,7 +2525,7 @@ def _db_delete_message(self, msg_hash): db.commit() def _db_clean_messages(self): - RNS.log("Purging stale messages... "+str(self.db_path)) + RNS.log(f"Purging stale messages... {self.db_path)}") with self.db_lock: db = self.__db_connect() dbc = db.cursor() @@ -2552,7 +2552,7 @@ def _db_message_set_state(self, lxm_hash, state, is_retry=False, ratchet_id=None msg_extras["stamp_value"] = originator_stamp[2] except Exception as e: - RNS.log("An error occurred while getting message extras: "+str(e)) + RNS.log(f"An error occurred while getting message extras: {e)}") with self.db_lock: db = self.__db_connect() @@ -2573,7 +2573,7 @@ def _db_message_set_state(self, lxm_hash, state, is_retry=False, ratchet_id=None db.commit() result = dbc.fetchall() except Exception as e: - RNS.log("An error occurred while updating message state: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating message state: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2592,7 +2592,7 @@ def _db_message_set_method(self, lxm_hash, method): db.commit() result = dbc.fetchall() except Exception as e: - RNS.log("An error occurred while updating message method: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while updating message method: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2756,15 +2756,15 @@ def _db_save_lxm(self, lxm, context_dest, originator = False, own_command = Fals appearance = telemetry_entry[3] max_timebase = max(max_timebase, ttstamp) if self._db_save_telemetry(tsource, tpacked, via = context_dest): - RNS.log("Saved telemetry stream entry from "+RNS.prettyhexrep(tsource), RNS.LOG_DEBUG) + RNS.log(f"Saved telemetry stream entry from {RNS.prettyhexrep(tsource)}", RNS.LOG_DEBUG) if appearance != None: self._db_update_appearance(tsource, ttstamp, appearance, from_bulk_telemetry=True) - RNS.log("Updated appearance entry from "+RNS.prettyhexrep(tsource), RNS.LOG_DEBUG) + RNS.log(f"Updated appearance entry from {RNS.prettyhexrep(tsource)}", RNS.LOG_DEBUG) self.setpersistent(f"telemetry.{RNS.hexrep(context_dest, delimit=False)}.timebase", max_timebase) else: - RNS.log("Received telemetry stream field with no data: "+str(lxm.fields[LXMF.FIELD_TELEMETRY_STREAM]), RNS.LOG_DEBUG) + RNS.log(f"Received telemetry stream field with no data: {lxm.fields[LXMF.FIELD_TELEMETRY_STREAM])}", RNS.LOG_DEBUG) if own_command or len(lxm.content) != 0 or len(lxm.title) != 0: with self.db_lock: @@ -2820,7 +2820,7 @@ def _db_save_lxm(self, lxm, context_dest, originator = False, own_command = Fals try: db.commit() except Exception as e: - RNS.log("An error occurred while saving message to database: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while saving message to database: {e)}", RNS.LOG_ERROR) self.__db_reconnect() # if not is_retry: # RNS.log("Retrying operation...", RNS.LOG_ERROR) @@ -2834,7 +2834,7 @@ def _db_save_announce(self, destination_hash, app_data, dest_type="lxmf.delivery db = self.__db_connect() dbc = db.cursor() - query = "delete from announce where id is NULL or id not in (select id from announce order by received desc limit "+str(self.MAX_ANNOUNCES)+")" + query = f"delete from announce where id is NULL or id not in (select id from announce order by received desc limit {self.MAX_ANNOUNCES)})" dbc.execute(query) query = "delete from announce where (source=:source);" @@ -2866,7 +2866,7 @@ def lxmf_announce(self, attached_interface=None): self.lxmf_destination.announce(attached_interface=attached_interface) self.last_lxmf_announce = time.time() 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("Next auto announce in "+RNS.prettytime(self.next_auto_announce-time.time()), RNS.LOG_DEBUG) + RNS.log(f"Next auto announce in {RNS.prettytime(self.next_auto_announce - time.time())}", RNS.LOG_DEBUG) self.setstate("wants.announce", False) else: @@ -2898,7 +2898,7 @@ def telemetry_job(): except Exception as e: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"An {str(type(e))} occurred while updating service telemetry: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"An {type(e))} occurred while updating service telemetry: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) time.sleep(SidebandCore.SERVICE_TELEMETRY_INTERVAL) @@ -2960,12 +2960,12 @@ def update_telemetry(self): try: self.service_set_latest_telemetry(self.latest_telemetry, self.latest_packed_telemetry) except Exception as e: - RNS.log("Error while sending latest telemetry to service: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while sending latest telemetry to service: {e)}", RNS.LOG_ERROR) except Exception as e: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"An {str(type(e))} occurred while updating telemetry: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"An {type(e))} occurred while updating telemetry: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) def update_telemeter_config(self): @@ -2978,7 +2978,7 @@ def update_telemeter_config(self): sensors = ["location", "information", "battery", "pressure", "temperature", "humidity", "magnetic_field", "ambient_light", "gravity", "angular_velocity", "acceleration", "proximity"] for sensor in sensors: - if self.config["telemetry_s_"+sensor]: + if self.config[f"telemetry_s_{sensor}"]: self.telemeter.enable(sensor) else: if sensor == "location": @@ -2998,7 +2998,7 @@ def update_telemeter_config(self): plugin.update_telemetry(self.telemeter) except Exception as e: - RNS.log("An error occurred while "+str(telemetry_plugin)+" was handling telemetry. The contained exception was: "+str(e), RNS.LOG_ERROR) + 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"]: @@ -3059,7 +3059,7 @@ def request_key(self, dest_hash): return True except Exception as e: - RNS.log("Error while querying for key: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while querying for key: {e)}", RNS.LOG_ERROR) return False def _update_delivery_limits(self): @@ -3070,10 +3070,10 @@ def _update_delivery_limits(self): lxm_limit = self.default_lxm_limit if self.message_router.delivery_per_transfer_limit != lxm_limit: self.message_router.delivery_per_transfer_limit = lxm_limit - RNS.log("Updated delivery limit to "+RNS.prettysize(self.message_router.delivery_per_transfer_limit*1000), RNS.LOG_DEBUG) + 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("Error while updating LXMF router delivery limit: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while updating LXMF router delivery limit: {e)}", RNS.LOG_ERROR) def _service_jobs(self): if self.is_service: @@ -3137,7 +3137,7 @@ def job(): except Exception as e: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"An {str(type(e))} occurred while running interface checks: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"An {type(e))} occurred while running interface checks: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) announce_wanted = self.getstate("wants.announce") @@ -3152,13 +3152,13 @@ def job(): if hasattr(self.interface_local, "had_peers"): if not self.interface_local.had_peers and have_peers: - RNS.log("Peers became reachable on the interface "+str(self.interface_local), RNS.LOG_DEBUG) + RNS.log(f"Peers became reachable on the interface {self.interface_local)}", RNS.LOG_DEBUG) needs_if_change_announce = True announce_attached_interface = self.interface_local announce_delay = 10 if self.interface_local.had_peers and not have_peers: - RNS.log("No peers reachable on the interface "+str(self.interface_local), RNS.LOG_DEBUG) + RNS.log(f"No peers reachable on the interface {self.interface_local)}", RNS.LOG_DEBUG) needs_if_change_announce = True self.interface_local.had_peers = have_peers @@ -3167,11 +3167,11 @@ def job(): if not hasattr(self, "interface_local") or interface != self.interface_local: if hasattr(interface, "was_online"): if not interface.was_online and interface.online: - RNS.log("The interface "+str(interface)+" became available", RNS.LOG_DEBUG) + RNS.log(f"The interface {interface)} became available", RNS.LOG_DEBUG) needs_if_change_announce = True if interface.was_online and not interface.online: - RNS.log("The interface "+str(interface)+" became unavailable", RNS.LOG_DEBUG) + RNS.log(f"The interface {interface)} became unavailable", RNS.LOG_DEBUG) needs_if_change_announce = True interface.was_online = interface.online @@ -3242,7 +3242,7 @@ def x(): target_port = self.owner_app.usb_devices[0]["port"] RNS.Interfaces.Android.RNodeInterface.RNodeInterface.bluetooth_control(port=target_port, pairing_mode = True) except Exception as e: - self.setstate("hardware_operation.error", "An error occurred while trying to communicate with the device. Please make sure that Sideband has been granted permissions to access the device.\n\nThe reported error was:\n\n[i]"+str(e)+"[/i]") + self.setstate("hardware_operation.error", f"An error occurred while trying to communicate with the device. Please make sure that Sideband has been granted permissions to access the device.\n\nThe reported error was:\n\n[i]{e)}[/i]") else: RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR) self.setstate("executing.bt_pair", False) @@ -3256,7 +3256,7 @@ def x(): if len(self.owner_app.usb_devices) > 0: target_device = self.owner_app.usb_devices[0] if self.interface_rnode.port != target_device["port"]: - RNS.log("Updating RNode device to "+str(target_device)) + RNS.log(f"Updating RNode device to {target_device)}") self.interface_rnode.port = target_device["port"] if self.interface_serial != None and not self.interface_serial.online: @@ -3267,7 +3267,7 @@ def x(): if len(self.owner_app.usb_devices) > 0: target_device = self.owner_app.usb_devices[0] if self.interface_serial.port != target_device["port"]: - RNS.log("Updating serial device to "+str(target_device)) + RNS.log(f"Updating serial device to {target_device)}") self.interface_serial.port = target_device["port"] if self.interface_modem != None and not self.interface_modem.online: @@ -3278,7 +3278,7 @@ def x(): if len(self.owner_app.usb_devices) > 0: target_device = self.owner_app.usb_devices[0] if self.interface_modem.port != target_device["port"]: - RNS.log("Updating modem device to "+str(target_device)) + RNS.log(f"Updating modem device to {target_device)}") self.interface_modem.port = target_device["port"] def _periodic_jobs(self): @@ -3299,8 +3299,8 @@ def _periodic_jobs(self): lastsync = self.getpersistent("lxmf.lastsync") nextsync = lastsync+syncinterval - RNS.log("Last LXMF sync was "+RNS.prettytime(now-lastsync)+" ago", RNS.LOG_EXTREME) - RNS.log("Next LXMF sync is "+("in "+RNS.prettytime(nextsync-now) if nextsync-now > 0 else "now"), RNS.LOG_EXTREME) + RNS.log(f"Last LXMF sync was {RNS.prettytime(now - lastsync)} ago", RNS.LOG_EXTREME) + RNS.log(f"Next LXMF sync is {f'in {RNS.prettytime(nextsync - now)}' if nextsync - now > 0 else 'now'}", RNS.LOG_EXTREME) if now > nextsync: if self.request_lxmf_sync(): RNS.log("Scheduled LXMF sync succeeded", RNS.LOG_DEBUG) @@ -3308,7 +3308,7 @@ def _periodic_jobs(self): self.setpersistent("lxmf.syncretrying", False) else: if not self.getpersistent("lxmf.syncretrying"): - RNS.log("Scheduled LXMF sync failed, retrying in "+RNS.prettytime(SidebandCore.PERIODIC_SYNC_RETRY), RNS.LOG_DEBUG) + RNS.log(f"Scheduled LXMF sync failed, retrying in {RNS.prettytime(SidebandCore.PERIODIC_SYNC_RETRY)}", RNS.LOG_DEBUG) self.setpersistent("lxmf.lastsync", lastsync+SidebandCore.PERIODIC_SYNC_RETRY) self.setpersistent("lxmf.syncretrying", True) else: @@ -3328,8 +3328,8 @@ def _periodic_jobs(self): scheduled = next_send-now; blocked = self.telemetry_send_blocked_until-now next_send_in = max(scheduled, blocked) - RNS.log("Last telemetry send was "+RNS.prettytime(now-last_send_timebase)+" ago", RNS.LOG_EXTREME) - RNS.log("Next telemetry send is "+("in "+RNS.prettytime(next_send_in) if next_send_in > 0 else "now"), RNS.LOG_EXTREME) + RNS.log(f"Last telemetry send was {RNS.prettytime(now - last_send_timebase)} ago", RNS.LOG_EXTREME) + RNS.log(f"Next telemetry send is {f'in {RNS.prettytime(next_send_in)}' if next_send_in > 0 else 'now'}", RNS.LOG_EXTREME) if now > last_send_timebase+send_interval and now > self.telemetry_send_blocked_until: RNS.log("Initiating telemetry send to collector", RNS.LOG_DEBUG) @@ -3350,7 +3350,7 @@ def _periodic_jobs(self): self.pending_telemetry_send_try = 0 except Exception as e: - RNS.log("An error occurred while sending scheduled telemetry to collector: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while sending scheduled telemetry to collector: {e)}", RNS.LOG_ERROR) if self.config["telemetry_request_from_collector"]: if self.config["telemetry_collector"] != None and self.config["telemetry_collector"] != self.lxmf_destination.hash: @@ -3361,18 +3361,18 @@ def _periodic_jobs(self): request_interval = self.config["telemetry_request_interval"] next_request = last_request_timebase+request_interval - RNS.log("Last telemetry request was "+RNS.prettytime(now-last_request_timebase)+" ago", RNS.LOG_EXTREME) - RNS.log("Next telemetry request is "+("in "+RNS.prettytime(next_request-now) if next_request-now > 0 else "now"), RNS.LOG_EXTREME) + RNS.log(f"Last telemetry request was {RNS.prettytime(now - last_request_timebase)} ago", RNS.LOG_EXTREME) + RNS.log(f"Next telemetry request is {f'in {RNS.prettytime(next_request - now)}' if next_request - now > 0 else 'now'}", RNS.LOG_EXTREME) if now > last_request_timebase+request_interval: try: RNS.log("Initiating telemetry request to collector", RNS.LOG_DEBUG) self.request_latest_telemetry(from_addr=self.config["telemetry_collector"]) except Exception as e: - RNS.log("An error occurred while requesting a telemetry update from collector. The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while requesting a telemetry update from collector. The contained exception was: {e)}", RNS.LOG_ERROR) except Exception as e: - RNS.log("An error occurred while requesting scheduled telemetry from collector: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while requesting scheduled telemetry from collector: {e)}", RNS.LOG_ERROR) def __start_jobs_deferred(self): if self.is_service: @@ -3443,7 +3443,7 @@ def __add_localinterface(self, delay=None): self.interface_local_adding = False except Exception as e: - RNS.log("Error while adding AutoInterface. The contained exception was: "+str(e)) + RNS.log(f"Error while adding AutoInterface. The contained exception was: {e)}") self.interface_local = None self.interface_local_adding = False @@ -3583,7 +3583,7 @@ def __add_rnodeinterface(self, delay=None): self.interface_rnode.disable_external_framebuffer() except Exception as e: - RNS.log("Error while adding RNode Interface. The contained exception was: "+str(e)) + RNS.log(f"Error while adding RNode Interface. The contained exception was: {e)}") self.interface_rnode = None self.interface_rnode_adding = False @@ -3687,7 +3687,7 @@ def __start_jobs_immediate(self): self.interface_tcp = tcpinterface except Exception as e: - RNS.log("Error while adding TCP Interface. The contained exception was: "+str(e)) + RNS.log(f"Error while adding TCP Interface. The contained exception was: {e)}") self.interface_tcp = None if self.config["connect_i2p"]: @@ -3742,7 +3742,7 @@ def __start_jobs_immediate(self): except Exception as e: - RNS.log("Error while adding I2P Interface. The contained exception was: "+str(e)) + RNS.log(f"Error while adding I2P Interface. The contained exception was: {e)}") self.interface_i2p = None if self.config["connect_rnode"]: @@ -3799,7 +3799,7 @@ def __start_jobs_immediate(self): self.interface_serial = serialinterface except Exception as e: - RNS.log("Error while adding Serial Interface. The contained exception was: "+str(e)) + RNS.log(f"Error while adding Serial Interface. The contained exception was: {e)}") self.interface_serial = None elif self.config["connect_modem"]: @@ -3859,7 +3859,7 @@ def __start_jobs_immediate(self): self.interface_modem = modeminterface except Exception as e: - RNS.log("Error while adding Modem Interface. The contained exception was: "+str(e)) + RNS.log(f"Error while adding Modem Interface. The contained exception was: {e)}") self.interface_modem = None RNS.log("Reticulum started, activating LXMF...") @@ -3918,7 +3918,7 @@ def message_notification(self, message, no_display=False): if not no_display: self.lxm_ingest(message, originator=True) else: - RNS.log("Direct delivery of "+str(message)+" failed. Retrying as propagated message.", RNS.LOG_VERBOSE) + RNS.log(f"Direct delivery of {message)} failed. Retrying as propagated message.", RNS.LOG_VERBOSE) message.try_propagation_on_fail = None message.delivery_attempts = 0 if hasattr(message, "next_delivery_attempt"): @@ -3936,10 +3936,10 @@ def message_notification(self, message, no_display=False): try: telemeter = Telemeter.from_packed(message.fields[LXMF.FIELD_TELEMETRY]) telemetry_timebase = telemeter.read_all()["time"]["utc"] - RNS.log("Setting last successul telemetry timebase for "+RNS.prettyhexrep(message.destination_hash)+" to "+str(telemetry_timebase), RNS.LOG_DEBUG) + RNS.log(f"Setting last successul telemetry timebase for {RNS.prettyhexrep(message.destination_hash)} to {telemetry_timebase)}", RNS.LOG_DEBUG) self.setpersistent(f"telemetry.{RNS.hexrep(message.destination_hash, delimit=False)}.last_send_success_timebase", telemetry_timebase) except Exception as e: - RNS.log("Error while setting last successul telemetry timebase for "+RNS.prettyhexrep(message.destination_hash), RNS.LOG_DEBUG) + RNS.log(f"Error while setting last successul telemetry timebase for {RNS.prettyhexrep(message.destination_hash)}", RNS.LOG_DEBUG) def get_message_fields(self, context_dest, telemetry_update=False, is_authorized_telemetry_request=False, signal_already_sent=False): fields = {} @@ -3953,7 +3953,7 @@ def get_message_fields(self, context_dest, telemetry_update=False, is_authorized if telemetry_timebase > last_success_tb: RNS.log("Embedding own telemetry in message since current telemetry is newer than latest successful timebase", RNS.LOG_DEBUG) else: - RNS.log("Not embedding own telemetry in message since current telemetry timebase ("+str(telemetry_timebase)+") is not newer than latest successful timebase ("+str(last_success_tb)+")", RNS.LOG_DEBUG) + RNS.log(f"Not embedding own telemetry in message since current telemetry timebase ({telemetry_timebase)}) is not newer than latest successful timebase ({last_success_tb)})", RNS.LOG_DEBUG) send_telemetry = False send_appearance = False if signal_already_sent: @@ -4000,7 +4000,7 @@ def paper_message(self, content, destination_hash): return True except Exception as e: - RNS.log("Error while creating paper message: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating paper message: {e)}", RNS.LOG_ERROR) return False def _service_get_lxm_progress(self, lxm_hash): @@ -4012,7 +4012,7 @@ def _service_get_lxm_progress(self, lxm_hash): return self.service_rpc_request({"get_lxm_progress": {"lxm_hash": lxm_hash}}) except Exception as e: - RNS.log("Error while getting LXM progress over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while getting LXM progress over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) return False else: @@ -4027,14 +4027,14 @@ def get_lxm_progress(self, lxm_hash): return prg except Exception as e: - RNS.log("An error occurred while getting message transfer progress: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while getting message transfer progress: {e)}", RNS.LOG_ERROR) return None def get_lxm_stamp_cost(self, lxm_hash): try: return self.message_router.get_outbound_lxm_stamp_cost(lxm_hash) except Exception as e: - RNS.log("An error occurred while getting message transfer stamp cost: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while getting message transfer stamp cost: {e)}", RNS.LOG_ERROR) return None def _service_send_message(self, content, destination_hash, propagation, skip_fields=False, no_display=False, attachment = None, image = None, audio = None): @@ -4055,7 +4055,7 @@ def _service_send_message(self, content, destination_hash, propagation, skip_fie }) except Exception as e: - RNS.log("Error while sending message over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while sending message over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) return False else: @@ -4074,7 +4074,7 @@ def _service_send_command(self, content, destination_hash, propagation): }) except Exception as e: - RNS.log("Error while sending command over RPC: "+str(e), RNS.LOG_DEBUG) + RNS.log(f"Error while sending command over RPC: {e)}", RNS.LOG_DEBUG) RNS.trace_exception(e) return False else: @@ -4086,7 +4086,7 @@ def send_message(self, content, destination_hash, propagation, skip_fields=False return self._service_send_message(content, destination_hash, propagation, skip_fields, no_display, attachment, image, audio) except Exception as e: - RNS.log("Error while sending message: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while sending message: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) return False @@ -4141,7 +4141,7 @@ def send_message(self, content, destination_hash, propagation, skip_fields=False return True except Exception as e: - RNS.log("Error while sending message: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while sending message: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) return False @@ -4151,7 +4151,7 @@ def send_command(self, content, destination_hash, propagation): return self._service_send_command(content, destination_hash, propagation) except Exception as e: - RNS.log("Error while sending message: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while sending message: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) return False @@ -4202,7 +4202,7 @@ def send_command(self, content, destination_hash, propagation): return True except Exception as e: - RNS.log("Error while sending message: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while sending message: {e)}", RNS.LOG_ERROR) return False def new_conversation(self, dest_str, name = "", trusted = False): @@ -4214,7 +4214,7 @@ def new_conversation(self, dest_str, name = "", trusted = False): self._db_create_conversation(addr_b, name, trusted) except Exception as e: - RNS.log("Error while creating conversation: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating conversation: {e)}", RNS.LOG_ERROR) return False return True @@ -4224,7 +4224,7 @@ def create_conversation(self, context_dest, name = None, trusted = False): self._db_create_conversation(context_dest, name, trusted) except Exception as e: - RNS.log("Error while creating conversation: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating conversation: {e)}", RNS.LOG_ERROR) return False return True @@ -4273,7 +4273,7 @@ def lxm_ingest(self, message, originator = False): own_command = True if self._db_message(message.hash): - RNS.log("Message exists, setting state to: "+str(message.state), RNS.LOG_DEBUG) + RNS.log(f"Message exists, setting state to: {message.state)}", RNS.LOG_DEBUG) stamp = None if originator and message.stamp != None: stamp = [message.stamp, message.stamp_valid, message.stamp_value] @@ -4345,7 +4345,7 @@ def lxm_ingest(self, message, originator = False): try: self.notify(title=self.peer_display_name(context_dest), content=notification_content, group="LXM", context_id=RNS.hexrep(context_dest, delimit=False)) except Exception as e: - RNS.log("Could not post notification for received message: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Could not post notification for received message: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) def ptt_playback(self, message): @@ -4375,12 +4375,12 @@ def ptt_playback(self, message): return if audio_field[0] == LXMF.AM_OPUS_OGG: - temp_path = self.rec_cache+"/msg.ogg" + temp_path = f"{self.rec_cache}/msg.ogg" with open(temp_path, "wb") as af: af.write(self.last_msg_audio) elif audio_field[0] >= LXMF.AM_CODEC2_700C and audio_field[0] <= LXMF.AM_CODEC2_3200: - temp_path = self.rec_cache+"/msg.ogg" + temp_path = f"{self.rec_cache}/msg.ogg" from sideband.audioproc import samples_to_ogg, decode_codec2, detect_codec2 target_rate = 8000 @@ -4389,7 +4389,7 @@ def ptt_playback(self, message): if detect_codec2(): if samples_to_ogg(decode_codec2(audio_field[1], audio_field[0]), temp_path, input_rate=8000, output_rate=target_rate): - RNS.log("Wrote OGG file to: "+temp_path, RNS.LOG_DEBUG) + RNS.log(f"Wrote OGG file to: {temp_path}", RNS.LOG_DEBUG) else: RNS.log("OGG write failed", RNS.LOG_DEBUG) else: @@ -4411,7 +4411,7 @@ def ptt_playback(self, message): RNS.log("Playback was requested, but no audio data was loaded for playback", RNS.LOG_ERROR) except Exception as e: - RNS.log("Error while playing message audio:"+str(e)) + RNS.log(f"Error while playing message audio:{e)}") RNS.trace_exception(e) def ptt_event(self, message): @@ -4422,7 +4422,7 @@ def ptt_job(): time.sleep(0.5) self.ptt_playback(message) except Exception as e: - RNS.log("Error while starting playback for PTT-enabled conversation: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while starting playback for PTT-enabled conversation: {e)}", RNS.LOG_ERROR) finally: self.ptt_playback_lock.release() @@ -4445,7 +4445,7 @@ def start(self): thread.start() self.setstate("core.started", True) - RNS.log("Sideband Core "+str(self)+" "+str(self.version_str)+" started") + RNS.log(f"Sideband Core {self)} {self.version_str)} started") def stop_webshare(self): if self.webshare_server != None: @@ -4468,22 +4468,22 @@ def do_GET(self): self.path = self.path.split("?")[0] path = serve_root + self.path if self.path == "/": - path = serve_root + "/index.html" + path = f"{serve_root}/index.html" if "/.." in self.path: self.send_response(403) self.end_headers() - self.write("Forbidden".encode("utf-8")) + self.write(b"Forbidden") elif self.path == "/pkglist": try: self.send_response(200) self.send_header("Content-type", "text/json") self.end_headers() - json_result = json.dumps(os.listdir(serve_root+"/pkg")) + json_result = json.dumps(os.listdir(f"{serve_root}/pkg")) self.wfile.write(json_result.encode("utf-8")) except Exception as e: self.send_response(500) self.end_headers() - RNS.log("Error listing directory "+str(path)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error listing directory {path)}: {e)}", RNS.LOG_ERROR) es = "Error" self.wfile.write(es.encode("utf-8")) else: @@ -4498,7 +4498,7 @@ def do_GET(self): except Exception as e: self.send_response(500) self.end_headers() - RNS.log("Error serving file "+str(path)+": "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error serving file {path)}: {e)}", RNS.LOG_ERROR) es = "Error" self.wfile.write(es.encode("utf-8")) @@ -4513,7 +4513,7 @@ def do_GET(self): def request_lxmf_sync(self, limit = None): if self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_IDLE or self.message_router.propagation_transfer_state >= LXMF.LXMRouter.PR_COMPLETE: self.message_router.request_messages_from_propagation_node(self.identity, max_messages = limit) - RNS.log("LXMF message sync requested from propagation node "+RNS.prettyhexrep(self.message_router.get_outbound_propagation_node())+" for "+str(self.identity)) + RNS.log(f"LXMF message sync requested from propagation node {RNS.prettyhexrep(self.message_router.get_outbound_propagation_node())} for {self.identity)}") return True else: return False @@ -4547,13 +4547,13 @@ def lxmf_delivery(self, message): if message.unverified_reason == LXMF.LXMessage.SOURCE_UNKNOWN: signature_string = "Cannot verify, source is unknown" - RNS.log("LXMF delivery "+str(time_string)+". "+str(signature_string)+".", RNS.LOG_DEBUG) + RNS.log(f"LXMF delivery {time_string)}. {signature_string)}.", RNS.LOG_DEBUG) try: context_dest = message.source_hash if self.config["lxmf_ignore_unknown"] == True: if self._db_conversation(context_dest) == None: - RNS.log("Dropping message from unknown sender "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Dropping message from unknown sender {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) return if message.signature_validated and LXMF.FIELD_COMMANDS in message.fields: @@ -4563,13 +4563,13 @@ def lxmf_delivery(self, message): else: # TODO: Add these event to built-in log/event viewer # when it is implemented. - RNS.log("Unauthorized command received from "+RNS.prettyhexrep(context_dest), RNS.LOG_WARNING) + RNS.log(f"Unauthorized command received from {RNS.prettyhexrep(context_dest)}", RNS.LOG_WARNING) else: self.lxm_ingest(message) except Exception as e: - RNS.log("Error while ingesting LXMF message "+RNS.prettyhexrep(message.hash)+" to database: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while ingesting LXMF message {RNS.prettyhexrep(message.hash)} to database: {e)}", RNS.LOG_ERROR) def handle_plugin_command(self, command_string, message): try: @@ -4577,21 +4577,21 @@ def handle_plugin_command(self, command_string, message): command = call[0] arguments = call[1:] if command in self.active_command_plugins: - RNS.log("Handling command \""+str(command)+"\" via command plugin "+str(self.active_command_plugins[command]), RNS.LOG_DEBUG) + RNS.log(f"Handling command \"{command)}\" via command plugin {self.active_command_plugins[command])}", RNS.LOG_DEBUG) self.active_command_plugins[command].handle_command(arguments, message) except Exception as e: - RNS.log("An error occurred while handling a plugin command. The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while handling a plugin command. The contained exception was: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) def handle_commands(self, commands, message): try: context_dest = message.source_hash - RNS.log("Handling commands from "+RNS.prettyhexrep(context_dest), RNS.LOG_DEBUG) + RNS.log(f"Handling commands from {RNS.prettyhexrep(context_dest)}", RNS.LOG_DEBUG) for command in commands: if Commands.TELEMETRY_REQUEST in command: timebase = int(command[Commands.TELEMETRY_REQUEST]) - RNS.log("Handling telemetry request with timebase "+str(timebase), RNS.LOG_DEBUG) + RNS.log(f"Handling telemetry request with timebase {timebase)}", RNS.LOG_DEBUG) if self.config["telemetry_collector_enabled"]: RNS.log(f"Collector requests enabled, returning complete telemetry response for all known objects since {timebase}", RNS.LOG_DEBUG) self.create_telemetry_collector_response(to_addr=context_dest, timebase=timebase, is_authorized_telemetry_request=True) @@ -4604,7 +4604,7 @@ def handle_commands(self, commands, message): self.send_message("Ping reply", context_dest, False, skip_fields=True, no_display=True) elif Commands.ECHO in command: - msg_content = "Echo reply: "+command[Commands.ECHO].decode("utf-8") + 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) @@ -4628,7 +4628,7 @@ def handle_commands(self, commands, message): self.handle_plugin_command(command[Commands.PLUGIN_COMMAND], message) except Exception as e: - RNS.log("Error while handling commands: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while handling commands: {e)}", RNS.LOG_ERROR) def create_telemetry_collector_response(self, to_addr, timebase, is_authorized_telemetry_request=False): added_sources = {} @@ -4698,7 +4698,7 @@ def get_sync_status(self): if new_msgs == 0: return "Done, no new messages" else: - return "Downloaded "+str(new_msgs)+" new messages" + return f"Downloaded {new_msgs)} new messages" else: return "Unknown" diff --git a/sbapp/sideband/geo.py b/sbapp/sideband/geo.py index 77ad157..3c423e1 100644 --- a/sbapp/sideband/geo.py +++ b/sbapp/sideband/geo.py @@ -312,7 +312,7 @@ def altitude_to_aamsl(alt, lat, lon): # LGPLv3 License # ###################################################### -class GeoidHeight(object): +class GeoidHeight: c0 = 240 c3 = ( ( 9, -18, -88, 0, 96, 90, 0, 0, -60, -20), diff --git a/sbapp/sideband/sense.py b/sbapp/sideband/sense.py index aa1c3fa..6c567e6 100644 --- a/sbapp/sideband/sense.py +++ b/sbapp/sideband/sense.py @@ -38,7 +38,7 @@ def from_packed(packed): return t except Exception as e: - RNS.log("An error occurred while unpacking telemetry. The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while unpacking telemetry. The contained exception was: {e)}", RNS.LOG_ERROR) return None def __init__(self, from_packed=False, android_context=None, service=False, location_provider=None): @@ -153,18 +153,18 @@ def check_permission(self, permission): if RNS.vendor.platformutils.is_android(): if self.android_context != None: try: - result = self.android_context.checkSelfPermission("android.permission."+permission) + result = self.android_context.checkSelfPermission(f"android.permission.{permission}") if result == 0: return True except Exception as e: - RNS.log("Error while checking permission: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) return False else: from android.permissions import check_permission - return check_permission("android.permission."+permission) + return check_permission(f"android.permission.{permission}") else: return False @@ -273,7 +273,7 @@ def check_permission(self, permission): return self._telemeter.check_permission(permission) else: from android.permissions import check_permission - return check_permission("android.permission."+permission) + return check_permission(f"android.permission.{permission}") class Time(Sensor): SID = Sensor.SID_TIME @@ -446,9 +446,9 @@ def __init__(self): bn = 0 node_name = None for bi in range(0,10): - path = os.path.join('/sys', 'class', 'power_supply', 'BAT'+str(bi)) + path = os.path.join('/sys', 'class', 'power_supply', f"BAT{bi)}") if os.path.isdir(path): - node_name = "BAT"+str(bi) + node_name = f"BAT{bi)}" break self.battery_node_name = node_name @@ -784,7 +784,7 @@ def pack(self): d["last_update"], ] except Exception as e: - RNS.log("An error occurred while packing location sensor data. The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while packing location sensor data. The contained exception was: {e)}", RNS.LOG_ERROR) return None def unpack(self, packed): diff --git a/sbapp/ui/__init__.py b/sbapp/ui/__init__.py index f49e360..1d03710 100644 --- a/sbapp/ui/__init__.py +++ b/sbapp/ui/__init__.py @@ -1,5 +1,5 @@ import os import glob -modules = glob.glob(os.path.dirname(__file__)+"/*.py") +modules = glob.glob(f"{os.path.dirname(__file__)}/*.py") __all__ = [ os.path.basename(f)[:-3] for f in modules if not f.endswith('__init__.py')] \ No newline at end of file diff --git a/sbapp/ui/announces.py b/sbapp/ui/announces.py index 5e58dbb..b021988 100644 --- a/sbapp/ui/announces.py +++ b/sbapp/ui/announces.py @@ -63,7 +63,7 @@ def update(self): self.fetch_announces() self.update_widget() self.app.sideband.setstate("app.flags.new_announces", False) - RNS.log("Updated announce stream widgets in "+RNS.prettytime(time.time()-us), RNS.LOG_DEBUG) + RNS.log(f"Updated announce stream widgets in {RNS.prettytime(time.time() - us)}", RNS.LOG_DEBUG) def update_widget(self): if self.list == None: @@ -105,10 +105,10 @@ def gen_info(ts, dest, name, cost, dtype): def x(sender): yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) if dtype == "lxmf.delivery": - ad_text = "[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 + 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}" if dtype == "lxmf.propagation": - ad_text = "[size=22dp]LXMF Propagation Node[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest) + ad_text = f"[size=22dp]LXMF Propagation Node[/size]\n\n[b]Received[/b] {ts}\n[b]Address[/b] {RNS.prettyhexrep(dest)}" dialog = MDDialog( text=ad_text, @@ -130,7 +130,7 @@ def dl_yes(s): iconl = IconLeftWidget(icon=trust_icon) elif dest_type == "lxmf.propagation": - disp_name = "Propagation Node "+RNS.prettyhexrep(context_dest) + disp_name = f"Propagation Node {RNS.prettyhexrep(context_dest)}" iconl = IconLeftWidget(icon="upload-network") else: diff --git a/sbapp/ui/conversations.py b/sbapp/ui/conversations.py index 4427af3..0f38b62 100644 --- a/sbapp/ui/conversations.py +++ b/sbapp/ui/conversations.py @@ -224,7 +224,7 @@ def x(): dialog = MDDialog( title="Edit Conversation", - text= "With "+RNS.prettyhexrep(dest), + text= f"With {RNS.prettyhexrep(dest)}", type="custom", content_cls=dialog_content, buttons=[ yes_button, no_button ], @@ -269,7 +269,7 @@ def dl_yes(s): self.app.sideband.named_conversation(name, dest) except Exception as e: - RNS.log("Error while saving conversation settings: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while saving conversation settings: {e)}", RNS.LOG_ERROR) dialog.dismiss() @@ -284,10 +284,10 @@ def dl_no(s): no_button.bind(on_release=dl_no) item.dmenu.dismiss() dialog.open() - RNS.log("Generated edit dialog in "+str(RNS.prettytime(time.time()-t_s)), RNS.LOG_DEBUG) + RNS.log(f"Generated edit dialog in {RNS.prettytime(time.time() - t_s))}", RNS.LOG_DEBUG) except Exception as e: - RNS.log("Error while creating conversation settings: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while creating conversation settings: {e)}", RNS.LOG_ERROR) return x @@ -479,7 +479,7 @@ def x(sender): self.list.children.sort(key=lambda w: (w.trusted, w.last_activity)) - RNS.log("Updated conversation list widgets in "+RNS.prettytime(time.time()-us), RNS.LOG_DEBUG) + RNS.log(f"Updated conversation list widgets in {RNS.prettytime(time.time() - us)}", RNS.LOG_DEBUG) def get_widget(self): return self.list diff --git a/sbapp/ui/helpers.py b/sbapp/ui/helpers.py index 68f73d4..93cc6ce 100644 --- a/sbapp/ui/helpers.py +++ b/sbapp/ui/helpers.py @@ -83,7 +83,7 @@ def multilingual_markup(data): if pfont != "default": do += "[/font]" if rfont != "default": - do += "[font="+str(rfont)+"]" + do += f"[font={rfont)}]" do += cp diff --git a/sbapp/ui/messages.py b/sbapp/ui/messages.py index 2047ecf..5c2f441 100644 --- a/sbapp/ui/messages.py +++ b/sbapp/ui/messages.py @@ -278,7 +278,7 @@ def lmcb(sender): sphrase = "Sending" prg = self.app.sideband.get_lxm_progress(msg["hash"]) if prg != None: - prgstr = ", "+str(round(prg*100, 1))+"% done" + prgstr = f", {round(prg * 100, 1))}% done" if prg <= 0.00: stamp_cost = self.app.sideband.get_lxm_stamp_cost(msg["hash"]) if stamp_cost: @@ -296,8 +296,8 @@ def lmcb(sender): sphrase = "Sending" if msg["title"]: - titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n" - w.heading = titlestr+"[b]Sent[/b] "+txstr+"\n[b]State[/b] "+sphrase+prgstr+" " + 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} " if w.has_audio: alstr = RNS.prettysize(w.audio_size) w.heading += f"\n[b]Audio Message[/b] ({alstr})" @@ -309,8 +309,8 @@ def lmcb(sender): txstr = time.strftime(ts_format, time.localtime(msg["sent"])) titlestr = "" if msg["title"]: - titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n" - w.heading = titlestr+"[b]Sent[/b] "+txstr+delivery_syms+"\n[b]State[/b] Delivered" + titlestr = f"[b]Title[/b] {msg['title'].decode('utf-8')}\n" + w.heading = f"{titlestr}[b]Sent[/b] {txstr}{delivery_syms}\n[b]State[/b] Delivered" if w.has_audio: alstr = RNS.prettysize(w.audio_size) w.heading += f"\n[b]Audio Message[/b] ({alstr})" @@ -321,8 +321,8 @@ def lmcb(sender): txstr = time.strftime(ts_format, time.localtime(msg["sent"])) titlestr = "" if msg["title"]: - titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n" - w.heading = titlestr+"[b]Sent[/b] "+txstr+"\n[b]State[/b] Paper Message" + titlestr = f"[b]Title[/b] {msg['title'].decode('utf-8')}\n" + w.heading = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] Paper Message" m["state"] = msg["state"] if msg["method"] == LXMF.LXMessage.PROPAGATED and msg["state"] == LXMF.LXMessage.SENT: @@ -330,8 +330,8 @@ def lmcb(sender): txstr = time.strftime(ts_format, time.localtime(msg["sent"])) titlestr = "" if msg["title"]: - titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n" - w.heading = titlestr+"[b]Sent[/b] "+txstr+delivery_syms+"\n[b]State[/b] On Propagation Net" + titlestr = f"[b]Title[/b] {msg['title'].decode('utf-8')}\n" + w.heading = f"{titlestr}[b]Sent[/b] {txstr}{delivery_syms}\n[b]State[/b] On Propagation Net" if w.has_audio: alstr = RNS.prettysize(w.audio_size) w.heading += f"\n[b]Audio Message[/b] ({alstr})" @@ -342,8 +342,8 @@ def lmcb(sender): txstr = time.strftime(ts_format, time.localtime(msg["sent"])) titlestr = "" if msg["title"]: - titlestr = "[b]Title[/b] "+msg["title"].decode("utf-8")+"\n" - w.heading = titlestr+"[b]Sent[/b] "+txstr+"\n[b]State[/b] Failed" + titlestr = f"[b]Title[/b] {msg['title'].decode('utf-8')}\n" + w.heading = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] Failed" m["state"] = msg["state"] if w.has_audio: alstr = RNS.prettysize(w.audio_size) @@ -388,7 +388,7 @@ def update_widget(self): if message_input.strip() == b"": if not ("lxm" in m and m["lxm"] != None and m["lxm"].fields != None and LXMF.FIELD_COMMANDS in m["lxm"].fields): - message_input = "[i]This message contains no text content[/i]".encode("utf-8") + message_input = b"[i]This message contains no text content[/i]" message_markup = multilingual_markup(message_input) @@ -438,18 +438,18 @@ def update_widget(self): commands = m["lxm"].fields[LXMF.FIELD_COMMANDS] for command in commands: if Commands.ECHO in command: - extra_content = "[font=RobotoMono-Regular]> echo "+command[Commands.ECHO].decode("utf-8")+"[/font]\n" + extra_content = f"[font=RobotoMono-Regular]> echo {command[Commands.ECHO].decode('utf-8')}[/font]\n" if Commands.PING in command: extra_content = "[font=RobotoMono-Regular]> ping[/font]\n" if Commands.SIGNAL_REPORT in command: extra_content = "[font=RobotoMono-Regular]> sig[/font]\n" if Commands.PLUGIN_COMMAND in command: cmd_content = command[Commands.PLUGIN_COMMAND] - extra_content = "[font=RobotoMono-Regular]> "+str(cmd_content)+"[/font]\n" + extra_content = f"[font=RobotoMono-Regular]> {cmd_content)}[/font]\n" extra_content = extra_content[:-1] force_markup = True except Exception as e: - RNS.log("Error while generating command display: "+str(e), RNS.LOG_ERROR) + RNS.log(f"Error while generating command display: {e)}", RNS.LOG_ERROR) if telemeter == None and "lxm" in m and m["lxm"] and m["lxm"].fields != None and LXMF.FIELD_TELEMETRY in m["lxm"].fields: try: @@ -488,11 +488,11 @@ def update_widget(self): if "euclidian" in d: edst = d["euclidian"] if edst != None: - rcvd_d_str = "\n[b]Distance[/b] "+RNS.prettydistance(edst) + rcvd_d_str = f"\n[b]Distance[/b] {RNS.prettydistance(edst)}" elif "geodesic" in d: gdst = d["geodesic"] if gdst != None: - rcvd_d_str = "\n[b]Distance[/b] "+RNS.prettydistance(gdst) + " (geodesic)" + rcvd_d_str = f"\n[b]Distance[/b] {RNS.prettydistance(gdst)} (geodesic)" phy_stats_str = "" if "extras" in m and m["extras"] != None: @@ -500,64 +500,64 @@ def update_widget(self): if "q" in phy_stats: try: lq = round(float(phy_stats["q"]), 1) - phy_stats_str += "[b]Link Quality[/b] "+str(lq)+"% " + phy_stats_str += f"[b]Link Quality[/b] {lq)}% " extra_telemetry["quality"] = lq except: pass if "rssi" in phy_stats: try: lr = round(float(phy_stats["rssi"]), 1) - phy_stats_str += "[b]RSSI[/b] "+str(lr)+"dBm " + phy_stats_str += f"[b]RSSI[/b] {lr)}dBm " extra_telemetry["rssi"] = lr except: pass if "snr" in phy_stats: try: ls = round(float(phy_stats["snr"]), 1) - phy_stats_str += "[b]SNR[/b] "+str(ls)+"dB " + phy_stats_str += f"[b]SNR[/b] {ls)}dB " extra_telemetry["snr"] = ls except: pass if m["title"]: - titlestr = "[b]Title[/b] "+m["title"].decode("utf-8")+"\n" + titlestr = f"[b]Title[/b] {m['title'].decode('utf-8')}\n" if m["source"] == self.app.sideband.lxmf_destination.hash: if m["state"] == LXMF.LXMessage.DELIVERED: msg_color = mdc(color_delivered, intensity_msgs) - heading_str = titlestr+"[b]Sent[/b] "+txstr+delivery_syms+"\n[b]State[/b] Delivered" + heading_str = f"{titlestr}[b]Sent[/b] {txstr}{delivery_syms}\n[b]State[/b] Delivered" elif m["method"] == LXMF.LXMessage.PROPAGATED and m["state"] == LXMF.LXMessage.SENT: msg_color = mdc(color_propagated, intensity_msgs) - heading_str = titlestr+"[b]Sent[/b] "+txstr+delivery_syms+"\n[b]State[/b] On Propagation Net" + heading_str = f"{titlestr}[b]Sent[/b] {txstr}{delivery_syms}\n[b]State[/b] On Propagation Net" elif m["method"] == LXMF.LXMessage.PAPER: msg_color = mdc(color_paper, intensity_msgs) - heading_str = titlestr+"[b]Created[/b] "+txstr+"\n[b]State[/b] Paper Message" + heading_str = f"{titlestr}[b]Created[/b] {txstr}\n[b]State[/b] Paper Message" elif m["state"] == LXMF.LXMessage.FAILED: msg_color = mdc(color_failed, intensity_msgs) - heading_str = titlestr+"[b]Sent[/b] "+txstr+"\n[b]State[/b] Failed" + heading_str = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] Failed" elif m["state"] == LXMF.LXMessage.OUTBOUND or m["state"] == LXMF.LXMessage.SENDING: msg_color = mdc(color_unknown, intensity_msgs) - heading_str = titlestr+"[b]Sent[/b] "+txstr+"\n[b]State[/b] Sending " + heading_str = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] Sending " else: msg_color = mdc(color_unknown, intensity_msgs) - heading_str = titlestr+"[b]Sent[/b] "+txstr+"\n[b]State[/b] Unknown" + heading_str = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] Unknown" else: msg_color = mdc(color_received, intensity_msgs) heading_str = titlestr if phy_stats_str != "" and self.app.sideband.config["advanced_stats"]: - heading_str += phy_stats_str+"\n" + heading_str += f"{phy_stats_str}\n" # TODO: Remove # if stamp_valid: # txstr += f" [b]Stamp[/b] value is {stamp_value} " - heading_str += "[b]Sent[/b] "+txstr+delivery_syms - heading_str += "\n[b]Received[/b] "+rxstr + heading_str += f"[b]Sent[/b] {txstr}{delivery_syms}" + heading_str += f"\n[b]Received[/b] {rxstr}" if rcvd_d_str != "": heading_str += rcvd_d_str @@ -575,7 +575,7 @@ def update_widget(self): if has_attachment: heading_str += "\n[b]Attachments[/b] " for attachment in attachments_field: - heading_str += str(attachment[0])+", " + heading_str += f"{attachment[0])}, " heading_str = heading_str[:-2] if has_audio: @@ -724,7 +724,7 @@ def gen_save_image(item): def x(): image_field = item.image_field extension = str(image_field[0]).replace(".", "") - filename = time.strftime("LXM_%Y_%m_%d_%H_%M_%S", time.localtime(time.time()))+"."+str(extension) + 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() @@ -735,11 +735,11 @@ def x(): image_field = item.image_field try: extension = str(image_field[0]).replace(".", "") - filename = time.strftime("LXM_%Y_%m_%d_%H_%M_%S", time.localtime(time.time()))+"."+str(extension) + filename = f"{time.strftime('LXM_%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))}.{extension)}" if RNS.vendor.platformutils.is_darwin(): save_path = str(plyer.storagepath.get_downloads_dir()+filename).replace("file://", "") else: - save_path = plyer.storagepath.get_downloads_dir()+"/"+filename + save_path = f"{plyer.storagepath.get_downloads_dir()}/{filename}" with open(save_path, "wb") as save_file: save_file.write(image_field[1]) @@ -749,7 +749,7 @@ def x(): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Image Saved", - text="The image has been saved to: "+save_path+"", + text=f"The image has been saved to: {save_path}", buttons=[ ok_button ], # elevation=0, ) @@ -764,7 +764,7 @@ def dl_ok(s): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Error", - text="Could not save the image:\n\n"+save_path+"\n\n"+str(e), + text=f"Could not save the image:\n\n{save_path}\n\n{e)}", buttons=[ ok_button ], # elevation=0, ) @@ -786,13 +786,13 @@ def x(): if RNS.vendor.platformutils.is_darwin(): output_path = str(plyer.storagepath.get_downloads_dir()).replace("file://", "") else: - output_path = plyer.storagepath.get_downloads_dir()+"/" + output_path = f"{plyer.storagepath.get_downloads_dir()}/" if len(attachments_field) == 1: - saved_text = "The attached file has been saved to: "+output_path + saved_text = f"The attached file has been saved to: {output_path}" saved_title = "Attachment Saved" else: - saved_text = "The attached files have been saved to: "+output_path + saved_text = f"The attached files have been saved to: {output_path}" saved_title = "Attachment Saved" for attachment in attachments_field: @@ -800,15 +800,15 @@ def x(): if RNS.vendor.platformutils.is_darwin(): save_path = str(plyer.storagepath.get_downloads_dir()+filename).replace("file://", "") else: - save_path = plyer.storagepath.get_downloads_dir()+"/"+filename + save_path = f"{plyer.storagepath.get_downloads_dir()}/{filename}" name_counter = 1 pre_count = save_path while os.path.exists(save_path): - save_path = str(pre_count)+"."+str(name_counter) + save_path = f"{pre_count)}.{name_counter)}" name_counter += 1 - saved_text = "The attached file has been saved to: "+save_path + saved_text = f"The attached file has been saved to: {save_path}" with open(save_path, "wb") as save_file: save_file.write(attachment[1]) @@ -833,7 +833,7 @@ def dl_ok(s): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Error", - text="Could not save the attachment:\n\n"+save_path+"\n\n"+str(e), + text=f"Could not save the attachment:\n\n{save_path}\n\n{e)}", buttons=[ ok_button ], # elevation=0, ) @@ -863,7 +863,7 @@ def x(): Clipboard.copy(str(tlm)) item.dmenu.dismiss() except Exception as e: - RNS.log("An error occurred while decoding telemetry. The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"An error occurred while decoding telemetry. The contained exception was: {e)}", RNS.LOG_ERROR) Clipboard.copy("Could not decode telemetry") return x @@ -880,7 +880,7 @@ def gen_save_qr(lxm, item): def x(): qr_image = lxm.as_qr() hash_str = RNS.hexrep(lxm.hash[-2:], delimit=False) - filename = "Paper_Message_"+time.strftime(file_ts_format, time.localtime(m["sent"]))+"_"+hash_str+".png" + filename = f"Paper_Message_{time.strftime(file_ts_format, time.localtime(m['sent']))}_{hash_str}.png" # filename = "Paper_Message.png" self.app.share_image(qr_image, filename) item.dmenu.dismiss() @@ -891,11 +891,11 @@ def x(): try: qr_image = lxm.as_qr() hash_str = RNS.hexrep(lxm.hash[-2:], delimit=False) - filename = "Paper_Message_"+time.strftime(file_ts_format, time.localtime(m["sent"]))+"_"+hash_str+".png" + filename = f"Paper_Message_{time.strftime(file_ts_format, time.localtime(m['sent']))}_{hash_str}.png" if RNS.vendor.platformutils.is_darwin(): save_path = str(plyer.storagepath.get_downloads_dir()+filename).replace("file://", "") else: - save_path = plyer.storagepath.get_downloads_dir()+"/"+filename + save_path = f"{plyer.storagepath.get_downloads_dir()}/{filename}" qr_image.save(save_path) item.dmenu.dismiss() @@ -903,7 +903,7 @@ def x(): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="QR Code Saved", - text="The paper message has been saved to: "+save_path+"", + text=f"The paper message has been saved to: {save_path}", buttons=[ ok_button ], # elevation=0, ) @@ -918,7 +918,7 @@ def dl_ok(s): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Error", - text="Could not save the paper message QR-code to:\n\n"+save_path+"\n\n"+str(e), + text=f"Could not save the paper message QR-code to:\n\n{save_path}\n\n{e)}", buttons=[ ok_button ], # elevation=0, ) @@ -940,10 +940,10 @@ def x(): def x(): try: qr_image = lxm.as_qr() - qr_tmp_path = self.app.sideband.tmp_dir+"/"+str(RNS.hexrep(lxm.hash, delimit=False)) + qr_tmp_path = f"{self.app.sideband.tmp_dir}/{RNS.hexrep(lxm.hash, delimit=False))}" qr_image.save(qr_tmp_path) - print_command = self.app.sideband.config["print_command"]+" "+qr_tmp_path + print_command = f"{self.app.sideband.config['print_command']} {qr_tmp_path}" return_code = subprocess.call(shlex.split(print_command), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.unlink(qr_tmp_path) @@ -955,7 +955,7 @@ def x(): ok_button = MDRectangleFlatButton(text="OK",font_size=dp(18)) dialog = MDDialog( title="Error", - text="Could not print the paper message QR-code.\n\n"+str(e), + text=f"Could not print the paper message QR-code.\n\n{e)}", buttons=[ ok_button ], # elevation=0, ) diff --git a/sbapp/ui/objectdetails.py b/sbapp/ui/objectdetails.py index 38d0074..1f0f446 100644 --- a/sbapp/ui/objectdetails.py +++ b/sbapp/ui/objectdetails.py @@ -155,9 +155,9 @@ def set_source(self, source_dest, from_conv=False, from_objects=False, from_tele self.screen.ids.name_label.text = pds if source_dest == own_address: - self.screen.ids.name_label.text = pds+" (this device)" + self.screen.ids.name_label.text = f"{pds} (this device)" elif source_dest == self.app.sideband.config["telemetry_collector"]: - self.screen.ids.name_label.text = pds+" (collector)" + self.screen.ids.name_label.text = f"{pds} (collector)" self.screen.ids.coordinates_button.disabled = True self.screen.ids.object_appearance.icon = appearance[0] @@ -211,7 +211,7 @@ def job(dt): except Exception as e: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"An {str(type(e))} occurred while updating service telemetry: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"An {type(e))} occurred while updating service telemetry: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) def reload(self): @@ -274,7 +274,7 @@ def clear_widget(self): def update(self): us = time.time() self.update_widget() - RNS.log("Updated object details in "+RNS.prettytime(time.time()-us), RNS.LOG_DEBUG) + RNS.log(f"Updated object details in {RNS.prettytime(time.time() - us)}", RNS.LOG_DEBUG) def update_widget(self): if self.widget == None: @@ -414,7 +414,7 @@ def copy_info(e=None): else: cs_str = f" ({cs})" - if p != None: formatted_values = f"{name} [b]{p}%[/b]"+cs_str + if p != None: formatted_values = f"{name} [b]{p}%[/b]{cs_str}" elif name == "Ambient Pressure": p = s["values"]["mbar"] @@ -447,10 +447,10 @@ def copy_info(e=None): if q != None: q_str = f"Link Quality [b]{q}%[/b]" if rssi != None: rssi_str = f"RSSI [b]{rssi} dBm[/b]" - if q != None: rssi_str = ", "+rssi_str + if q != None: rssi_str = f", {rssi_str}" if snr != None: snr_str = f"SNR [b]{snr} dB[/b]" - if q != None or rssi != None: snr_str = ", "+snr_str + 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 @@ -592,7 +592,7 @@ def copy_info(e=None): pct = round(load*100.0, 1) avgs_str = f", averages are [b]{round(avgs[0],2)}[/b], [b]{round(avgs[1],2)}[/b], [b]{round(avgs[2],2)}[/b]" if avgs != None and len(avgs) == 3 else "" - clock_str = " at [b]"+RNS.prettyfrequency(clock)+"[/b]" if clock != None else "" + clock_str = f" at [b]{RNS.prettyfrequency(clock)}[/b]" if clock != None else "" e_text = f"Using [b]{pct}%[/b] of {label}{clock_str}{avgs_str}" e_text = f"{label} use is [b]{pct}%[/b]{clock_str}{avgs_str}" @@ -650,7 +650,7 @@ def copy_info(e=None): speed_formatted_values = f"Object is [b]stationary[/b]" else: speed_formatted_values = None - extra_formatted_values = f"Uncertainty [b]{accuracy} meters[/b]"+updated_str + extra_formatted_values = f"Uncertainty [b]{accuracy} meters[/b]{updated_str}" data = {"icon": s["icon"], "text": f"{formatted_values}"} @@ -778,7 +778,7 @@ def lj(): except Exception as e: RNS.log("An error ocurred while displaying telemetry for object", RNS.LOG_ERROR) - RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR) + RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) RNS.trace_exception(e) try: @@ -816,7 +816,7 @@ def lj(): if ticket_expires: t_str = ", but have ticket" if stamp_cost: - self.entries.append({"icon": "postage-stamp", "text": f"Required stamp cost [b]{stamp_cost}[/b]"+t_str, "on_release": pass_job}) + self.entries.append({"icon": "postage-stamp", "text": f"Required stamp cost [b]{stamp_cost}[/b]{t_str}", "on_release": pass_job}) else: self.entries.append({"icon": "postage-stamp", "text": f"No required stamp cost", "on_release": pass_job}) if ticket_expires: @@ -834,7 +834,7 @@ def lj(): except Exception as e: import traceback exception_info = "".join(traceback.TracebackException.from_exception(e).format()) - RNS.log(f"An {str(type(e))} occurred while updating service telemetry: {str(e)}", RNS.LOG_ERROR) + RNS.log(f"An {type(e))} occurred while updating service telemetry: {e)}", RNS.LOG_ERROR) RNS.log(exception_info, RNS.LOG_ERROR) diff --git a/sbapp/ui/telemetry.py b/sbapp/ui/telemetry.py index 71858b5..60ab64f 100644 --- a/sbapp/ui/telemetry.py +++ b/sbapp/ui/telemetry.py @@ -99,7 +99,7 @@ def __init__(self, app): info += "Sideband will become a Telemetry Collector, and other authorized peers will be able to query its collected data.\n" if self.app.theme_cls.theme_style == "Dark": - info = "[color=#"+self.app.dark_theme_text_color+"]"+info+"[/color]" + info = f"[color=#{self.app.dark_theme_text_color}]{info}[/color]" self.screen.ids.telemetry_info.text = info @@ -118,7 +118,7 @@ def send_interval_change(sender=None, event=None, save=True): interval_text = RNS.prettytime(interval) if self.screen.ids.telemetry_send_to_collector.active: - self.screen.ids.telemetry_send_to_collector_label.text = "Auto sync to collector every "+interval_text + self.screen.ids.telemetry_send_to_collector_label.text = f"Auto sync to collector every {interval_text}" else: self.screen.ids.telemetry_send_to_collector_label.text = "Auto sync to collector" @@ -164,7 +164,7 @@ def request_interval_change(sender=None, event=None, save=True): interval_text = RNS.prettytime(interval) if self.screen.ids.telemetry_request_from_collector.active: - self.screen.ids.telemetry_request_from_collector_label.text = "Auto sync from collector every "+interval_text + self.screen.ids.telemetry_request_from_collector_label.text = f"Auto sync from collector every {interval_text}" else: self.screen.ids.telemetry_request_from_collector_label.text = "Auto sync from collector" @@ -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 = "[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 @@ -506,7 +506,7 @@ def telemetry_set_icon(self, text="", search=False): self.own_appearance_changed = True def icons_selected(self, selected=None): - RNS.log("Selected: "+str(selected)) + RNS.log(f"Selected: {selected)}") if selected == None: selected = "alpha-p-circle-outline" self.telemetry_set_icon(selected) diff --git a/setup.py b/setup.py index 35df592..1f1f6e7 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import setuptools from pathlib import Path -with open("README.md", "r") as fh: +with open("README.md") as fh: long_description = fh.read() def get_version() -> str: @@ -11,7 +11,7 @@ def get_version() -> str: os.path.dirname(__file__), "sbapp", "main.py" ) - version_file_data = open(version_file, "rt", encoding="utf-8").read() + version_file_data = open(version_file, encoding="utf-8").read() version_regex = r"(?<=^__version__ = ['\"])[^'\"]+(?=['\"]$)" try: version = re.findall(version_regex, version_file_data, re.M)[0] @@ -24,7 +24,7 @@ def get_variant() -> str: os.path.dirname(__file__), "sbapp", "main.py" ) - version_file_data = open(version_file, "rt", encoding="utf-8").read() + version_file_data = open(version_file, encoding="utf-8").read() version_regex = r"(?<=^__variant__ = ['\"])[^'\"]+(?=['\"]$)" try: version = re.findall(version_regex, version_file_data, re.M)[0] @@ -69,8 +69,8 @@ def glob_paths(pattern): variant_str = "" if __variant__: - variant_str = " "+__variant__ -print("Packaging Sideband "+__version__+variant_str) + variant_str = f" {__variant__}" +print(f"Packaging Sideband {__version__}{variant_str}") setuptools.setup( name="sbapp", From 236e0901fa9dc949891b851ac41ca531d19264d5 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Mon, 7 Oct 2024 11:17:22 +0200 Subject: [PATCH 2/2] remove dangling spaces --- docs/example_plugins/gpsd_location.py | 2 +- docs/example_plugins/view.py | 24 +-- docs/utilities/rns_audio_call_calc.py | 2 +- recipes/codec2/__init__.py | 2 +- recipes/opusfile/__init__.py | 2 +- recipes/pycodec2/__init__.py | 4 +- sbapp/kivymd/uix/chip/chip.py | 14 +- sbapp/main.py | 282 ++++++++++++------------- sbapp/mapview/downloader.py | 2 +- sbapp/mapview/view.py | 6 +- sbapp/patches/AndroidManifest.tmpl.xml | 4 +- sbapp/patches/PythonService.java | 4 +- sbapp/plyer/platforms/android/audio.py | 2 +- sbapp/plyer/platforms/linux/audio.py | 4 +- sbapp/plyer/platforms/macosx/audio.py | 2 +- sbapp/pydub/effects.py | 86 ++++---- sbapp/pydub/generators.py | 6 +- sbapp/pydub/scipy_effects.py | 32 +-- sbapp/pyogg/__init__.py | 8 +- sbapp/pyogg/audio_file.py | 10 +- sbapp/pyogg/flac.py | 40 ++-- sbapp/pyogg/flac_file.py | 2 +- sbapp/pyogg/library_loader.py | 20 +- sbapp/pyogg/ogg.py | 6 +- sbapp/pyogg/ogg_opus_writer.py | 8 +- sbapp/pyogg/opus.py | 40 ++-- sbapp/pyogg/opus_buffered_encoder.py | 20 +- sbapp/pyogg/opus_decoder.py | 10 +- sbapp/pyogg/opus_encoder.py | 24 +-- sbapp/pyogg/opus_file.py | 2 +- sbapp/pyogg/opus_file_stream.py | 2 +- sbapp/pyogg/vorbis.py | 30 +-- sbapp/pyogg/vorbis_file.py | 12 +- sbapp/pyogg/vorbis_file_stream.py | 2 +- sbapp/services/sidebandservice.py | 32 +-- sbapp/share/pkgs.html | 2 +- sbapp/sideband/audioproc.py | 12 +- sbapp/sideband/core.py | 174 +++++++-------- sbapp/sideband/geo.py | 12 +- sbapp/sideband/res.py | 62 +++--- sbapp/sideband/sense.py | 90 ++++---- sbapp/ui/announces.py | 10 +- sbapp/ui/conversations.py | 14 +- sbapp/ui/helpers.py | 2 +- sbapp/ui/layouts.py | 176 +++++++-------- sbapp/ui/messages.py | 32 +-- sbapp/ui/objectdetails.py | 56 ++--- sbapp/ui/telemetry.py | 94 ++++----- 48 files changed, 742 insertions(+), 742 deletions(-) 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/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"
%s
{complete_filename}