remove dangling spaces

This commit is contained in:
Pavol Rusnak 2024-10-07 11:17:22 +02:00
parent 2a13ed0921
commit 236e0901fa
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
48 changed files with 741 additions and 741 deletions

View File

@ -103,7 +103,7 @@ class GpsdLocationPlugin(SidebandTelemetryPlugin):
telemeter.sensors["location"].accuracy = self.accuracy telemeter.sensors["location"].accuracy = self.accuracy
telemeter.sensors["location"].stale_time = 5 telemeter.sensors["location"].stale_time = 5
telemeter.sensors["location"].set_update_time(self.last_update) telemeter.sensors["location"].set_update_time(self.last_update)
else: else:
RNS.log("No location from GPSd yet", RNS.LOG_DEBUG) RNS.log("No location from GPSd yet", RNS.LOG_DEBUG)

View File

@ -71,7 +71,7 @@ class ViewSource():
try: try:
if self.is_stale(): if self.is_stale():
self.update() self.update()
if self.source_data != None: if self.source_data != None:
max_dimension = quality_presets[preset]["max"] max_dimension = quality_presets[preset]["max"]
quality = quality_presets[preset]["quality"] quality = quality_presets[preset]["quality"]
@ -121,13 +121,13 @@ class CameraSource(ViewSource):
if not ret: if not ret:
self.camera_ready = False self.camera_ready = False
break break
if not self.frame_queue.empty(): if not self.frame_queue.empty():
try: try:
self.frame_queue.get_nowait() self.frame_queue.get_nowait()
except queue.Empty: except queue.Empty:
pass pass
self.frame_queue.put(frame) self.frame_queue.put(frame)
except Exception as e: except Exception as e:
@ -140,9 +140,9 @@ class CameraSource(ViewSource):
self.start_reading() self.start_reading()
while not self.camera_ready: while not self.camera_ready:
time.sleep(0.2) time.sleep(0.2)
retval, frame = self.camera.read() retval, frame = self.camera.read()
if not retval: if not retval:
self.source_data = None self.source_data = None
else: else:
@ -154,8 +154,8 @@ class CameraSource(ViewSource):
try: try:
self.camera.release() self.camera.release()
except: except:
pass pass
self.camera = None self.camera = None
self.camera_ready = False self.camera_ready = False
@ -185,14 +185,14 @@ class StreamSource(ViewSource):
if not ret: if not ret:
self.stream_ready = False self.stream_ready = False
else: else:
self.stream_ready = True self.stream_ready = True
if not self.frame_queue.empty(): if not self.frame_queue.empty():
if self.frame_queue.qsize() > 1: if self.frame_queue.qsize() > 1:
try: try:
self.frame_queue.get_nowait() self.frame_queue.get_nowait()
except queue.Empty: except queue.Empty:
pass pass
self.frame_queue.put(frame) self.frame_queue.put(frame)
RNS.log(f"{self)} idled", RNS.LOG_DEBUG) RNS.log(f"{self)} idled", RNS.LOG_DEBUG)
@ -220,8 +220,8 @@ class StreamSource(ViewSource):
try: try:
self.stream.release() self.stream.release()
except: except:
pass pass
self.stream = None self.stream = None
self.stream_ready = False self.stream_ready = False
@ -306,7 +306,7 @@ class ViewCommandPlugin(SidebandCommandPlugin):
if not source in self.sources: if not source in self.sources:
self.message_response("The specified view source does not exist on this system", requestor) self.message_response("The specified view source does not exist on this system", requestor)
else: else:
image_field = self.sources[source].get_image_field(quality_preset) image_field = self.sources[source].get_image_field(quality_preset)
image_timestamp = self.timestamp_str(self.sources[source].last_update) image_timestamp = self.timestamp_str(self.sources[source].last_update)

View File

@ -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) PAYLOAD_LATENCY = round(ENCRYPTED_PAYLOAD_LEN*PER_BYTE_LATENCY_MS, 1)
RAW_DATA_LATENCY = round(AUDIO_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) PACKING_LATENCY = round(PACKING_OVERHEAD*PER_BYTE_LATENCY_MS, 1)
DATA_LATENCY = round(ENCRYPTED_PAYLOAD_LEN*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) ENCRYPTION_LATENCY = round((ENCRYPTED_PAYLOAD_LEN-PL_LEN)*PER_BYTE_LATENCY_MS, 1)
if ENCRYPTED_PAYLOAD_LEN-PL_LEN == 1: if ENCRYPTED_PAYLOAD_LEN-PL_LEN == 1:

View File

@ -27,7 +27,7 @@ class Codec2Recipe(Recipe):
# variable `LIBS`''' # variable `LIBS`'''
# return ' -lcodec2{version} -lssl{version}'.format(version=self.version) # 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)): with current_directory(self.get_build_dir(arch.arch)):
env = self.get_recipe_env(arch) env = self.get_recipe_env(arch)
flags = [ flags = [

View File

@ -33,7 +33,7 @@ class OpusFileRecipe(Recipe):
# env['CFLAGS'] += openssl_recipe.include_flags(arch) # env['CFLAGS'] += openssl_recipe.include_flags(arch)
# env['LDFLAGS'] += openssl_recipe.link_dirs_flags(arch) # env['LDFLAGS'] += openssl_recipe.link_dirs_flags(arch)
# env['LIBS'] = openssl_recipe.link_libs_flags() # env['LIBS'] = openssl_recipe.link_libs_flags()
from rich.pretty import pprint from rich.pretty import pprint
pprint(env) pprint(env)
time.sleep(5) time.sleep(5)

View File

@ -21,7 +21,7 @@ class PyCodec2Recipe(CythonRecipe):
env['LDFLAGS'] += f' -L{self.ctx.get_libs_dir(arch.arch)}' env['LDFLAGS'] += f' -L{self.ctx.get_libs_dir(arch.arch)}'
env['LDFLAGS'] += f' -L{self.ctx.libs_dir}' env['LDFLAGS'] += f' -L{self.ctx.libs_dir}'
env['LDFLAGS'] += codec2_recipe.link_dirs_flags(arch) env['LDFLAGS'] += codec2_recipe.link_dirs_flags(arch)
return env return env
def build_arch(self, arch): def build_arch(self, arch):
@ -32,7 +32,7 @@ class PyCodec2Recipe(CythonRecipe):
# print(arch) # print(arch)
# shprint(sh.Command("pwd")) # shprint(sh.Command("pwd"))
# shprint(sh.Command("ls")) # 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"] # 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) # shprint(sh.Command("patchelf"), *pe_args)

View File

@ -294,18 +294,18 @@ Example of filtering
orientation: "vertical" orientation: "vertical"
''' '''
) )
class CustomOneLineIconListItem(OneLineIconListItem): class CustomOneLineIconListItem(OneLineIconListItem):
icon = StringProperty() icon = StringProperty()
class PreviewIconsScreen(MDScreen): class PreviewIconsScreen(MDScreen):
filter = ListProperty() # list of tags for filtering icons filter = ListProperty() # list of tags for filtering icons
def set_filter_chips(self): def set_filter_chips(self):
'''Asynchronously creates and adds chips to the container.''' '''Asynchronously creates and adds chips to the container.'''
async def set_filter_chips(): async def set_filter_chips():
for tag in ["Outline", "Off", "On"]: for tag in ["Outline", "Off", "On"]:
await asynckivy.sleep(0) await asynckivy.sleep(0)
@ -318,7 +318,7 @@ Example of filtering
) )
chip.bind(active=lambda x, y, z=tag: self.set_filter(y, z)) chip.bind(active=lambda x, y, z=tag: self.set_filter(y, z))
self.ids.chip_box.add_widget(chip) self.ids.chip_box.add_widget(chip)
asynckivy.start(set_filter_chips()) asynckivy.start(set_filter_chips())
def set_filter(self, active: bool, tag: str) -> None: def set_filter(self, active: bool, tag: str) -> None:

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,7 @@ class Downloader:
logging.getLogger("urllib3.connection").setLevel(logging.WARNING) logging.getLogger("urllib3.connection").setLevel(logging.WARNING)
logging.getLogger("urllib3.connectionpool").setLevel(logging.WARNING) logging.getLogger("urllib3.connectionpool").setLevel(logging.WARNING)
logging.getLogger("requests").setLevel(logging.WARNING) logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").propagate = True logging.getLogger("urllib3").propagate = True
logging.getLogger("requests").propagate = True logging.getLogger("requests").propagate = True
logging.getLogger("urllib3.response").propagate = True logging.getLogger("urllib3.response").propagate = True

View File

@ -721,7 +721,7 @@ class MapView(Widget):
if int_diff < 0.08: if int_diff < 0.08:
target = scatter.scale-diff target = scatter.scale-diff
factor = target/scatter.scale factor = target/scatter.scale
scatter.apply_transform( scatter.apply_transform(
Matrix().scale(factor, factor, factor), Matrix().scale(factor, factor, factor),
post_multiply=True, post_multiply=True,
@ -746,7 +746,7 @@ class MapView(Widget):
d = 1 if touch.button == "scrolldown" else -1 d = 1 if touch.button == "scrolldown" else -1
else: else:
d = 0.1 if touch.button == "scrolldown" else -0.1 d = 0.1 if touch.button == "scrolldown" else -0.1
self.animated_diff_scale_at(d, *touch.pos) self.animated_diff_scale_at(d, *touch.pos)
return True return True
elif touch.is_double_tap and self.double_tap_zoom: elif touch.is_double_tap and self.double_tap_zoom:
@ -793,7 +793,7 @@ class MapView(Widget):
zoom = self._zoom zoom = self._zoom
scatter = self._scatter scatter = self._scatter
scale = scatter.scale scale = scatter.scale
if self.high_res: if self.high_res:
if self.high_res_mode == 2: if self.high_res_mode == 2:
# Double resolution mode # Double resolution mode

View File

@ -75,7 +75,7 @@
> >
<intent-filter> <intent-filter>
{% if args.launcher %} {% if args.launcher %}
<action android:name="org.kivy.LAUNCH" /> <action android:name="org.kivy.LAUNCH" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:scheme="{{ url_scheme }}" /> <data android:scheme="{{ url_scheme }}" />
@ -146,7 +146,7 @@
<!-- ressource file to create --> <!-- ressource file to create -->
<meta-data <meta-data
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"> android:resource="@xml/file_paths">
</meta-data> </meta-data>
</provider> </provider>
</application> </application>

View File

@ -132,9 +132,9 @@ public class PythonService extends Service implements Runnable {
// https://stackoverflow.com/questions/47531742/startforeground-fail-after-upgrade-to-android-8-1 // https://stackoverflow.com/questions/47531742/startforeground-fail-after-upgrade-to-android-8-1
String NOTIFICATION_CHANNEL_ID = "io.unsigned.sideband.reticulum"; String NOTIFICATION_CHANNEL_ID = "io.unsigned.sideband.reticulum";
String channelName = "Background Service"; String channelName = "Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName,
NotificationManager.IMPORTANCE_NONE); NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE); chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_SECRET); chan.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
chan.setShowBadge(false); chan.setShowBadge(false);

View File

@ -37,7 +37,7 @@ class AndroidAudio(Audio):
time.sleep(0.25) time.sleep(0.25)
self.is_playing = False self.is_playing = False
if self._finished_callback and callable(self._finished_callback): if self._finished_callback and callable(self._finished_callback):
self._check_thread = None self._check_thread = None
self._finished_callback(self) self._finished_callback(self)

View File

@ -34,7 +34,7 @@ class LinuxAudio(Audio):
run = False run = False
self.is_playing = False self.is_playing = False
if self._finished_callback and callable(self._finished_callback): if self._finished_callback and callable(self._finished_callback):
self._check_thread = None self._check_thread = None
self._finished_callback(self) self._finished_callback(self)
@ -52,7 +52,7 @@ class LinuxAudio(Audio):
frame_duration = frame_duration_ms/1000 frame_duration = frame_duration_ms/1000
frame_size = int(frame_duration * samples_per_second) frame_size = int(frame_duration * samples_per_second)
bytes_per_frame = frame_size*bytes_per_sample bytes_per_frame = frame_size*bytes_per_sample
read_bytes = 0 read_bytes = 0
pcm_buf = b"" pcm_buf = b""
should_continue = True should_continue = True

View File

@ -41,7 +41,7 @@ class OSXAudio(Audio):
def _check_playback(self): def _check_playback(self):
while self._player and self._player.isPlaying: while self._player and self._player.isPlaying:
time.sleep(0.25) time.sleep(0.25)
if self._finished_callback and callable(self._finished_callback): if self._finished_callback and callable(self._finished_callback):
self._check_thread = None self._check_thread = None
self._finished_callback(self) self._finished_callback(self)

View File

@ -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) headroom is how close to the maximum volume to boost the signal up to (specified in dB)
""" """
peak_sample_val = seg.max peak_sample_val = seg.max
# if the max is 0, this audio segment is silent, and can't be normalized # if the max is 0, this audio segment is silent, and can't be normalized
if peak_sample_val == 0: if peak_sample_val == 0:
return seg return seg
target_peak = seg.max_possible_amplitude * db_to_float(-headroom) target_peak = seg.max_possible_amplitude * db_to_float(-headroom)
needed_boost = ratio_to_db(target_peak / peak_sample_val) 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 out += last_chunk
return out return out
@register_pydub_effect @register_pydub_effect
def strip_silence(seg, silence_len=1000, silence_thresh=-16, padding=100): 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): def compress_dynamic_range(seg, threshold=-20.0, ratio=4.0, attack=5.0, release=50.0):
""" """
Keyword Arguments: Keyword Arguments:
threshold - default: -20.0 threshold - default: -20.0
Threshold in dBFS. default of -20.0 means -20dB relative to the Threshold in dBFS. default of -20.0 means -20dB relative to the
maximum possible volume. 0dBFS is the maximum possible value so maximum possible volume. 0dBFS is the maximum possible value so
all values for this argument sould be negative. all values for this argument sould be negative.
ratio - default: 4.0 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 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. a setting of 4:1 in a pro-audio compressor like the Waves C1.
attack - default: 5.0 attack - default: 5.0
Attack in milliseconds. How long it should take for the compressor Attack in milliseconds. How long it should take for the compressor
to kick in once the audio has exceeded the threshold. 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 Release in milliseconds. How long it should take for the compressor
to stop compressing after the audio has falled below the threshold. to stop compressing after the audio has falled below the threshold.
For an overview of Dynamic Range Compression, and more detailed explanation 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 http://en.wikipedia.org/wiki/Dynamic_range_compression
""" """
thresh_rms = seg.max_possible_amplitude * db_to_float(threshold) thresh_rms = seg.max_possible_amplitude * db_to_float(threshold)
look_frames = int(seg.frame_count(ms=attack)) look_frames = int(seg.frame_count(ms=attack))
def rms_at(frame_i): def rms_at(frame_i):
return seg.get_sample_slice(frame_i - look_frames, frame_i).rms return seg.get_sample_slice(frame_i - look_frames, frame_i).rms
@ -155,34 +155,34 @@ def compress_dynamic_range(seg, threshold=-20.0, ratio=4.0, attack=5.0, release=
# amount to reduce the volume of the audio by (in dB) # amount to reduce the volume of the audio by (in dB)
attenuation = 0.0 attenuation = 0.0
attack_frames = seg.frame_count(ms=attack) attack_frames = seg.frame_count(ms=attack)
release_frames = seg.frame_count(ms=release) release_frames = seg.frame_count(ms=release)
for i in xrange(int(seg.frame_count())): for i in xrange(int(seg.frame_count())):
rms_now = rms_at(i) rms_now = rms_at(i)
# with a ratio of 4.0 this means the volume will exceed the threshold by # 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 # 1/4 the amount (of dB) that it would otherwise
max_attenuation = (1 - (1.0 / ratio)) * db_over_threshold(rms_now) max_attenuation = (1 - (1.0 / ratio)) * db_over_threshold(rms_now)
attenuation_inc = max_attenuation / attack_frames attenuation_inc = max_attenuation / attack_frames
attenuation_dec = max_attenuation / release_frames attenuation_dec = max_attenuation / release_frames
if rms_now > thresh_rms and attenuation <= max_attenuation: if rms_now > thresh_rms and attenuation <= max_attenuation:
attenuation += attenuation_inc attenuation += attenuation_inc
attenuation = min(attenuation, max_attenuation) attenuation = min(attenuation, max_attenuation)
else: else:
attenuation -= attenuation_dec attenuation -= attenuation_dec
attenuation = max(attenuation, 0) attenuation = max(attenuation, 0)
frame = seg.get_frame(i) frame = seg.get_frame(i)
if attenuation != 0.0: if attenuation != 0.0:
frame = audioop.mul(frame, frame = audioop.mul(frame,
seg.sample_width, seg.sample_width,
db_to_float(-attenuation)) db_to_float(-attenuation))
output.append(frame) output.append(frame)
return seg._spawn(data=b''.join(output)) 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. Note that mono AudioSegments will become stereo.
""" """
if channels == (1, 1): 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) return seg._spawn(data=inverted)
else: else:
if seg.channels == 2: if seg.channels == 2:
left, right = seg.split_to_mono() left, right = seg.split_to_mono()
else: else:
raise Exception(f"Can't implicitly convert an AudioSegment with {seg.channels)} channels to stereo.") 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() left = left.invert_phase()
else: else:
right = right.invert_phase() right = right.invert_phase()
return seg.from_mono_audiosegments(left, right) return seg.from_mono_audiosegments(left, right)
# High and low pass filters based on implementation found on Stack Overflow: # 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 dt = 1.0 / seg.frame_rate
alpha = dt / (RC + dt) alpha = dt / (RC + dt)
original = seg.get_array_of_samples() original = seg.get_array_of_samples()
filteredArray = array.array(seg.array_type, original) filteredArray = array.array(seg.array_type, original)
frame_count = int(seg.frame_count()) frame_count = int(seg.frame_count())
last_val = [0] * seg.channels last_val = [0] * seg.channels
@ -258,10 +258,10 @@ def high_pass_filter(seg, cutoff):
alpha = RC / (RC + dt) alpha = RC / (RC + dt)
minval, maxval = get_min_max_value(seg.sample_width * 8) minval, maxval = get_min_max_value(seg.sample_width * 8)
original = seg.get_array_of_samples() original = seg.get_array_of_samples()
filteredArray = array.array(seg.array_type, original) filteredArray = array.array(seg.array_type, original)
frame_count = int(seg.frame_count()) frame_count = int(seg.frame_count())
last_val = [0] * seg.channels 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)) filteredArray[offset] = int(min(max(last_val[j], minval), maxval))
return seg._spawn(data=filteredArray) return seg._spawn(data=filteredArray)
@register_pydub_effect @register_pydub_effect
def pan(seg, pan_amount): def pan(seg, pan_amount):
""" """
pan_amount should be between -1.0 (100% left) and +1.0 (100% right) 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. When pan_amount == 0.0 the left/right balance is not changed.
Panning does not alter the *perceived* loundness, but since loudness Panning does not alter the *perceived* loundness, but since loudness
is decreasing on one side, the other side needs to get louder to 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. compensate. When panned hard left, the left channel will be 3dB louder.
""" """
if not -1.0 <= pan_amount <= 1.0: if not -1.0 <= pan_amount <= 1.0:
raise ValueError("pan_amount should be between -1.0 (100% left) and +1.0 (100% right)") raise ValueError("pan_amount should be between -1.0 (100% left) and +1.0 (100% right)")
max_boost_db = ratio_to_db(2.0) max_boost_db = ratio_to_db(2.0)
boost_db = abs(pan_amount) * max_boost_db boost_db = abs(pan_amount) * max_boost_db
boost_factor = db_to_float(boost_db) boost_factor = db_to_float(boost_db)
reduce_factor = db_to_float(max_boost_db) - boost_factor reduce_factor = db_to_float(max_boost_db) - boost_factor
reduce_db = ratio_to_db(reduce_factor) reduce_db = ratio_to_db(reduce_factor)
# Cut boost in half (max boost== 3dB) - in reality 2 speakers # Cut boost in half (max boost== 3dB) - in reality 2 speakers
# do not sum to a full 6 dB. # do not sum to a full 6 dB.
boost_db = boost_db / 2.0 boost_db = boost_db / 2.0
if pan_amount < 0: if pan_amount < 0:
return seg.apply_gain_stereo(boost_db, reduce_db) return seg.apply_gain_stereo(boost_db, reduce_db)
else: else:
return seg.apply_gain_stereo(reduce_db, boost_db) return seg.apply_gain_stereo(reduce_db, boost_db)
@register_pydub_effect @register_pydub_effect
def apply_gain_stereo(seg, left_gain=0.0, right_gain=0.0): 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) 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) right_gain - amount of gain to apply to the right channel (in dB)
note: mono audio segments will be converted to stereo note: mono audio segments will be converted to stereo
""" """
if seg.channels == 1: if seg.channels == 1:
left = right = seg left = right = seg
elif seg.channels == 2: elif seg.channels == 2:
left, right = seg.split_to_mono() left, right = seg.split_to_mono()
l_mult_factor = db_to_float(left_gain) l_mult_factor = db_to_float(left_gain)
r_mult_factor = db_to_float(right_gain) r_mult_factor = db_to_float(right_gain)
left_data = audioop.mul(left._data, left.sample_width, l_mult_factor) left_data = audioop.mul(left._data, left.sample_width, l_mult_factor)
left_data = audioop.tostereo(left_data, left.sample_width, 1, 0) 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.mul(right._data, right.sample_width, r_mult_factor)
right_data = audioop.tostereo(right_data, right.sample_width, 0, 1) right_data = audioop.tostereo(right_data, right.sample_width, 0, 1)
output = audioop.add(left_data, right_data, seg.sample_width) output = audioop.add(left_data, right_data, seg.sample_width)
return seg._spawn(data=output, return seg._spawn(data=output,
overrides={'channels': 2, overrides={'channels': 2,
'frame_width': 2 * seg.sample_width}) 'frame_width': 2 * seg.sample_width})

View File

@ -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 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). 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 here: http://en.wikipedia.org/wiki/Waveform
""" """
@ -44,7 +44,7 @@ class SignalGenerator:
sample_data = itertools.islice(sample_data, 0, sample_count) sample_data = itertools.islice(sample_data, 0, sample_count)
data = array.array(array_type, sample_data) data = array.array(array_type, sample_data)
try: try:
data = data.tobytes() data = data.tobytes()
except: except:

