remove dangling spaces
This commit is contained in:
parent
2a13ed0921
commit
236e0901fa
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
282
sbapp/main.py
282
sbapp/main.py
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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})
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
#
|
#
|
||||||
|
|
|
@ -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. "+
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 = ""
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
]
|
]
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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":
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
"""
|
"""
|
|
@ -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"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue