aprsd 3.3.4__tar.gz → 3.4.0__tar.gz
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-3.3.4 → aprsd-3.4.0}/ChangeLog +104 -7
- {aprsd-3.3.4 → aprsd-3.4.0}/PKG-INFO +14 -16
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/client.py +133 -20
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/clients/aprsis.py +6 -3
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/clients/fake.py +1 -1
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/clients/kiss.py +1 -1
- aprsd-3.4.0/aprsd/cmds/completion.py +22 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/fetch_stats.py +53 -57
- aprsd-3.4.0/aprsd/cmds/healthcheck.py +86 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/list_plugins.py +2 -2
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/listen.py +33 -17
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/send_message.py +2 -2
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/server.py +26 -9
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/webchat.py +34 -29
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/common.py +46 -31
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/log/log.py +28 -6
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/main.py +4 -17
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/packets/__init__.py +3 -2
- aprsd-3.4.0/aprsd/packets/collector.py +56 -0
- aprsd-3.4.0/aprsd/packets/core.py +823 -0
- aprsd-3.4.0/aprsd/packets/log.py +143 -0
- aprsd-3.4.0/aprsd/packets/packet_list.py +116 -0
- aprsd-3.4.0/aprsd/packets/seen_list.py +54 -0
- aprsd-3.4.0/aprsd/packets/tracker.py +109 -0
- aprsd-3.4.0/aprsd/packets/watch_list.py +122 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugin.py +41 -16
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/email.py +35 -7
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/time.py +3 -2
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/version.py +4 -5
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/weather.py +0 -1
- aprsd-3.4.0/aprsd/stats/__init__.py +20 -0
- aprsd-3.4.0/aprsd/stats/app.py +46 -0
- aprsd-3.4.0/aprsd/stats/collector.py +38 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/threads/__init__.py +3 -2
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/threads/aprsd.py +67 -36
- aprsd-3.4.0/aprsd/threads/keep_alive.py +121 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/threads/log_monitor.py +46 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/threads/rx.py +43 -24
- aprsd-3.4.0/aprsd/threads/stats.py +44 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/threads/tx.py +36 -17
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/__init__.py +12 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/counter.py +6 -3
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/json.py +20 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/objectstore.py +22 -17
- aprsd-3.4.0/aprsd/web/admin/static/css/prism.css +4 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/js/charts.js +9 -7
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/js/echarts.js +71 -9
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/js/main.js +47 -6
- aprsd-3.4.0/aprsd/web/admin/static/js/prism.js +12 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/templates/index.html +18 -7
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/gps.js +3 -1
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/main.js +4 -3
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/send-message.js +5 -2
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/templates/index.html +1 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/wsgi.py +62 -127
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/PKG-INFO +14 -16
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/SOURCES.txt +7 -10
- aprsd-3.4.0/aprsd.egg-info/pbr.json +1 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/requires.txt +13 -15
- {aprsd-3.3.4 → aprsd-3.4.0}/dev-requirements.txt +24 -25
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/Dockerfile +5 -4
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/Dockerfile-dev +7 -5
- aprsd-3.4.0/docker/bin/setup.sh +50 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/build.sh +1 -1
- {aprsd-3.3.4 → aprsd-3.4.0}/requirements.in +1 -3
- {aprsd-3.3.4 → aprsd-3.4.0}/requirements.txt +13 -15
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/cmds/test_webchat.py +2 -5
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/fake.py +13 -2
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_version.py +5 -8
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_weather.py +1 -1
- aprsd-3.4.0/tests/test_packets.py +285 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/test_plugin.py +2 -6
- {aprsd-3.3.4 → aprsd-3.4.0}/tox.ini +1 -1
- aprsd-3.3.4/aprsd/cmds/completion.py +0 -36
- aprsd-3.3.4/aprsd/cmds/healthcheck.py +0 -84
- aprsd-3.3.4/aprsd/packets/core.py +0 -688
- aprsd-3.3.4/aprsd/packets/packet_list.py +0 -99
- aprsd-3.3.4/aprsd/packets/seen_list.py +0 -43
- aprsd-3.3.4/aprsd/packets/tracker.py +0 -111
- aprsd-3.3.4/aprsd/packets/watch_list.py +0 -96
- aprsd-3.3.4/aprsd/plugins/query.py +0 -81
- aprsd-3.3.4/aprsd/rpc/__init__.py +0 -14
- aprsd-3.3.4/aprsd/rpc/client.py +0 -165
- aprsd-3.3.4/aprsd/rpc/server.py +0 -99
- aprsd-3.3.4/aprsd/stats.py +0 -266
- aprsd-3.3.4/aprsd/threads/keep_alive.py +0 -115
- aprsd-3.3.4/aprsd/web/admin/static/css/prism.css +0 -189
- aprsd-3.3.4/aprsd/web/admin/static/js/prism.js +0 -2247
- aprsd-3.3.4/aprsd/web/admin/static/json-viewer/jquery.json-viewer.css +0 -57
- aprsd-3.3.4/aprsd/web/admin/static/json-viewer/jquery.json-viewer.js +0 -158
- aprsd-3.3.4/aprsd/web/chat/static/json-viewer/jquery.json-viewer.css +0 -57
- aprsd-3.3.4/aprsd/web/chat/static/json-viewer/jquery.json-viewer.js +0 -158
- aprsd-3.3.4/aprsd.egg-info/pbr.json +0 -1
- aprsd-3.3.4/tests/plugins/test_query.py +0 -54
- aprsd-3.3.4/tests/test_packets.py +0 -102
- {aprsd-3.3.4 → aprsd-3.4.0}/.coveragerc +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.github/workflows/codeql.yml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.github/workflows/manual_build.yml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.github/workflows/master-build.yml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.github/workflows/python.yml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.github/workflows/release_build.yml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.pre-commit-config.yaml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/.readthedocs.yaml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/AUTHORS +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/INSTALL.txt +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/LICENSE +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/MANIFEST.in +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/Makefile +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/README.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cli_helper.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/clients/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/cmds/dev.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/client.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/log.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/opts.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/plugin_common.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/conf/plugin_email.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/exception.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/log/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/messaging.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugin_utils.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/fortune.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/location.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/notify.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/plugins/ping.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/threads/registry.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/fuzzyclock.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/ring_buffer.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/utils/trace.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/css/index.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/css/tabs.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/images/Untitled.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/images/aprs-symbols-16-0.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/images/aprs-symbols-16-1.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/images/aprs-symbols-64-0.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/images/aprs-symbols-64-1.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/images/aprs-symbols-64-2.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/js/logs.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/js/send-message.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/admin/static/js/tabs.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/chat.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/index.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/style.css.map +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/tabs.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/bootstrap.min.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/font.woff2 +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/google-fonts.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/jquery-ui.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/jquery.toast.css +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff2 +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff2 +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/Untitled.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/aprs-symbols-16-0.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/aprs-symbols-16-1.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/aprs-symbols-64-0.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/aprs-symbols-64-1.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/aprs-symbols-64-2.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/images/globe.svg +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/tabs.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/upstream/bootstrap.bundle.min.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/upstream/jquery-3.7.1.min.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/upstream/jquery-ui.min.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/upstream/jquery.toast.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/upstream/semantic.min.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd/web/chat/static/js/upstream/socket.io.min.js +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd-lnav.json +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/dependency_links.txt +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/entry_points.txt +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/not-zip-safe +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/aprsd.egg-info/top_level.txt +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/dev-requirements.in +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/bin/admin.sh +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/bin/listen.sh +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/bin/run.sh +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docker/docker-compose.yml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/_static/.keep +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/_static/aprsd_overview.png +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/_static/aprsd_overview.svg +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/_templates/.keep +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.clients.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.cmds.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.conf.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.packets.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.plugins.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.rpc.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.threads.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.utils.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.web.admin.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/aprsd.web.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/apidoc/modules.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/aprsd.drawio +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/changelog.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/clean_docs.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/conf.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/configure.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/index.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/install.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/links.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/plugin.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/readme.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/docs/server.rst +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/examples/plugins/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/examples/plugins/example_plugin.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/gray.conf +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/pyproject.toml +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/setup.cfg +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/setup.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/cmds/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/cmds/test_send_message.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/__init__.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_fortune.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_location.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_notify.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_ping.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/plugins/test_time.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/test_email.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tests/test_main.py +0 -0
- {aprsd-3.3.4 → aprsd-3.4.0}/tools/fast8.sh +0 -0
@@ -1,16 +1,113 @@
|
|
1
1
|
CHANGES
|
2
2
|
=======
|
3
3
|
|
4
|
-
v3.
|
5
|
-
------
|
6
|
-
|
7
|
-
* Fixed entry\_points
|
8
|
-
* Fix for entry\_points where python < 3.10
|
9
|
-
|
10
|
-
v3.3.3
|
4
|
+
v3.4.0
|
11
5
|
------
|
12
6
|
|
7
|
+
* Change setup.h
|
8
|
+
* Fixed docker setup.sh comparison
|
9
|
+
* Fixed unit tests failing with WatchList
|
10
|
+
* Added config enable\_packet\_logging
|
11
|
+
* Make all the Objectstore children use the same lock
|
12
|
+
* Fixed PacketTrack with UnknownPacket
|
13
|
+
* Removed the requirement on click-completion
|
14
|
+
* Update Dockerfiles
|
15
|
+
* Added fox for entry\_points with old python
|
16
|
+
* Added config for enable\_seen\_list
|
17
|
+
* Fix APRSDStats start\_time
|
18
|
+
* Added default\_packet\_send\_count config
|
19
|
+
* Call packet collecter after prepare during tx
|
20
|
+
* Added PacketTrack to packet collector
|
21
|
+
* Webchat Send Beacon uses Path selected in UI
|
22
|
+
* Added try except blocks in collectors
|
23
|
+
* Remove error logs from watch list
|
24
|
+
* Fixed issue with PacketList being empty
|
25
|
+
* Added new PacketCollector
|
26
|
+
* Fixed Keepalive access to email stats
|
27
|
+
* Added support for RX replyacks
|
28
|
+
* Changed Stats Collector registration
|
29
|
+
* Added PacketList.set\_maxlen()
|
30
|
+
* another fix for tx send
|
31
|
+
* removed Packet.last\_send\_attempt and just use send\_count
|
32
|
+
* Fix access to PacketList.\_maxlen
|
33
|
+
* added packet\_count in packet\_list stats
|
34
|
+
* force uwsgi to 2.0.24
|
35
|
+
* ismall update
|
36
|
+
* Added new config optons for PacketList
|
37
|
+
* Update requirements
|
38
|
+
* Added threads chart to admin ui graphs
|
39
|
+
* set packetlist max back to 100
|
40
|
+
* ensure thread count is updated
|
41
|
+
* Added threads table in the admin web ui
|
42
|
+
* Fixed issue with APRSDThreadList stats()
|
43
|
+
* Added new default\_ack\_send\_count config option
|
44
|
+
* Remove packet from tracker after max attempts
|
45
|
+
* Limit packets to 50 in PacketList
|
46
|
+
* syncronize the add for StatsStore
|
47
|
+
* Lock on stats for PacketList
|
48
|
+
* Fixed PacketList maxlen
|
49
|
+
* Fixed a problem with the webchat tab notification
|
50
|
+
* Another fix for ACK packets
|
51
|
+
* Fix issue not tracking RX Ack packets for stats
|
52
|
+
* Fix time plugin
|
53
|
+
* add GATE route to webchat along with WIDE1, etc
|
54
|
+
* Update webchat, include GATE route along with WIDE, ARISS, etc
|
55
|
+
* Get rid of some useless warning logs
|
56
|
+
* Added human\_info property to MessagePackets
|
57
|
+
* Fixed scrolling problem with new webchat sent msg
|
58
|
+
* Fix some issues with listen command
|
59
|
+
* Admin interface catch empty stats
|
60
|
+
* Ensure StatsStore has empty data
|
61
|
+
* Ensure latest pip is in docker image
|
62
|
+
* LOG failed requests post to admin ui
|
63
|
+
* changed admin web\_ip to StrOpt
|
64
|
+
* Updated prism to 1.29
|
65
|
+
* Removed json-viewer
|
66
|
+
* Remove rpyc as a requirement
|
67
|
+
* Delete more stats from webchat
|
68
|
+
* Admin UI working again
|
69
|
+
* Removed RPC Server and client
|
70
|
+
* Remove the logging of the conf password if not set
|
71
|
+
* Lock around client reset
|
72
|
+
* Allow stats collector to serialize upon creation
|
73
|
+
* Fixed issues with watch list at startup
|
74
|
+
* Fixed access to log\_monitor
|
75
|
+
* Got unit tests working again
|
76
|
+
* Fixed pep8 errors and missing files
|
77
|
+
* Reworked the stats making the rpc server obsolete
|
78
|
+
* Update client.py to add consumer in the API
|
13
79
|
* Fix for sample-config warning
|
80
|
+
* update requirements
|
81
|
+
* Put packet.json back in
|
82
|
+
* Change debug log color
|
83
|
+
* Fix for filtering curse words
|
84
|
+
* added packet counter random int
|
85
|
+
* More packet cleanup and tests
|
86
|
+
* Show comment in multiline packet output
|
87
|
+
* Added new config option log\_packet\_format
|
88
|
+
* Some packet cleanup
|
89
|
+
* Added new webchat config option for logging
|
90
|
+
* Fix some pep8 issues
|
91
|
+
* Completely redo logging of packets!!
|
92
|
+
* Fixed some logging in webchat
|
93
|
+
* Added missing packet types in listen command
|
94
|
+
* Don't call stats so often in webchat
|
95
|
+
* Eliminated need for from\_aprslib\_dict
|
96
|
+
* Fix for micE packet decoding with mbits
|
97
|
+
* updated dev-requirements
|
98
|
+
* Fixed some tox errors related to mypy
|
99
|
+
* Refactored packets
|
100
|
+
* removed print
|
101
|
+
* small refactor of stats usage in version plugin
|
102
|
+
* Added type setting on pluging.py for mypy
|
103
|
+
* Moved Threads list for mypy
|
104
|
+
* No need to synchronize on stats
|
105
|
+
* Start to add types
|
106
|
+
* Update tox for mypy runs
|
107
|
+
* Bump black from 24.2.0 to 24.3.0
|
108
|
+
* replaced access to conf from uwsgi
|
109
|
+
* Fixed call to setup\_logging in uwsgi
|
110
|
+
* Fixed access to conf.log in logging\_setup
|
14
111
|
|
15
112
|
v3.3.2
|
16
113
|
------
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: aprsd
|
3
|
-
Version: 3.
|
3
|
+
Version: 3.4.0
|
4
4
|
Summary: Amateur radio APRS daemon which listens for messages and responds
|
5
5
|
Home-page: http://aprsd.readthedocs.org
|
6
6
|
Author: Craig Lamparter
|
@@ -31,14 +31,13 @@ Requires-Dist: click==8.1.7
|
|
31
31
|
Requires-Dist: click-completion==0.5.2
|
32
32
|
Requires-Dist: click-params==0.5.0
|
33
33
|
Requires-Dist: commonmark==0.9.1
|
34
|
-
Requires-Dist: dacite2==2.0.0
|
35
34
|
Requires-Dist: dataclasses==0.6
|
36
35
|
Requires-Dist: dataclasses-json==0.6.4
|
37
36
|
Requires-Dist: debtcollector==3.0.0
|
38
37
|
Requires-Dist: deprecated==1.2.14
|
39
38
|
Requires-Dist: dnspython==2.6.1
|
40
|
-
Requires-Dist: eventlet==0.
|
41
|
-
Requires-Dist: flask==3.0.
|
39
|
+
Requires-Dist: eventlet==0.36.1
|
40
|
+
Requires-Dist: flask==3.0.3
|
42
41
|
Requires-Dist: flask-httpauth==4.8.0
|
43
42
|
Requires-Dist: flask-socketio==5.3.6
|
44
43
|
Requires-Dist: geographiclib==2.0
|
@@ -46,10 +45,10 @@ Requires-Dist: geopy==2.4.1
|
|
46
45
|
Requires-Dist: gevent==24.2.1
|
47
46
|
Requires-Dist: greenlet==3.0.3
|
48
47
|
Requires-Dist: h11==0.14.0
|
49
|
-
Requires-Dist: idna==3.
|
48
|
+
Requires-Dist: idna==3.7
|
50
49
|
Requires-Dist: imapclient==3.0.1
|
51
|
-
Requires-Dist: importlib-metadata==7.0
|
52
|
-
Requires-Dist: itsdangerous==2.
|
50
|
+
Requires-Dist: importlib-metadata==7.1.0
|
51
|
+
Requires-Dist: itsdangerous==2.2.0
|
53
52
|
Requires-Dist: jinja2==3.1.3
|
54
53
|
Requires-Dist: kiss3==8.0.0
|
55
54
|
Requires-Dist: loguru==0.7.2
|
@@ -59,21 +58,19 @@ Requires-Dist: mypy-extensions==1.0.0
|
|
59
58
|
Requires-Dist: netaddr==1.2.1
|
60
59
|
Requires-Dist: oslo-config==9.4.0
|
61
60
|
Requires-Dist: oslo-i18n==6.3.0
|
62
|
-
Requires-Dist: packaging==
|
61
|
+
Requires-Dist: packaging==24.0
|
63
62
|
Requires-Dist: pbr==6.0.0
|
64
|
-
Requires-Dist: pluggy==1.
|
65
|
-
Requires-Dist: plumbum==1.8.2
|
63
|
+
Requires-Dist: pluggy==1.5.0
|
66
64
|
Requires-Dist: pygments==2.17.2
|
67
65
|
Requires-Dist: pyserial==3.5
|
68
66
|
Requires-Dist: pyserial-asyncio==0.6
|
69
67
|
Requires-Dist: python-engineio==4.9.0
|
70
|
-
Requires-Dist: python-socketio==5.11.
|
68
|
+
Requires-Dist: python-socketio==5.11.2
|
71
69
|
Requires-Dist: pytz==2024.1
|
72
70
|
Requires-Dist: pyyaml==6.0.1
|
73
71
|
Requires-Dist: requests==2.31.0
|
74
72
|
Requires-Dist: rfc3986==2.0.0
|
75
73
|
Requires-Dist: rich==12.6.0
|
76
|
-
Requires-Dist: rpyc==6.0.0
|
77
74
|
Requires-Dist: rush==2021.4.0
|
78
75
|
Requires-Dist: shellingham==1.5.4
|
79
76
|
Requires-Dist: simple-websocket==1.0.0
|
@@ -82,17 +79,18 @@ Requires-Dist: soupsieve==2.5
|
|
82
79
|
Requires-Dist: stevedore==5.2.0
|
83
80
|
Requires-Dist: tabulate==0.9.0
|
84
81
|
Requires-Dist: thesmuggler==1.0.1
|
85
|
-
Requires-Dist: typing-extensions==4.
|
82
|
+
Requires-Dist: typing-extensions==4.11.0
|
86
83
|
Requires-Dist: typing-inspect==0.9.0
|
84
|
+
Requires-Dist: tzlocal==5.2
|
87
85
|
Requires-Dist: update-checker==0.18.0
|
88
86
|
Requires-Dist: urllib3==2.2.1
|
89
87
|
Requires-Dist: validators==0.22.0
|
90
|
-
Requires-Dist: werkzeug==3.0.
|
88
|
+
Requires-Dist: werkzeug==3.0.2
|
91
89
|
Requires-Dist: wrapt==1.16.0
|
92
90
|
Requires-Dist: wsproto==1.2.0
|
93
|
-
Requires-Dist: zipp==3.
|
91
|
+
Requires-Dist: zipp==3.18.1
|
94
92
|
Requires-Dist: zope-event==5.0
|
95
|
-
Requires-Dist: zope-interface==6.
|
93
|
+
Requires-Dist: zope-interface==6.3
|
96
94
|
|
97
95
|
===============================================
|
98
96
|
APRSD - Ham radio APRS-IS Message plugin server
|
@@ -1,15 +1,18 @@
|
|
1
1
|
import abc
|
2
|
+
import datetime
|
2
3
|
import logging
|
4
|
+
import threading
|
3
5
|
import time
|
4
6
|
|
5
7
|
import aprslib
|
6
8
|
from aprslib.exceptions import LoginError
|
7
9
|
from oslo_config import cfg
|
10
|
+
import wrapt
|
8
11
|
|
9
12
|
from aprsd import exception
|
10
13
|
from aprsd.clients import aprsis, fake, kiss
|
11
|
-
from aprsd.packets import core
|
12
|
-
from aprsd.utils import trace
|
14
|
+
from aprsd.packets import core
|
15
|
+
from aprsd.utils import singleton, trace
|
13
16
|
|
14
17
|
|
15
18
|
CONF = cfg.CONF
|
@@ -25,6 +28,34 @@ TRANSPORT_FAKE = "fake"
|
|
25
28
|
factory = None
|
26
29
|
|
27
30
|
|
31
|
+
@singleton
|
32
|
+
class APRSClientStats:
|
33
|
+
|
34
|
+
lock = threading.Lock()
|
35
|
+
|
36
|
+
@wrapt.synchronized(lock)
|
37
|
+
def stats(self, serializable=False):
|
38
|
+
client = factory.create()
|
39
|
+
stats = {
|
40
|
+
"transport": client.transport(),
|
41
|
+
"filter": client.filter,
|
42
|
+
"connected": client.connected,
|
43
|
+
}
|
44
|
+
|
45
|
+
if client.transport() == TRANSPORT_APRSIS:
|
46
|
+
stats["server_string"] = client.client.server_string
|
47
|
+
keepalive = client.client.aprsd_keepalive
|
48
|
+
if serializable:
|
49
|
+
keepalive = keepalive.isoformat()
|
50
|
+
stats["server_keepalive"] = keepalive
|
51
|
+
elif client.transport() == TRANSPORT_TCPKISS:
|
52
|
+
stats["host"] = CONF.kiss_tcp.host
|
53
|
+
stats["port"] = CONF.kiss_tcp.port
|
54
|
+
elif client.transport() == TRANSPORT_SERIALKISS:
|
55
|
+
stats["device"] = CONF.kiss_serial.device
|
56
|
+
return stats
|
57
|
+
|
58
|
+
|
28
59
|
class Client:
|
29
60
|
"""Singleton client class that constructs the aprslib connection."""
|
30
61
|
|
@@ -32,16 +63,21 @@ class Client:
|
|
32
63
|
_client = None
|
33
64
|
|
34
65
|
connected = False
|
35
|
-
server_string = None
|
36
66
|
filter = None
|
67
|
+
lock = threading.Lock()
|
37
68
|
|
38
69
|
def __new__(cls, *args, **kwargs):
|
39
70
|
"""This magic turns this into a singleton."""
|
40
71
|
if cls._instance is None:
|
41
72
|
cls._instance = super().__new__(cls)
|
42
73
|
# Put any initialization here.
|
74
|
+
cls._instance._create_client()
|
43
75
|
return cls._instance
|
44
76
|
|
77
|
+
@abc.abstractmethod
|
78
|
+
def stats(self) -> dict:
|
79
|
+
pass
|
80
|
+
|
45
81
|
def set_filter(self, filter):
|
46
82
|
self.filter = filter
|
47
83
|
if self._client:
|
@@ -50,21 +86,32 @@ class Client:
|
|
50
86
|
@property
|
51
87
|
def client(self):
|
52
88
|
if not self._client:
|
53
|
-
|
54
|
-
self._client = self.setup_connection()
|
55
|
-
if self.filter:
|
56
|
-
LOG.info("Creating APRS client filter")
|
57
|
-
self._client.set_filter(self.filter)
|
89
|
+
self._create_client()
|
58
90
|
return self._client
|
59
91
|
|
92
|
+
def _create_client(self):
|
93
|
+
self._client = self.setup_connection()
|
94
|
+
if self.filter:
|
95
|
+
LOG.info("Creating APRS client filter")
|
96
|
+
self._client.set_filter(self.filter)
|
97
|
+
|
98
|
+
def stop(self):
|
99
|
+
if self._client:
|
100
|
+
LOG.info("Stopping client connection.")
|
101
|
+
self._client.stop()
|
102
|
+
|
60
103
|
def send(self, packet: core.Packet):
|
61
|
-
|
104
|
+
"""Send a packet to the network."""
|
62
105
|
self.client.send(packet)
|
63
106
|
|
107
|
+
@wrapt.synchronized(lock)
|
64
108
|
def reset(self):
|
65
109
|
"""Call this to force a rebuild/reconnect."""
|
110
|
+
LOG.info("Resetting client connection.")
|
66
111
|
if self._client:
|
112
|
+
self._client.close()
|
67
113
|
del self._client
|
114
|
+
self._create_client()
|
68
115
|
else:
|
69
116
|
LOG.warning("Client not initialized, nothing to reset.")
|
70
117
|
|
@@ -89,11 +136,38 @@ class Client:
|
|
89
136
|
def decode_packet(self, *args, **kwargs):
|
90
137
|
pass
|
91
138
|
|
139
|
+
@abc.abstractmethod
|
140
|
+
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
141
|
+
pass
|
142
|
+
|
143
|
+
@abc.abstractmethod
|
144
|
+
def is_alive(self):
|
145
|
+
pass
|
146
|
+
|
147
|
+
@abc.abstractmethod
|
148
|
+
def close(self):
|
149
|
+
pass
|
150
|
+
|
92
151
|
|
93
152
|
class APRSISClient(Client):
|
94
153
|
|
95
154
|
_client = None
|
96
155
|
|
156
|
+
def __init__(self):
|
157
|
+
max_timeout = {"hours": 0.0, "minutes": 2, "seconds": 0}
|
158
|
+
self.max_delta = datetime.timedelta(**max_timeout)
|
159
|
+
|
160
|
+
def stats(self) -> dict:
|
161
|
+
stats = {}
|
162
|
+
if self.is_configured():
|
163
|
+
stats = {
|
164
|
+
"server_string": self._client.server_string,
|
165
|
+
"sever_keepalive": self._client.aprsd_keepalive,
|
166
|
+
"filter": self.filter,
|
167
|
+
}
|
168
|
+
|
169
|
+
return stats
|
170
|
+
|
97
171
|
@staticmethod
|
98
172
|
def is_enabled():
|
99
173
|
# Defaults to True if the enabled flag is non existent
|
@@ -125,44 +199,56 @@ class APRSISClient(Client):
|
|
125
199
|
return True
|
126
200
|
return True
|
127
201
|
|
202
|
+
def _is_stale_connection(self):
|
203
|
+
delta = datetime.datetime.now() - self._client.aprsd_keepalive
|
204
|
+
if delta > self.max_delta:
|
205
|
+
LOG.error(f"Connection is stale, last heard {delta} ago.")
|
206
|
+
return True
|
207
|
+
|
128
208
|
def is_alive(self):
|
129
209
|
if self._client:
|
130
|
-
return self._client.is_alive()
|
210
|
+
return self._client.is_alive() and not self._is_stale_connection()
|
131
211
|
else:
|
212
|
+
LOG.warning(f"APRS_CLIENT {self._client} alive? NO!!!")
|
132
213
|
return False
|
133
214
|
|
215
|
+
def close(self):
|
216
|
+
if self._client:
|
217
|
+
self._client.stop()
|
218
|
+
self._client.close()
|
219
|
+
|
134
220
|
@staticmethod
|
135
221
|
def transport():
|
136
222
|
return TRANSPORT_APRSIS
|
137
223
|
|
138
224
|
def decode_packet(self, *args, **kwargs):
|
139
225
|
"""APRS lib already decodes this."""
|
140
|
-
return core.
|
226
|
+
return core.factory(args[0])
|
141
227
|
|
142
228
|
def setup_connection(self):
|
143
229
|
user = CONF.aprs_network.login
|
144
230
|
password = CONF.aprs_network.password
|
145
231
|
host = CONF.aprs_network.host
|
146
232
|
port = CONF.aprs_network.port
|
147
|
-
connected = False
|
233
|
+
self.connected = False
|
148
234
|
backoff = 1
|
149
235
|
aprs_client = None
|
150
|
-
while not connected:
|
236
|
+
while not self.connected:
|
151
237
|
try:
|
152
|
-
LOG.info("Creating aprslib client")
|
238
|
+
LOG.info(f"Creating aprslib client({host}:{port}) and logging in {user}.")
|
153
239
|
aprs_client = aprsis.Aprsdis(user, passwd=password, host=host, port=port)
|
154
240
|
# Force the log to be the same
|
155
241
|
aprs_client.logger = LOG
|
156
242
|
aprs_client.connect()
|
157
|
-
connected = True
|
243
|
+
self.connected = True
|
158
244
|
backoff = 1
|
159
245
|
except LoginError as e:
|
160
246
|
LOG.error(f"Failed to login to APRS-IS Server '{e}'")
|
161
|
-
connected = False
|
247
|
+
self.connected = False
|
162
248
|
time.sleep(backoff)
|
163
249
|
except Exception as e:
|
164
250
|
LOG.error(f"Unable to connect to APRS-IS server. '{e}' ")
|
165
|
-
connected = False
|
251
|
+
self.connected = False
|
166
252
|
time.sleep(backoff)
|
167
253
|
# Don't allow the backoff to go to inifinity.
|
168
254
|
if backoff > 5:
|
@@ -170,15 +256,28 @@ class APRSISClient(Client):
|
|
170
256
|
else:
|
171
257
|
backoff += 1
|
172
258
|
continue
|
173
|
-
LOG.debug(f"Logging in to APRS-IS with user '{user}'")
|
174
259
|
self._client = aprs_client
|
175
260
|
return aprs_client
|
176
261
|
|
262
|
+
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
263
|
+
self._client.consumer(
|
264
|
+
callback, blocking=blocking,
|
265
|
+
immortal=immortal, raw=raw,
|
266
|
+
)
|
267
|
+
|
177
268
|
|
178
269
|
class KISSClient(Client):
|
179
270
|
|
180
271
|
_client = None
|
181
272
|
|
273
|
+
def stats(self) -> dict:
|
274
|
+
stats = {}
|
275
|
+
if self.is_configured():
|
276
|
+
return {
|
277
|
+
"transport": self.transport(),
|
278
|
+
}
|
279
|
+
return stats
|
280
|
+
|
182
281
|
@staticmethod
|
183
282
|
def is_enabled():
|
184
283
|
"""Return if tcp or serial KISS is enabled."""
|
@@ -217,6 +316,10 @@ class KISSClient(Client):
|
|
217
316
|
else:
|
218
317
|
return False
|
219
318
|
|
319
|
+
def close(self):
|
320
|
+
if self._client:
|
321
|
+
self._client.stop()
|
322
|
+
|
220
323
|
@staticmethod
|
221
324
|
def transport():
|
222
325
|
if CONF.kiss_serial.enabled:
|
@@ -238,7 +341,7 @@ class KISSClient(Client):
|
|
238
341
|
# LOG.debug(f"Decoding {msg}")
|
239
342
|
|
240
343
|
raw = aprslib.parse(str(frame))
|
241
|
-
packet = core.
|
344
|
+
packet = core.factory(raw)
|
242
345
|
if isinstance(packet, core.ThirdParty):
|
243
346
|
return packet.subpacket
|
244
347
|
else:
|
@@ -246,11 +349,18 @@ class KISSClient(Client):
|
|
246
349
|
|
247
350
|
def setup_connection(self):
|
248
351
|
self._client = kiss.KISS3Client()
|
352
|
+
self.connected = True
|
249
353
|
return self._client
|
250
354
|
|
355
|
+
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
356
|
+
self._client.consumer(callback)
|
357
|
+
|
251
358
|
|
252
359
|
class APRSDFakeClient(Client, metaclass=trace.TraceWrapperMetaclass):
|
253
360
|
|
361
|
+
def stats(self) -> dict:
|
362
|
+
return {}
|
363
|
+
|
254
364
|
@staticmethod
|
255
365
|
def is_enabled():
|
256
366
|
if CONF.fake_client.enabled:
|
@@ -264,7 +374,11 @@ class APRSDFakeClient(Client, metaclass=trace.TraceWrapperMetaclass):
|
|
264
374
|
def is_alive(self):
|
265
375
|
return True
|
266
376
|
|
377
|
+
def close(self):
|
378
|
+
pass
|
379
|
+
|
267
380
|
def setup_connection(self):
|
381
|
+
self.connected = True
|
268
382
|
return fake.APRSDFakeClient()
|
269
383
|
|
270
384
|
@staticmethod
|
@@ -304,7 +418,6 @@ class ClientFactory:
|
|
304
418
|
key = TRANSPORT_FAKE
|
305
419
|
|
306
420
|
builder = self._builders.get(key)
|
307
|
-
LOG.debug(f"Creating client {key}")
|
308
421
|
if not builder:
|
309
422
|
raise ValueError(key)
|
310
423
|
return builder()
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import datetime
|
1
2
|
import logging
|
2
3
|
import select
|
3
4
|
import threading
|
@@ -11,7 +12,6 @@ from aprslib.exceptions import (
|
|
11
12
|
import wrapt
|
12
13
|
|
13
14
|
import aprsd
|
14
|
-
from aprsd import stats
|
15
15
|
from aprsd.packets import core
|
16
16
|
|
17
17
|
|
@@ -24,6 +24,9 @@ class Aprsdis(aprslib.IS):
|
|
24
24
|
# flag to tell us to stop
|
25
25
|
thread_stop = False
|
26
26
|
|
27
|
+
# date for last time we heard from the server
|
28
|
+
aprsd_keepalive = datetime.datetime.now()
|
29
|
+
|
27
30
|
# timeout in seconds
|
28
31
|
select_timeout = 1
|
29
32
|
lock = threading.Lock()
|
@@ -142,7 +145,6 @@ class Aprsdis(aprslib.IS):
|
|
142
145
|
|
143
146
|
self.logger.info(f"Connected to {server_string}")
|
144
147
|
self.server_string = server_string
|
145
|
-
stats.APRSDStats().set_aprsis_server(server_string)
|
146
148
|
|
147
149
|
except LoginError as e:
|
148
150
|
self.logger.error(str(e))
|
@@ -176,13 +178,14 @@ class Aprsdis(aprslib.IS):
|
|
176
178
|
try:
|
177
179
|
for line in self._socket_readlines(blocking):
|
178
180
|
if line[0:1] != b"#":
|
181
|
+
self.aprsd_keepalive = datetime.datetime.now()
|
179
182
|
if raw:
|
180
183
|
callback(line)
|
181
184
|
else:
|
182
185
|
callback(self._parse(line))
|
183
186
|
else:
|
184
187
|
self.logger.debug("Server: %s", line.decode("utf8"))
|
185
|
-
|
188
|
+
self.aprsd_keepalive = datetime.datetime.now()
|
186
189
|
except ParseError as exp:
|
187
190
|
self.logger.log(
|
188
191
|
11,
|
@@ -67,7 +67,7 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
|
|
67
67
|
# Generate packets here?
|
68
68
|
raw = "GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW"
|
69
69
|
pkt_raw = aprslib.parse(raw)
|
70
|
-
pkt = core.
|
70
|
+
pkt = core.factory(pkt_raw)
|
71
71
|
callback(packet=pkt)
|
72
72
|
LOG.debug(f"END blocking FAKE consumer {self}")
|
73
73
|
time.sleep(8)
|
@@ -81,7 +81,7 @@ class KISS3Client:
|
|
81
81
|
LOG.error("Failed to parse bytes received from KISS interface.")
|
82
82
|
LOG.exception(ex)
|
83
83
|
|
84
|
-
def consumer(self, callback
|
84
|
+
def consumer(self, callback):
|
85
85
|
LOG.debug("Start blocking KISS consumer")
|
86
86
|
self._parse_callback = callback
|
87
87
|
self.kiss.read(callback=self.parse_frame, min_frames=None)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import click
|
2
|
+
import click.shell_completion
|
3
|
+
|
4
|
+
from aprsd.main import cli
|
5
|
+
|
6
|
+
|
7
|
+
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
8
|
+
|
9
|
+
|
10
|
+
@cli.command()
|
11
|
+
@click.argument("shell", type=click.Choice(list(click.shell_completion._available_shells)))
|
12
|
+
def completion(shell):
|
13
|
+
"""Show the shell completion code"""
|
14
|
+
from click.utils import _detect_program_name
|
15
|
+
|
16
|
+
cls = click.shell_completion.get_completion_class(shell)
|
17
|
+
prog_name = _detect_program_name()
|
18
|
+
complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper()
|
19
|
+
print(cls(cli, {}, prog_name, complete_var).source())
|
20
|
+
print("# Add the following line to your shell configuration file to have aprsd command line completion")
|
21
|
+
print("# but remove the leading '#' character.")
|
22
|
+
print(f"# eval \"$(aprsd completion {shell})\"")
|