View File

@ -72,30 +72,30 @@ def _eq(seg, focus_freq, bandwidth=100, mode="peak", gain_dB=0, order=2):
bandwidth - range of the equalizer band bandwidth - range of the equalizer band
mode - Mode of Equalization(Peak/Notch(Bell Curve),High Shelf, Low Shelf) mode - Mode of Equalization(Peak/Notch(Bell Curve),High Shelf, Low Shelf)
order - Rolloff factor(1 - 6dB/Octave 2 - 12dB/Octave) order - Rolloff factor(1 - 6dB/Octave 2 - 12dB/Octave)
Returns: Returns:
Equalized/Filtered AudioSegment Equalized/Filtered AudioSegment
""" """
filt_mode = ["peak", "low_shelf", "high_shelf"] filt_mode = ["peak", "low_shelf", "high_shelf"]
if mode not in filt_mode: if mode not in filt_mode:
raise ValueError("Incorrect Mode Selection") raise ValueError("Incorrect Mode Selection")
if gain_dB >= 0: if gain_dB >= 0:
if mode == "peak": if mode == "peak":
sec = band_pass_filter(seg, focus_freq - bandwidth/2, focus_freq + bandwidth/2, order = order) sec = band_pass_filter(seg, focus_freq - bandwidth/2, focus_freq + bandwidth/2, order = order)
seg = seg.overlay(sec - (3 - gain_dB)) seg = seg.overlay(sec - (3 - gain_dB))
return seg return seg
if mode == "low_shelf": if mode == "low_shelf":
sec = low_pass_filter(seg, focus_freq, order=order) sec = low_pass_filter(seg, focus_freq, order=order)
seg = seg.overlay(sec - (3 - gain_dB)) seg = seg.overlay(sec - (3 - gain_dB))
return seg return seg
if mode == "high_shelf": if mode == "high_shelf":
sec = high_pass_filter(seg, focus_freq, order=order) sec = high_pass_filter(seg, focus_freq, order=order)
seg = seg.overlay(sec - (3 - gain_dB)) seg = seg.overlay(sec - (3 - gain_dB))
return seg return seg
if gain_dB < 0: if gain_dB < 0:
if mode == "peak": if mode == "peak":
sec = high_pass_filter(seg, focus_freq - bandwidth/2, order=order) 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) sec = low_pass_filter(seg, focus_freq + bandwidth/2, order=order)
seg = seg.overlay(sec - (3 + gain_dB)) + gain_dB seg = seg.overlay(sec - (3 + gain_dB)) + gain_dB
return seg return seg
if mode == "low_shelf": if mode == "low_shelf":
sec = high_pass_filter(seg, focus_freq, order=order) sec = high_pass_filter(seg, focus_freq, order=order)
seg = seg.overlay(sec - (3 + gain_dB)) + gain_dB seg = seg.overlay(sec - (3 + gain_dB)) + gain_dB
return seg return seg
if mode=="high_shelf": if mode=="high_shelf":
sec=low_pass_filter(seg, focus_freq, order=order) sec=low_pass_filter(seg, focus_freq, order=order)
seg=seg.overlay(sec - (3 + gain_dB)) +gain_dB seg=seg.overlay(sec - (3 + gain_dB)) +gain_dB
return seg return seg
@register_pydub_effect @register_pydub_effect
def eq(seg, focus_freq, bandwidth=100, channel_mode="L+R", filter_mode="peak", gain_dB=0, order=2): 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. Mono Audio Segments are completely filtered.
filter_mode - Mode of Equalization(Peak/Notch(Bell Curve),High Shelf, Low Shelf) filter_mode - Mode of Equalization(Peak/Notch(Bell Curve),High Shelf, Low Shelf)
order - Rolloff factor(1 - 6dB/Octave 2 - 12dB/Octave) order - Rolloff factor(1 - 6dB/Octave 2 - 12dB/Octave)
Returns: Returns:
Equalized/Filtered AudioSegment Equalized/Filtered AudioSegment
""" """
channel_modes = ["L+R", "M+S", "L", "R", "M", "S"] channel_modes = ["L+R", "M+S", "L", "R", "M", "S"]
if channel_mode not in channel_modes: if channel_mode not in channel_modes:
raise ValueError("Incorrect Channel Mode Selection") raise ValueError("Incorrect Channel Mode Selection")
if seg.channels == 1: if seg.channels == 1:
return _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order) return _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order)
if channel_mode == "L+R": if channel_mode == "L+R":
return _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order) return _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order)
if channel_mode == "L": if channel_mode == "L":
seg = seg.split_to_mono() seg = seg.split_to_mono()
seg = [_eq(seg[0], focus_freq, bandwidth, filter_mode, gain_dB, order), seg[1]] seg = [_eq(seg[0], focus_freq, bandwidth, filter_mode, gain_dB, order), seg[1]]
return AudioSegment.from_mono_audio_segements(seg[0], seg[1]) return AudioSegment.from_mono_audio_segements(seg[0], seg[1])
if channel_mode == "R": if channel_mode == "R":
seg = seg.split_to_mono() seg = seg.split_to_mono()
seg = [seg[0], _eq(seg[1], focus_freq, bandwidth, filter_mode, gain_dB, order)] seg = [seg[0], _eq(seg[1], focus_freq, bandwidth, filter_mode, gain_dB, order)]
return AudioSegment.from_mono_audio_segements(seg[0], seg[1]) return AudioSegment.from_mono_audio_segements(seg[0], seg[1])
if channel_mode == "M+S": if channel_mode == "M+S":
seg = stereo_to_ms(seg) seg = stereo_to_ms(seg)
seg = _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order) seg = _eq(seg, focus_freq, bandwidth, filter_mode, gain_dB, order)
return ms_to_stereo(seg) return ms_to_stereo(seg)
if channel_mode == "M": if channel_mode == "M":
seg = stereo_to_ms(seg).split_to_mono() seg = stereo_to_ms(seg).split_to_mono()
seg = [_eq(seg[0], focus_freq, bandwidth, filter_mode, gain_dB, order), seg[1]] seg = [_eq(seg[0], focus_freq, bandwidth, filter_mode, gain_dB, order), seg[1]]
seg = AudioSegment.from_mono_audio_segements(seg[0], seg[1]) seg = AudioSegment.from_mono_audio_segements(seg[0], seg[1])
return ms_to_stereo(seg) return ms_to_stereo(seg)
if channel_mode == "S": if channel_mode == "S":
seg = stereo_to_ms(seg).split_to_mono() seg = stereo_to_ms(seg).split_to_mono()
seg = [seg[0], _eq(seg[1], focus_freq, bandwidth, filter_mode, gain_dB, order)] seg = [seg[0], _eq(seg[1], focus_freq, bandwidth, filter_mode, gain_dB, order)]

View File

@ -76,22 +76,22 @@ else:
class OpusBufferedEncoder: # type: ignore class OpusBufferedEncoder: # type: ignore
def __init__(*args, **kw): 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?)") 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 class OpusDecoder: # type: ignore
def __init__(*args, **kw): 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?)") 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 # OggOpusWriter
from .ogg_opus_writer import OggOpusWriter from .ogg_opus_writer import OggOpusWriter
else: else:
class OggOpusWriter: # type: ignore class OggOpusWriter: # type: ignore
def __init__(*args, **kw): def __init__(*args, **kw):
if not PYOGG_OGG_AVAIL: 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 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?)") 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: if PYOGG_FLAC_AVAIL:
# FlacFile # FlacFile

View File

@ -9,8 +9,8 @@ class AudioFile:
def __init__(self): def __init__(self):
raise PyOggError("AudioFile is an Abstract Base Class "+ raise PyOggError("AudioFile is an Abstract Base Class "+
"and should not be instantiated") "and should not be instantiated")
def as_array(self): def as_array(self):
"""Returns the buffer as a NumPy array. """Returns the buffer as a NumPy array.
@ -26,9 +26,9 @@ class AudioFile:
""" """
# Assumes that self.buffer is a one-dimensional array of # Assumes that self.buffer is a one-dimensional array of
# bytes and that channels are interleaved. # bytes and that channels are interleaved.
import numpy # type: ignore import numpy # type: ignore
assert self.buffer is not None assert self.buffer is not None
assert self.channels is not None assert self.channels is not None
@ -43,7 +43,7 @@ class AudioFile:
1: numpy.int8, 1: numpy.int8,
2: numpy.int16 2: numpy.int16
} }
# Convert the ctypes buffer to a NumPy array # Convert the ctypes buffer to a NumPy array
array = numpy.frombuffer( array = numpy.frombuffer(
self.buffer, self.buffer,

View File

@ -64,7 +64,7 @@ if libflac:
PYOGG_FLAC_AVAIL = True PYOGG_FLAC_AVAIL = True
else: else:
PYOGG_FLAC_AVAIL = False PYOGG_FLAC_AVAIL = False
# ctypes # ctypes
c_ubyte_p = POINTER(c_ubyte) c_ubyte_p = POINTER(c_ubyte)
c_uchar_p = c_ubyte_p c_uchar_p = c_ubyte_p
@ -76,7 +76,7 @@ c_off_t = c_int32
if PYOGG_FLAC_AVAIL: if PYOGG_FLAC_AVAIL:
# Sanity check also satisfies mypy type checking # Sanity check also satisfies mypy type checking
assert libflac is not None assert libflac is not None
# ordinals # ordinals
FLAC__int8 = c_int8 FLAC__int8 = c_int8
@ -170,7 +170,7 @@ if PYOGG_FLAC_AVAIL:
FLAC__EntropyCodingMethodType = c_int FLAC__EntropyCodingMethodType = c_int
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0 FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0
FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1
@ -272,10 +272,10 @@ if PYOGG_FLAC_AVAIL:
_fields_ = [("type", FLAC__SubframeType), _fields_ = [("type", FLAC__SubframeType),
("data", FLAC__Subframe_data), ("data", FLAC__Subframe_data),
("wasted_bits", c_uint)] ("wasted_bits", c_uint)]
FLAC__SUBFRAME_ZERO_PAD_LEN = c_uint.in_dll(libflac, "FLAC__SUBFRAME_ZERO_PAD_LEN") 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_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") FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = c_uint.in_dll(libflac, "FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN")
@ -327,7 +327,7 @@ if PYOGG_FLAC_AVAIL:
("number_type", FLAC__FrameNumberType), ("number_type", FLAC__FrameNumberType),
("number", FLAC__FrameHeader_number), ("number", FLAC__FrameHeader_number),
("crc", FLAC__uint8)] ("crc", FLAC__uint8)]
FLAC__FRAME_HEADER_SYNC = c_uint.in_dll(libflac, "FLAC__FRAME_HEADER_SYNC") FLAC__FRAME_HEADER_SYNC = c_uint.in_dll(libflac, "FLAC__FRAME_HEADER_SYNC")
@ -360,7 +360,7 @@ if PYOGG_FLAC_AVAIL:
_fields_ = [("header", FLAC__FrameHeader), _fields_ = [("header", FLAC__FrameHeader),
("subframes", FLAC__Subframe * FLAC__MAX_CHANNELS), ("subframes", FLAC__Subframe * FLAC__MAX_CHANNELS),
("footer", FLAC__FrameFooter)] ("footer", FLAC__FrameFooter)]
FLAC__MetadataType = c_int FLAC__MetadataType = c_int
@ -435,7 +435,7 @@ if PYOGG_FLAC_AVAIL:
("data", FLAC__byte_p)] ("data", FLAC__byte_p)]
FLAC__STREAM_METADATA_APPLICATION_ID_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_APPLICATION_ID_LEN") FLAC__STREAM_METADATA_APPLICATION_ID_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_APPLICATION_ID_LEN")
class FLAC__StreamMetadata_SeekPoint(Structure): class FLAC__StreamMetadata_SeekPoint(Structure):
_fields_ = [("sample_number", FLAC__uint64), _fields_ = [("sample_number", FLAC__uint64),
@ -475,10 +475,10 @@ if PYOGG_FLAC_AVAIL:
class FLAC__StreamMetadata_CueSheet_Index(Structure): class FLAC__StreamMetadata_CueSheet_Index(Structure):
_fields_ = [("offset", FLAC__uint64), _fields_ = [("offset", FLAC__uint64),
("number", FLAC__byte)] ("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_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_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") FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN")
@ -494,7 +494,7 @@ if PYOGG_FLAC_AVAIL:
("indices", POINTER(FLAC__StreamMetadata_CueSheet_Index))] ("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_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_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") FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN")
@ -516,7 +516,7 @@ if PYOGG_FLAC_AVAIL:
("tracks", POINTER(FLAC__StreamMetadata_CueSheet_Track))] ("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_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") FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN")
@ -584,7 +584,7 @@ if PYOGG_FLAC_AVAIL:
FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_PICTURE_COLORS_LEN") FLAC__STREAM_METADATA_PICTURE_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): class FLAC__StreamMetadata_Unknown(Structure):
@ -608,7 +608,7 @@ if PYOGG_FLAC_AVAIL:
("data", FLAC__StreamMetadata_data)] ("data", FLAC__StreamMetadata_data)]
FLAC__STREAM_METADATA_IS_LAST_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_IS_LAST_LEN") 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_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") FLAC__STREAM_METADATA_LENGTH_LEN = c_uint.in_dll(libflac, "FLAC__STREAM_METADATA_LENGTH_LEN")
@ -798,7 +798,7 @@ if PYOGG_FLAC_AVAIL:
def FLAC__metadata_simple_iterator_get_block(iterator): def FLAC__metadata_simple_iterator_get_block(iterator):
return libflac.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.restype = FLAC__bool
libflac.FLAC__metadata_simple_iterator_set_block.argtypes = [POINTER(FLAC__Metadata_SimpleIterator), POINTER(FLAC__StreamMetadata), FLAC__bool] libflac.FLAC__metadata_simple_iterator_set_block.argtypes = [POINTER(FLAC__Metadata_SimpleIterator), POINTER(FLAC__StreamMetadata), FLAC__bool]
@ -819,7 +819,7 @@ if PYOGG_FLAC_AVAIL:
class FLAC__Metadata_Chain(Structure): class FLAC__Metadata_Chain(Structure):
_fields_ = [("dummy", c_int)] _fields_ = [("dummy", c_int)]
class FLAC__Metadata_Iterator(Structure): class FLAC__Metadata_Iterator(Structure):
_fields_ = [("dummy", c_int)] _fields_ = [("dummy", c_int)]
@ -1261,13 +1261,13 @@ if PYOGG_FLAC_AVAIL:
FLAC__StreamDecoderStateEnum = ["FLAC__STREAM_DECODER_SEARCH_FOR_METADATA", FLAC__StreamDecoderStateEnum = ["FLAC__STREAM_DECODER_SEARCH_FOR_METADATA",
"FLAC__STREAM_DECODER_READ_METADATA", "FLAC__STREAM_DECODER_READ_METADATA",
"FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC", "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_END_OF_STREAM",
"FLAC__STREAM_DECODER_OGG_ERROR", "FLAC__STREAM_DECODER_OGG_ERROR",
"FLAC__STREAM_DECODER_SEEK_ERROR", "FLAC__STREAM_DECODER_SEEK_ERROR",
"FLAC__STREAM_DECODER_ABORTED", "FLAC__STREAM_DECODER_ABORTED",
"FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR", "FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
"FLAC__STREAM_DECODER_UNINITIALIZED"] "FLAC__STREAM_DECODER_UNINITIALIZED"]
libflac.FLAC__StreamDecoderStateString.restype = c_char_p libflac.FLAC__StreamDecoderStateString.restype = c_char_p
libflac.FLAC__StreamDecoderStateString.argtypes = [] libflac.FLAC__StreamDecoderStateString.argtypes = []
@ -1280,7 +1280,7 @@ if PYOGG_FLAC_AVAIL:
FLAC__StreamDecoderInitStatusEnum = ["FLAC__STREAM_DECODER_INIT_STATUS_OK", FLAC__StreamDecoderInitStatusEnum = ["FLAC__STREAM_DECODER_INIT_STATUS_OK",
"FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER", "FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER",
"FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS", "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_ERROR_OPENING_FILE",
"FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED"] "FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED"]

View File

