aprsd 3.4.3__py3-none-any.whl → 3.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aprsd/client/aprsis.py +39 -10
- aprsd/client/base.py +47 -10
- aprsd/client/drivers/aprsis.py +5 -2
- aprsd/client/factory.py +6 -1
- aprsd/client/fake.py +5 -2
- aprsd/client/kiss.py +26 -5
- aprsd/client/stats.py +1 -19
- aprsd/cmds/admin.py +57 -0
- aprsd/cmds/dev.py +1 -1
- aprsd/cmds/fetch_stats.py +155 -0
- aprsd/cmds/healthcheck.py +2 -2
- aprsd/cmds/listen.py +93 -6
- aprsd/cmds/server.py +18 -10
- aprsd/cmds/webchat.py +41 -53
- aprsd/conf/common.py +11 -0
- aprsd/main.py +10 -6
- aprsd/packets/core.py +28 -27
- aprsd/packets/packet_list.py +13 -23
- aprsd/plugin.py +12 -5
- aprsd/plugins/email.py +6 -0
- aprsd/plugins/fortune.py +2 -2
- aprsd/plugins/location.py +6 -4
- aprsd/stats/__init__.py +0 -2
- aprsd/stats/collector.py +6 -1
- aprsd/threads/aprsd.py +47 -5
- aprsd/threads/keep_alive.py +8 -0
- aprsd/threads/rx.py +40 -12
- aprsd/threads/tx.py +31 -6
- aprsd/utils/__init__.py +20 -5
- aprsd/utils/counter.py +15 -12
- aprsd/utils/trace.py +4 -2
- aprsd/web/chat/static/js/send-message.js +48 -21
- aprsd/wsgi.py +8 -1
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/METADATA +89 -33
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/RECORD +40 -39
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/WHEEL +1 -1
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/AUTHORS +0 -0
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/LICENSE +0 -0
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/entry_points.txt +0 -0
- {aprsd-3.4.3.dist-info → aprsd-3.4.4.dist-info}/top_level.txt +0 -0
@@ -17,25 +17,24 @@ function reload_popovers() {
|
|
17
17
|
}
|
18
18
|
|
19
19
|
function build_location_string(msg) {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
21
|
+
loc = "Last Location Update: " + dt.toLocaleString();
|
22
|
+
loc += "<br>Latitude: " + msg['lat'] + "<br>Longitude: " + msg['lon'];
|
23
|
+
loc += "<br>" + "Altitude: " + msg['altitude'] + " m";
|
24
|
+
loc += "<br>" + "Speed: " + msg['speed'] + " kph";
|
25
|
+
loc += "<br>" + "Bearing: " + msg['compass_bearing'];
|
26
|
+
loc += "<br>" + "distance: " + msg['distance'] + " km";
|
27
|
+
return loc;
|
28
28
|
}
|
29
29
|
|
30
30
|
function build_location_string_small(msg) {
|
31
|
-
|
32
|
-
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
33
|
-
|
31
|
+
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
34
32
|
loc = "" + msg['distance'] + "km";
|
35
33
|
//loc += "Lat " + msg['lat'] + " Lon " + msg['lon'];
|
36
|
-
loc += "
|
34
|
+
loc += " " + msg['compass_bearing'];
|
37
35
|
//loc += " Distance " + msg['distance'] + " km";
|
38
|
-
loc += " " + dt.toLocaleString();
|
36
|
+
//loc += " " + dt.toLocaleString();
|
37
|
+
loc += " " + msg['timeago'];
|
39
38
|
return loc;
|
40
39
|
}
|
41
40
|
|
@@ -101,7 +100,7 @@ function init_chat() {
|
|
101
100
|
|
102
101
|
$("#sendform").submit(function(event) {
|
103
102
|
event.preventDefault();
|
104
|
-
to_call = $('#to_call').val();
|
103
|
+
to_call = $('#to_call').val().toUpperCase();
|
105
104
|
message = $('#message').val();
|
106
105
|
path = $('#pkt_path option:selected').val();
|
107
106
|
if (to_call == "") {
|
@@ -116,6 +115,8 @@ function init_chat() {
|
|
116
115
|
//console.log(msg);
|
117
116
|
socket.emit("send", msg);
|
118
117
|
$('#message').val('');
|
118
|
+
callsign_select(to_call);
|
119
|
+
activate_callsign_tab(to_call);
|
119
120
|
}
|
120
121
|
});
|
121
122
|
|
@@ -344,9 +345,9 @@ function create_callsign_tab_content(callsign, active=false) {
|
|
344
345
|
item_html += '<div class="" style="border: 1px solid #999999;background-color:#aaaaaa;">';
|
345
346
|
item_html += '<div class="row" style="padding-top:4px;padding-bottom:4px;background-color:#aaaaaa;margin:0px;">';
|
346
347
|
item_html += '<div class="d-flex col-md-10 justify-content-left" style="padding:0px;margin:0px;">';
|
347
|
-
item_html += '<button onclick="call_callsign_location(\''+callsign+'\');" style="margin-left:2px;padding: 0px 4px 0px 4px;" type="button" class="btn btn-primary">';
|
348
|
-
item_html += '<span id="'+location_id+'Spinner" class="d-none spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>Update</button>';
|
349
|
-
item_html += ' <span id="'+location_id+'">'+location_str+'</span></div>';
|
348
|
+
item_html += '<button onclick="call_callsign_location(\''+callsign+'\');" style="margin-left:2px;padding: 0px 4px 0px 4px;font-size: .9rem" type="button" class="btn btn-primary">';
|
349
|
+
item_html += '<span id="'+location_id+'Spinner" class="d-none spinner-border spinner-border-sm" role="status" aria-hidden="true" style="font-size: .9rem"></span>Update</button>';
|
350
|
+
item_html += ' <span id="'+location_id+'" style="font-size: .9rem">'+location_str+'</span></div>';
|
350
351
|
item_html += '</div>';
|
351
352
|
item_html += '<div class="speech-wrapper" id="'+wrapper_id+'"></div>';
|
352
353
|
item_html += '</div>';
|
@@ -418,10 +419,10 @@ function append_message(callsign, msg, msg_html) {
|
|
418
419
|
|
419
420
|
// Find the right div to place the html
|
420
421
|
new_callsign = add_callsign(callsign, msg);
|
421
|
-
update_callsign_path(callsign, msg);
|
422
|
+
//update_callsign_path(callsign, msg);
|
422
423
|
append_message_html(callsign, msg_html, new_callsign);
|
423
424
|
len = Object.keys(callsign_list).length;
|
424
|
-
if (new_callsign
|
425
|
+
if (new_callsign) {
|
425
426
|
//Now click the tab if and only if there is only one tab
|
426
427
|
callsign_tab_id = callsign_tab(callsign);
|
427
428
|
$(callsign_tab_id).click();
|
@@ -506,6 +507,15 @@ function sent_msg(msg) {
|
|
506
507
|
append_message(msg['to_call'], msg, msg_html);
|
507
508
|
save_data();
|
508
509
|
scroll_main_content(msg['to_call']);
|
510
|
+
reload_popovers();
|
511
|
+
}
|
512
|
+
|
513
|
+
function str_to_int(my_string) {
|
514
|
+
total = 0
|
515
|
+
for (let i = 0; i < my_string.length; i++) {
|
516
|
+
total += my_string.charCodeAt(i);
|
517
|
+
}
|
518
|
+
return total
|
509
519
|
}
|
510
520
|
|
511
521
|
function from_msg(msg) {
|
@@ -513,6 +523,17 @@ function from_msg(msg) {
|
|
513
523
|
from_msg_list[msg["from_call"]] = new Array();
|
514
524
|
}
|
515
525
|
|
526
|
+
// Try to account for messages that have no msgNo
|
527
|
+
console.log(msg)
|
528
|
+
if (msg["msgNo"] == null) {
|
529
|
+
console.log("Need to add msgNO!!")
|
530
|
+
// create an artificial msgNo
|
531
|
+
total = str_to_int(msg["from_call"])
|
532
|
+
total += str_to_int(msg["addresse"])
|
533
|
+
total += str_to_int(msg["message_text"])
|
534
|
+
msg["msgNo"] = total
|
535
|
+
}
|
536
|
+
|
516
537
|
if (msg["msgNo"] in from_msg_list[msg["from_call"]]) {
|
517
538
|
// We already have this message
|
518
539
|
//console.log("We already have this message msgNo=" + msg["msgNo"]);
|
@@ -532,6 +553,7 @@ function from_msg(msg) {
|
|
532
553
|
append_message(from, msg, msg_html);
|
533
554
|
save_data();
|
534
555
|
scroll_main_content(from);
|
556
|
+
reload_popovers();
|
535
557
|
}
|
536
558
|
|
537
559
|
function ack_msg(msg) {
|
@@ -565,16 +587,21 @@ function ack_msg(msg) {
|
|
565
587
|
scroll_main_content();
|
566
588
|
}
|
567
589
|
|
590
|
+
function activate_callsign_tab(callsign) {
|
591
|
+
tab_content = tab_string(callsign, id=true);
|
592
|
+
$(tab_content).click();
|
593
|
+
}
|
594
|
+
|
568
595
|
function callsign_select(callsign) {
|
569
596
|
var tocall = $("#to_call");
|
570
|
-
tocall.val(callsign);
|
597
|
+
tocall.val(callsign.toUpperCase());
|
571
598
|
scroll_main_content(callsign);
|
572
599
|
selected_tab_callsign = callsign;
|
573
600
|
tab_notify_id = tab_notification_id(callsign, true);
|
574
601
|
$(tab_notify_id).addClass('visually-hidden');
|
575
602
|
$(tab_notify_id).text(0);
|
576
603
|
// Now update the path
|
577
|
-
$('#pkt_path').val(callsign_list[callsign]);
|
604
|
+
// $('#pkt_path').val(callsign_list[callsign]);
|
578
605
|
}
|
579
606
|
|
580
607
|
function call_callsign_location(callsign) {
|
aprsd/wsgi.py
CHANGED
@@ -3,6 +3,7 @@ import importlib.metadata as imp
|
|
3
3
|
import io
|
4
4
|
import json
|
5
5
|
import logging
|
6
|
+
import os
|
6
7
|
import queue
|
7
8
|
|
8
9
|
import flask
|
@@ -23,6 +24,12 @@ CONF = cfg.CONF
|
|
23
24
|
LOG = logging.getLogger("gunicorn.access")
|
24
25
|
logging_queue = queue.Queue()
|
25
26
|
|
27
|
+
|
28
|
+
# ADMIN_COMMAND True means we are running from `aprsd admin`
|
29
|
+
# the `aprsd admin` command will import this file after setting
|
30
|
+
# the APRSD_ADMIN_COMMAND environment variable.
|
31
|
+
ADMIN_COMMAND = os.environ.get("APRSD_ADMIN_COMMAND", False)
|
32
|
+
|
26
33
|
auth = HTTPBasicAuth()
|
27
34
|
users: dict[str, str] = {}
|
28
35
|
app = Flask(
|
@@ -297,7 +304,7 @@ if __name__ == "uwsgi_file_aprsd_wsgi":
|
|
297
304
|
CONF.log_opt_values(LOG, logging.DEBUG)
|
298
305
|
|
299
306
|
|
300
|
-
if __name__ == "aprsd.wsgi":
|
307
|
+
if __name__ == "aprsd.wsgi" and not ADMIN_COMMAND:
|
301
308
|
# set async_mode to 'threading', 'eventlet', 'gevent' or 'gevent_uwsgi' to
|
302
309
|
# force a mode else, the best mode is selected automatically from what's
|
303
310
|
# installed
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: aprsd
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.4
|
4
4
|
Summary: APRSd is a APRS-IS server that can be used to connect to APRS-IS and send and receive APRS packets.
|
5
5
|
Author-email: Craig Lamparter <craig@craiger.org>, "Walter A. Boring IV" <waboring@hemna.com>, Emre Saglam <emresaglam@gmail.com>, Jason Martin <jhmartin@toger.us>, John <johng42@users.noreply.github.com>, Martiros Shakhzadyan <vrzh@vrzh.net>, Zoe Moore <zoenb@mailbox.org>, ranguli <hello@joshmurphy.ca>
|
6
6
|
Maintainer-email: Craig Lamparter <craig@craiger.org>, "Walter A. Boring IV" <waboring@hemna.com>
|
@@ -207,17 +207,16 @@ Requires-Dist: ax253==0.1.5.post1
|
|
207
207
|
Requires-Dist: beautifulsoup4==4.12.3
|
208
208
|
Requires-Dist: bidict==0.23.1
|
209
209
|
Requires-Dist: bitarray==3.0.0
|
210
|
-
Requires-Dist: blinker==1.
|
210
|
+
Requires-Dist: blinker==1.9.0
|
211
211
|
Requires-Dist: certifi==2024.8.30
|
212
212
|
Requires-Dist: charset-normalizer==3.4.0
|
213
213
|
Requires-Dist: click==8.1.7
|
214
214
|
Requires-Dist: click-params==0.5.0
|
215
215
|
Requires-Dist: commonmark==0.9.1
|
216
|
-
Requires-Dist: dataclasses==0.6
|
217
216
|
Requires-Dist: dataclasses-json==0.6.7
|
218
217
|
Requires-Dist: debtcollector==3.0.0
|
219
|
-
Requires-Dist: deprecated==1.2.
|
220
|
-
Requires-Dist: flask==3.0
|
218
|
+
Requires-Dist: deprecated==1.2.15
|
219
|
+
Requires-Dist: flask==3.1.0
|
221
220
|
Requires-Dist: flask-httpauth==4.8.0
|
222
221
|
Requires-Dist: flask-socketio==5.4.1
|
223
222
|
Requires-Dist: geographiclib==2.0
|
@@ -231,12 +230,12 @@ Requires-Dist: jinja2==3.1.4
|
|
231
230
|
Requires-Dist: kiss3==8.0.0
|
232
231
|
Requires-Dist: loguru==0.7.2
|
233
232
|
Requires-Dist: markupsafe==3.0.2
|
234
|
-
Requires-Dist: marshmallow==3.23.
|
233
|
+
Requires-Dist: marshmallow==3.23.1
|
235
234
|
Requires-Dist: mypy-extensions==1.0.0
|
236
235
|
Requires-Dist: netaddr==1.3.0
|
237
|
-
Requires-Dist: oslo-config==9.
|
238
|
-
Requires-Dist: oslo-i18n==6.
|
239
|
-
Requires-Dist: packaging==24.
|
236
|
+
Requires-Dist: oslo-config==9.7.0
|
237
|
+
Requires-Dist: oslo-i18n==6.5.0
|
238
|
+
Requires-Dist: packaging==24.2
|
240
239
|
Requires-Dist: pbr==6.1.0
|
241
240
|
Requires-Dist: pluggy==1.5.0
|
242
241
|
Requires-Dist: pygments==2.18.0
|
@@ -254,19 +253,20 @@ Requires-Dist: shellingham==1.5.4
|
|
254
253
|
Requires-Dist: simple-websocket==1.1.0
|
255
254
|
Requires-Dist: six==1.16.0
|
256
255
|
Requires-Dist: soupsieve==2.6
|
257
|
-
Requires-Dist: stevedore==5.
|
256
|
+
Requires-Dist: stevedore==5.4.0
|
258
257
|
Requires-Dist: tabulate==0.9.0
|
259
258
|
Requires-Dist: thesmuggler==1.0.1
|
259
|
+
Requires-Dist: timeago==1.0.16
|
260
260
|
Requires-Dist: typing-extensions==4.12.2
|
261
261
|
Requires-Dist: typing-inspect==0.9.0
|
262
262
|
Requires-Dist: tzlocal==5.2
|
263
263
|
Requires-Dist: update-checker==0.18.0
|
264
264
|
Requires-Dist: urllib3==2.2.3
|
265
265
|
Requires-Dist: validators==0.22.0
|
266
|
-
Requires-Dist: werkzeug==3.
|
267
|
-
Requires-Dist: wrapt==1.
|
266
|
+
Requires-Dist: werkzeug==3.1.3
|
267
|
+
Requires-Dist: wrapt==1.17.0
|
268
268
|
Requires-Dist: wsproto==1.2.0
|
269
|
-
Requires-Dist: zipp==3.
|
269
|
+
Requires-Dist: zipp==3.21.0
|
270
270
|
Provides-Extra: dev
|
271
271
|
Requires-Dist: add-trailing-comma==3.1.0; extra == "dev"
|
272
272
|
Requires-Dist: alabaster==1.0.0; extra == "dev"
|
@@ -284,7 +284,7 @@ Requires-Dist: click==8.1.7; extra == "dev"
|
|
284
284
|
Requires-Dist: colorama==0.4.6; extra == "dev"
|
285
285
|
Requires-Dist: commonmark==0.9.1; extra == "dev"
|
286
286
|
Requires-Dist: configargparse==1.7; extra == "dev"
|
287
|
-
Requires-Dist: coverage[toml]==7.6.
|
287
|
+
Requires-Dist: coverage[toml]==7.6.8; extra == "dev"
|
288
288
|
Requires-Dist: distlib==0.3.9; extra == "dev"
|
289
289
|
Requires-Dist: docutils==0.21.2; extra == "dev"
|
290
290
|
Requires-Dist: exceptiongroup==1.2.2; extra == "dev"
|
@@ -292,22 +292,22 @@ Requires-Dist: filelock==3.16.1; extra == "dev"
|
|
292
292
|
Requires-Dist: fixit==2.1.0; extra == "dev"
|
293
293
|
Requires-Dist: flake8==7.1.1; extra == "dev"
|
294
294
|
Requires-Dist: gray==0.15.0; extra == "dev"
|
295
|
-
Requires-Dist: identify==2.6.
|
295
|
+
Requires-Dist: identify==2.6.3; extra == "dev"
|
296
296
|
Requires-Dist: idna==3.10; extra == "dev"
|
297
297
|
Requires-Dist: imagesize==1.4.1; extra == "dev"
|
298
298
|
Requires-Dist: iniconfig==2.0.0; extra == "dev"
|
299
299
|
Requires-Dist: isort==5.13.2; extra == "dev"
|
300
300
|
Requires-Dist: jinja2==3.1.4; extra == "dev"
|
301
|
-
Requires-Dist: libcst==1.5.
|
301
|
+
Requires-Dist: libcst==1.5.1; extra == "dev"
|
302
302
|
Requires-Dist: m2r==0.3.1; extra == "dev"
|
303
303
|
Requires-Dist: markupsafe==3.0.2; extra == "dev"
|
304
304
|
Requires-Dist: mccabe==0.7.0; extra == "dev"
|
305
305
|
Requires-Dist: mistune==0.8.4; extra == "dev"
|
306
306
|
Requires-Dist: moreorless==0.4.0; extra == "dev"
|
307
|
-
Requires-Dist: mypy==1.
|
307
|
+
Requires-Dist: mypy==1.13.0; extra == "dev"
|
308
308
|
Requires-Dist: mypy-extensions==1.0.0; extra == "dev"
|
309
309
|
Requires-Dist: nodeenv==1.9.1; extra == "dev"
|
310
|
-
Requires-Dist: packaging==24.
|
310
|
+
Requires-Dist: packaging==24.2; extra == "dev"
|
311
311
|
Requires-Dist: pathspec==0.12.1; extra == "dev"
|
312
312
|
Requires-Dist: pep8-naming==0.14.1; extra == "dev"
|
313
313
|
Requires-Dist: pip-tools==7.4.1; extra == "dev"
|
@@ -319,9 +319,9 @@ Requires-Dist: pyflakes==3.2.0; extra == "dev"
|
|
319
319
|
Requires-Dist: pygments==2.18.0; extra == "dev"
|
320
320
|
Requires-Dist: pyproject-api==1.8.0; extra == "dev"
|
321
321
|
Requires-Dist: pyproject-hooks==1.2.0; extra == "dev"
|
322
|
-
Requires-Dist: pytest==8.3.
|
323
|
-
Requires-Dist: pytest-cov==
|
324
|
-
Requires-Dist: pyupgrade==3.
|
322
|
+
Requires-Dist: pytest==8.3.4; extra == "dev"
|
323
|
+
Requires-Dist: pytest-cov==6.0.0; extra == "dev"
|
324
|
+
Requires-Dist: pyupgrade==3.19.0; extra == "dev"
|
325
325
|
Requires-Dist: pyyaml==6.0.2; extra == "dev"
|
326
326
|
Requires-Dist: requests==2.32.3; extra == "dev"
|
327
327
|
Requires-Dist: rich==12.6.0; extra == "dev"
|
@@ -333,17 +333,17 @@ Requires-Dist: sphinxcontrib-htmlhelp==2.1.0; extra == "dev"
|
|
333
333
|
Requires-Dist: sphinxcontrib-jsmath==1.0.1; extra == "dev"
|
334
334
|
Requires-Dist: sphinxcontrib-qthelp==2.0.0; extra == "dev"
|
335
335
|
Requires-Dist: sphinxcontrib-serializinghtml==2.0.0; extra == "dev"
|
336
|
-
Requires-Dist: tokenize-rt==6.
|
336
|
+
Requires-Dist: tokenize-rt==6.1.0; extra == "dev"
|
337
337
|
Requires-Dist: toml==0.10.2; extra == "dev"
|
338
|
-
Requires-Dist: tomli==2.
|
339
|
-
Requires-Dist: tox==4.23.
|
338
|
+
Requires-Dist: tomli==2.2.1; extra == "dev"
|
339
|
+
Requires-Dist: tox==4.23.2; extra == "dev"
|
340
340
|
Requires-Dist: trailrunner==1.4.0; extra == "dev"
|
341
341
|
Requires-Dist: typing-extensions==4.12.2; extra == "dev"
|
342
342
|
Requires-Dist: unify==0.5; extra == "dev"
|
343
343
|
Requires-Dist: untokenize==0.1.1; extra == "dev"
|
344
344
|
Requires-Dist: urllib3==2.2.3; extra == "dev"
|
345
|
-
Requires-Dist: virtualenv==20.
|
346
|
-
Requires-Dist: wheel==0.
|
345
|
+
Requires-Dist: virtualenv==20.28.0; extra == "dev"
|
346
|
+
Requires-Dist: wheel==0.45.1; extra == "dev"
|
347
347
|
|
348
348
|
===============================================
|
349
349
|
APRSD - Ham radio APRS-IS Message plugin server
|
@@ -358,6 +358,37 @@ ____________________
|
|
358
358
|
`APRSD <http://github.com/craigerl/aprsd>`_ is a Ham radio `APRS <http://aprs.org>`_ message command gateway built on python.
|
359
359
|
|
360
360
|
|
361
|
+
Table of Contents
|
362
|
+
=================
|
363
|
+
|
364
|
+
1. `What is APRSD <#what-is-aprsd>`_
|
365
|
+
2. `APRSD Overview Diagram <#aprsd-overview-diagram>`_
|
366
|
+
3. `Typical Use Case <#typical-use-case>`_
|
367
|
+
4. `Installation <#installation>`_
|
368
|
+
5. `Example Usage <#example-usage>`_
|
369
|
+
6. `Help <#help>`_
|
370
|
+
7. `Commands <#commands>`_
|
371
|
+
- `Configuration <#configuration>`_
|
372
|
+
- `Server <#server>`_
|
373
|
+
- `Current List of Built-in Plugins <#current-list-of-built-in-plugins>`_
|
374
|
+
- `Pypi.org APRSD Installable Plugin Packages <#pypiorg-aprsd-installable-plugin-packages>`_
|
375
|
+
- `🐍 APRSD Installed 3rd Party Plugins <#aprsd-installed-3rd-party-plugins>`_
|
376
|
+
- `Send Message <#send-message>`_
|
377
|
+
- `Send Email (Radio to SMTP Server) <#send-email-radio-to-smtp-server>`_
|
378
|
+
- `Receive Email (IMAP Server to Radio) <#receive-email-imap-server-to-radio>`_
|
379
|
+
- `Location <#location>`_
|
380
|
+
- `Web Admin Interface <#web-admin-interface>`_
|
381
|
+
8. `Development <#development>`_
|
382
|
+
- `Building Your Own APRSD Plugins <#building-your-own-aprsd-plugins>`_
|
383
|
+
9. `Workflow <#workflow>`_
|
384
|
+
10. `Release <#release>`_
|
385
|
+
11. `Docker Container <#docker-container>`_
|
386
|
+
- `Building <#building-1>`_
|
387
|
+
- `Official Build <#official-build>`_
|
388
|
+
- `Development Build <#development-build>`_
|
389
|
+
- `Running the Container <#running-the-container>`_
|
390
|
+
|
391
|
+
|
361
392
|
What is APRSD
|
362
393
|
=============
|
363
394
|
APRSD is a python application for interacting with the APRS network and providing
|
@@ -494,8 +525,7 @@ look for incomming commands to the callsign configured in the config file
|
|
494
525
|
|
495
526
|
|
496
527
|
Current list of built-in plugins
|
497
|
-
|
498
|
-
|
528
|
+
--------------------------------
|
499
529
|
::
|
500
530
|
|
501
531
|
└─> aprsd list-plugins
|
@@ -647,18 +677,21 @@ AND... ping, fortune, time.....
|
|
647
677
|
|
648
678
|
Web Admin Interface
|
649
679
|
===================
|
680
|
+
APRSD has a web admin interface that allows you to view the status of the running APRSD server instance.
|
681
|
+
The web admin interface shows graphs of packet counts, packet types, number of threads running, the latest
|
682
|
+
packets sent and received, and the status of each of the plugins that are loaded. You can also view the logfile
|
683
|
+
and view the raw APRSD configuration file.
|
684
|
+
|
650
685
|
To start the web admin interface, You have to install gunicorn in your virtualenv that already has aprsd installed.
|
651
686
|
|
652
687
|
::
|
653
688
|
|
654
689
|
source <path to APRSD's virtualenv>/bin/activate
|
655
|
-
|
656
|
-
gunicorn --bind 0.0.0.0:8080 "aprsd.wsgi:app"
|
690
|
+
aprsd admin --loglevel INFO
|
657
691
|
|
658
692
|
The web admin interface will be running on port 8080 on the local machine. http://localhost:8080
|
659
693
|
|
660
694
|
|
661
|
-
|
662
695
|
Development
|
663
696
|
===========
|
664
697
|
|
@@ -667,7 +700,7 @@ Development
|
|
667
700
|
* ``make``
|
668
701
|
|
669
702
|
Workflow
|
670
|
-
|
703
|
+
--------
|
671
704
|
|
672
705
|
While working aprsd, The workflow is as follows:
|
673
706
|
|
@@ -696,7 +729,7 @@ While working aprsd, The workflow is as follows:
|
|
696
729
|
|
697
730
|
|
698
731
|
Release
|
699
|
-
|
732
|
+
-------
|
700
733
|
|
701
734
|
To do release to pypi:
|
702
735
|
|
@@ -717,6 +750,29 @@ To do release to pypi:
|
|
717
750
|
``make upload``
|
718
751
|
|
719
752
|
|
753
|
+
Building your own APRSD plugins
|
754
|
+
-------------------------------
|
755
|
+
|
756
|
+
APRSD plugins are the mechanism by which APRSD can respond to APRS Messages. The plugins are loaded at server startup
|
757
|
+
and can also be loaded at listen startup. When a packet is received by APRSD, it is passed to each of the plugins
|
758
|
+
in the order they were registered in the config file. The plugins can then decide what to do with the packet.
|
759
|
+
When a plugin is called, it is passed a APRSD Packet object. The plugin can then do something with the packet and
|
760
|
+
return a reply message if desired. If a plugin does not want to reply to the packet, it can just return None.
|
761
|
+
When a plugin does return a reply message, APRSD will send the reply message to the appropriate destination.
|
762
|
+
|
763
|
+
For example, when a 'ping' message is received, the PingPlugin will return a reply message of 'pong'. When APRSD
|
764
|
+
receives the 'pong' message, it will be sent back to the original caller of the ping message.
|
765
|
+
|
766
|
+
APRSD plugins are simply python packages that can be installed from pypi.org. They are installed into the
|
767
|
+
aprsd virtualenv and can be imported by APRSD at runtime. The plugins are registered in the config file and loaded
|
768
|
+
at startup of the aprsd server command or the aprsd listen command.
|
769
|
+
|
770
|
+
Overview
|
771
|
+
--------
|
772
|
+
You can build your own plugins by following the instructions in the `Building your own APRSD plugins`_ section.
|
773
|
+
|
774
|
+
Plugins are called by APRSD when packe
|
775
|
+
|
720
776
|
Docker Container
|
721
777
|
================
|
722
778
|
|
@@ -1,34 +1,35 @@
|
|
1
1
|
aprsd/__init__.py,sha256=ci_49KK2a4GXyxcM2lFZfNAOsBfXzh0yayIGQazw56I,687
|
2
2
|
aprsd/cli_helper.py,sha256=AgSSn6oTUdCDv4Ne1Jyg_0bi7GwINBBKotTLk_QE-cY,4568
|
3
3
|
aprsd/exception.py,sha256=FyeehwYENwsRKyrU2WmgEPmcHsDLjdGRAe35f01Bu5A,502
|
4
|
-
aprsd/main.py,sha256=
|
5
|
-
aprsd/plugin.py,sha256=
|
4
|
+
aprsd/main.py,sha256=z-Irj3n_TSOdzJgsP3zwQIEPqMckbnUk3KN0-UeOkzs,4809
|
5
|
+
aprsd/plugin.py,sha256=ewarmdA94jqoQ-jJ9Dsd9Q71EDyZPCEJSjm-lXAdx9A,17559
|
6
6
|
aprsd/plugin_utils.py,sha256=xKQbliwikJxw_E5TGK_BcBPXkHeJ1PqVxSCFcDbf1xg,2507
|
7
|
-
aprsd/wsgi.py,sha256=
|
7
|
+
aprsd/wsgi.py,sha256=J5oJ5l86QziVYQS6y82BiHjPr8sJgrZYKEWn54s6FuY,8988
|
8
8
|
aprsd/client/__init__.py,sha256=aajKndFPk259RLTUuobVDleJmOENHvdRVodfhY5BmX8,348
|
9
|
-
aprsd/client/aprsis.py,sha256=
|
10
|
-
aprsd/client/base.py,sha256=
|
11
|
-
aprsd/client/factory.py,sha256=
|
12
|
-
aprsd/client/fake.py,sha256
|
13
|
-
aprsd/client/kiss.py,sha256=
|
14
|
-
aprsd/client/stats.py,sha256=
|
9
|
+
aprsd/client/aprsis.py,sha256=NtjV2wZCdPfiG7fI3G5fWLwIbXs1j-Xyvd_7SgMCK_c,5496
|
10
|
+
aprsd/client/base.py,sha256=Xa0Zx68jSDDlYjlXXnffvmWcuTDIXBmuqbMCPq7bGT8,3424
|
11
|
+
aprsd/client/factory.py,sha256=DiBarZVAUiTZyc_48FAgtvl1Mm3tj-E4WuNQvAVi4j0,2307
|
12
|
+
aprsd/client/fake.py,sha256=nmlm7Zc4u9pWn2hCt4NyyiiuBNSkMgdw8Sokycvm-9w,1121
|
13
|
+
aprsd/client/kiss.py,sha256=Arc_xKPrNcojJ3bJJzQdVU9Dvi_guI1kTrMSnRRbN28,3902
|
14
|
+
aprsd/client/stats.py,sha256=xXQn6yR6cqv3lIcydY4jV7qIn_MxWZh3cnVazUuKIGw,353
|
15
15
|
aprsd/client/drivers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
|
-
aprsd/client/drivers/aprsis.py,sha256=
|
16
|
+
aprsd/client/drivers/aprsis.py,sha256=HmIBQ7w5CiOXe-sungtwrEyDN6NC0n9qIoNb04a4nRk,7421
|
17
17
|
aprsd/client/drivers/fake.py,sha256=TyqwQ4XYzbT83r0jSBI-oyl9q6BK60TgVuFm2_nkrnw,2059
|
18
18
|
aprsd/client/drivers/kiss.py,sha256=XvXvBgpv_i1kgV5MmdTR5DwRXEiT86M49Pa7vw8-gsA,3350
|
19
19
|
aprsd/cmds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
+
aprsd/cmds/admin.py,sha256=tvHiIKEmWF9mB-tIIGCHbyV2EGiQcgsCW4wrmBoRfSI,1510
|
20
21
|
aprsd/cmds/completion.py,sha256=KZNniU_9pTmLtItXzl-ATcLn9vi_0795pJ5D4lZXFG8,799
|
21
|
-
aprsd/cmds/dev.py,sha256=
|
22
|
-
aprsd/cmds/fetch_stats.py,sha256=
|
23
|
-
aprsd/cmds/healthcheck.py,sha256=
|
22
|
+
aprsd/cmds/dev.py,sha256=JbL8U-mu_G6OnbC8xM5WQQBY6h8MvZRZ17uM-F3V5oY,4431
|
23
|
+
aprsd/cmds/fetch_stats.py,sha256=_9Kenv7eCwzzphJGfiNopWdjlbdkQIRmxuwsZ1JNrIc,9657
|
24
|
+
aprsd/cmds/healthcheck.py,sha256=mBaJtb7xliwm1Qy0uYMAET689Mh8GUVhnF4JuN1YDjw,2633
|
24
25
|
aprsd/cmds/list_plugins.py,sha256=gSIa7uMZAvXylJ89GI3RU9wj6TPioREvBNfClVyfiOM,10653
|
25
|
-
aprsd/cmds/listen.py,sha256=
|
26
|
+
aprsd/cmds/listen.py,sha256=5R7HzUOuSoS5sLZ1gB9zFP_JVoVPjRLQeWX0QbWJpRo,9759
|
26
27
|
aprsd/cmds/send_message.py,sha256=hoTKPsSMzd9ajz9fl9pbVxA0JL7AAW29L1jgZAlq2zw,4729
|
27
|
-
aprsd/cmds/server.py,sha256=
|
28
|
-
aprsd/cmds/webchat.py,sha256=
|
28
|
+
aprsd/cmds/server.py,sha256=9z_faI3Q5yn9O6hzlYlAp318QLI-UYP4DWCh57RwCgw,4457
|
29
|
+
aprsd/cmds/webchat.py,sha256=E06CbzUeTz0gL7YgAsTXpByDsuFQztgfbHQhOwCdaaY,19881
|
29
30
|
aprsd/conf/__init__.py,sha256=6j-N6jT49OYcp8dD8oZGt7mxWSOSUnWXeTIZW_C0bmw,1725
|
30
31
|
aprsd/conf/client.py,sha256=w_Z6Pc5LUYzJzDsfhCcnMBLkPi9njNdCGOe3GfbpGaA,3029
|
31
|
-
aprsd/conf/common.py,sha256=
|
32
|
+
aprsd/conf/common.py,sha256=Qqah5RTj95P4ZXff_5oMztD99A0zvXTtFtHPPcLATE4,9327
|
32
33
|
aprsd/conf/log.py,sha256=v5C2Lda6x39IdamHpelOY6tDHPkqHyx_qmPF3WEmeAE,1424
|
33
34
|
aprsd/conf/opts.py,sha256=Jq1DPyDdNyN2rbuHq8O-lF2Entkb9tFTbh9gjZwWC5s,2701
|
34
35
|
aprsd/conf/plugin_common.py,sha256=pqYNKKwHTYVI-yUnrX3MZhrQz8fVx6arZN7VfAIbnzs,5999
|
@@ -37,39 +38,39 @@ aprsd/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
38
|
aprsd/log/log.py,sha256=cd1bMGdlcWHW393btpAw1cc3oYD0nEzY5O596MO6H94,3884
|
38
39
|
aprsd/packets/__init__.py,sha256=ELcYtnQKDvdCRhQmhiHaKG4w5JYl2foeWxnqTqsB-08,786
|
39
40
|
aprsd/packets/collector.py,sha256=VhuHj2CRxVtaC6QDKiYMnxRzNVj-fc7wkMyPpTl83Og,2322
|
40
|
-
aprsd/packets/core.py,sha256=
|
41
|
+
aprsd/packets/core.py,sha256=dGz7kHpLjAMYUAwm0TjIcY9Pl4hcNJQoAJK4gTNi2Vw,27620
|
41
42
|
aprsd/packets/log.py,sha256=mqYq06mK4JgESPKZ4JQ6vWJqorTSp73u7IiITqdlWwE,5347
|
42
|
-
aprsd/packets/packet_list.py,sha256=
|
43
|
+
aprsd/packets/packet_list.py,sha256=5DZubd7F1oVy4qIpNjYqmZm4ihsjj9cazSf7SGsCwII,3048
|
43
44
|
aprsd/packets/seen_list.py,sha256=fV87eyXeFxaZKqWfY1GOCQ6zfnjI1Or6i3KS_qJLuoA,1375
|
44
45
|
aprsd/packets/tracker.py,sha256=Fr7B9Ex2kikmAkUz0HNUEsx9p60ap9L7A96bkv9WaO0,2950
|
45
46
|
aprsd/packets/watch_list.py,sha256=TcvQsleypvxI2o_fbTr4sAAlmjRb9YpC7LbyNxTwfic,3728
|
46
47
|
aprsd/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
|
-
aprsd/plugins/email.py,sha256=
|
48
|
-
aprsd/plugins/fortune.py,sha256=
|
49
|
-
aprsd/plugins/location.py,sha256=
|
48
|
+
aprsd/plugins/email.py,sha256=XBc8Yc8r1TyRKobDU0uk8pMj8uvQrr0pMroh9QXCTe0,23932
|
49
|
+
aprsd/plugins/fortune.py,sha256=BUa14AMI5lZIy2L7opMWygV7fO7ZvMIpDvLDzkyy64A,1559
|
50
|
+
aprsd/plugins/location.py,sha256=bpCQyr-9_0wo6nX891epuGEe6VpNas6Ebx1BT-Rehkk,6450
|
50
51
|
aprsd/plugins/notify.py,sha256=5Qk7P1ZsFl8pNYQMIBmVYnTcKua9gzvgkUwbrcQ6Byc,1969
|
51
52
|
aprsd/plugins/ping.py,sha256=A3yLMPUDU-PA1Q98xStd0WM04MZvGn3FzVpGKjyoXDc,763
|
52
53
|
aprsd/plugins/time.py,sha256=59-tMl7ogccLobWl9hMDm8mUVXdqW6kB5javrtp0rok,3535
|
53
54
|
aprsd/plugins/version.py,sha256=NAPFKQ0lQqgjoDyTVy8tZcRGmdcJE_ZogRElDz27V2U,839
|
54
55
|
aprsd/plugins/weather.py,sha256=iZ4Zv_23-2dquNKXhsiimFVlMEVoBNKyom4LtORwuoU,13333
|
55
|
-
aprsd/stats/__init__.py,sha256=
|
56
|
+
aprsd/stats/__init__.py,sha256=ltAtUiEvpokBEtOpq0sxpDGOLQT2evgeZSVBzDzjkSo,808
|
56
57
|
aprsd/stats/app.py,sha256=axqMA137zKqU03yO8XI5f1QE8ajmr9YK0J9O9m4iSzo,1378
|
57
|
-
aprsd/stats/collector.py,sha256=
|
58
|
+
aprsd/stats/collector.py,sha256=PexUprznK7vU7Rz_0QB1qJmhZj0MPnwBH4E4chp5h1U,1439
|
58
59
|
aprsd/threads/__init__.py,sha256=b8Dma0cWE7356WU_Ehvm0RtL4-zCJNUchPFArJd2Gtw,274
|
59
|
-
aprsd/threads/aprsd.py,sha256=
|
60
|
-
aprsd/threads/keep_alive.py,sha256
|
60
|
+
aprsd/threads/aprsd.py,sha256=xAlkvng0g3a4uSR6MVelvhhDMmpUdf7ziRHvxPtVzys,4709
|
61
|
+
aprsd/threads/keep_alive.py,sha256=-DkemoEZT0GZ33POAAVyMJV_Yf__Fg1-rEZxfBqG3dQ,5572
|
61
62
|
aprsd/threads/log_monitor.py,sha256=_-ku02-Sy8m2sG1HFHP2Q_KfzUQfwjd4xaJ5XQlNUTw,3368
|
62
63
|
aprsd/threads/registry.py,sha256=5DuzNSwhOEwI0Gl5j9e286uqbxzKLSHzInfPy61r7PI,1702
|
63
|
-
aprsd/threads/rx.py,sha256=
|
64
|
+
aprsd/threads/rx.py,sha256=uhb5kAshuSu4IdXxOOZM5ByTH4hWR8v0gUE966nta6s,14440
|
64
65
|
aprsd/threads/stats.py,sha256=Yey3B2iuGUQsNuUiFxvXKJU_1pif8gfOb5uP_U2-hS8,959
|
65
|
-
aprsd/threads/tx.py,sha256=
|
66
|
-
aprsd/utils/__init__.py,sha256=
|
67
|
-
aprsd/utils/counter.py,sha256=
|
66
|
+
aprsd/threads/tx.py,sha256=R73xUNpu0rVBTACU1oRRvP9y0kVe1FF9-xAT3j2f8E8,9265
|
67
|
+
aprsd/utils/__init__.py,sha256=5CcewFZIknHX1El_mO5M_aG77P8Awkvd5B6RxFpwMxY,6956
|
68
|
+
aprsd/utils/counter.py,sha256=GQH2E1FEBshR5PROhCNS13I6CaYZLW7VJumaYd7yQcY,1378
|
68
69
|
aprsd/utils/fuzzyclock.py,sha256=qKV8SYZhQGOHG9biF8TeueLb6RMppspx1Zg4IOy1Z10,3265
|
69
70
|
aprsd/utils/json.py,sha256=LR2g-sealCRyXnujjTNxNYUxBagrdBqYQxNLYJQGYaM,2487
|
70
71
|
aprsd/utils/objectstore.py,sha256=b4tNw21lQJ-g6vGN_0Hhc_VRbGiCc5tAZ2jszhRtfyM,3541
|
71
72
|
aprsd/utils/ring_buffer.py,sha256=lWWuw7lEbc2URhqAJfRLjpXBDLiK6UUWzk3j2VFnERQ,1111
|
72
|
-
aprsd/utils/trace.py,sha256=
|
73
|
+
aprsd/utils/trace.py,sha256=NfdC9sdnU-yHoXAT8BcX4yBK3SvNPTtekfonYSmVRBE,5689
|
73
74
|
aprsd/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
75
|
aprsd/web/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
76
|
aprsd/web/admin/static/css/index.css,sha256=A0knpKbvbu2hxwV4yHXzb7l712GviOfEM4fl1NkjhEc,1282
|
@@ -115,7 +116,7 @@ aprsd/web/chat/static/images/aprs-symbols-64-2.png,sha256=OIP7l9temgE-GfB8s29fyt
|
|
115
116
|
aprsd/web/chat/static/images/globe.svg,sha256=x7kmRI-9gJaZI4FBlpG53K4ZscmqN_gajnzH-P4DzOI,1197
|
116
117
|
aprsd/web/chat/static/js/gps.js,sha256=8_DFgKvfCf8V54jULhN3GYvP3QKicJfcM-mfVPx6DzQ,2370
|
117
118
|
aprsd/web/chat/static/js/main.js,sha256=IZARmM7l-bNncXSTEo3Oq-SJfyUPPmKoEZPpVoRtXDc,1259
|
118
|
-
aprsd/web/chat/static/js/send-message.js,sha256=
|
119
|
+
aprsd/web/chat/static/js/send-message.js,sha256=_e6QmaRcPxP-xQt8wxKJlrpJz9SdW7d9fn9z-LlXyqY,19765
|
119
120
|
aprsd/web/chat/static/js/tabs.js,sha256=cRePBekcExNQO54eRVGCnNXB1JHM9uURnv6LNoe8LMs,889
|
120
121
|
aprsd/web/chat/static/js/upstream/bootstrap.bundle.min.js,sha256=gGVATfqL6AhR6ukxISDCnWUX6UkUakDC2XchR0dpCDo,80664
|
121
122
|
aprsd/web/chat/static/js/upstream/jquery-3.7.1.min.js,sha256=_JqT3SQfawRcv_BIHPThkBvs0OEvtFFmqPF_lYI_Cxo,87533
|
@@ -124,10 +125,10 @@ aprsd/web/chat/static/js/upstream/jquery.toast.js,sha256=V4m4PbwAYUb9yr3uP64y2og
|
|
124
125
|
aprsd/web/chat/static/js/upstream/semantic.min.js,sha256=AYdrntK9PGcU1ZsyD7fTBJ4o0j1bMeD4xn7P-UagMW4,403125
|
125
126
|
aprsd/web/chat/static/js/upstream/socket.io.min.js,sha256=dYF5MG5zs6ekpbIOXBXelJXquX0gi_c48kkYm8tCaYE,64274
|
126
127
|
aprsd/web/chat/templates/index.html,sha256=9z8JoF3W6SlPndf28iCgdHwiaG9_f9fnk5nXWEfx5wg,6633
|
127
|
-
aprsd-3.4.
|
128
|
-
aprsd-3.4.
|
129
|
-
aprsd-3.4.
|
130
|
-
aprsd-3.4.
|
131
|
-
aprsd-3.4.
|
132
|
-
aprsd-3.4.
|
133
|
-
aprsd-3.4.
|
128
|
+
aprsd-3.4.4.dist-info/AUTHORS,sha256=-4JB7i9LE12SYMbLc4Rk6iXlQ0J7C4mC1RV6-vnO53E,467
|
129
|
+
aprsd-3.4.4.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
|
130
|
+
aprsd-3.4.4.dist-info/METADATA,sha256=SHvKcTlKybhAdFVyGLOZt8orGfHkdxQqPsxyluu5IEg,42885
|
131
|
+
aprsd-3.4.4.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
132
|
+
aprsd-3.4.4.dist-info/entry_points.txt,sha256=4fReoJUB-bFqOUK6eeXYYCvTdVLprL7KVH0hWQRP9eM,171
|
133
|
+
aprsd-3.4.4.dist-info/top_level.txt,sha256=v1O96niUcJOTMh9aQnFRknbScJ6mMOwqurdbxeaeSjs,6
|
134
|
+
aprsd-3.4.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|