@ -107,7 +107,7 @@ class FlacFile(AudioFile):
ctypes.c_byte * ctypes.c_byte *
(self.bytes_per_sample * len(self.buffer)) (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 # FLAC audio is always signed. See
# https://xiph.org/flac/api/group__flac__stream__decoder.html#gaf98a4f9e2cac5747da6018c3dfc8dde1 # https://xiph.org/flac/api/group__flac__stream__decoder.html#gaf98a4f9e2cac5747da6018c3dfc8dde1

View File

@ -24,7 +24,7 @@ if architecture == "32bit":
for arch_style in ["32bit", "32" "86", "win32", "x86", "_x86", "_32", "_win32", "_32bit"]: for arch_style in ["32bit", "32" "86", "win32", "x86", "_x86", "_32", "_win32", "_32bit"]:
for style in ["{}", "lib{}"]: for style in ["{}", "lib{}"]:
_windows_styles.append(style.format(f"{{}}{arch_style}")) _windows_styles.append(style.format(f"{{}}{arch_style}"))
elif architecture == "64bit": elif architecture == "64bit":
for arch_style in ["64bit", "64" "86_64", "amd64", "win_amd64", "x86_64", "_x86_64", "_64", "_amd64", "_64bit"]: for arch_style in ["64bit", "64" "86_64", "amd64", "win_amd64", "x86_64", "_x86_64", "_64", "_amd64", "_64bit"]:
for style in ["{}", "lib{}"]: for style in ["{}", "lib{}"]:
@ -33,7 +33,7 @@ elif architecture == "64bit":
run_tests = lambda lib, tests: [f(lib) for f in tests] 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 # on the current platform and architecture
platform_ = platform.system() platform_ = platform.system()
lib_dir = None lib_dir = None
@ -53,7 +53,7 @@ class Library:
if lib is None: if lib is None:
lib = ExternalLibrary.load(names["external"], paths, tests) lib = ExternalLibrary.load(names["external"], paths, tests)
return lib return lib
class InternalLibrary: class InternalLibrary:
@staticmethod @staticmethod
@ -61,7 +61,7 @@ class InternalLibrary:
# If we do not have a library directory, give up immediately # If we do not have a library directory, give up immediately
if lib_dir is None: if lib_dir is None:
return None return None
# Get the appropriate library filename given the platform # Get the appropriate library filename given the platform
try: try:
name = names[platform_] name = names[platform_]
@ -69,7 +69,7 @@ class InternalLibrary:
return None return None
# Attempt to load the library from here # Attempt to load the library from here
path = f"{_here}/{lib_dir}/{name}" path = f"{_here}/{lib_dir}/{name}"
try: try:
lib = ctypes.CDLL(path) lib = ctypes.CDLL(path)
except OSError as e: except OSError as e:
@ -81,7 +81,7 @@ class InternalLibrary:
# Library failed tests # Library failed tests
return None return None
# Cache of libraries that have already been loaded # Cache of libraries that have already been loaded
_loaded_libraries: Dict[str, ctypes.CDLL] = {} _loaded_libraries: Dict[str, ctypes.CDLL] = {}
@ -119,7 +119,7 @@ class ExternalLibrary:
def load_windows(name, paths = None, tests = []): def load_windows(name, paths = None, tests = []):
os.environ["PATH"] += f";{f"{os.getcwd()};{_here}"}" os.environ["PATH"] += f";{f"{os.getcwd()};{_here}"}"
if paths: os.environ["PATH"] += f";{';'.join(paths)}" if paths: os.environ["PATH"] += f";{';'.join(paths)}"
not_supported = [] # libraries that were found, but are not supported not_supported = [] # libraries that were found, but are not supported
for style in _windows_styles: for style in _windows_styles:
candidate = style.format(name) candidate = style.format(name)
@ -134,7 +134,7 @@ class ExternalLibrary:
pass pass
except OSError: except OSError:
not_supported.append(library) not_supported.append(library)
if not_supported: if not_supported:
raise ExternalLibraryError(f"library '{name}' couldn't be loaded, because the following candidates were not supported:" raise ExternalLibraryError(f"library '{name}' couldn't be loaded, because the following candidates were not supported:"
@ -142,6 +142,6 @@ class ExternalLibrary:
raise ExternalLibraryError(f"library '{name}' couldn't be loaded") raise ExternalLibraryError(f"library '{name}' couldn't be loaded")

View File

@ -212,7 +212,7 @@ if PYOGG_OGG_AVAIL:
og_p = POINTER(ogg_page) og_p = POINTER(ogg_page)
os_p = POINTER(ogg_stream_state) os_p = POINTER(ogg_stream_state)
iov_p = POINTER(ogg_iovec_t) iov_p = POINTER(ogg_iovec_t)
libogg.oggpack_writeinit.restype = None libogg.oggpack_writeinit.restype = None
libogg.oggpack_writeinit.argtypes = [b_p] libogg.oggpack_writeinit.argtypes = [b_p]
@ -330,13 +330,13 @@ if PYOGG_OGG_AVAIL:
def oggpackB_writeinit(b): def oggpackB_writeinit(b):
libogg.oggpackB_writeinit(b) libogg.oggpackB_writeinit(b)
try: try:
libogg.oggpackB_writecheck.restype = c_int libogg.oggpackB_writecheck.restype = c_int
libogg.oggpackB_writecheck.argtypes = [b_p] libogg.oggpackB_writecheck.argtypes = [b_p]
def oggpackB_writecheck(b): def oggpackB_writecheck(b):
return libogg.oggpackB_writecheck(b) return libogg.oggpackB_writecheck(b)
except: except:
pass pass

View File

@ -18,7 +18,7 @@ from .pyogg_error import PyOggError
class OggOpusWriter(): class OggOpusWriter():
"""Encodes PCM data into an OggOpus file.""" """Encodes PCM data into an OggOpus file."""
def __init__(self, def __init__(self,
f: Union[BinaryIO, str], f: Union[BinaryIO, str],
encoder: OpusBufferedEncoder, encoder: OpusBufferedEncoder,
custom_pre_skip: Optional[int] = None) -> None: custom_pre_skip: Optional[int] = None) -> None:
@ -29,7 +29,7 @@ class OggOpusWriter():
If f is an already-opened file handle, then it is the If f is an already-opened file handle, then it is the
user's responsibility to close the file when they are 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. in binary (not text) mode.
The encoder should be a The encoder should be a
@ -123,7 +123,7 @@ class OggOpusWriter():
def _write_to_oggopus(self, pcm: memoryview, flush: bool = False) -> None: def _write_to_oggopus(self, pcm: memoryview, flush: bool = False) -> None:
assert self._encoder is not None assert self._encoder is not None
def handle_encoded_packet(encoded_packet: memoryview, def handle_encoded_packet(encoded_packet: memoryview,
samples: int, samples: int,
end_of_stream: bool) -> None: end_of_stream: bool) -> None:
@ -132,7 +132,7 @@ class OggOpusWriter():
encoded_packet_ctypes = Buffer.from_buffer(encoded_packet) encoded_packet_ctypes = Buffer.from_buffer(encoded_packet)
# Obtain a pointer to the encoded packet # Obtain a pointer to the encoded packet
encoded_packet_ptr = ctypes.cast( encoded_packet_ptr = ctypes.cast(
encoded_packet_ctypes, encoded_packet_ctypes,
ctypes.POINTER(ctypes.c_ubyte) ctypes.POINTER(ctypes.c_ubyte)
) )

View File

@ -232,7 +232,7 @@ if libopus:
PYOGG_OPUS_AVAIL = True PYOGG_OPUS_AVAIL = True
else: else:
PYOGG_OPUS_AVAIL = False PYOGG_OPUS_AVAIL = False
if libopusfile: if libopusfile:
PYOGG_OPUS_FILE_AVAIL = True PYOGG_OPUS_FILE_AVAIL = True
else: else:
@ -345,22 +345,22 @@ OPUS_APPLICATION_AUDIO = 2049
OPUS_APPLICATION_RESTRICTED_LOWDELAY =2051 OPUS_APPLICATION_RESTRICTED_LOWDELAY =2051
OPUS_SIGNAL_VOICE =3001 OPUS_SIGNAL_VOICE =3001
OPUS_SIGNAL_MUSIC =3002 OPUS_SIGNAL_MUSIC =3002
OPUS_BANDWIDTH_NARROWBAND =1101 OPUS_BANDWIDTH_NARROWBAND =1101
OPUS_BANDWIDTH_MEDIUMBAND =1102 OPUS_BANDWIDTH_MEDIUMBAND =1102
OPUS_BANDWIDTH_WIDEBAND =1103 OPUS_BANDWIDTH_WIDEBAND =1103
OPUS_BANDWIDTH_SUPERWIDEBAND =1104 OPUS_BANDWIDTH_SUPERWIDEBAND =1104
OPUS_BANDWIDTH_FULLBAND =1105 OPUS_BANDWIDTH_FULLBAND =1105
OPUS_FRAMESIZE_ARG =5000 OPUS_FRAMESIZE_ARG =5000
OPUS_FRAMESIZE_2_5_MS =5001 OPUS_FRAMESIZE_2_5_MS =5001
OPUS_FRAMESIZE_5_MS =5002 OPUS_FRAMESIZE_5_MS =5002
OPUS_FRAMESIZE_10_MS =5003 OPUS_FRAMESIZE_10_MS =5003
OPUS_FRAMESIZE_20_MS =5004 OPUS_FRAMESIZE_20_MS =5004
OPUS_FRAMESIZE_40_MS =5005 OPUS_FRAMESIZE_40_MS =5005
OPUS_FRAMESIZE_60_MS =5006 OPUS_FRAMESIZE_60_MS =5006
OPUS_FRAMESIZE_80_MS =5007 OPUS_FRAMESIZE_80_MS =5007
OPUS_FRAMESIZE_100_MS =5008 OPUS_FRAMESIZE_100_MS =5008
OPUS_FRAMESIZE_120_MS =5009 OPUS_FRAMESIZE_120_MS =5009
OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST =5120 OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST =5120
@ -405,7 +405,7 @@ opus_int32 = c_int32
opus_int32_p = POINTER(opus_int32) opus_int32_p = POINTER(opus_int32)
opus_uint32 = c_uint32 opus_uint32 = c_uint32
opus_int = c_int opus_int = c_int
opus_int64= c_longlong opus_int64= c_longlong
opus_int8= c_int8 opus_int8= c_int8
@ -640,7 +640,7 @@ if PYOGG_OPUS_AVAIL:
def opus_multistream_packet_unpad(data, len, nb_streams): def opus_multistream_packet_unpad(data, len, nb_streams):
return libopus.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.restype = c_char_p
libopus.opus_strerror.argtypes = [c_int] libopus.opus_strerror.argtypes = [c_int]
@ -770,7 +770,7 @@ if PYOGG_OPUS_AVAIL:
if PYOGG_OPUS_FILE_AVAIL: if PYOGG_OPUS_FILE_AVAIL:
assert libopusfile is not None assert libopusfile is not None
# opusfile # opusfile
class OggOpusFile(ctypes.Structure): class OggOpusFile(ctypes.Structure):
@ -1212,7 +1212,7 @@ if PYOGG_OPUS_AVAIL:
if PYOGG_OPUS_ENC_AVAIL: if PYOGG_OPUS_ENC_AVAIL:
# Sanity check also satisfies mypy type checking # Sanity check also satisfies mypy type checking
assert libopusenc is not None assert libopusenc is not None
ope_write_func = ctypes.CFUNCTYPE(c_int, ope_write_func = ctypes.CFUNCTYPE(c_int,
c_void_p, c_void_p,
c_uchar_p, c_uchar_p,

View File

@ -105,7 +105,7 @@ class OpusBufferedEncoder(OpusEncoder):
"rather than bytes)." "rather than bytes)."
) )
pcm_ctypes = Buffer.from_buffer(pcm_bytes) pcm_ctypes = Buffer.from_buffer(pcm_bytes)
# Either store the encoded packet to return at the end of the # Either store the encoded packet to return at the end of the
# method or immediately call the callback with the encoded # method or immediately call the callback with the encoded
# packet. # packet.
@ -135,7 +135,7 @@ class OpusBufferedEncoder(OpusEncoder):
assert self._buffer_index is not None assert self._buffer_index is not None
assert self._channels is not None assert self._channels is not None
assert self._buffer is not None assert self._buffer is not None
# If the buffer is already empty, we have no work to do # If the buffer is already empty, we have no work to do
if self._buffer_index == 0: if self._buffer_index == 0:
return return
@ -156,7 +156,7 @@ class OpusBufferedEncoder(OpusEncoder):
# count # count
len(self._buffer) - self._buffer_index len(self._buffer) - self._buffer_index
) )
# Encode the PCM # Encode the PCM
# As at 2020-11-05, mypy is unaware that ctype Arrays # As at 2020-11-05, mypy is unaware that ctype Arrays
# support the buffer protocol. # support the buffer protocol.
@ -166,16 +166,16 @@ class OpusBufferedEncoder(OpusEncoder):
# callback # callback
store_or_callback(encoded_packet, samples, True) store_or_callback(encoded_packet, samples, True)
# Copy the data remaining from the provided PCM into the # Copy the data remaining from the provided PCM into the
# buffer. Flush if required. # buffer. Flush if required.
def copy_insufficient_data() -> None: def copy_insufficient_data() -> None:
# Sanity checks to satisfy mypy # Sanity checks to satisfy mypy
assert self._buffer is not None assert self._buffer is not None
# Calculate remaining data # Calculate remaining data
remaining_data = len(pcm_bytes) - pcm_index remaining_data = len(pcm_bytes) - pcm_index
# Copy the data into the buffer. # Copy the data into the buffer.
ctypes.memmove( ctypes.memmove(
# destination # destination
@ -191,7 +191,7 @@ class OpusBufferedEncoder(OpusEncoder):
# If we've been asked to flush the buffer then do so # If we've been asked to flush the buffer then do so
if flush: if flush:
flush_buffer() flush_buffer()
# Loop through the provided PCM and the current buffer, # Loop through the provided PCM and the current buffer,
# encoding as we have full packets. # encoding as we have full packets.
while True: while True:
@ -227,7 +227,7 @@ class OpusBufferedEncoder(OpusEncoder):
// self._channels // self._channels
// ctypes.sizeof(opus.opus_int16) // ctypes.sizeof(opus.opus_int16)
) )
# Encode the PCM # Encode the PCM
encoded_packet = super().encode(frame_data) encoded_packet = super().encode(frame_data)
@ -266,7 +266,7 @@ class OpusBufferedEncoder(OpusEncoder):
pcm_index += remaining pcm_index += remaining
self._buffer_index += remaining self._buffer_index += remaining
assert self._buffer_index == len(self._buffer) assert self._buffer_index == len(self._buffer)
# Encode the PCM # Encode the PCM
encoded_packet = super().encode( encoded_packet = super().encode(
# Memoryviews of ctypes do work, even though # Memoryviews of ctypes do work, even though
@ -284,7 +284,7 @@ class OpusBufferedEncoder(OpusEncoder):
# We've now processed the buffer # We've now processed the buffer
self._buffer_index = 0 self._buffer_index = 0
# Either store the encoded packet or call the # Either store the encoded packet or call the
# callback # callback
store_or_callback(encoded_packet, samples) store_or_callback(encoded_packet, samples)

View File

@ -87,7 +87,7 @@ class OpusDecoder:
# data) # data)
Buffer = ctypes.c_char * len(encoded_bytes) Buffer = ctypes.c_char * len(encoded_bytes)
encoded_bytes_ctypes = Buffer.from_buffer(encoded_bytes) encoded_bytes_ctypes = Buffer.from_buffer(encoded_bytes)
# Create pointer to encoded bytes # Create pointer to encoded bytes
encoded_bytes_ptr = ctypes.cast( encoded_bytes_ptr = ctypes.cast(
encoded_bytes_ctypes, encoded_bytes_ctypes,
@ -127,16 +127,16 @@ class OpusDecoder:
* ctypes.sizeof(opus.opus_int16) * ctypes.sizeof(opus.opus_int16)
* self._channels * self._channels
) )
# Create memoryview of PCM buffer to avoid copying data during slice. # Create memoryview of PCM buffer to avoid copying data during slice.
mv = memoryview(self._pcm_buffer) mv = memoryview(self._pcm_buffer)
# Cast memoryview to chars # Cast memoryview to chars
mv = mv.cast('c') mv = mv.cast('c')
# Slice memoryview to extract only valid data # Slice memoryview to extract only valid data
mv = mv[:end_valid_data] mv = mv[:end_valid_data]
return mv return mv

View File

@ -131,8 +131,8 @@ class OpusEncoder:
ctypes.cast(ctypes.pointer(self._output_buffer), ctypes.cast(ctypes.pointer(self._output_buffer),
ctypes.POINTER(ctypes.c_ubyte)) ctypes.POINTER(ctypes.c_ubyte))
) )
def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview: def encode(self, pcm: Union[bytes, bytearray, memoryview]) -> memoryview:
"""Encodes PCM data into an Opus frame. """Encodes PCM data into an Opus frame.
@ -146,7 +146,7 @@ class OpusEncoder:
# If we haven't already created an encoder, do so now # If we haven't already created an encoder, do so now
if self._encoder is None: if self._encoder is None:
self._encoder = self._create_encoder() self._encoder = self._create_encoder()
# Sanity checks also satisfy mypy type checking # Sanity checks also satisfy mypy type checking
assert self._channels is not None assert self._channels is not None
assert self._samples_per_second is not None assert self._samples_per_second is not None
@ -177,7 +177,7 @@ class OpusEncoder:
PcmCtypes = ctypes.c_ubyte * len(pcm) PcmCtypes = ctypes.c_ubyte * len(pcm)
try: try:
# Attempt to share the PCM memory # Attempt to share the PCM memory
# Unfortunately, as at 2020-09-27, the type hinting for # Unfortunately, as at 2020-09-27, the type hinting for
# read-only and writeable buffer protocols was a # read-only and writeable buffer protocols was a
# work-in-progress. The following only works for writable # work-in-progress. The following only works for writable
@ -225,27 +225,27 @@ class OpusEncoder:
# * https://github.com/python/typing/issues/593 # * https://github.com/python/typing/issues/593
# * https://github.com/python/typeshed/pull/4232 # * https://github.com/python/typeshed/pull/4232
mv = memoryview(self._output_buffer) # type: ignore mv = memoryview(self._output_buffer) # type: ignore
# Cast the memoryview to char # Cast the memoryview to char
mv = mv.cast('c') mv = mv.cast('c')
# Slice just the valid data from the memoryview # Slice just the valid data from the memoryview
valid_data_as_bytes = mv[:result] valid_data_as_bytes = mv[:result]
# DEBUG # DEBUG
# Convert memoryview back to ctypes instance # Convert memoryview back to ctypes instance
Buffer = ctypes.c_ubyte * len(valid_data_as_bytes) Buffer = ctypes.c_ubyte * len(valid_data_as_bytes)
buf = Buffer.from_buffer( valid_data_as_bytes ) buf = Buffer.from_buffer( valid_data_as_bytes )
# Convert PCM back to pointer and dump 4,000-byte buffer # Convert PCM back to pointer and dump 4,000-byte buffer
ptr = ctypes.cast( ptr = ctypes.cast(
buf, buf,
ctypes.POINTER(ctypes.c_ubyte) ctypes.POINTER(ctypes.c_ubyte)
) )
return valid_data_as_bytes return valid_data_as_bytes
def get_algorithmic_delay(self): def get_algorithmic_delay(self):
"""Gets the total samples of delay added by the entire codec. """Gets the total samples of delay added by the entire codec.
@ -266,9 +266,9 @@ class OpusEncoder:
# If we haven't already created an encoder, do so now # If we haven't already created an encoder, do so now
if self._encoder is None: if self._encoder is None:
self._encoder = self._create_encoder() self._encoder = self._create_encoder()
# Obtain the algorithmic delay of the Opus encoder. See # 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() delay = opus.opus_int32()
result = opus.opus_encoder_ctl( result = opus.opus_encoder_ctl(
@ -285,7 +285,7 @@ class OpusEncoder:
delay_samples = delay.value delay_samples = delay.value
return delay_samples return delay_samples
# #
# Internal methods # Internal methods
# #

View File

@ -14,7 +14,7 @@ class OpusFile(AudioFile):
ctypes.pointer(error) ctypes.pointer(error)
) )
# Check for errors # Check for errors
if error.value != 0: if error.value != 0:
raise PyOggError( raise PyOggError(
("File '{}' couldn't be opened or doesn't exist. "+ ("File '{}' couldn't be opened or doesn't exist. "+

View File

@ -14,7 +14,7 @@ class OpusFileStream:
An exception will be raised if the file cannot be opened An exception will be raised if the file cannot be opened
correctly. correctly.
""" """
error = ctypes.c_int() error = ctypes.c_int()
self.of = opus.op_open_file(ogg.to_char_p(path), ctypes.pointer(error)) self.of = opus.op_open_file(ogg.to_char_p(path), ctypes.pointer(error))

View File

@ -180,7 +180,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
("res_bits", ogg_int64_t), ("res_bits", ogg_int64_t),
("backend_state", c_void_p)] ("backend_state", c_void_p)]
class alloc_chain(ctypes.Structure): class alloc_chain(ctypes.Structure):
""" """
Wrapper for: Wrapper for:
@ -232,7 +232,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
("comments", c_int), ("comments", c_int),
("vendor", c_char_p)] ("vendor", c_char_p)]
vi_p = POINTER(vorbis_info) vi_p = POINTER(vorbis_info)
vc_p = POINTER(vorbis_comment) vc_p = POINTER(vorbis_comment)
@ -285,7 +285,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_comment_clear(vc) libvorbis.vorbis_comment_clear(vc)
libvorbis.vorbis_block_init.restype = c_int libvorbis.vorbis_block_init.restype = c_int
libvorbis.vorbis_block_init.argtypes = [vd_p, vb_p] libvorbis.vorbis_block_init.argtypes = [vd_p, vb_p]
def vorbis_block_init(v,vb): def vorbis_block_init(v,vb):
@ -307,7 +307,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
return libvorbis.vorbis_granule_time(v, granulepos) return libvorbis.vorbis_granule_time(v, granulepos)
libvorbis.vorbis_version_string.restype = c_char_p libvorbis.vorbis_version_string.restype = c_char_p
libvorbis.vorbis_version_string.argtypes = [] libvorbis.vorbis_version_string.argtypes = []
def vorbis_version_string(): def vorbis_version_string():
@ -326,7 +326,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_commentheader_out.argtypes = [vc_p, op_p] libvorbis.vorbis_commentheader_out.argtypes = [vc_p, op_p]
def vorbis_commentheader_out(vc, op): def vorbis_commentheader_out(vc, op):
return libvorbis.vorbis_commentheader_out(vc, op) return libvorbis.vorbis_commentheader_out(vc, op)
libvorbis.vorbis_analysis_headerout.restype = c_int libvorbis.vorbis_analysis_headerout.restype = c_int
libvorbis.vorbis_analysis_headerout.argtypes = [vd_p, vc_p, op_p, op_p, op_p] 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): def vorbis_analysis_headerout(v,vc, op, op_comm, op_code):
@ -346,7 +346,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_analysis_blockout.argtypes = [vd_p, vb_p] libvorbis.vorbis_analysis_blockout.argtypes = [vd_p, vb_p]
def vorbis_analysis_blockout(v, vb): def vorbis_analysis_blockout(v, vb):
return libvorbis.vorbis_analysis_blockout(v, vb) return libvorbis.vorbis_analysis_blockout(v, vb)
libvorbis.vorbis_analysis.restype = c_int libvorbis.vorbis_analysis.restype = c_int
libvorbis.vorbis_analysis.argtypes = [vb_p, op_p] libvorbis.vorbis_analysis.argtypes = [vb_p, op_p]
def vorbis_analysis(vb, op): def vorbis_analysis(vb, op):
@ -359,7 +359,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_bitrate_addblock.argtypes = [vb_p] libvorbis.vorbis_bitrate_addblock.argtypes = [vb_p]
def vorbis_bitrate_addblock(vb): def vorbis_bitrate_addblock(vb):
return libvorbis.vorbis_bitrate_addblock(vb) return libvorbis.vorbis_bitrate_addblock(vb)
libvorbis.vorbis_bitrate_flushpacket.restype = c_int libvorbis.vorbis_bitrate_flushpacket.restype = c_int
libvorbis.vorbis_bitrate_flushpacket.argtypes = [vd_p, op_p] libvorbis.vorbis_bitrate_flushpacket.argtypes = [vd_p, op_p]
def vorbis_bitrate_flushpacket(vd, op): def vorbis_bitrate_flushpacket(vd, op):
@ -372,7 +372,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_synthesis_idheader.argtypes = [op_p] libvorbis.vorbis_synthesis_idheader.argtypes = [op_p]
def vorbis_synthesis_idheader(op): def vorbis_synthesis_idheader(op):
return libvorbis.vorbis_synthesis_idheader(op) return libvorbis.vorbis_synthesis_idheader(op)
libvorbis.vorbis_synthesis_headerin.restype = c_int libvorbis.vorbis_synthesis_headerin.restype = c_int
libvorbis.vorbis_synthesis_headerin.argtypes = [vi_p, vc_p, op_p] libvorbis.vorbis_synthesis_headerin.argtypes = [vi_p, vc_p, op_p]
def vorbis_synthesis_headerin(vi, vc, op): def vorbis_synthesis_headerin(vi, vc, op):
@ -400,7 +400,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_synthesis_trackonly.argtypes = [vb_p, op_p] libvorbis.vorbis_synthesis_trackonly.argtypes = [vb_p, op_p]
def vorbis_synthesis_trackonly(vb, op): def vorbis_synthesis_trackonly(vb, op):
return libvorbis.vorbis_synthesis_trackonly(vb, op) return libvorbis.vorbis_synthesis_trackonly(vb, op)
libvorbis.vorbis_synthesis_blockin.restype = c_int libvorbis.vorbis_synthesis_blockin.restype = c_int
libvorbis.vorbis_synthesis_blockin.argtypes = [vd_p, vb_p] libvorbis.vorbis_synthesis_blockin.argtypes = [vd_p, vb_p]
def vorbis_synthesis_blockin(v, vb): def vorbis_synthesis_blockin(v, vb):
@ -410,7 +410,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_synthesis_pcmout.argtypes = [vd_p, c_float_p_p_p] libvorbis.vorbis_synthesis_pcmout.argtypes = [vd_p, c_float_p_p_p]
def vorbis_synthesis_pcmout(v, pcm): def vorbis_synthesis_pcmout(v, pcm):
return libvorbis.vorbis_synthesis_pcmout(v, pcm) return libvorbis.vorbis_synthesis_pcmout(v, pcm)
libvorbis.vorbis_synthesis_lapout.restype = c_int libvorbis.vorbis_synthesis_lapout.restype = c_int
libvorbis.vorbis_synthesis_lapout.argtypes = [vd_p, c_float_p_p_p] libvorbis.vorbis_synthesis_lapout.argtypes = [vd_p, c_float_p_p_p]
def vorbis_synthesis_lapout(v, pcm): def vorbis_synthesis_lapout(v, pcm):
@ -420,7 +420,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_synthesis_read.argtypes = [vd_p, c_int] libvorbis.vorbis_synthesis_read.argtypes = [vd_p, c_int]
def vorbis_synthesis_read(v, samples): def vorbis_synthesis_read(v, samples):
return libvorbis.vorbis_synthesis_read(v, samples) return libvorbis.vorbis_synthesis_read(v, samples)
libvorbis.vorbis_packet_blocksize.restype = c_long libvorbis.vorbis_packet_blocksize.restype = c_long
libvorbis.vorbis_packet_blocksize.argtypes = [vi_p, op_p] libvorbis.vorbis_packet_blocksize.argtypes = [vi_p, op_p]
def vorbis_packet_blocksize(vi, op): def vorbis_packet_blocksize(vi, op):
@ -432,7 +432,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
libvorbis.vorbis_synthesis_halfrate.argtypes = [vi_p, c_int] libvorbis.vorbis_synthesis_halfrate.argtypes = [vi_p, c_int]
def vorbis_synthesis_halfrate(v, flag): def vorbis_synthesis_halfrate(v, flag):
return libvorbis.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.restype = c_int
libvorbis.vorbis_synthesis_halfrate_p.argtypes = [vi_p] libvorbis.vorbis_synthesis_halfrate_p.argtypes = [vi_p]
def vorbis_synthesis_halfrate_p(vi): def vorbis_synthesis_halfrate_p(vi):
@ -483,7 +483,7 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
("seek_func", seek_func), ("seek_func", seek_func),
("close_func", close_func), ("close_func", close_func),
("tell_func", tell_func)] ("tell_func", tell_func)]
NOTOPEN = 0 NOTOPEN = 0
PARTOPEN = 1 PARTOPEN = 1
OPENED = 2 OPENED = 2
@ -768,10 +768,10 @@ if PYOGG_OGG_AVAIL and PYOGG_VORBIS_AVAIL and PYOGG_VORBIS_FILE_AVAIL:
try: try:
# vorbisenc # vorbisenc
# Sanity check also satisfies mypy type checking # Sanity check also satisfies mypy type checking
assert libvorbisenc is not None assert libvorbisenc is not None
libvorbisenc.vorbis_encode_init.restype = c_int libvorbisenc.vorbis_encode_init.restype = c_int
libvorbisenc.vorbis_encode_init.argtypes = [vi_p, c_long, c_long, c_long, c_long, c_long] libvorbisenc.vorbis_encode_init.argtypes = [vi_p, c_long, c_long, c_long, c_long, c_long]

View File

@ -22,7 +22,7 @@ class VorbisFile(AudioFile):
bytes_per_sample: int = 2, bytes_per_sample: int = 2,
signed:bool = True) -> None: signed:bool = True) -> None:
"""Load an OggVorbis File. """Load an OggVorbis File.
path specifies the location of the Vorbis file. Unicode path specifies the location of the Vorbis file. Unicode
filenames may not work correctly under Windows. filenames may not work correctly under Windows.
@ -40,7 +40,7 @@ class VorbisFile(AudioFile):
# Sanity check that the vorbis library is available (for mypy) # Sanity check that the vorbis library is available (for mypy)
assert vorbis.libvorbisfile is not None assert vorbis.libvorbisfile is not None
#: Bytes per sample #: Bytes per sample
self.bytes_per_sample = bytes_per_sample self.bytes_per_sample = bytes_per_sample
@ -104,7 +104,7 @@ class VorbisFile(AudioFile):
) )
# Storage for the index of the logical bitstream # Storage for the index of the logical bitstream
bitstream_previous = None bitstream_previous = None
bitstream = ctypes.c_int() bitstream = ctypes.c_int()
# Set bytes remaining to read into PCM # Set bytes remaining to read into PCM
@ -142,9 +142,9 @@ class VorbisFile(AudioFile):
if bitstream_previous != bitstream: if bitstream_previous != bitstream:
raise PyOggError( raise PyOggError(
"PyOgg currently supports Vorbis files "+ "PyOgg currently supports Vorbis files "+
"with only one logical stream" "with only one logical stream"
) )
# Check for end of file # Check for end of file
if result == 0: if result == 0:
break break
@ -154,7 +154,7 @@ class VorbisFile(AudioFile):
# Update the pointer into the buffer # Update the pointer into the buffer
buf_ptr.value += result buf_ptr.value += result
# Close the file and clean up memory # Close the file and clean up memory
vorbis.libvorbisfile.ov_clear(ctypes.byref(vf)) vorbis.libvorbisfile.ov_clear(ctypes.byref(vf))

View File

@ -7,7 +7,7 @@ class VorbisFileStream:
def __init__(self, path, buffer_size=8192): def __init__(self, path, buffer_size=8192):
self.exists = False self.exists = False
self._buffer_size = buffer_size self._buffer_size = buffer_size
self.vf = vorbis.OggVorbis_File() self.vf = vorbis.OggVorbis_File()
error = vorbis.ov_fopen(path, ctypes.byref(self.vf)) error = vorbis.ov_fopen(path, ctypes.byref(self.vf))
if error != 0: if error != 0:

View File

@ -30,7 +30,7 @@ if RNS.vendor.platformutils.get_platform() == "android":
from android import python_act from android import python_act
android_api_version = autoclass('android.os.Build$VERSION').SDK_INT android_api_version = autoclass('android.os.Build$VERSION').SDK_INT
Intent = autoclass('android.content.Intent') Intent = autoclass('android.content.Intent')
BitmapFactory = autoclass('android.graphics.BitmapFactory') BitmapFactory = autoclass('android.graphics.BitmapFactory')
Icon = autoclass("android.graphics.drawable.Icon") Icon = autoclass("android.graphics.drawable.Icon")
@ -63,7 +63,7 @@ class SidebandService():
0x239A: [0x8029], # Adafruit (RAK4631) 0x239A: [0x8029], # Adafruit (RAK4631)
0x303A: [0x1001], # ESP-32S3 0x303A: [0x1001], # ESP-32S3
} }
def android_notification(self, title="", content="", ticker="", group=None, context_id=None): def android_notification(self, title="", content="", ticker="", group=None, context_id=None):
if android_api_version < 26: if android_api_version < 26:
return return
@ -99,7 +99,7 @@ class SidebandService():
notification.setContentTitle(title) notification.setContentTitle(title)
notification.setContentText(AndroidString(content)) notification.setContentText(AndroidString(content))
notification.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) notification.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
# if group != None: # if group != None:
# notification.setGroup(group_id) # notification.setGroup(group_id)
@ -140,9 +140,9 @@ class SidebandService():
except Exception as e: except Exception as e:
RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR)
return False return False
else: else:
return False return False
@ -184,7 +184,7 @@ class SidebandService():
if self.should_update_location(): if self.should_update_location():
if not self._gps_started: if not self._gps_started:
RNS.log("Starting service location provider", RNS.LOG_DEBUG) RNS.log("Starting service location provider", RNS.LOG_DEBUG)
if self.gps == None: if self.gps == None:
from plyer import gps from plyer import gps
self.gps = gps self.gps = gps
@ -232,7 +232,7 @@ class SidebandService():
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.android_service = autoclass('org.kivy.android.PythonService').mService self.android_service = autoclass('org.kivy.android.PythonService').mService
self.app_context = self.android_service.getApplication().getApplicationContext() self.app_context = self.android_service.getApplication().getApplicationContext()
try: try:
self.wifi_manager = self.app_context.getSystemService(Context.WIFI_SERVICE) self.wifi_manager = self.app_context.getSystemService(Context.WIFI_SERVICE)
except Exception as e: except Exception as e:
@ -248,7 +248,7 @@ class SidebandService():
RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR)
self.discover_usb_devices() 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) 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"]: if self.sideband.config["debug"]:
@ -257,7 +257,7 @@ class SidebandService():
self.sideband.start() self.sideband.start()
self.update_connectivity_type() self.update_connectivity_type()
self.update_power_restrictions() self.update_power_restrictions()
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
RNS.log(f"Discovered USB devices: {self.usb_devices)}", RNS.LOG_EXTREME) RNS.log(f"Discovered USB devices: {self.usb_devices)}", RNS.LOG_EXTREME)
self.update_location_provider() self.update_location_provider()
@ -282,7 +282,7 @@ class SidebandService():
except Exception as e: except Exception as e:
RNS.log(f"Could not list USB devices. The contained exception was: {e)}", RNS.LOG_ERROR) RNS.log(f"Could not list USB devices. The contained exception was: {e)}", RNS.LOG_ERROR)
def start(self): def start(self):
self.should_run = True self.should_run = True
self.take_locks() self.take_locks()
@ -334,7 +334,7 @@ class SidebandService():
is_controlling = True is_controlling = True
self.sideband.setpersistent("service.is_controlling_connectivity", is_controlling) self.sideband.setpersistent("service.is_controlling_connectivity", is_controlling)
def get_connectivity_status(self): def get_connectivity_status(self):
if self.sideband.reticulum.is_connected_to_shared_instance: 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." return "[size=22dp][b]Connectivity Status[/b][/size]\n\nSideband is connected via a shared Reticulum instance running on this system. Use the rnstatus utility to obtain full connectivity info."
@ -425,23 +425,23 @@ class SidebandService():
if self.sideband.interface_local != None: if self.sideband.interface_local != None:
total_rxb += self.sideband.interface_local.rxb total_rxb += self.sideband.interface_local.rxb
total_txb += self.sideband.interface_local.txb total_txb += self.sideband.interface_local.txb
if self.sideband.interface_rnode != None: if self.sideband.interface_rnode != None:
total_rxb += self.sideband.interface_rnode.rxb total_rxb += self.sideband.interface_rnode.rxb
total_txb += self.sideband.interface_rnode.txb total_txb += self.sideband.interface_rnode.txb
if self.sideband.interface_modem != None: if self.sideband.interface_modem != None:
total_rxb += self.sideband.interface_modem.rxb total_rxb += self.sideband.interface_modem.rxb
total_txb += self.sideband.interface_modem.txb total_txb += self.sideband.interface_modem.txb
if self.sideband.interface_serial != None: if self.sideband.interface_serial != None:
total_rxb += self.sideband.interface_serial.rxb total_rxb += self.sideband.interface_serial.rxb
total_txb += self.sideband.interface_serial.txb total_txb += self.sideband.interface_serial.txb
if self.sideband.interface_tcp != None: if self.sideband.interface_tcp != None:
total_rxb += self.sideband.interface_tcp.rxb total_rxb += self.sideband.interface_tcp.rxb
total_txb += self.sideband.interface_tcp.txb total_txb += self.sideband.interface_tcp.txb
if self.sideband.interface_i2p != None: if self.sideband.interface_i2p != None:
total_rxb += self.sideband.interface_i2p.rxb total_rxb += self.sideband.interface_i2p.rxb
total_txb += self.sideband.interface_i2p.txb total_txb += self.sideband.interface_i2p.txb

View File

@ -42,7 +42,7 @@ var got_data = function(err, data) {
for (e in data) { for (e in data) {
url = "/pkg/"+data[e]; url = "/pkg/"+data[e];
name = data[e]; name = data[e];
// create a new div element // create a new div element
const listitem = document.createElement("li"); const listitem = document.createElement("li");
const anc = document.createElement("a") const anc = document.createElement("a")

View File

@ -37,14 +37,14 @@ def samples_from_ogg(file_path=None, output_rate=8000):
audio = AudioSegment( audio = AudioSegment(
bytes(opus_file.as_array()), bytes(opus_file.as_array()),
frame_rate=opus_file.frequency, frame_rate=opus_file.frequency,
sample_width=opus_file.bytes_per_sample, sample_width=opus_file.bytes_per_sample,
channels=opus_file.channels) channels=opus_file.channels)
audio = audio.split_to_mono()[0] audio = audio.split_to_mono()[0]
audio = audio.apply_gain(-audio.max_dBFS) audio = audio.apply_gain(-audio.max_dBFS)
audio = audio.set_frame_rate(output_rate) audio = audio.set_frame_rate(output_rate)
audio = audio.set_sample_width(2) audio = audio.set_sample_width(2)
return audio.get_array_of_samples() return audio.get_array_of_samples()
def resample(samples, width, channels, input_rate, output_rate, normalize): 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_duration = frame_duration_ms/1000.0
frame_size = int(frame_duration * samples_per_second) frame_size = int(frame_duration * samples_per_second)
bytes_per_frame = frame_size*bytes_per_sample bytes_per_frame = frame_size*bytes_per_sample
ogg_opus_writer.write(memoryview(bytearray(samples))) ogg_opus_writer.write(memoryview(bytearray(samples)))
ogg_opus_writer.close() ogg_opus_writer.close()
return True return True
except Exception as e: except Exception as e:
RNS.trace_exception(e) RNS.trace_exception(e)
return False return False
@ -153,7 +153,7 @@ def encode_codec2(samples, mode):
N_FRAMES = math.floor(len(samples)/SPF) N_FRAMES = math.floor(len(samples)/SPF)
# TODO: Add padding to align to whole frames # TODO: Add padding to align to whole frames
frames = np.array(samples[0:N_FRAMES*SPF], dtype=np.int16) frames = np.array(samples[0:N_FRAMES*SPF], dtype=np.int16)
encoded = b"" encoded = b""
for pi in range(0, N_FRAMES): for pi in range(0, N_FRAMES):
pstart = pi*SPF pstart = pi*SPF

View File

@ -168,7 +168,7 @@ class SidebandCore():
self.app_dir = config_path self.app_dir = config_path
self.cache_dir = f"{self.app_dir}/cache" self.cache_dir = f"{self.app_dir}/cache"
self.rns_configdir = None self.rns_configdir = None
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.app_dir = f"{android_app_dir}/io.unsigned.sideband/files/" self.app_dir = f"{android_app_dir}/io.unsigned.sideband/files/"
@ -215,7 +215,7 @@ class SidebandCore():
self.tmp_dir = f"{self.app_dir}/app_storage/tmp" self.tmp_dir = f"{self.app_dir}/app_storage/tmp"
self.exports_dir = f"{self.app_dir}/exports" self.exports_dir = f"{self.app_dir}/exports"
self.webshare_dir = "./share/" self.webshare_dir = "./share/"
self.first_run = True self.first_run = True
self.saving_configuration = False self.saving_configuration = False
self.last_lxmf_announce = 0 self.last_lxmf_announce = 0
@ -246,7 +246,7 @@ class SidebandCore():
if os.path.isdir(self.exports_dir): if os.path.isdir(self.exports_dir):
self.clear_exports_dir() self.clear_exports_dir()
except Exception as e: except Exception as e:
RNS.log(f"Error while configuring Sideband: {e)}", RNS.LOG_ERROR) RNS.log(f"Error while configuring Sideband: {e)}", RNS.LOG_ERROR)
@ -275,7 +275,7 @@ class SidebandCore():
except Exception as e: except Exception as e:
RNS.log(f"Error while configuring Reticulum instance: {e)}", RNS.LOG_ERROR) RNS.log(f"Error while configuring Reticulum instance: {e)}", RNS.LOG_ERROR)
else: else:
pass pass
@ -423,7 +423,7 @@ class SidebandCore():
self.config["connect_ifmode_modem"] = "full" self.config["connect_ifmode_modem"] = "full"
self.config["connect_ifmode_serial"] = "full" self.config["connect_ifmode_serial"] = "full"
self.config["connect_ifmode_bluetooth"] = "full" self.config["connect_ifmode_bluetooth"] = "full"
# Hardware # Hardware
self.config["hw_rnode_frequency"] = None self.config["hw_rnode_frequency"] = None
self.config["hw_rnode_modulation"] = "LoRa" self.config["hw_rnode_modulation"] = "LoRa"
@ -470,7 +470,7 @@ class SidebandCore():
def clear_map_cache(self): def clear_map_cache(self):
for entry in os.scandir(self.map_cache): for entry in os.scandir(self.map_cache):
os.unlink(entry.path) os.unlink(entry.path)
def get_map_cache_size(self): def get_map_cache_size(self):
total = 0 total = 0
for entry in os.scandir(self.map_cache): for entry in os.scandir(self.map_cache):
@ -624,7 +624,7 @@ class SidebandCore():
self.config["hw_modem_beaconinterval"] = None self.config["hw_modem_beaconinterval"] = None
if not "hw_modem_beacondata" in self.config: if not "hw_modem_beacondata" in self.config:
self.config["hw_modem_beacondata"] = None self.config["hw_modem_beacondata"] = None
if not "hw_serial_baudrate" in self.config: if not "hw_serial_baudrate" in self.config:
self.config["hw_serial_baudrate"] = 57600 self.config["hw_serial_baudrate"] = 57600
if not "hw_serial_databits" in self.config: if not "hw_serial_databits" in self.config:
@ -735,7 +735,7 @@ class SidebandCore():
self.config["map_use_online"] = True self.config["map_use_online"] = True
if not "map_layer" in self.config: if not "map_layer" in self.config:
self.config["map_layer"] = None self.config["map_layer"] = None
if not "map_storage_path" in self.config: if not "map_storage_path" in self.config:
self.config["map_storage_path"] = None self.config["map_storage_path"] = None
if not "map_storage_file" in self.config: if not "map_storage_file" in self.config:
@ -791,7 +791,7 @@ class SidebandCore():
command_plugins_enabled = self.config["command_plugins_enabled"] == True command_plugins_enabled = self.config["command_plugins_enabled"] == True
service_plugins_enabled = self.config["service_plugins_enabled"] == True service_plugins_enabled = self.config["service_plugins_enabled"] == True
plugins_enabled = service_plugins_enabled plugins_enabled = service_plugins_enabled
if plugins_enabled: if plugins_enabled:
if plugins_path != None: if plugins_path != None:
RNS.log("Loading Sideband plugins...", RNS.LOG_DEBUG) RNS.log("Loading Sideband plugins...", RNS.LOG_DEBUG)
@ -806,7 +806,7 @@ class SidebandCore():
plugin_path = os.path.join(plugins_path, file) plugin_path = os.path.join(plugins_path, file)
exec(open(plugin_path).read(), plugin_globals) exec(open(plugin_path).read(), plugin_globals)
plugin_class = plugin_globals["plugin_class"] plugin_class = plugin_globals["plugin_class"]
if plugin_class != None: if plugin_class != None:
plugin = plugin_class(self) plugin = plugin_class(self)
plugin.start() plugin.start()
@ -819,7 +819,7 @@ class SidebandCore():
RNS.log(f"Registered {plugin)} as handler for command \"{command_name)}\"", RNS.LOG_NOTICE) RNS.log(f"Registered {plugin)} as handler for command \"{command_name)}\"", RNS.LOG_NOTICE)
else: else:
RNS.log(f"Could not register {plugin)} as handler for command \"{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): elif issubclass(type(plugin), SidebandServicePlugin):
service_name = plugin.service_name service_name = plugin.service_name
if not service_name in self.active_service_plugins: if not service_name in self.active_service_plugins:
@ -874,7 +874,7 @@ class SidebandCore():
self.active_propagation_node = dest self.active_propagation_node = dest
self.config["last_lxmf_propagation_node"] = dest self.config["last_lxmf_propagation_node"] = dest
self.message_router.set_outbound_propagation_node(dest) self.message_router.set_outbound_propagation_node(dest)
RNS.log(f"Active propagation node set to: {RNS.prettyhexrep(dest)}") RNS.log(f"Active propagation node set to: {RNS.prettyhexrep(dest)}")
self.__save_config() self.__save_config()
except Exception as e: except Exception as e:
@ -887,7 +887,7 @@ class SidebandCore():
title = strip_emojis(title) title = strip_emojis(title)
content = strip_emojis(content) content = strip_emojis(content)
if self.config["notifications_on"]: if self.config["notifications_on"]:
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
if self.getpersistent("permissions.notifications"): if self.getpersistent("permissions.notifications"):
@ -1033,7 +1033,7 @@ class SidebandCore():
return existing_conv["trust"] == 1 return existing_conv["trust"] == 1
return self.requests_allowed_from(context_dest) return self.requests_allowed_from(context_dest)
except Exception as e: except Exception as e:
RNS.log(f"Error while checking request permissions for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) RNS.log(f"Error while checking request permissions for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR)
return False return False
@ -1226,7 +1226,7 @@ class SidebandCore():
if self.is_client: if self.is_client:
try: try:
return self.service_rpc_request({"request_latest_telemetry": {"from_addr": from_addr}}) return self.service_rpc_request({"request_latest_telemetry": {"from_addr": from_addr}})
except Exception as e: except Exception as e:
RNS.log(f"Error while requesting latest telemetry over RPC: {e)}", RNS.LOG_DEBUG) RNS.log(f"Error while requesting latest telemetry over RPC: {e)}", RNS.LOG_DEBUG)
RNS.trace_exception(e) RNS.trace_exception(e)
@ -1244,7 +1244,7 @@ class SidebandCore():
RNS.trace_exception(e) RNS.trace_exception(e)
return "not_sent" return "not_sent"
else: else:
if from_addr == None or from_addr == self.lxmf_destination.hash: if from_addr == None or from_addr == self.lxmf_destination.hash:
return "no_address" return "no_address"
else: else:
@ -1254,7 +1254,7 @@ class SidebandCore():
if from_addr != None: if from_addr != None:
dest_identity = RNS.Identity.recall(from_addr) dest_identity = RNS.Identity.recall(from_addr)
if dest_identity == None: 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.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) RNS.Transport.request_path(from_addr)
@ -1264,7 +1264,7 @@ class SidebandCore():
now = time.time() now = time.time()
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination source = self.lxmf_destination
if self.config["telemetry_use_propagation_only"] == True: if self.config["telemetry_use_propagation_only"] == True:
desired_method = LXMF.LXMessage.PROPAGATED desired_method = LXMF.LXMessage.PROPAGATED
else: else:
@ -1335,7 +1335,7 @@ class SidebandCore():
if (self.latest_packed_telemetry != None and self.latest_telemetry != None) or stream != None: if (self.latest_packed_telemetry != None and self.latest_telemetry != None) or stream != None:
dest_identity = RNS.Identity.recall(to_addr) dest_identity = RNS.Identity.recall(to_addr)
if dest_identity == None: 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.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) RNS.Transport.request_path(to_addr)
@ -1344,7 +1344,7 @@ class SidebandCore():
else: else:
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination source = self.lxmf_destination
if self.config["telemetry_use_propagation_only"] == True: if self.config["telemetry_use_propagation_only"] == True:
desired_method = LXMF.LXMessage.PROPAGATED desired_method = LXMF.LXMessage.PROPAGATED
else: else:
@ -1385,7 +1385,7 @@ class SidebandCore():
self.setstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending", True) self.setstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending", True)
self.message_router.handle_outbound(lxm) self.message_router.handle_outbound(lxm)
return "sent" return "sent"
else: else:
RNS.log(f"Telemetry update with timebase {telemetry_timebase} was already successfully sent", RNS.LOG_DEBUG) RNS.log(f"Telemetry update with timebase {telemetry_timebase} was already successfully sent", RNS.LOG_DEBUG)
return "already_sent" return "already_sent"
@ -1695,7 +1695,7 @@ class SidebandCore():
RNS.log("Ready for next RPC client", RNS.LOG_DEBUG) RNS.log("Ready for next RPC client", RNS.LOG_DEBUG)
rpc_connection = self.rpc_listener.accept() rpc_connection = self.rpc_listener.accept()
RNS.log("Accepted RPC client", RNS.LOG_DEBUG) RNS.log("Accepted RPC client", RNS.LOG_DEBUG)
def job_factory(connection): def job_factory(connection):
def rpc_client_job(): def rpc_client_job():
try: try:
@ -1876,7 +1876,7 @@ class SidebandCore():
try: try:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "select * from persistent where property=:uprop" query = "select * from persistent where property=:uprop"
dbc.execute(query, {"uprop": prop.encode("utf-8")}) dbc.execute(query, {"uprop": prop.encode("utf-8")})
result = dbc.fetchall() result = dbc.fetchall()
@ -1896,7 +1896,7 @@ class SidebandCore():
except Exception as e: 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) RNS.log(f"Could not unpack persistent value from database for property \"{prop)}\". The contained exception was: {e)}", RNS.LOG_ERROR)
return None return None
except Exception as e: except Exception as e:
RNS.log(f"An error occurred during persistent getstate database operation: {e)}", RNS.LOG_ERROR) RNS.log(f"An error occurred during persistent getstate database operation: {e)}", RNS.LOG_ERROR)
self.db = None self.db = None
@ -1917,7 +1917,7 @@ class SidebandCore():
data = (uprop, bval) data = (uprop, bval)
dbc.execute(query, data) dbc.execute(query, data)
db.commit() db.commit()
except Exception as e: except Exception as e:
RNS.log(f"Error while setting persistent state property {prop)} in DB: {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...") RNS.log("Retrying as update query...")
@ -1929,7 +1929,7 @@ class SidebandCore():
query = "UPDATE persistent set value=:bval where property=:uprop;" query = "UPDATE persistent set value=:bval where property=:uprop;"
dbc.execute(query, {"bval": bval, "uprop": uprop}) dbc.execute(query, {"bval": bval, "uprop": uprop})
db.commit() db.commit()
except Exception as e: except Exception as e:
RNS.log(f"An error occurred during persistent setstate database operation: {e)}", RNS.LOG_ERROR) RNS.log(f"An error occurred during persistent setstate database operation: {e)}", RNS.LOG_ERROR)
self.db = None self.db = None
@ -1958,7 +1958,7 @@ class SidebandCore():
try: try:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
if unread: if unread:
if tx: if tx:
query = "UPDATE conv set unread = ?, last_tx = ? where dest_context = ?" query = "UPDATE conv set unread = ?, last_tx = ? where dest_context = ?"
@ -2003,7 +2003,7 @@ class SidebandCore():
query = query = "select * from telemetry" query = query = "select * from telemetry"
dbc.execute(query, {}) dbc.execute(query, {})
else: else:
if after != None and before == None: if after != None and before == None:
query = f"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}) dbc.execute(query, {"context_dest": context_dest, "after_ts": after})
@ -2027,12 +2027,12 @@ class SidebandCore():
telemetry_source = entry[1] telemetry_source = entry[1]
telemetry_timestamp = entry[2] telemetry_timestamp = entry[2]
telemetry_data = entry[3] telemetry_data = entry[3]
if not telemetry_source in results: if not telemetry_source in results:
results[telemetry_source] = [] results[telemetry_source] = []
results[telemetry_source].append([telemetry_timestamp, telemetry_data]) results[telemetry_source].append([telemetry_timestamp, telemetry_data])
return results return results
def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, source_dest = None, via = None, is_retry = False): def _db_save_telemetry(self, context_dest, telemetry, physical_link = None, source_dest = None, via = None, is_retry = False):
@ -2096,7 +2096,7 @@ class SidebandCore():
remote_telemeter.sensors["received"].via = via remote_telemeter.sensors["received"].via = via
remote_telemeter.sensors["received"].update_data() remote_telemeter.sensors["received"].update_data()
telemetry = remote_telemeter.packed() telemetry = remote_telemeter.packed()
query = "INSERT INTO telemetry (dest_context, ts, data) values (?, ?, ?)" query = "INSERT INTO telemetry (dest_context, ts, data) values (?, ?, ?)"
data = (context_dest, telemetry_timestamp, telemetry) data = (context_dest, telemetry_timestamp, telemetry)
dbc.execute(query, data) dbc.execute(query, data)
@ -2130,7 +2130,7 @@ class SidebandCore():
# TODO: Clean out these temporary values at some interval. # TODO: Clean out these temporary values at some interval.
# Probably expire after 14 days or so. # Probably expire after 14 days or so.
self.setpersistent(f"temp.peer_appearance.{RNS.hexrep(context_dest, delimit=False)}", ae) self.setpersistent(f"temp.peer_appearance.{RNS.hexrep(context_dest, delimit=False)}", ae)
else: else:
with self.db_lock: with self.db_lock:
data_dict = conv["data"] data_dict = conv["data"]
@ -2147,10 +2147,10 @@ class SidebandCore():
if data_dict["appearance"] != appearance: if data_dict["appearance"] != appearance:
data_dict["appearance"] = appearance data_dict["appearance"] = appearance
packed_dict = msgpack.packb(data_dict) packed_dict = msgpack.packb(data_dict)
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set data = ? where dest_context = ?" query = "UPDATE conv set data = ? where dest_context = ?"
data = (packed_dict, context_dest) data = (packed_dict, context_dest)
dbc.execute(query, data) dbc.execute(query, data)
@ -2195,7 +2195,7 @@ class SidebandCore():
appearance = data_dict["appearance"] appearance = data_dict["appearance"]
else: else:
appearance = [data_dict["appearance"][0], htf(data_dict["appearance"][1]), htf(data_dict["appearance"][2])] appearance = [data_dict["appearance"][0], htf(data_dict["appearance"][1]), htf(data_dict["appearance"][2])]
return appearance return appearance
except Exception as e: except Exception as e:
RNS.log(f"Could not retrieve appearance for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR) RNS.log(f"Could not retrieve appearance for {RNS.prettyhexrep(context_dest)}: {e)}", RNS.LOG_ERROR)
@ -2211,11 +2211,11 @@ class SidebandCore():
data_dict["telemetry"] = send_telemetry data_dict["telemetry"] = send_telemetry
packed_dict = msgpack.packb(data_dict) packed_dict = msgpack.packb(data_dict)
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set data = ? where dest_context = ?" query = "UPDATE conv set data = ? where dest_context = ?"
data = (packed_dict, context_dest) data = (packed_dict, context_dest)
dbc.execute(query, data) dbc.execute(query, data)
@ -2238,11 +2238,11 @@ class SidebandCore():
data_dict["allow_requests"] = allow_requests data_dict["allow_requests"] = allow_requests
packed_dict = msgpack.packb(data_dict) packed_dict = msgpack.packb(data_dict)
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set data = ? where dest_context = ?" query = "UPDATE conv set data = ? where dest_context = ?"
data = (packed_dict, context_dest) data = (packed_dict, context_dest)
dbc.execute(query, data) dbc.execute(query, data)
@ -2265,11 +2265,11 @@ class SidebandCore():
data_dict["is_object"] = is_object data_dict["is_object"] = is_object
packed_dict = msgpack.packb(data_dict) packed_dict = msgpack.packb(data_dict)
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set data = ? where dest_context = ?" query = "UPDATE conv set data = ? where dest_context = ?"
data = (packed_dict, context_dest) data = (packed_dict, context_dest)
dbc.execute(query, data) dbc.execute(query, data)
@ -2292,11 +2292,11 @@ class SidebandCore():
data_dict["ptt_enabled"] = ptt_enabled data_dict["ptt_enabled"] = ptt_enabled
packed_dict = msgpack.packb(data_dict) packed_dict = msgpack.packb(data_dict)
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set data = ? where dest_context = ?" query = "UPDATE conv set data = ? where dest_context = ?"
data = (packed_dict, context_dest) data = (packed_dict, context_dest)
dbc.execute(query, data) dbc.execute(query, data)
@ -2315,7 +2315,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set trust = ? where dest_context = ?" query = "UPDATE conv set trust = ? where dest_context = ?"
data = (trusted, context_dest) data = (trusted, context_dest)
dbc.execute(query, data) dbc.execute(query, data)
@ -2334,11 +2334,11 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE conv set name=:name_data where dest_context=:ctx;" query = "UPDATE conv set name=:name_data where dest_context=:ctx;"
dbc.execute(query, {"ctx": context_dest, "name_data": name.encode("utf-8")}) dbc.execute(query, {"ctx": context_dest, "name_data": name.encode("utf-8")})
result = dbc.fetchall() result = dbc.fetchall()
try: try:
db.commit() db.commit()
except Exception as e: except Exception as e:
@ -2352,7 +2352,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
dbc.execute("select * from conv") dbc.execute("select * from conv")
result = dbc.fetchall() result = dbc.fetchall()
@ -2397,7 +2397,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
dbc.execute("select * from announce order by received desc") dbc.execute("select * from announce order by received desc")
result = dbc.fetchall() result = dbc.fetchall()
@ -2429,7 +2429,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "select * from conv where dest_context=:ctx" query = "select * from conv where dest_context=:ctx"
dbc.execute(query, {"ctx": context_dest}) dbc.execute(query, {"ctx": context_dest})
result = dbc.fetchall() result = dbc.fetchall()
@ -2562,7 +2562,7 @@ class SidebandCore():
extras = msgpack.packb(msg_extras) extras = msgpack.packb(msg_extras)
query = "UPDATE lxm set state = ?, extra = ? where lxm_hash = ?" query = "UPDATE lxm set state = ?, extra = ? where lxm_hash = ?"
data = (state, extras, lxm_hash) data = (state, extras, lxm_hash)
else: else:
query = "UPDATE lxm set state = ? where lxm_hash = ?" query = "UPDATE lxm set state = ? where lxm_hash = ?"
data = (state, lxm_hash) data = (state, lxm_hash)
@ -2583,7 +2583,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "UPDATE lxm set method = ? where lxm_hash = ?" query = "UPDATE lxm set method = ? where lxm_hash = ?"
data = (method, lxm_hash) data = (method, lxm_hash)
dbc.execute(query, data) dbc.execute(query, data)
@ -2605,7 +2605,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "select * from lxm where lxm_hash=:mhash" query = "select * from lxm where lxm_hash=:mhash"
dbc.execute(query, {"mhash": msg_hash}) dbc.execute(query, {"mhash": msg_hash})
result = dbc.fetchall() result = dbc.fetchall()
@ -2653,7 +2653,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
query = "select count(*) from lxm where dest=:context_dest or source=:context_dest" query = "select count(*) from lxm where dest=:context_dest or source=:context_dest"
dbc.execute(query, {"context_dest": context_dest}) dbc.execute(query, {"context_dest": context_dest})
@ -2668,7 +2668,7 @@ class SidebandCore():
with self.db_lock: with self.db_lock:
db = self.__db_connect() db = self.__db_connect()
dbc = db.cursor() dbc = db.cursor()
if after != None and before == None: if after != None and before == None:
query = "select * from lxm where (dest=:context_dest or source=:context_dest) and rx_ts>:after_ts" 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}) dbc.execute(query, {"context_dest": context_dest, "after_ts": after})
@ -2698,7 +2698,7 @@ class SidebandCore():
packed_lxm = entry[10] packed_lxm = entry[10]
lxm = LXMF.LXMessage.unpack_from_bytes(packed_lxm, original_method = lxm_method) lxm = LXMF.LXMessage.unpack_from_bytes(packed_lxm, original_method = lxm_method)
if lxm.desired_method == LXMF.LXMessage.PAPER: if lxm.desired_method == LXMF.LXMessage.PAPER:
lxm.paper_packed = paper_packed_lxm lxm.paper_packed = paper_packed_lxm
@ -2707,7 +2707,7 @@ class SidebandCore():
extras = msgpack.unpackb(entry[11]) extras = msgpack.unpackb(entry[11])
except: except:
pass pass
message = { message = {
"hash": lxm.hash, "hash": lxm.hash,
"dest": lxm.destination_hash, "dest": lxm.destination_hash,
@ -2868,13 +2868,13 @@ class SidebandCore():
self.next_auto_announce = time.time() + 60*(random.random()*(SidebandCore.AUTO_ANNOUNCE_RANDOM_MAX-SidebandCore.AUTO_ANNOUNCE_RANDOM_MIN)+SidebandCore.AUTO_ANNOUNCE_RANDOM_MIN) 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) RNS.log(f"Next auto announce in {RNS.prettytime(self.next_auto_announce - time.time())}", RNS.LOG_DEBUG)
self.setstate("wants.announce", False) self.setstate("wants.announce", False)
else: else:
if self.config["lxmf_require_stamps"]: if self.config["lxmf_require_stamps"]:
self.message_router.set_inbound_stamp_cost(self.lxmf_destination.hash, self.config["lxmf_inbound_stamp_cost"]) self.message_router.set_inbound_stamp_cost(self.lxmf_destination.hash, self.config["lxmf_inbound_stamp_cost"])
else: else:
self.message_router.set_inbound_stamp_cost(self.lxmf_destination.hash, None) self.message_router.set_inbound_stamp_cost(self.lxmf_destination.hash, None)
self.setstate("wants.announce", True) self.setstate("wants.announce", True)
def run_telemetry(self): def run_telemetry(self):
@ -3000,7 +3000,7 @@ class SidebandCore():
except Exception as e: 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.log(f"An error occurred while {telemetry_plugin)} was handling telemetry. The contained exception was: {e)}", RNS.LOG_ERROR)
RNS.trace_exception(e) RNS.trace_exception(e)
if self.config["telemetry_s_fixed_location"]: if self.config["telemetry_s_fixed_location"]:
self.telemeter.synthesize("location") self.telemeter.synthesize("location")
self.telemeter.sensors["location"].latitude = self.config["telemetry_s_fixed_latlon"][0] self.telemeter.sensors["location"].latitude = self.config["telemetry_s_fixed_latlon"][0]
@ -3071,7 +3071,7 @@ class SidebandCore():
if self.message_router.delivery_per_transfer_limit != lxm_limit: if self.message_router.delivery_per_transfer_limit != lxm_limit:
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) RNS.log(f"Updated delivery limit to {RNS.prettysize(self.message_router.delivery_per_transfer_limit * 1000)}", RNS.LOG_DEBUG)
except Exception as e: except Exception as e:
RNS.log(f"Error while updating LXMF router delivery limit: {e)}", RNS.LOG_ERROR) RNS.log(f"Error while updating LXMF router delivery limit: {e)}", RNS.LOG_ERROR)
@ -3213,7 +3213,7 @@ class SidebandCore():
else: else:
RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR) RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR)
self.setstate("executing.bt_on", False) self.setstate("executing.bt_on", False)
if self.getstate("wants.bt_off"): if self.getstate("wants.bt_off"):
self.setstate("wants.bt_off", False) self.setstate("wants.bt_off", False)
self.owner_app.discover_usb_devices() self.owner_app.discover_usb_devices()
@ -3228,7 +3228,7 @@ class SidebandCore():
else: else:
RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR) RNS.log("Could not execute RNode Bluetooth control command, no USB devices available", RNS.LOG_ERROR)
self.setstate("executing.bt_off", False) self.setstate("executing.bt_off", False)
if self.getstate("wants.bt_pair"): if self.getstate("wants.bt_pair"):
self.setstate("wants.bt_pair", False) self.setstate("wants.bt_pair", False)
self.owner_app.discover_usb_devices() self.owner_app.discover_usb_devices()
@ -3379,7 +3379,7 @@ class SidebandCore():
self.service_thread = threading.Thread(target=self._service_jobs, daemon=True) self.service_thread = threading.Thread(target=self._service_jobs, daemon=True)
self.service_thread.start() 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"]: if self.config["start_announce"]:
def da(): def da():
time.sleep(8) time.sleep(8)
@ -3437,7 +3437,7 @@ class SidebandCore():
if_mode = Interface.Interface.MODE_BOUNDARY if_mode = Interface.Interface.MODE_BOUNDARY
else: else:
if_mode = None if_mode = None
self.reticulum._add_interface(autointerface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.reticulum._add_interface(autointerface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey)
self.interface_local = autointerface self.interface_local = autointerface
self.interface_local_adding = False self.interface_local_adding = False
@ -3464,7 +3464,7 @@ class SidebandCore():
target_port = target_device["port"] target_port = target_device["port"]
else: else:
target_port = None target_port = None
bt_device_name = None bt_device_name = None
rnode_allow_bluetooth = False rnode_allow_bluetooth = False
rnode_allow_ble = False rnode_allow_ble = False
@ -3563,7 +3563,7 @@ class SidebandCore():
if_mode = Interface.Interface.MODE_BOUNDARY if_mode = Interface.Interface.MODE_BOUNDARY
else: else:
if_mode = None if_mode = None
self.reticulum._add_interface(rnodeinterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.reticulum._add_interface(rnodeinterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey)
self.interface_rnode = rnodeinterface self.interface_rnode = rnodeinterface
self.interface_rnode_adding = False self.interface_rnode_adding = False
@ -3622,7 +3622,7 @@ class SidebandCore():
if not self.reticulum.is_connected_to_shared_instance: if not self.reticulum.is_connected_to_shared_instance:
RNS.log("Running as master or standalone instance, adding interfaces") RNS.log("Running as master or standalone instance, adding interfaces")
self.interface_local = None self.interface_local = None
self.interface_tcp = None self.interface_tcp = None
self.interface_i2p = None self.interface_i2p = None
@ -3682,7 +3682,7 @@ class SidebandCore():
if_mode = Interface.Interface.MODE_BOUNDARY if_mode = Interface.Interface.MODE_BOUNDARY
else: else:
if_mode = None if_mode = None
self.reticulum._add_interface(tcpinterface, mode=if_mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, ifac_size=ifac_size) self.reticulum._add_interface(tcpinterface, mode=if_mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, ifac_size=ifac_size)
self.interface_tcp = tcpinterface self.interface_tcp = tcpinterface
@ -3733,9 +3733,9 @@ class SidebandCore():
if_mode = Interface.Interface.MODE_BOUNDARY if_mode = Interface.Interface.MODE_BOUNDARY
else: else:
if_mode = None if_mode = None
self.reticulum._add_interface(i2pinterface, mode = if_mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, ifac_size=ifac_size) 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: for si in RNS.Transport.interfaces:
if type(si) == RNS.Interfaces.I2PInterface.I2PInterfacePeer: if type(si) == RNS.Interfaces.I2PInterface.I2PInterfacePeer:
self.interface_i2p = si self.interface_i2p = si
@ -3794,7 +3794,7 @@ class SidebandCore():
if_mode = Interface.Interface.MODE_BOUNDARY if_mode = Interface.Interface.MODE_BOUNDARY
else: else:
if_mode = None if_mode = None
self.reticulum._add_interface(serialinterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.reticulum._add_interface(serialinterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey)
self.interface_serial = serialinterface self.interface_serial = serialinterface
@ -3854,7 +3854,7 @@ class SidebandCore():
if_mode = Interface.Interface.MODE_BOUNDARY if_mode = Interface.Interface.MODE_BOUNDARY
else: else:
if_mode = None if_mode = None
self.reticulum._add_interface(modeminterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey) self.reticulum._add_interface(modeminterface, mode = if_mode, ifac_netname = ifac_netname, ifac_netkey = ifac_netkey)
self.interface_modem = modeminterface self.interface_modem = modeminterface
@ -3864,7 +3864,7 @@ class SidebandCore():
RNS.log("Reticulum started, activating LXMF...") RNS.log("Reticulum started, activating LXMF...")
self.setstate("init.loadingstate", "Activating LXMF Router") self.setstate("init.loadingstate", "Activating LXMF Router")
if self.config["lxm_limit_1mb"]: if self.config["lxm_limit_1mb"]:
lxm_limit = 1000 lxm_limit = 1000
else: else:
@ -3882,7 +3882,7 @@ class SidebandCore():
self.message_router.enforce_stamps() self.message_router.enforce_stamps()
else: else:
self.message_router.ignore_stamps() 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) # 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 # Currently overrides the LXMF routers auto-generated announce data so that Sideband will announce old-format
# LXMF announces if require_stamps is disabled. # LXMF announces if require_stamps is disabled.
@ -3990,7 +3990,7 @@ class SidebandCore():
dest_identity = RNS.Identity.recall(destination_hash) dest_identity = RNS.Identity.recall(destination_hash)
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination source = self.lxmf_destination
desired_method = LXMF.LXMessage.PAPER desired_method = LXMF.LXMessage.PAPER
# TODO: Should paper messages also include a ticket to trusted peers? # 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)) lxm = LXMF.LXMessage(dest, source, content, title="", desired_method=desired_method, fields = self.get_message_fields(destination_hash), include_ticket=self.is_trusted(destination_hash))
@ -4010,7 +4010,7 @@ class SidebandCore():
if self.is_client: if self.is_client:
try: try:
return self.service_rpc_request({"get_lxm_progress": {"lxm_hash": lxm_hash}}) return self.service_rpc_request({"get_lxm_progress": {"lxm_hash": lxm_hash}})
except Exception as e: except Exception as e:
RNS.log(f"Error while getting LXM progress over RPC: {e)}", RNS.LOG_DEBUG) RNS.log(f"Error while getting LXM progress over RPC: {e)}", RNS.LOG_DEBUG)
RNS.trace_exception(e) RNS.trace_exception(e)
@ -4053,7 +4053,7 @@ class SidebandCore():
"image": image, "image": image,
"audio": audio} "audio": audio}
}) })
except Exception as e: except Exception as e:
RNS.log(f"Error while sending message over RPC: {e)}", RNS.LOG_DEBUG) RNS.log(f"Error while sending message over RPC: {e)}", RNS.LOG_DEBUG)
RNS.trace_exception(e) RNS.trace_exception(e)
@ -4098,7 +4098,7 @@ class SidebandCore():
dest_identity = RNS.Identity.recall(destination_hash) dest_identity = RNS.Identity.recall(destination_hash)
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination source = self.lxmf_destination
if propagation: if propagation:
desired_method = LXMF.LXMessage.PROPAGATED desired_method = LXMF.LXMessage.PROPAGATED
else: else:
@ -4121,7 +4121,7 @@ class SidebandCore():
fields[LXMF.FIELD_AUDIO] = audio 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)) lxm = LXMF.LXMessage(dest, source, content, title="", desired_method=desired_method, fields = fields, include_ticket=self.is_trusted(destination_hash))
if not no_display: if not no_display:
lxm.register_delivery_callback(self.message_notification) lxm.register_delivery_callback(self.message_notification)
lxm.register_failed_callback(self.message_notification) lxm.register_failed_callback(self.message_notification)
@ -4178,7 +4178,7 @@ class SidebandCore():
dest_identity = RNS.Identity.recall(destination_hash) dest_identity = RNS.Identity.recall(destination_hash)
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination source = self.lxmf_destination
if propagation: if propagation:
desired_method = LXMF.LXMessage.PROPAGATED desired_method = LXMF.LXMessage.PROPAGATED
else: else:
@ -4240,13 +4240,13 @@ class SidebandCore():
if ingest_result == False: if ingest_result == False:
response = "The URI contained no decodable messages" response = "The URI contained no decodable messages"
elif ingest_result == local_delivery_signal: elif ingest_result == local_delivery_signal:
response = "Message was decoded, decrypted successfully, and added to your conversation list." response = "Message was decoded, decrypted successfully, and added to your conversation list."
elif ingest_result == duplicate_signal: elif ingest_result == duplicate_signal:
response = "The decoded message has already been processed by the LXMF Router, and will not be ingested again." response = "The decoded message has already been processed by the LXMF Router, and will not be ingested again."
else: else:
# TODO: Add message to sneakernet queues # TODO: Add message to sneakernet queues
response = "The decoded message was not addressed to your LXMF address, and has been discarded." response = "The decoded message was not addressed to your LXMF address, and has been discarded."
@ -4382,7 +4382,7 @@ class SidebandCore():
elif audio_field[0] >= LXMF.AM_CODEC2_700C and audio_field[0] <= LXMF.AM_CODEC2_3200: elif audio_field[0] >= LXMF.AM_CODEC2_700C and audio_field[0] <= LXMF.AM_CODEC2_3200:
temp_path = f"{self.rec_cache}/msg.ogg" temp_path = f"{self.rec_cache}/msg.ogg"
from sideband.audioproc import samples_to_ogg, decode_codec2, detect_codec2 from sideband.audioproc import samples_to_ogg, decode_codec2, detect_codec2
target_rate = 8000 target_rate = 8000
if RNS.vendor.platformutils.is_linux(): if RNS.vendor.platformutils.is_linux():
target_rate = 48000 target_rate = 48000
@ -4395,7 +4395,7 @@ class SidebandCore():
else: else:
self.last_msg_audio = None self.last_msg_audio = None
return return
else: else:
# Unimplemented audio type # Unimplemented audio type
pass pass
@ -4598,16 +4598,16 @@ class SidebandCore():
else: else:
RNS.log("Responding with own latest telemetry", RNS.LOG_DEBUG) RNS.log("Responding with own latest telemetry", RNS.LOG_DEBUG)
self.send_latest_telemetry(to_addr=context_dest) self.send_latest_telemetry(to_addr=context_dest)
elif Commands.PING in command: elif Commands.PING in command:
RNS.log("Handling ping request", RNS.LOG_DEBUG) RNS.log("Handling ping request", RNS.LOG_DEBUG)
self.send_message("Ping reply", context_dest, False, skip_fields=True, no_display=True) self.send_message("Ping reply", context_dest, False, skip_fields=True, no_display=True)
elif Commands.ECHO in command: elif Commands.ECHO in command:
msg_content = f"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) RNS.log("Handling echo request", RNS.LOG_DEBUG)
self.send_message(msg_content, context_dest, False, skip_fields=True, no_display=True) self.send_message(msg_content, context_dest, False, skip_fields=True, no_display=True)
elif Commands.SIGNAL_REPORT in command: elif Commands.SIGNAL_REPORT in command:
RNS.log("Handling signal report", RNS.LOG_DEBUG) RNS.log("Handling signal report", RNS.LOG_DEBUG)
phy_str = "" phy_str = ""

View File

@ -139,12 +139,12 @@ def ellipsoid_distance(c1, c2):
sin_sigma = t**0.5 sin_sigma = t**0.5
cos_sigma = sin(U1)*sin(U2) + cos(U1)*cos(U2)*cos(lambda_old) cos_sigma = sin(U1)*sin(U2) + cos(U1)*cos(U2)*cos(lambda_old)
sigma = atan2(sin_sigma, cos_sigma) sigma = atan2(sin_sigma, cos_sigma)
sin_alpha = cos(U1)*cos(U2)*sin(lambda_old) / sin_sigma sin_alpha = cos(U1)*cos(U2)*sin(lambda_old) / sin_sigma
cos_sq_alpha = 1 - sin_alpha**2 cos_sq_alpha = 1 - sin_alpha**2
cos_2sigma_m = cos_sigma - 2*sin(U1)*sin(U2)/cos_sq_alpha 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 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)) 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 lambda_new = L + (1 - C)*f*sin_alpha*t
if abs(lambda_new - lambda_old) <= tolerance: if abs(lambda_new - lambda_old) <= tolerance:
@ -155,7 +155,7 @@ def ellipsoid_distance(c1, c2):
if iteration%1000 == 0: if iteration%1000 == 0:
if iteration >= max_iterations: if iteration >= max_iterations:
return None return None
if time.time() > st+timeout: if time.time() > st+timeout:
return None return None
@ -171,7 +171,7 @@ def ellipsoid_distance(c1, c2):
except Exception as e: except Exception as e:
return None return None
def azalt(c1, c2, ellipsoid=True): def azalt(c1, c2, ellipsoid=True):
c2rp = rotate_globe(c1, c2, ellipsoid=ellipsoid) c2rp = rotate_globe(c1, c2, ellipsoid=ellipsoid)
altitude = None altitude = None
azimuth = None azimuth = None
@ -280,7 +280,7 @@ def radio_horizon(h, rh=0, ellipsoid=False):
def shared_radio_horizon(c1, c2,): def shared_radio_horizon(c1, c2,):
lat1 = c1[0]; lon1 = c1[1]; h1 = c1[2] lat1 = c1[0]; lon1 = c1[1]; h1 = c1[2]
lat2 = c2[0]; lon2 = c2[1]; h2 = c2[2] lat2 = c2[0]; lon2 = c2[1]; h2 = c2[2]
geodesic_distance = orthodromic_distance((lat1, lon1, 0.0), (lat2, lon2, 0.0) , ellipsoid=False) geodesic_distance = orthodromic_distance((lat1, lon1, 0.0), (lat2, lon2, 0.0) , ellipsoid=False)
antenna_distance = euclidian_distance(c1,c2,ellipsoid=False) antenna_distance = euclidian_distance(c1,c2,ellipsoid=False)
rh1 = radio_horizon(h1) rh1 = radio_horizon(h1)
@ -532,7 +532,7 @@ class GeoidHeight:
# us = time.time() # us = time.time()
# ld = c1+c2; g = geod.Inverse(c1[0], c1[1], c2[0], c2[1]) # 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") # 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) # eld = orthodromic_distance(c1,c2,ellipsoid=True)
# if eld: # if eld:
# print("Own computed in "+str(round((time.time()-us)*1e6, 3))+"us") # print("Own computed in "+str(round((time.time()-us)*1e6, 3))+"us")

View File

@ -1,34 +1,34 @@
sideband_fb_data = [ sideband_fb_data = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
] ]

View File

@ -93,7 +93,7 @@ class Telemeter():
self.sensors[sensor]._telemeter = self self.sensors[sensor]._telemeter = self
if not self.sensors[sensor].active: if not self.sensors[sensor].active:
self.sensors[sensor].start() self.sensors[sensor].start()
def disable(self, sensor): def disable(self, sensor):
if not self.from_packed: if not self.from_packed:
if sensor in self.available: if sensor in self.available:
@ -159,9 +159,9 @@ class Telemeter():
except Exception as e: except Exception as e:
RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR) RNS.log(f"Error while checking permission: {e)}", RNS.LOG_ERROR)
return False return False
else: else:
from android.permissions import check_permission from android.permissions import check_permission
return check_permission(f"android.permission.{permission}") return check_permission(f"android.permission.{permission}")
@ -440,7 +440,7 @@ class Battery(Sensor):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
from plyer import battery from plyer import battery
self.battery = battery self.battery = battery
elif RNS.vendor.platformutils.is_linux(): elif RNS.vendor.platformutils.is_linux():
node_exists = False node_exists = False
bn = 0 bn = 0
@ -467,7 +467,7 @@ class Battery(Sensor):
self.battery.get_state() self.battery.get_state()
b = self.battery.status b = self.battery.status
self.data = {"charge_percent": b["percentage"], "charging": b["isCharging"], "temperature": None} self.data = {"charge_percent": b["percentage"], "charging": b["isCharging"], "temperature": None}
elif RNS.vendor.platformutils.is_linux(): elif RNS.vendor.platformutils.is_linux():
if self.battery_node_name: if self.battery_node_name:
status = {"isCharging": None, "percentage": None} status = {"isCharging": None, "percentage": None}
@ -486,7 +486,7 @@ class Battery(Sensor):
is_charging = output['POWER_SUPPLY_STATUS'] == 'Charging' is_charging = output['POWER_SUPPLY_STATUS'] == 'Charging'
charge_percent = float(output['POWER_SUPPLY_CAPACITY']) charge_percent = float(output['POWER_SUPPLY_CAPACITY'])
self.data = {"charge_percent": round(charge_percent, 1), "charging": is_charging, "temperature": None} self.data = {"charge_percent": round(charge_percent, 1), "charging": is_charging, "temperature": None}
except: except:
self.data = None self.data = None
@ -515,7 +515,7 @@ class Battery(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
d = self.data d = self.data
p = d["charge_percent"] p = d["charge_percent"]
t = d["temperature"] t = d["temperature"]
@ -580,7 +580,7 @@ class Pressure(Sensor):
try: try:
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.data = {"mbar": round(self.android_sensor.pressure, 2)} self.data = {"mbar": round(self.android_sensor.pressure, 2)}
except: except:
self.data = None self.data = None
@ -623,7 +623,7 @@ class Pressure(Sensor):
class Location(Sensor): class Location(Sensor):
SID = Sensor.SID_LOCATION SID = Sensor.SID_LOCATION
STALE_TIME = 15 STALE_TIME = 15
MIN_DISTANCE = 4 MIN_DISTANCE = 4
ACCURACY_TARGET = 250 ACCURACY_TARGET = 250
@ -679,11 +679,11 @@ class Location(Sensor):
self._location_provider = self self._location_provider = self
self.update_data() self.update_data()
def teardown_sensor(self): def teardown_sensor(self):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.gps.stop() self.gps.stop()
self.latitude = None self.latitude = None
self.longitude = None self.longitude = None
self.altitude = None self.altitude = None
@ -764,7 +764,7 @@ class Location(Sensor):
"accuracy": round(self.accuracy, 2), "accuracy": round(self.accuracy, 2),
"last_update": int(self._last_update), "last_update": int(self._last_update),
} }
except: except:
self.data = None self.data = None
@ -816,7 +816,7 @@ class Location(Sensor):
coords = (self.data["latitude"], self.data["longitude"], aamsl) coords = (self.data["latitude"], self.data["longitude"], aamsl)
obj_ath = angle_to_horizon(coords) obj_ath = angle_to_horizon(coords)
obj_rh = radio_horizon(aamsl) obj_rh = radio_horizon(aamsl)
rendered = { rendered = {
"icon": "map-marker", "icon": "map-marker",
"name": "Location", "name": "Location",
@ -856,7 +856,7 @@ class Location(Sensor):
above_horizon = True above_horizon = True
else: else:
above_horizon = False above_horizon = False
srh = shared_radio_horizon(cs, cr) srh = shared_radio_horizon(cs, cr)
if salt != None and alt != None: if salt != None and alt != None:
dalt = salt-alt dalt = salt-alt
@ -917,7 +917,7 @@ class PhysicalLink(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
q = self.data["q"] q = self.data["q"]
rendered = { rendered = {
"icon": "network-strength-outline", "icon": "network-strength-outline",
@ -956,7 +956,7 @@ class Temperature(Sensor):
try: try:
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.data = {"c": round(self.android_sensor.temperature, 2)} self.data = {"c": round(self.android_sensor.temperature, 2)}
except: except:
self.data = None self.data = None
@ -1012,7 +1012,7 @@ class Humidity(Sensor):
try: try:
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.data = {"percent_relative": round(self.android_sensor.tell, 2)} self.data = {"percent_relative": round(self.android_sensor.tell, 2)}
except: except:
self.data = None self.data = None
@ -1035,7 +1035,7 @@ class Humidity(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
rendered = { rendered = {
"icon": "water-percent", "icon": "water-percent",
"name": "Relative Humidity", "name": "Relative Humidity",
@ -1069,7 +1069,7 @@ class MagneticField(Sensor):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
vectors = self.android_sensor.field vectors = self.android_sensor.field
self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)}
except: except:
self.data = None self.data = None
@ -1092,7 +1092,7 @@ class MagneticField(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
rendered = { rendered = {
"icon": "magnet", "icon": "magnet",
"name": "Magnetic Field", "name": "Magnetic Field",
@ -1125,7 +1125,7 @@ class AmbientLight(Sensor):
try: try:
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.data = {"lux": round(self.android_sensor.illumination, 2)} self.data = {"lux": round(self.android_sensor.illumination, 2)}
except: except:
self.data = None self.data = None
@ -1155,7 +1155,7 @@ class AmbientLight(Sensor):
if rs.data != None and "lux" in rs.data and rs.data["lux"] != None: if rs.data != None and "lux" in rs.data and rs.data["lux"] != None:
if self.data["lux"] != None: if self.data["lux"] != None:
delta = round(rs.data["lux"] - self.data["lux"], 2) delta = round(rs.data["lux"] - self.data["lux"], 2)
rendered = { rendered = {
"icon": "white-balance-sunny", "icon": "white-balance-sunny",
"name": "Ambient Light", "name": "Ambient Light",
@ -1192,7 +1192,7 @@ class Gravity(Sensor):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
vectors = self.android_sensor.gravity vectors = self.android_sensor.gravity
self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)}
except: except:
self.data = None self.data = None
@ -1215,7 +1215,7 @@ class Gravity(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
rendered = { rendered = {
"icon": "arrow-down-thin-circle-outline", "icon": "arrow-down-thin-circle-outline",
"name": "Gravity", "name": "Gravity",
@ -1249,7 +1249,7 @@ class AngularVelocity(Sensor):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
vectors = self.android_sensor.rotation vectors = self.android_sensor.rotation
self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)}
except: except:
self.data = None self.data = None
@ -1272,7 +1272,7 @@ class AngularVelocity(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
rendered = { rendered = {
"icon": "orbit", "icon": "orbit",
"name": "Angular Velocity", "name": "Angular Velocity",
@ -1306,7 +1306,7 @@ class Acceleration(Sensor):
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
vectors = self.android_sensor.acceleration vectors = self.android_sensor.acceleration
self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)} self.data = {"x": round(vectors[0], 6), "y": round(vectors[1], 6), "z": round(vectors[2], 6)}
except: except:
self.data = None self.data = None
@ -1351,7 +1351,7 @@ class Proximity(Sensor):
try: try:
if RNS.vendor.platformutils.is_android(): if RNS.vendor.platformutils.is_android():
self.data = self.android_sensor.proximity self.data = self.android_sensor.proximity
except: except:
self.data = None self.data = None
@ -1374,7 +1374,7 @@ class Proximity(Sensor):
def render(self, relative_to=None): def render(self, relative_to=None):
if self.data == None: if self.data == None:
return None return None
rendered = { rendered = {
"icon": "signal-distance-variant", "icon": "signal-distance-variant",
"name": "Proximity", "name": "Proximity",
@ -1439,7 +1439,7 @@ class PowerConsumption(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1454,7 +1454,7 @@ class PowerConsumption(Sensor):
else: else:
label = type_label label = type_label
consumers.append({"label": label, "w": self.data[type_label][0], "custom_icon": self.data[type_label][1]}) consumers.append({"label": label, "w": self.data[type_label][0], "custom_icon": self.data[type_label][1]})
rendered = { rendered = {
"icon": "power-plug-outline", "icon": "power-plug-outline",
"name": "Power Consumption", "name": "Power Consumption",
@ -1520,7 +1520,7 @@ class PowerProduction(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1535,7 +1535,7 @@ class PowerProduction(Sensor):
else: else:
label = type_label label = type_label
producers.append({"label": label, "w": self.data[type_label][0], "custom_icon": self.data[type_label][1]}) producers.append({"label": label, "w": self.data[type_label][0], "custom_icon": self.data[type_label][1]})
rendered = { rendered = {
"icon": "lightning-bolt", "icon": "lightning-bolt",
"name": "Power Production", "name": "Power Production",
@ -1601,7 +1601,7 @@ class Processor(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1621,7 +1621,7 @@ class Processor(Sensor):
"load_avgs": self.data[type_label][1], "load_avgs": self.data[type_label][1],
"clock": self.data[type_label][2], "clock": self.data[type_label][2],
}) })
rendered = { rendered = {
"icon": "chip", "icon": "chip",
"name": "Processor", "name": "Processor",
@ -1687,7 +1687,7 @@ class RandomAccessMemory(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1708,7 +1708,7 @@ class RandomAccessMemory(Sensor):
"free": self.data[type_label][0]-self.data[type_label][1], "free": self.data[type_label][0]-self.data[type_label][1],
"percent": (self.data[type_label][1]/self.data[type_label][0])*100, "percent": (self.data[type_label][1]/self.data[type_label][0])*100,
}) })
rendered = { rendered = {
"icon": "memory", "icon": "memory",
"name": "Random Access Memory", "name": "Random Access Memory",
@ -1774,7 +1774,7 @@ class NonVolatileMemory(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1795,7 +1795,7 @@ class NonVolatileMemory(Sensor):
"free": self.data[type_label][0]-self.data[type_label][1], "free": self.data[type_label][0]-self.data[type_label][1],
"percent": (self.data[type_label][1]/self.data[type_label][0])*100, "percent": (self.data[type_label][1]/self.data[type_label][0])*100,
}) })
rendered = { rendered = {
"icon": "harddisk", "icon": "harddisk",
"name": "Non-Volatile Memory", "name": "Non-Volatile Memory",
@ -1861,7 +1861,7 @@ class Custom(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1880,7 +1880,7 @@ class Custom(Sensor):
"value": self.data[type_label][0], "value": self.data[type_label][0],
"custom_icon": self.data[type_label][1], "custom_icon": self.data[type_label][1],
}) })
rendered = { rendered = {
"icon": "ruler", "icon": "ruler",
"name": "Custom", "name": "Custom",
@ -1950,7 +1950,7 @@ class Tank(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -1974,7 +1974,7 @@ class Tank(Sensor):
"percent": (self.data[type_label][1]/self.data[type_label][0])*100, "percent": (self.data[type_label][1]/self.data[type_label][0])*100,
"custom_icon": self.data[type_label][3], "custom_icon": self.data[type_label][3],
}) })
rendered = { rendered = {
"icon": "storage-tank", "icon": "storage-tank",
"name": "Tank", "name": "Tank",
@ -2043,7 +2043,7 @@ class Fuel(Sensor):
for entry in packed: for entry in packed:
unpacked[entry[0]] = entry[1] unpacked[entry[0]] = entry[1]
return unpacked return unpacked
except: except:
return None return None
@ -2067,7 +2067,7 @@ class Fuel(Sensor):
"percent": (self.data[type_label][1]/self.data[type_label][0])*100, "percent": (self.data[type_label][1]/self.data[type_label][0])*100,
"custom_icon": self.data[type_label][3], "custom_icon": self.data[type_label][3],
}) })
rendered = { rendered = {
"icon": "fuel", "icon": "fuel",
"name": "Fuel", "name": "Fuel",

View File

@ -73,7 +73,7 @@ class Announces():
for item in self.list.children: for item in self.list.children:
if not item.sb_uid in (a["dest"] for a in self.announces): if not item.sb_uid in (a["dest"] for a in self.announces):
remove_widgets.append(item) remove_widgets.append(item)
else: else:
for announce in self.announces: for announce in self.announces:
if announce["dest"] == item.sb_uid: if announce["dest"] == item.sb_uid:
@ -103,7 +103,7 @@ class Announces():
name = multilingual_markup(escape_markup(str(name)).encode("utf-8")).decode("utf-8") name = multilingual_markup(escape_markup(str(name)).encode("utf-8")).decode("utf-8")
cost = str(cost) cost = str(cost)
def x(sender): 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": 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}" ad_text = f"[size=22dp]LXMF Peer[/size]\n\n[b]Received[/b] {ts}\n[b]Address[/b] {RNS.prettyhexrep(dest)}\n[b]Name[/b] {name}\n[b]Stamp Cost[/b] {cost}"
@ -235,7 +235,7 @@ class Announces():
dm_items = [] dm_items = []
item.iconr = IconRightWidget(icon="dots-vertical"); item.iconr = IconRightWidget(icon="dots-vertical");
item.dmenu = MDDropdownMenu( item.dmenu = MDDropdownMenu(
caller=item.iconr, caller=item.iconr,
items=dm_items, items=dm_items,
@ -253,7 +253,7 @@ class Announces():
item.iconr.bind(on_release=callback_factory(item)) item.iconr.bind(on_release=callback_factory(item))
item.add_widget(item.iconr) item.add_widget(item.iconr)
self.added_item_dests.append(context_dest) self.added_item_dests.append(context_dest)
self.list.add_widget(item, index=len(self.list.children)) self.list.add_widget(item, index=len(self.list.children))
@ -263,7 +263,7 @@ class Announces():
layout_announces_screen = """ layout_announces_screen = """
MDScreen: MDScreen:
name: "announces_screen" name: "announces_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"

View File

@ -51,7 +51,7 @@ class Conversations():
self.screen.app = self.app self.screen.app = self.app
self.ids = self.screen.ids self.ids = self.screen.ids
self.app.root.ids.screen_manager.add_widget(self.screen) self.app.root.ids.screen_manager.add_widget(self.screen)
self.conversation_dropdown = None self.conversation_dropdown = None
self.delete_dialog = None self.delete_dialog = None
self.clear_dialog = None self.clear_dialog = None
@ -73,9 +73,9 @@ class Conversations():
def update(self): def update(self):
# if self.app.sideband.getstate("app.flags.unread_conversations"): # if self.app.sideband.getstate("app.flags.unread_conversations"):
# self.clear_list() # self.clear_list()
self.context_dests = self.app.sideband.list_conversations(conversations=self.app.include_conversations, objects=self.app.include_objects) self.context_dests = self.app.sideband.list_conversations(conversations=self.app.include_conversations, objects=self.app.include_objects)
view_title = "Conversations" view_title = "Conversations"
if self.app.include_conversations: if self.app.include_conversations:
if self.app.include_objects: if self.app.include_objects:
@ -104,7 +104,7 @@ class Conversations():
trust_icon = "email" trust_icon = "email"
else: else:
trust_icon = appearance[0] or da[0]; trust_icon = appearance[0] or da[0];
else: else:
if self.app.sideband.requests_allowed_from(context_dest): if self.app.sideband.requests_allowed_from(context_dest):
if unread: if unread:
@ -183,7 +183,7 @@ class Conversations():
for w in remove_widgets: for w in remove_widgets:
self.list.remove_widget(w) self.list.remove_widget(w)
for conv in self.context_dests: for conv in self.context_dests:
context_dest = conv["dest"] context_dest = conv["dest"]
unread = conv["unread"] unread = conv["unread"]
@ -447,7 +447,7 @@ class Conversations():
item.add_widget(item.iconr) item.add_widget(item.iconr)
item.trusted = self.app.sideband.is_trusted(context_dest, conv_data=existing_conv) item.trusted = self.app.sideband.is_trusted(context_dest, conv_data=existing_conv)
self.added_item_dests.append(context_dest) self.added_item_dests.append(context_dest)
self.list.add_widget(item) self.list.add_widget(item)
@ -487,7 +487,7 @@ class Conversations():
conv_screen_kv = """ conv_screen_kv = """
MDScreen: MDScreen:
name: "conversations_screen" name: "conversations_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"

View File

@ -72,7 +72,7 @@ def multilingual_markup(data):
match = True match = True
if rfont != mapped_font: if rfont != mapped_font:
rfont = mapped_font rfont = mapped_font
switch = True switch = True
break break
if (not match) and rfont != "default": if (not match) and rfont != "default":

View File

@ -12,7 +12,7 @@ MDNavigationLayout:
MDScreen: MDScreen:
name: "starting_screen" name: "starting_screen"
AnchorLayout: AnchorLayout:
padding: [dp(0), dp(72), dp(0), dp(0)] padding: [dp(0), dp(72), dp(0), dp(0)]
anchor_x: "center" anchor_x: "center"
@ -49,141 +49,141 @@ MDNavigationLayout:
id: nav_scrollview id: nav_scrollview
DrawerList: DrawerList:
id: md_list id: md_list
MDList: MDList:
OneLineIconListItem: OneLineIconListItem:
text: "Conversations" text: "Conversations"
on_release: root.ids.screen_manager.app.conversations_action(self) on_release: root.ids.screen_manager.app.conversations_action(self)
# _no_ripple_effect: True # _no_ripple_effect: True
IconLeftWidget: IconLeftWidget:
icon: "comment-text-multiple" icon: "comment-text-multiple"
on_release: root.ids.screen_manager.app.conversations_action(self) on_release: root.ids.screen_manager.app.conversations_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Objects & Devices" text: "Objects & Devices"
on_release: root.ids.screen_manager.app.objects_action(self) on_release: root.ids.screen_manager.app.objects_action(self)
# _no_ripple_effect: True # _no_ripple_effect: True
IconLeftWidget: IconLeftWidget:
icon: "devices" icon: "devices"
on_release: root.ids.screen_manager.app.objects_action(self) on_release: root.ids.screen_manager.app.objects_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Situation Map" text: "Situation Map"
on_release: root.ids.screen_manager.app.map_action(self) on_release: root.ids.screen_manager.app.map_action(self)
IconLeftWidget: IconLeftWidget:
icon: "map" icon: "map"
on_release: root.ids.screen_manager.app.map_action(self) on_release: root.ids.screen_manager.app.map_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Announce Stream" text: "Announce Stream"
on_release: root.ids.screen_manager.app.announces_action(self) on_release: root.ids.screen_manager.app.announces_action(self)
IconLeftWidget: IconLeftWidget:
icon: "account-voice" icon: "account-voice"
on_release: root.ids.screen_manager.app.announces_action(self) on_release: root.ids.screen_manager.app.announces_action(self)
# OneLineIconListItem: # OneLineIconListItem:
# text: "Local Broadcasts" # text: "Local Broadcasts"
# on_release: root.ids.screen_manager.app.broadcasts_action(self) # on_release: root.ids.screen_manager.app.broadcasts_action(self)
# IconLeftWidget: # IconLeftWidget:
# icon: "radio-tower" # icon: "radio-tower"
# on_release: root.ids.screen_manager.app.broadcasts_action(self) # on_release: root.ids.screen_manager.app.broadcasts_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Telemetry" text: "Telemetry"
on_release: root.ids.screen_manager.app.telemetry_action(self) on_release: root.ids.screen_manager.app.telemetry_action(self)
IconLeftWidget: IconLeftWidget:
icon: "map-marker-path" icon: "map-marker-path"
on_release: root.ids.screen_manager.app.telemetry_action(self) on_release: root.ids.screen_manager.app.telemetry_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Preferences" text: "Preferences"
on_release: root.ids.screen_manager.app.settings_action(self) on_release: root.ids.screen_manager.app.settings_action(self)
IconLeftWidget: IconLeftWidget:
icon: "cog" icon: "cog"
on_release: root.ids.screen_manager.app.settings_action(self) on_release: root.ids.screen_manager.app.settings_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Connectivity" text: "Connectivity"
on_release: root.ids.screen_manager.app.connectivity_action(self) on_release: root.ids.screen_manager.app.connectivity_action(self)
IconLeftWidget: IconLeftWidget:
icon: "wifi" icon: "wifi"
on_release: root.ids.screen_manager.app.connectivity_action(self) on_release: root.ids.screen_manager.app.connectivity_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Hardware" text: "Hardware"
on_release: root.ids.screen_manager.app.hardware_action(self) on_release: root.ids.screen_manager.app.hardware_action(self)
IconLeftWidget: IconLeftWidget:
icon: "router-wireless" icon: "router-wireless"
on_release: root.ids.screen_manager.app.hardware_action(self) on_release: root.ids.screen_manager.app.hardware_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Encryption Keys" text: "Encryption Keys"
on_release: root.ids.screen_manager.app.keys_action(self) on_release: root.ids.screen_manager.app.keys_action(self)
IconLeftWidget: IconLeftWidget:
icon: "key-chain" icon: "key-chain"
on_release: root.ids.screen_manager.app.keys_action(self) on_release: root.ids.screen_manager.app.keys_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Plugins" text: "Plugins"
on_release: root.ids.screen_manager.app.plugins_action(self) on_release: root.ids.screen_manager.app.plugins_action(self)
IconLeftWidget: IconLeftWidget:
icon: "google-circles-extended" icon: "google-circles-extended"
on_release: root.ids.screen_manager.app.keys_action(self) on_release: root.ids.screen_manager.app.keys_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Guide" text: "Guide"
on_release: root.ids.screen_manager.app.guide_action(self) on_release: root.ids.screen_manager.app.guide_action(self)
IconLeftWidget: IconLeftWidget:
icon: "book-open" icon: "book-open"
on_release: root.ids.screen_manager.app.guide_action(self) on_release: root.ids.screen_manager.app.guide_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Repository" text: "Repository"
on_release: root.ids.screen_manager.app.repository_action(self) on_release: root.ids.screen_manager.app.repository_action(self)
IconLeftWidget: IconLeftWidget:
icon: "book-multiple" icon: "book-multiple"
on_release: root.ids.screen_manager.app.guide_action(self) on_release: root.ids.screen_manager.app.guide_action(self)
OneLineIconListItem: OneLineIconListItem:
id: app_version_info id: app_version_info
text: "" text: ""
on_release: root.ids.screen_manager.app.information_action(self) on_release: root.ids.screen_manager.app.information_action(self)
IconLeftWidget: IconLeftWidget:
icon: "information" icon: "information"
on_release: root.ids.screen_manager.app.information_action(self) on_release: root.ids.screen_manager.app.information_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Shutdown" text: "Shutdown"
on_release: root.ids.screen_manager.app.quit_action(self) on_release: root.ids.screen_manager.app.quit_action(self)
IconLeftWidget: IconLeftWidget:
icon: "power" icon: "power"
on_release: root.ids.screen_manager.app.quit_action(self) on_release: root.ids.screen_manager.app.quit_action(self)
@ -193,7 +193,7 @@ MDNavigationLayout:
layout_broadcasts_screen = """ layout_broadcasts_screen = """
MDScreen: MDScreen:
name: "broadcasts_screen" name: "broadcasts_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -230,7 +230,7 @@ MDScreen:
layout_exit_screen = """ layout_exit_screen = """
MDScreen: MDScreen:
name: "exit_screen" name: "exit_screen"
AnchorLayout: AnchorLayout:
padding: [dp(0), dp(72), dp(0), dp(0)] padding: [dp(0), dp(72), dp(0), dp(0)]
anchor_x: "center" anchor_x: "center"
@ -262,7 +262,7 @@ MDScreen:
layout_loader_screen = """ layout_loader_screen = """
MDScreen: MDScreen:
name: "loader_screen" name: "loader_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -295,7 +295,7 @@ MDScreen:
layout_connectivity_screen = """ layout_connectivity_screen = """
MDScreen: MDScreen:
name: "connectivity_screen" name: "connectivity_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -337,7 +337,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_local_label id: connectivity_local_label
text: "Connect via local WiFi/Ethernet" text: "Connect via local WiFi/Ethernet"
@ -380,7 +380,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_tcp_label id: connectivity_tcp_label
text: "Connect via TCP" text: "Connect via TCP"
@ -429,7 +429,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_i2p_label id: connectivity_i2p_label
text: "Connect via I2P" text: "Connect via I2P"
@ -472,7 +472,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_rnode_label id: connectivity_rnode_label
text: "Connect via RNode" text: "Connect via RNode"
@ -510,7 +510,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_modem_label id: connectivity_modem_label
text: "Connect via Radio Modem" text: "Connect via Radio Modem"
@ -548,7 +548,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_serial_label id: connectivity_serial_label
text: "Connect via Serial Port" text: "Connect via Serial Port"
@ -586,7 +586,7 @@ MDScreen:
# padding: [0,0,dp(24),0] # padding: [0,0,dp(24),0]
# size_hint_y: None # size_hint_y: None
# height: dp(24) # height: dp(24)
# MDLabel: # MDLabel:
# id: connectivity_bluetooth_label # id: connectivity_bluetooth_label
# text: "Connect via Bluetooth" # text: "Connect via Bluetooth"
@ -648,7 +648,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(24) height: dp(24)
MDLabel: MDLabel:
id: connectivity_transport_label id: connectivity_transport_label
text: "Enable Reticulum Transport" text: "Enable Reticulum Transport"
@ -751,7 +751,7 @@ MDScreen:
layout_guide_screen = """ layout_guide_screen = """
MDScreen: MDScreen:
name: "guide_screen" name: "guide_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -859,7 +859,7 @@ MDScreen:
layout_information_screen = """ layout_information_screen = """
MDScreen: MDScreen:
name: "information_screen" name: "information_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -913,7 +913,7 @@ MDScreen:
layout_map_settings_screen = """ layout_map_settings_screen = """
MDScreen: MDScreen:
name: "map_settings_screen" name: "map_settings_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -961,7 +961,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Use online map sources" text: "Use online map sources"
font_style: "H6" font_style: "H6"
@ -976,7 +976,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Use offline map source" text: "Use offline map source"
font_style: "H6" font_style: "H6"
@ -991,7 +991,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(48) height: dp(48)
MDLabel: MDLabel:
id: map_storage_external_label id: map_storage_external_label
text: "Use external storage path" text: "Use external storage path"
@ -1035,7 +1035,7 @@ MDScreen:
layout_map_screen = """ layout_map_screen = """
MDScreen: MDScreen:
name: "map_screen" name: "map_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1063,7 +1063,7 @@ MDScreen:
layout_keys_screen = """ layout_keys_screen = """
MDScreen: MDScreen:
name: "keys_screen" name: "keys_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1155,7 +1155,7 @@ MDScreen:
layout_plugins_screen = """ layout_plugins_screen = """
MDScreen: MDScreen:
name: "plugins_screen" name: "plugins_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1200,7 +1200,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(26),dp(0)] padding: [0,0,dp(26),dp(0)]
height: dp(24) height: dp(24)
MDLabel: MDLabel:
text: "Enable Plugins" text: "Enable Plugins"
font_style: "H6" font_style: "H6"
@ -1215,7 +1215,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(26),dp(0)] padding: [0,0,dp(26),dp(0)]
height: dp(24) height: dp(24)
MDLabel: MDLabel:
text: "Enable Command Plugins" text: "Enable Command Plugins"
font_style: "H6" font_style: "H6"
@ -1262,7 +1262,7 @@ MDScreen:
layout_settings_screen = """ layout_settings_screen = """
MDScreen: MDScreen:
name: "settings_screen" name: "settings_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1404,7 +1404,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Notifications" text: "Notifications"
font_style: "H6" font_style: "H6"
@ -1419,7 +1419,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Dark Mode" text: "Dark Mode"
font_style: "H6" font_style: "H6"
@ -1434,7 +1434,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "E-Ink Mode" text: "E-Ink Mode"
font_style: "H6" font_style: "H6"
@ -1449,7 +1449,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Show user icons in conversation list" text: "Show user icons in conversation list"
font_style: "H6" font_style: "H6"
@ -1464,7 +1464,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Only show user icons from trusted" text: "Only show user icons from trusted"
font_style: "H6" font_style: "H6"
@ -1479,7 +1479,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Advanced Metrics" text: "Advanced Metrics"
font_style: "H6" font_style: "H6"
@ -1516,7 +1516,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Announce Automatically" text: "Announce Automatically"
font_style: "H6" font_style: "H6"
@ -1531,7 +1531,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Try propagation on direct delivery failure" text: "Try propagation on direct delivery failure"
font_style: "H6" font_style: "H6"
@ -1547,7 +1547,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Send via Propagation Node by default" text: "Send via Propagation Node by default"
font_style: "H6" font_style: "H6"
@ -1563,7 +1563,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Ignore unknown senders" text: "Ignore unknown senders"
font_style: "H6" font_style: "H6"
@ -1579,7 +1579,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Limit incoming messages to 1MB" text: "Limit incoming messages to 1MB"
font_style: "H6" font_style: "H6"
@ -1595,7 +1595,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Limit each sync to 3 messages" text: "Limit each sync to 3 messages"
font_style: "H6" font_style: "H6"
@ -1611,7 +1611,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
id: settings_lxmf_sync_periodic id: settings_lxmf_sync_periodic
text: "Sync with Propagation Node periodically" text: "Sync with Propagation Node periodically"
@ -1643,7 +1643,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
id: settings_lxmf_require_stamps_label id: settings_lxmf_require_stamps_label
text: "Require stamps for incoming" text: "Require stamps for incoming"
@ -1675,7 +1675,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Ignore messages with invalid stamps" text: "Ignore messages with invalid stamps"
font_style: "H6" font_style: "H6"
@ -1691,7 +1691,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Use high-quality voice for PTT" text: "Use high-quality voice for PTT"
font_style: "H6" font_style: "H6"
@ -1707,7 +1707,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Use Home Node as Broadcast Repeater" text: "Use Home Node as Broadcast Repeater"
font_style: "H6" font_style: "H6"
@ -1723,7 +1723,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(24)] padding: [0,0,dp(24),dp(24)]
height: dp(48+24) height: dp(48+24)
MDLabel: MDLabel:
text: "Debug Logging" text: "Debug Logging"
font_style: "H6" font_style: "H6"
@ -1761,7 +1761,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Latin, Greek, Cyrillic" text: "Latin, Greek, Cyrillic"
font_style: "H6" font_style: "H6"
@ -1776,7 +1776,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Chinese" text: "Chinese"
font_style: "H6" font_style: "H6"
@ -1791,7 +1791,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Japanese" text: "Japanese"
font_style: "H6" font_style: "H6"
@ -1806,7 +1806,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Korean" text: "Korean"
font_style: "H6" font_style: "H6"
@ -1821,7 +1821,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Devanagari" text: "Devanagari"
font_style: "H6" font_style: "H6"
@ -1836,7 +1836,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Hebrew (incomplete)" text: "Hebrew (incomplete)"
font_style: "H6" font_style: "H6"
@ -1851,7 +1851,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Block Predictive Text" text: "Block Predictive Text"
font_style: "H6" font_style: "H6"
@ -1882,7 +1882,7 @@ MDScreen:
layout_repository_screen = """ layout_repository_screen = """
MDScreen: MDScreen:
name: "repository_screen" name: "repository_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1971,7 +1971,7 @@ MDScreen:
layout_hardware_screen = """ layout_hardware_screen = """
MDScreen: MDScreen:
name: "hardware_screen" name: "hardware_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -2052,7 +2052,7 @@ MDScreen:
layout_hardware_modem_screen = """ layout_hardware_modem_screen = """
MDScreen: MDScreen:
name: "hardware_modem_screen" name: "hardware_modem_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -2200,7 +2200,7 @@ MDScreen:
layout_hardware_rnode_screen = """ layout_hardware_rnode_screen = """
MDScreen: MDScreen:
name: "hardware_rnode_screen" name: "hardware_rnode_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -2366,7 +2366,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Control RNode Display" text: "Control RNode Display"
font_style: "H6" font_style: "H6"
@ -2381,7 +2381,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Connect using Bluetooth" text: "Connect using Bluetooth"
font_style: "H6" font_style: "H6"
@ -2396,7 +2396,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Device requires BLE" text: "Device requires BLE"
font_style: "H6" font_style: "H6"
@ -2463,7 +2463,7 @@ MDScreen:
layout_hardware_serial_screen = """ layout_hardware_serial_screen = """
MDScreen: MDScreen:
name: "hardware_serial_screen" name: "hardware_serial_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"

View File

@ -104,7 +104,7 @@ class Messages():
def message_details_dialog(self, lxm_hash): def message_details_dialog(self, lxm_hash):
ss = int(dp(16)) ss = int(dp(16))
ms = int(dp(14)) ms = int(dp(14))
msg = self.app.sideband.message(lxm_hash) msg = self.app.sideband.message(lxm_hash)
if msg: if msg:
close_button = MDRectangleFlatButton(text="Close", font_size=dp(18)) close_button = MDRectangleFlatButton(text="Close", font_size=dp(18))
@ -144,7 +144,7 @@ class Messages():
d_text += f"[size={ss}][b]Encrypted[/b] with destination identity key[/size]\n" d_text += f"[size={ss}][b]Encrypted[/b] with destination identity key[/size]\n"
else: else:
d_text += f"[size={ss}][b]Encryption[/b] status unknown[/size]\n" d_text += f"[size={ss}][b]Encryption[/b] status unknown[/size]\n"
if msg["extras"] != None and "stamp_checked" in msg["extras"]: if msg["extras"] != None and "stamp_checked" in msg["extras"]:
valid_str = " is not valid" valid_str = " is not valid"
if msg["extras"]["stamp_valid"] == True: if msg["extras"]["stamp_valid"] == True:
@ -294,7 +294,7 @@ class Messages():
sphrase = "Link established" sphrase = "Link established"
elif prg >= 0.05: elif prg >= 0.05:
sphrase = "Sending" sphrase = "Sending"
if msg["title"]: if msg["title"]:
titlestr = f"[b]Title[/b] {msg['title'].decode('utf-8')}\n" 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} " w.heading = f"{titlestr}[b]Sent[/b] {txstr}\n[b]State[/b] {sphrase}{prgstr} "
@ -481,7 +481,7 @@ class Messages():
pass pass
rcvd_d_str = "" rcvd_d_str = ""
trcvd = telemeter.read("received") if telemeter else None trcvd = telemeter.read("received") if telemeter else None
if trcvd and "distance" in trcvd: if trcvd and "distance" in trcvd:
d = trcvd["distance"] d = trcvd["distance"]
@ -725,7 +725,7 @@ class Messages():
image_field = item.image_field image_field = item.image_field
extension = str(image_field[0]).replace(".", "") extension = str(image_field[0]).replace(".", "")
filename = f"{time.strftime('LXM_%Y_%m_%d_%H_%M_%S', time.localtime(time.time()))}.{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) self.app.share_image(image_field[1], filename)
item.dmenu.dismiss() item.dmenu.dismiss()
return x return x
@ -755,7 +755,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -770,7 +770,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -824,7 +824,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -839,7 +839,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -858,7 +858,7 @@ class Messages():
if "snr" in physical_link: telemeter.sensors["physical_link"].snr = physical_link["snr"] 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"] if "quality" in physical_link: telemeter.sensors["physical_link"].q = physical_link["quality"]
telemeter.sensors["physical_link"].update_data() telemeter.sensors["physical_link"].update_data()
tlm = telemeter.read_all() tlm = telemeter.read_all()
Clipboard.copy(str(tlm)) Clipboard.copy(str(tlm))
item.dmenu.dismiss() item.dmenu.dismiss()
@ -909,7 +909,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -924,7 +924,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -935,7 +935,7 @@ class Messages():
def x(): def x():
item.dmenu.dismiss() item.dmenu.dismiss()
return x return x
else: else:
def x(): def x():
try: try:
@ -961,7 +961,7 @@ class Messages():
) )
def dl_ok(s): def dl_ok(s):
dialog.dismiss() dialog.dismiss()
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
dialog.open() dialog.open()
@ -1166,7 +1166,7 @@ class Messages():
messages_screen_kv = """ messages_screen_kv = """
MDScreen: MDScreen:
name: "messages_screen" name: "messages_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1227,7 +1227,7 @@ MDScreen:
on_release: root.app.message_ptt_up_action(self) on_release: root.app.message_ptt_up_action(self)
_no_ripple_effect: True _no_ripple_effect: True
background_normal: "" background_normal: ""
background_down: "" background_down: ""
BoxLayout: BoxLayout:
id: message_input_part id: message_input_part

View File

@ -115,7 +115,7 @@ class ObjectDetails():
yes_button.bind(on_release=dl_yes) yes_button.bind(on_release=dl_yes)
no_button.bind(on_release=dl_no) no_button.bind(on_release=dl_no)
self.delete_dialog.open() self.delete_dialog.open()
def reload_telemetry(self, sender=None, notoast=False): def reload_telemetry(self, sender=None, notoast=False):
@ -195,7 +195,7 @@ class ObjectDetails():
def job(dt): def job(dt):
self.screen.ids.coordinates_button.disabled = False self.screen.ids.coordinates_button.disabled = False
Clock.schedule_once(job, 0.01) Clock.schedule_once(job, 0.01)
self.telemetry_list.update_source(rendered_telemetry) self.telemetry_list.update_source(rendered_telemetry)
def job(dt): def job(dt):
self.screen.ids.telemetry_button.disabled = False self.screen.ids.telemetry_button.disabled = False
@ -239,7 +239,7 @@ class ObjectDetails():
else: else:
title_str = "Unknown Status" title_str = "Unknown Status"
info_str = "The status of the telemetry update is unknown." info_str = "The status of the telemetry update is unknown."
self.info_dialog.title = title_str self.info_dialog.title = title_str
self.info_dialog.text = info_str self.info_dialog.text = info_str
self.info_dialog.open() self.info_dialog.open()
@ -263,7 +263,7 @@ class ObjectDetails():
else: else:
title_str = "Unknown Status" title_str = "Unknown Status"
info_str = "The status of the telemetry request is unknown." info_str = "The status of the telemetry request is unknown."
self.info_dialog.title = title_str self.info_dialog.title = title_str
self.info_dialog.text = info_str self.info_dialog.text = info_str
self.info_dialog.open() self.info_dialog.open()
@ -273,7 +273,7 @@ class ObjectDetails():
def update(self): def update(self):
us = time.time() us = time.time()
self.update_widget() self.update_widget()
RNS.log(f"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): def update_widget(self):
@ -303,7 +303,7 @@ class RVDetails(MDRecycleView):
try: try:
if not rendered_telemetry: if not rendered_telemetry:
rendered_telemetry = [] rendered_telemetry = []
sort = { sort = {
"Information": 5, "Information": 5,
"Physical Link": 10, "Physical Link": 10,
@ -329,7 +329,7 @@ class RVDetails(MDRecycleView):
"Timestamp": 190, "Timestamp": 190,
"Received": 200, "Received": 200,
} }
def pass_job(sender=None): def pass_job(sender=None):
pass pass
@ -341,7 +341,7 @@ class RVDetails(MDRecycleView):
release_function = pass_job release_function = pass_job
formatted_values = None formatted_values = None
name = s["name"] name = s["name"]
if name == "Timestamp": if name == "Timestamp":
ts = s["values"]["UTC"] ts = s["values"]["UTC"]
if ts != None: if ts != None:
@ -351,7 +351,7 @@ class RVDetails(MDRecycleView):
Clipboard.copy(ts_str) Clipboard.copy(ts_str)
toast("Copied to clipboard") toast("Copied to clipboard")
release_function = copy_info release_function = copy_info
elif name == "Information": elif name == "Information":
info = s["values"]["contents"] info = s["values"]["contents"]
if info != None: if info != None:
@ -362,7 +362,7 @@ class RVDetails(MDRecycleView):
release_function = copy_info release_function = copy_info
external_text = multilingual_markup(escape_markup(istr).encode("utf-8")).decode("utf-8") external_text = multilingual_markup(escape_markup(istr).encode("utf-8")).decode("utf-8")
formatted_values = f"[b]Information[/b]: {external_text}" formatted_values = f"[b]Information[/b]: {external_text}"
elif name == "Received": elif name == "Received":
formatted_values = "" formatted_values = ""
by = s["values"]["by"]; by = s["values"]["by"];
@ -380,14 +380,14 @@ class RVDetails(MDRecycleView):
if via != None and via == by: if via != None and via == by:
vstr = self.app.sideband.peer_display_name(via) vstr = self.app.sideband.peer_display_name(via)
formatted_values = f"Received from, and collected by [b]{vstr}[/b]" formatted_values = f"Received from, and collected by [b]{vstr}[/b]"
else: else:
if via != None: if via != None:
vstr = self.app.sideband.peer_display_name(via) vstr = self.app.sideband.peer_display_name(via)
via_str = f"Received from [b]{vstr}[/b]" via_str = f"Received from [b]{vstr}[/b]"
else: else:
via_str = "Received from an [b]unknown peer[/b]" via_str = "Received from an [b]unknown peer[/b]"
if by != None: if by != None:
dstr = self.app.sideband.peer_display_name(by) dstr = self.app.sideband.peer_display_name(by)
by_str = f", collected by [b]{dstr}[/b]" by_str = f", collected by [b]{dstr}[/b]"
@ -401,7 +401,7 @@ class RVDetails(MDRecycleView):
if not by == self.app.sideband.lxmf_destination.hash and not self.app.sideband.is_trusted(by): 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"}) extra_entries.append({"icon": "alert", "text": "Collected by a [b]non-trusted[/b] peer"})
elif name == "Battery": elif name == "Battery":
p = s["values"]["percent"] p = s["values"]["percent"]
cs = s["values"]["_meta"] cs = s["values"]["_meta"]
@ -415,7 +415,7 @@ class RVDetails(MDRecycleView):
cs_str = f" ({cs})" 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": elif name == "Ambient Pressure":
p = s["values"]["mbar"] p = s["values"]["mbar"]
if p != None: formatted_values = f"{name} [b]{p} mbar[/b]" if p != None: formatted_values = f"{name} [b]{p} mbar[/b]"
@ -423,7 +423,7 @@ class RVDetails(MDRecycleView):
if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None:
d = s["deltas"][dt] d = s["deltas"][dt]
formatted_values += f" (Δ = {d} mbar)" formatted_values += f" (Δ = {d} mbar)"
elif name == "Ambient Temperature": elif name == "Ambient Temperature":
c = s["values"]["c"] c = s["values"]["c"]
if c != None: formatted_values = f"{name} [b]{c}° C[/b]" if c != None: formatted_values = f"{name} [b]{c}° C[/b]"
@ -431,7 +431,7 @@ class RVDetails(MDRecycleView):
if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None:
d = s["deltas"][dt] d = s["deltas"][dt]
formatted_values += f" (Δ = {d}° C)" formatted_values += f" (Δ = {d}° C)"
elif name == "Relative Humidity": elif name == "Relative Humidity":
r = s["values"]["percent"] r = s["values"]["percent"]
if r != None: formatted_values = f"{name} [b]{r}%[/b]" if r != None: formatted_values = f"{name} [b]{r}%[/b]"
@ -439,7 +439,7 @@ class RVDetails(MDRecycleView):
if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None: if "deltas" in s and dt in s["deltas"] and s["deltas"][dt] != None:
d = s["deltas"][dt] d = s["deltas"][dt]
formatted_values += f" (Δ = {d}%)" formatted_values += f" (Δ = {d}%)"
elif name == "Physical Link": elif name == "Physical Link":
rssi = s["values"]["rssi"]; rssi_str = None rssi = s["values"]["rssi"]; rssi_str = None
snr = s["values"]["snr"]; snr_str = None snr = s["values"]["snr"]; snr_str = None
@ -453,7 +453,7 @@ class RVDetails(MDRecycleView):
if q != None or rssi != None: snr_str = f", {snr_str}" if q != None or rssi != None: snr_str = f", {snr_str}"
if q_str or rssi_str or snr_str: if q_str or rssi_str or snr_str:
formatted_values = q_str+rssi_str+snr_str formatted_values = q_str+rssi_str+snr_str
elif name == "Power Consumption": elif name == "Power Consumption":
cs = s["values"] cs = s["values"]
if cs != None: if cs != None:
@ -664,13 +664,13 @@ class RVDetails(MDRecycleView):
if od != None: if od != None:
od_text = f"Geodesic distance [b]{RNS.prettydistance(od)}[/b]" od_text = f"Geodesic distance [b]{RNS.prettydistance(od)}[/b]"
extra_entries.append({"icon": "earth", "text": od_text}) extra_entries.append({"icon": "earth", "text": od_text})
if "euclidian" in s["distance"]: if "euclidian" in s["distance"]:
ed = s["distance"]["euclidian"] ed = s["distance"]["euclidian"]
if ed != None: if ed != None:
ed_text = f"Euclidian distance [b]{RNS.prettydistance(ed)}[/b]" ed_text = f"Euclidian distance [b]{RNS.prettydistance(ed)}[/b]"
extra_entries.append({"icon": "axis-arrow", "text": ed_text}) extra_entries.append({"icon": "axis-arrow", "text": ed_text})
if "vertical" in s["distance"]: if "vertical" in s["distance"]:
vd = s["distance"]["vertical"] vd = s["distance"]["vertical"]
if vd != None: if vd != None:
@ -710,7 +710,7 @@ class RVDetails(MDRecycleView):
az = s["azalt"]["azimuth"] az = s["azalt"]["azimuth"]
az_text = f"Azimuth [b]{round(az,3)}°[/b]" az_text = f"Azimuth [b]{round(az,3)}°[/b]"
azalt_formatted_text += az_text azalt_formatted_text += az_text
if "altitude" in s["azalt"]: if "altitude" in s["azalt"]:
al = s["azalt"]["altitude"] al = s["azalt"]["altitude"]
al_text = f"altitude [b]{round(al,3)}°[/b]" al_text = f"altitude [b]{round(al,3)}°[/b]"
@ -740,7 +740,7 @@ class RVDetails(MDRecycleView):
rh_icon = "set-none" rh_icon = "set-none"
else: else:
rh_formatted_text = f"[b]Outside[/b] shared radio horizon of [b]{crange_text}[/b]" 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}) extra_entries.append({"icon": rh_icon, "text": rh_formatted_text})
def select(e=None): def select(e=None):
@ -763,7 +763,7 @@ class RVDetails(MDRecycleView):
formatted_values += ", " formatted_values += ", "
formatted_values = formatted_values[:-2] formatted_values = formatted_values[:-2]
data = None data = None
if formatted_values != None: if formatted_values != None:
if release_function: if release_function:
@ -775,7 +775,7 @@ class RVDetails(MDRecycleView):
self.entries.append(data) self.entries.append(data)
for extra in extra_entries: for extra in extra_entries:
self.entries.append(extra) self.entries.append(extra)
except Exception as e: except Exception as e:
RNS.log("An error ocurred while displaying telemetry for object", RNS.LOG_ERROR) RNS.log("An error ocurred while displaying telemetry for object", RNS.LOG_ERROR)
RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR) RNS.log(f"The contained exception was: {e)}", RNS.LOG_ERROR)
@ -860,7 +860,7 @@ layout_object_details = """
MDScreen: MDScreen:
name: "object_details_screen" name: "object_details_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -930,7 +930,7 @@ MDScreen:
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.delegate.copy_coordinates(self) on_release: root.delegate.copy_coordinates(self)
disabled: False disabled: False
MDSeparator: MDSeparator:
orientation: "horizontal" orientation: "horizontal"
height: dp(1) height: dp(1)
@ -938,7 +938,7 @@ MDScreen:
MDBoxLayout: MDBoxLayout:
orientation: "vertical" orientation: "vertical"
id: object_details_container id: object_details_container
MDSeparator: MDSeparator:
orientation: "horizontal" orientation: "horizontal"
height: dp(1) height: dp(1)
@ -989,5 +989,5 @@ MDScreen:
# size_hint: [1.0, None] # size_hint: [1.0, None]
# on_release: root.delegate.copy_telemetry(self) # on_release: root.delegate.copy_telemetry(self)
# disabled: False # disabled: False
""" """

View File

@ -30,7 +30,7 @@ class Telemetry():
self.sensors_screen = None self.sensors_screen = None
self.icons_screen = None self.icons_screen = None
self.color_picker = None self.color_picker = None
if not self.app.root.ids.screen_manager.has_screen("telemetry_screen"): if not self.app.root.ids.screen_manager.has_screen("telemetry_screen"):
self.screen = Builder.load_string(layout_telemetry_screen) self.screen = Builder.load_string(layout_telemetry_screen)
self.screen.app = self.app self.screen.app = self.app
@ -74,17 +74,17 @@ class Telemetry():
self.screen.ids.telemetry_try_propagation_on_fail.active = self.app.sideband.config["telemetry_try_propagation_on_fail"] self.screen.ids.telemetry_try_propagation_on_fail.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_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.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_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.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_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.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_allow_requests_from_anyone.bind(active=self.telemetry_save)
self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect 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 = "\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 " info += "machines or other systems over LXMF. You have complete control over what kind of telemetry to send, and who you share "
@ -100,7 +100,7 @@ class Telemetry():
if self.app.theme_cls.theme_style == "Dark": if self.app.theme_cls.theme_style == "Dark":
info = f"[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 self.screen.ids.telemetry_info.text = info
def send_interval_change(sender=None, event=None, save=True): def send_interval_change(sender=None, event=None, save=True):
@ -229,7 +229,7 @@ class Telemetry():
self.app.sideband.run_telemetry() self.app.sideband.run_telemetry()
else: else:
self.app.sideband.stop_telemetry() self.app.sideband.stop_telemetry()
def telemetry_save(self, sender=None, event=None): def telemetry_save(self, sender=None, event=None):
run_telemetry_update = False run_telemetry_update = False
if len(self.screen.ids.telemetry_collector.text) != 32: if len(self.screen.ids.telemetry_collector.text) != 32:
@ -259,7 +259,7 @@ class Telemetry():
self.app.sideband.config["telemetry_allow_requests_from_trusted"] = self.screen.ids.telemetry_allow_requests_from_trusted.active self.app.sideband.config["telemetry_allow_requests_from_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_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.config["telemetry_collector_enabled"] = self.screen.ids.telemetry_collector_enabled.active
self.app.sideband.save_configuration() self.app.sideband.save_configuration()
if run_telemetry_update: if run_telemetry_update:
self.app.sideband.update_telemetry() self.app.sideband.update_telemetry()
@ -276,14 +276,14 @@ class Telemetry():
def telemetry_fg_color(self, sender=None): def telemetry_fg_color(self, sender=None):
if self.color_picker == None: if self.color_picker == None:
self.color_picker = MDColorPicker(size_hint=(0.85, 0.85)) self.color_picker = MDColorPicker(size_hint=(0.85, 0.85))
self.color_picker.open() self.color_picker.open()
self.color_picker.bind(on_release=self.telemetry_fg_select) self.color_picker.bind(on_release=self.telemetry_fg_select)
def job(sender=None): def job(sender=None):
self.color_picker._rgb = self.app.sideband.config["telemetry_fg"][0:3] self.color_picker._rgb = self.app.sideband.config["telemetry_fg"][0:3]
self.color_picker.ids.view_headline.on_tab_press() self.color_picker.ids.view_headline.on_tab_press()
Clock.schedule_once(job, 0) Clock.schedule_once(job, 0)
def telemetry_fg_select(self, instance_color_picker: MDColorPicker, type_color: str, selected_color: Union[list, str]): 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] s = selected_color; color = [s[0], s[1], s[2], 1]
self.screen.ids.telemetry_icon_preview.icon_color = color self.screen.ids.telemetry_icon_preview.icon_color = color
@ -304,7 +304,7 @@ class Telemetry():
self.color_picker._rgb = self.app.sideband.config["telemetry_bg"][0:3] self.color_picker._rgb = self.app.sideband.config["telemetry_bg"][0:3]
self.color_picker.ids.view_headline.on_tab_press() self.color_picker.ids.view_headline.on_tab_press()
Clock.schedule_once(job, 0) Clock.schedule_once(job, 0)
def telemetry_bg_select(self, instance_color_picker: MDColorPicker, type_color: str, selected_color: Union[list, str]): 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] s = selected_color; color = [s[0], s[1], s[2], 1]
self.screen.ids.telemetry_icon_preview.md_bg_color = color self.screen.ids.telemetry_icon_preview.md_bg_color = color
@ -329,7 +329,7 @@ class Telemetry():
info3 = "\nTo include a specific type of telemetry data while sending, it must be enabled below. Please note that some sensor types are not supported on all devices. Sideband will only be able to read a specific type of sensor if your device actually includes hardware for it.\n" 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": 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.telemetry_info3.text = info3
self.sensors_screen.ids.sensors_scrollview.effect_cls = ScrollEffect self.sensors_screen.ids.sensors_scrollview.effect_cls = ScrollEffect
@ -491,7 +491,7 @@ class Telemetry():
self.app.root.ids.screen_manager.transition.direction = "left" self.app.root.ids.screen_manager.transition.direction = "left"
self.app.root.ids.screen_manager.current = "icons_screen" self.app.root.ids.screen_manager.current = "icons_screen"
self.app.sideband.setstate("app.displaying", self.app.root.ids.screen_manager.current) self.app.sideband.setstate("app.displaying", self.app.root.ids.screen_manager.current)
# sf = self.icons_screen.ids.icons_search_field.text # sf = self.icons_screen.ids.icons_search_field.text
# self.icons_filter(sf, len(sf)>0) # self.icons_filter(sf, len(sf)>0)
@ -541,7 +541,7 @@ class Telemetry():
layout_telemetry_screen = """ layout_telemetry_screen = """
MDScreen: MDScreen:
name: "telemetry_screen" name: "telemetry_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -582,7 +582,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(48) height: dp(48)
MDLabel: MDLabel:
id: telemetry_enabled_label id: telemetry_enabled_label
text: "Enable telemetry" text: "Enable telemetry"
@ -598,7 +598,7 @@ MDScreen:
padding: [0,0,dp(24),0] padding: [0,0,dp(24),0]
size_hint_y: None size_hint_y: None
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Enable collector" text: "Enable collector"
font_style: "H6" font_style: "H6"
@ -613,7 +613,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Send display style to everyone" text: "Send display style to everyone"
font_style: "H6" font_style: "H6"
@ -628,7 +628,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Only display trusted on map" text: "Only display trusted on map"
font_style: "H6" font_style: "H6"
@ -643,7 +643,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Only receive from trusted" text: "Only receive from trusted"
font_style: "H6" font_style: "H6"
@ -658,7 +658,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
id: telemetry_send_to_collector_label id: telemetry_send_to_collector_label
text: "Auto sync to collector" text: "Auto sync to collector"
@ -689,7 +689,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
id: telemetry_request_from_collector_label id: telemetry_request_from_collector_label
text: "Auto sync from collector" text: "Auto sync from collector"
@ -730,7 +730,7 @@ MDScreen:
text: "" text: ""
font_size: dp(24) font_size: dp(24)
# MDRectangleFlatIconButton: # MDRectangleFlatIconButton:
# id: telemetry_copy_button # id: telemetry_copy_button
# icon: "content-copy" # icon: "content-copy"
@ -799,7 +799,7 @@ MDScreen:
on_release: root.app.map_display_own_telemetry(self) on_release: root.app.map_display_own_telemetry(self)
disabled: False disabled: False
MDLabel: MDLabel:
text: "Display Options" text: "Display Options"
@ -897,7 +897,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Embed telemetry to all trusted" text: "Embed telemetry to all trusted"
font_style: "H6" font_style: "H6"
@ -912,7 +912,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Sync all known telemetry to collector" text: "Sync all known telemetry to collector"
font_style: "H6" font_style: "H6"
@ -927,7 +927,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Always use propagation for telemetry" text: "Always use propagation for telemetry"
font_style: "H6" font_style: "H6"
@ -942,7 +942,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Try propagation if direct delivery fails" text: "Try propagation if direct delivery fails"
font_style: "H6" font_style: "H6"
@ -957,7 +957,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Requests receive only latest" text: "Requests receive only latest"
font_style: "H6" font_style: "H6"
@ -972,7 +972,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Allow requests from all trusted" text: "Allow requests from all trusted"
font_style: "H6" font_style: "H6"
@ -987,7 +987,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Allow requests from anyone" text: "Allow requests from anyone"
font_style: "H6" font_style: "H6"
@ -997,13 +997,13 @@ MDScreen:
pos_hint: {"center_y": 0.3} pos_hint: {"center_y": 0.3}
active: False active: False
""" """
layout_sensors_screen = """ layout_sensors_screen = """
MDScreen: MDScreen:
name: "sensors_screen" name: "sensors_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"
@ -1051,7 +1051,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Location" text: "Location"
font_style: "H6" font_style: "H6"
@ -1066,7 +1066,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Battery State" text: "Battery State"
font_style: "H6" font_style: "H6"
@ -1081,7 +1081,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Pressure" text: "Pressure"
font_style: "H6" font_style: "H6"
@ -1096,7 +1096,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Temperature" text: "Temperature"
font_style: "H6" font_style: "H6"
@ -1111,7 +1111,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Humidity" text: "Humidity"
font_style: "H6" font_style: "H6"
@ -1126,7 +1126,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Magnetic Field" text: "Magnetic Field"
font_style: "H6" font_style: "H6"
@ -1141,7 +1141,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Ambient Light" text: "Ambient Light"
font_style: "H6" font_style: "H6"
@ -1156,7 +1156,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Gravity" text: "Gravity"
font_style: "H6" font_style: "H6"
@ -1171,7 +1171,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Angular Velocity" text: "Angular Velocity"
font_style: "H6" font_style: "H6"
@ -1186,7 +1186,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Acceleration" text: "Acceleration"
font_style: "H6" font_style: "H6"
@ -1201,7 +1201,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Proximity" text: "Proximity"
font_style: "H6" font_style: "H6"
@ -1216,7 +1216,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Information" text: "Information"
font_style: "H6" font_style: "H6"
@ -1247,7 +1247,7 @@ MDScreen:
size_hint_y: None size_hint_y: None
padding: [0,0,dp(24),dp(0)] padding: [0,0,dp(24),dp(0)]
height: dp(48) height: dp(48)
MDLabel: MDLabel:
text: "Fixed Location" text: "Fixed Location"
font_style: "H6" font_style: "H6"
@ -1285,7 +1285,7 @@ MDScreen:
layout_icons_screen = """ layout_icons_screen = """
MDScreen: MDScreen:
name: "icons_screen" name: "icons_screen"
BoxLayout: BoxLayout:
orientation: "vertical" orientation: "vertical"