aprsd 1.0.0__py3-none-any.whl → 3.4.2__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.
Files changed (140) hide show
  1. aprsd/__init__.py +6 -4
  2. aprsd/cli_helper.py +151 -0
  3. aprsd/client/__init__.py +13 -0
  4. aprsd/client/aprsis.py +132 -0
  5. aprsd/client/base.py +105 -0
  6. aprsd/client/drivers/__init__.py +0 -0
  7. aprsd/client/drivers/aprsis.py +228 -0
  8. aprsd/client/drivers/fake.py +73 -0
  9. aprsd/client/drivers/kiss.py +119 -0
  10. aprsd/client/factory.py +88 -0
  11. aprsd/client/fake.py +48 -0
  12. aprsd/client/kiss.py +103 -0
  13. aprsd/client/stats.py +38 -0
  14. aprsd/cmds/__init__.py +0 -0
  15. aprsd/cmds/completion.py +22 -0
  16. aprsd/cmds/dev.py +162 -0
  17. aprsd/cmds/fetch_stats.py +156 -0
  18. aprsd/cmds/healthcheck.py +86 -0
  19. aprsd/cmds/list_plugins.py +319 -0
  20. aprsd/cmds/listen.py +231 -0
  21. aprsd/cmds/send_message.py +171 -0
  22. aprsd/cmds/server.py +137 -0
  23. aprsd/cmds/webchat.py +674 -0
  24. aprsd/conf/__init__.py +56 -0
  25. aprsd/conf/client.py +131 -0
  26. aprsd/conf/common.py +301 -0
  27. aprsd/conf/log.py +65 -0
  28. aprsd/conf/opts.py +80 -0
  29. aprsd/conf/plugin_common.py +182 -0
  30. aprsd/conf/plugin_email.py +105 -0
  31. aprsd/exception.py +13 -0
  32. aprsd/log/__init__.py +0 -0
  33. aprsd/log/log.py +138 -0
  34. aprsd/main.py +104 -867
  35. aprsd/packets/__init__.py +20 -0
  36. aprsd/packets/collector.py +79 -0
  37. aprsd/packets/core.py +823 -0
  38. aprsd/packets/log.py +161 -0
  39. aprsd/packets/packet_list.py +110 -0
  40. aprsd/packets/seen_list.py +49 -0
  41. aprsd/packets/tracker.py +103 -0
  42. aprsd/packets/watch_list.py +119 -0
  43. aprsd/plugin.py +474 -284
  44. aprsd/plugin_utils.py +86 -0
  45. aprsd/plugins/__init__.py +0 -0
  46. aprsd/plugins/email.py +709 -0
  47. aprsd/plugins/fortune.py +61 -0
  48. aprsd/plugins/location.py +179 -0
  49. aprsd/plugins/notify.py +61 -0
  50. aprsd/plugins/ping.py +31 -0
  51. aprsd/plugins/time.py +115 -0
  52. aprsd/plugins/version.py +31 -0
  53. aprsd/plugins/weather.py +405 -0
  54. aprsd/stats/__init__.py +20 -0
  55. aprsd/stats/app.py +49 -0
  56. aprsd/stats/collector.py +37 -0
  57. aprsd/threads/__init__.py +11 -0
  58. aprsd/threads/aprsd.py +119 -0
  59. aprsd/threads/keep_alive.py +131 -0
  60. aprsd/threads/log_monitor.py +121 -0
  61. aprsd/threads/registry.py +56 -0
  62. aprsd/threads/rx.py +354 -0
  63. aprsd/threads/stats.py +44 -0
  64. aprsd/threads/tx.py +255 -0
  65. aprsd/utils/__init__.py +218 -0
  66. aprsd/utils/counter.py +51 -0
  67. aprsd/utils/json.py +80 -0
  68. aprsd/utils/objectstore.py +123 -0
  69. aprsd/utils/ring_buffer.py +40 -0
  70. aprsd/utils/trace.py +180 -0
  71. aprsd/web/__init__.py +0 -0
  72. aprsd/web/admin/__init__.py +0 -0
  73. aprsd/web/admin/static/css/index.css +84 -0
  74. aprsd/web/admin/static/css/prism.css +4 -0
  75. aprsd/web/admin/static/css/tabs.css +35 -0
  76. aprsd/web/admin/static/images/Untitled.png +0 -0
  77. aprsd/web/admin/static/images/aprs-symbols-16-0.png +0 -0
  78. aprsd/web/admin/static/images/aprs-symbols-16-1.png +0 -0
  79. aprsd/web/admin/static/images/aprs-symbols-64-0.png +0 -0
  80. aprsd/web/admin/static/images/aprs-symbols-64-1.png +0 -0
  81. aprsd/web/admin/static/images/aprs-symbols-64-2.png +0 -0
  82. aprsd/web/admin/static/js/charts.js +235 -0
  83. aprsd/web/admin/static/js/echarts.js +465 -0
  84. aprsd/web/admin/static/js/logs.js +26 -0
  85. aprsd/web/admin/static/js/main.js +231 -0
  86. aprsd/web/admin/static/js/prism.js +12 -0
  87. aprsd/web/admin/static/js/send-message.js +114 -0
  88. aprsd/web/admin/static/js/tabs.js +28 -0
  89. aprsd/web/admin/templates/index.html +196 -0
  90. aprsd/web/chat/static/css/chat.css +115 -0
  91. aprsd/web/chat/static/css/index.css +66 -0
  92. aprsd/web/chat/static/css/style.css.map +1 -0
  93. aprsd/web/chat/static/css/tabs.css +41 -0
  94. aprsd/web/chat/static/css/upstream/bootstrap.min.css +6 -0
  95. aprsd/web/chat/static/css/upstream/font.woff2 +0 -0
  96. aprsd/web/chat/static/css/upstream/google-fonts.css +23 -0
  97. aprsd/web/chat/static/css/upstream/jquery-ui.css +1311 -0
  98. aprsd/web/chat/static/css/upstream/jquery.toast.css +28 -0
  99. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
  100. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
  101. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
  102. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
  103. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff +0 -0
  104. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff2 +0 -0
  105. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff +0 -0
  106. aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff2 +0 -0
  107. aprsd/web/chat/static/images/Untitled.png +0 -0
  108. aprsd/web/chat/static/images/aprs-symbols-16-0.png +0 -0
  109. aprsd/web/chat/static/images/aprs-symbols-16-1.png +0 -0
  110. aprsd/web/chat/static/images/aprs-symbols-64-0.png +0 -0
  111. aprsd/web/chat/static/images/aprs-symbols-64-1.png +0 -0
  112. aprsd/web/chat/static/images/aprs-symbols-64-2.png +0 -0
  113. aprsd/web/chat/static/images/globe.svg +3 -0
  114. aprsd/web/chat/static/js/gps.js +84 -0
  115. aprsd/web/chat/static/js/main.js +45 -0
  116. aprsd/web/chat/static/js/send-message.js +585 -0
  117. aprsd/web/chat/static/js/tabs.js +28 -0
  118. aprsd/web/chat/static/js/upstream/bootstrap.bundle.min.js +7 -0
  119. aprsd/web/chat/static/js/upstream/jquery-3.7.1.min.js +2 -0
  120. aprsd/web/chat/static/js/upstream/jquery-ui.min.js +13 -0
  121. aprsd/web/chat/static/js/upstream/jquery.toast.js +374 -0
  122. aprsd/web/chat/static/js/upstream/semantic.min.js +11 -0
  123. aprsd/web/chat/static/js/upstream/socket.io.min.js +7 -0
  124. aprsd/web/chat/templates/index.html +139 -0
  125. aprsd/wsgi.py +315 -0
  126. aprsd-3.4.2.dist-info/AUTHORS +13 -0
  127. aprsd-3.4.2.dist-info/LICENSE +175 -0
  128. aprsd-3.4.2.dist-info/METADATA +793 -0
  129. aprsd-3.4.2.dist-info/RECORD +133 -0
  130. {aprsd-1.0.0.dist-info → aprsd-3.4.2.dist-info}/WHEEL +1 -1
  131. aprsd-3.4.2.dist-info/entry_points.txt +8 -0
  132. aprsd/fake_aprs.py +0 -83
  133. aprsd/utils.py +0 -166
  134. aprsd-1.0.0.dist-info/AUTHORS +0 -6
  135. aprsd-1.0.0.dist-info/METADATA +0 -181
  136. aprsd-1.0.0.dist-info/RECORD +0 -13
  137. aprsd-1.0.0.dist-info/entry_points.txt +0 -4
  138. aprsd-1.0.0.dist-info/pbr.json +0 -1
  139. /aprsd/{fuzzyclock.py → utils/fuzzyclock.py} +0 -0
  140. {aprsd-1.0.0.dist-info → aprsd-3.4.2.dist-info}/top_level.txt +0 -0
aprsd/cmds/listen.py ADDED
@@ -0,0 +1,231 @@
1
+ #
2
+ # License GPLv2
3
+ #
4
+
5
+ # python included libs
6
+ import datetime
7
+ import logging
8
+ import signal
9
+ import sys
10
+ import time
11
+
12
+ import click
13
+ from oslo_config import cfg
14
+ from rich.console import Console
15
+
16
+ # local imports here
17
+ import aprsd
18
+ from aprsd import cli_helper, packets, plugin, threads
19
+ from aprsd.client import client_factory
20
+ from aprsd.main import cli
21
+ from aprsd.packets import collector as packet_collector
22
+ from aprsd.packets import log as packet_log
23
+ from aprsd.packets import seen_list
24
+ from aprsd.stats import collector
25
+ from aprsd.threads import keep_alive, rx
26
+ from aprsd.threads import stats as stats_thread
27
+
28
+
29
+ # setup the global logger
30
+ # log.basicConfig(level=log.DEBUG) # level=10
31
+ LOG = logging.getLogger("APRSD")
32
+ CONF = cfg.CONF
33
+ console = Console()
34
+
35
+
36
+ def signal_handler(sig, frame):
37
+ threads.APRSDThreadList().stop_all()
38
+ if "subprocess" not in str(frame):
39
+ LOG.info(
40
+ "Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}".format(
41
+ datetime.datetime.now(),
42
+ ),
43
+ )
44
+ time.sleep(5)
45
+ # Last save to disk
46
+ collector.Collector().collect()
47
+
48
+
49
+ class APRSDListenThread(rx.APRSDRXThread):
50
+ def __init__(self, packet_queue, packet_filter=None, plugin_manager=None):
51
+ super().__init__(packet_queue)
52
+ self.packet_filter = packet_filter
53
+ self.plugin_manager = plugin_manager
54
+ if self.plugin_manager:
55
+ LOG.info(f"Plugins {self.plugin_manager.get_message_plugins()}")
56
+
57
+ def process_packet(self, *args, **kwargs):
58
+ packet = self._client.decode_packet(*args, **kwargs)
59
+ filters = {
60
+ packets.Packet.__name__: packets.Packet,
61
+ packets.AckPacket.__name__: packets.AckPacket,
62
+ packets.BeaconPacket.__name__: packets.BeaconPacket,
63
+ packets.GPSPacket.__name__: packets.GPSPacket,
64
+ packets.MessagePacket.__name__: packets.MessagePacket,
65
+ packets.MicEPacket.__name__: packets.MicEPacket,
66
+ packets.ObjectPacket.__name__: packets.ObjectPacket,
67
+ packets.StatusPacket.__name__: packets.StatusPacket,
68
+ packets.ThirdPartyPacket.__name__: packets.ThirdPartyPacket,
69
+ packets.WeatherPacket.__name__: packets.WeatherPacket,
70
+ packets.UnknownPacket.__name__: packets.UnknownPacket,
71
+ }
72
+
73
+ if self.packet_filter:
74
+ filter_class = filters[self.packet_filter]
75
+ if isinstance(packet, filter_class):
76
+ packet_log.log(packet)
77
+ if self.plugin_manager:
78
+ # Don't do anything with the reply
79
+ # This is the listen only command.
80
+ self.plugin_manager.run(packet)
81
+ else:
82
+ packet_log.log(packet)
83
+ if self.plugin_manager:
84
+ # Don't do anything with the reply.
85
+ # This is the listen only command.
86
+ self.plugin_manager.run(packet)
87
+
88
+ packet_collector.PacketCollector().rx(packet)
89
+
90
+
91
+ @cli.command()
92
+ @cli_helper.add_options(cli_helper.common_options)
93
+ @click.option(
94
+ "--aprs-login",
95
+ envvar="APRS_LOGIN",
96
+ show_envvar=True,
97
+ help="What callsign to send the message from.",
98
+ )
99
+ @click.option(
100
+ "--aprs-password",
101
+ envvar="APRS_PASSWORD",
102
+ show_envvar=True,
103
+ help="the APRS-IS password for APRS_LOGIN",
104
+ )
105
+ @click.option(
106
+ "--packet-filter",
107
+ type=click.Choice(
108
+ [
109
+ packets.AckPacket.__name__,
110
+ packets.BeaconPacket.__name__,
111
+ packets.GPSPacket.__name__,
112
+ packets.MicEPacket.__name__,
113
+ packets.MessagePacket.__name__,
114
+ packets.ObjectPacket.__name__,
115
+ packets.RejectPacket.__name__,
116
+ packets.StatusPacket.__name__,
117
+ packets.ThirdPartyPacket.__name__,
118
+ packets.UnknownPacket.__name__,
119
+ packets.WeatherPacket.__name__,
120
+ ],
121
+ case_sensitive=False,
122
+ ),
123
+ help="Filter by packet type",
124
+ )
125
+ @click.option(
126
+ "--load-plugins",
127
+ default=False,
128
+ is_flag=True,
129
+ help="Load plugins as enabled in aprsd.conf ?",
130
+ )
131
+ @click.argument(
132
+ "filter",
133
+ nargs=-1,
134
+ required=True,
135
+ )
136
+ @click.pass_context
137
+ @cli_helper.process_standard_options
138
+ def listen(
139
+ ctx,
140
+ aprs_login,
141
+ aprs_password,
142
+ packet_filter,
143
+ load_plugins,
144
+ filter,
145
+ ):
146
+ """Listen to packets on the APRS-IS Network based on FILTER.
147
+
148
+ FILTER is the APRS Filter to use.\n
149
+ see http://www.aprs-is.net/javAPRSFilter.aspx\n
150
+ r/lat/lon/dist - Range Filter Pass posits and objects within dist km from lat/lon.\n
151
+ p/aa/bb/cc... - Prefix Filter Pass traffic with fromCall that start with aa or bb or cc.\n
152
+ b/call1/call2... - Budlist Filter Pass all traffic from exact call: call1, call2, ... (* wild card allowed) \n
153
+ o/obj1/obj2... - Object Filter Pass all objects with the exact name of obj1, obj2, ... (* wild card allowed)\n
154
+
155
+ """
156
+ signal.signal(signal.SIGINT, signal_handler)
157
+ signal.signal(signal.SIGTERM, signal_handler)
158
+
159
+ if not aprs_login:
160
+ click.echo(ctx.get_help())
161
+ click.echo("")
162
+ ctx.fail("Must set --aprs-login or APRS_LOGIN")
163
+ ctx.exit()
164
+
165
+ if not aprs_password:
166
+ click.echo(ctx.get_help())
167
+ click.echo("")
168
+ ctx.fail("Must set --aprs-password or APRS_PASSWORD")
169
+ ctx.exit()
170
+
171
+ # CONF.aprs_network.login = aprs_login
172
+ # config["aprs"]["password"] = aprs_password
173
+
174
+ LOG.info(f"APRSD Listen Started version: {aprsd.__version__}")
175
+
176
+ CONF.log_opt_values(LOG, logging.DEBUG)
177
+ collector.Collector()
178
+
179
+ # Try and load saved MsgTrack list
180
+ LOG.debug("Loading saved MsgTrack object.")
181
+
182
+ # Initialize the client factory and create
183
+ # The correct client object ready for use
184
+ # Make sure we have 1 client transport enabled
185
+ if not client_factory.is_client_enabled():
186
+ LOG.error("No Clients are enabled in config.")
187
+ sys.exit(-1)
188
+
189
+ # Creates the client object
190
+ LOG.info("Creating client connection")
191
+ aprs_client = client_factory.create()
192
+ LOG.info(aprs_client)
193
+
194
+ LOG.debug(f"Filter by '{filter}'")
195
+ aprs_client.set_filter(filter)
196
+
197
+ keepalive = keep_alive.KeepAliveThread()
198
+ # keepalive.start()
199
+
200
+ if not CONF.enable_seen_list:
201
+ # just deregister the class from the packet collector
202
+ packet_collector.PacketCollector().unregister(seen_list.SeenList)
203
+
204
+ pm = None
205
+ pm = plugin.PluginManager()
206
+ if load_plugins:
207
+ LOG.info("Loading plugins")
208
+ pm.setup_plugins(load_help_plugin=False)
209
+ else:
210
+ LOG.warning(
211
+ "Not Loading any plugins use --load-plugins to load what's "
212
+ "defined in the config file.",
213
+ )
214
+ stats = stats_thread.APRSDStatsStoreThread()
215
+ stats.start()
216
+
217
+ LOG.debug("Create APRSDListenThread")
218
+ listen_thread = APRSDListenThread(
219
+ packet_queue=threads.packet_queue,
220
+ packet_filter=packet_filter,
221
+ plugin_manager=pm,
222
+ )
223
+ LOG.debug("Start APRSDListenThread")
224
+ listen_thread.start()
225
+
226
+ keepalive.start()
227
+ LOG.debug("keepalive Join")
228
+ keepalive.join()
229
+ LOG.debug("listen_thread Join")
230
+ listen_thread.join()
231
+ stats.join()
@@ -0,0 +1,171 @@
1
+ import logging
2
+ import sys
3
+ import time
4
+
5
+ import aprslib
6
+ from aprslib.exceptions import LoginError
7
+ import click
8
+ from oslo_config import cfg
9
+
10
+ import aprsd
11
+ from aprsd import cli_helper, packets
12
+ from aprsd import conf # noqa : F401
13
+ from aprsd.client import client_factory
14
+ from aprsd.main import cli
15
+ import aprsd.packets # noqa : F401
16
+ from aprsd.packets import collector
17
+ from aprsd.threads import tx
18
+
19
+
20
+ CONF = cfg.CONF
21
+ LOG = logging.getLogger("APRSD")
22
+
23
+
24
+ @cli.command()
25
+ @cli_helper.add_options(cli_helper.common_options)
26
+ @click.option(
27
+ "--aprs-login",
28
+ envvar="APRS_LOGIN",
29
+ show_envvar=True,
30
+ help="What callsign to send the message from. Defaults to config entry.",
31
+ )
32
+ @click.option(
33
+ "--aprs-password",
34
+ envvar="APRS_PASSWORD",
35
+ show_envvar=True,
36
+ help="the APRS-IS password for APRS_LOGIN. Defaults to config entry.",
37
+ )
38
+ @click.option(
39
+ "--no-ack",
40
+ "-n",
41
+ is_flag=True,
42
+ show_default=True,
43
+ default=False,
44
+ help="Don't wait for an ack, just sent it to APRS-IS and bail.",
45
+ )
46
+ @click.option(
47
+ "--wait-response",
48
+ "-w",
49
+ is_flag=True,
50
+ show_default=True,
51
+ default=False,
52
+ help="Wait for a response to the message?",
53
+ )
54
+ @click.option("--raw", default=None, help="Send a raw message. Implies --no-ack")
55
+ @click.argument("tocallsign", required=True)
56
+ @click.argument("command", nargs=-1, required=True)
57
+ @click.pass_context
58
+ @cli_helper.process_standard_options
59
+ def send_message(
60
+ ctx,
61
+ aprs_login,
62
+ aprs_password,
63
+ no_ack,
64
+ wait_response,
65
+ raw,
66
+ tocallsign,
67
+ command,
68
+ ):
69
+ """Send a message to a callsign via APRS_IS."""
70
+ global got_ack, got_response
71
+ quiet = ctx.obj["quiet"]
72
+
73
+ if not aprs_login:
74
+ if CONF.aprs_network.login == conf.client.DEFAULT_LOGIN:
75
+ click.echo("Must set --aprs_login or APRS_LOGIN")
76
+ ctx.exit(-1)
77
+ return
78
+ else:
79
+ aprs_login = CONF.aprs_network.login
80
+
81
+ if not aprs_password:
82
+ if not CONF.aprs_network.password:
83
+ click.echo("Must set --aprs-password or APRS_PASSWORD")
84
+ ctx.exit(-1)
85
+ return
86
+ else:
87
+ aprs_password = CONF.aprs_network.password
88
+
89
+ LOG.info(f"APRSD LISTEN Started version: {aprsd.__version__}")
90
+ if type(command) is tuple:
91
+ command = " ".join(command)
92
+ if not quiet:
93
+ if raw:
94
+ LOG.info(f"L'{aprs_login}' R'{raw}'")
95
+ else:
96
+ LOG.info(f"L'{aprs_login}' To'{tocallsign}' C'{command}'")
97
+
98
+ got_ack = False
99
+ got_response = False
100
+
101
+ def rx_packet(packet):
102
+ global got_ack, got_response
103
+ cl = client_factory.create()
104
+ packet = cl.decode_packet(packet)
105
+ collector.PacketCollector().rx(packet)
106
+ packet.log("RX")
107
+ # LOG.debug("Got packet back {}".format(packet))
108
+ if isinstance(packet, packets.AckPacket):
109
+ got_ack = True
110
+ else:
111
+ got_response = True
112
+ from_call = packet.from_call
113
+ our_call = CONF.callsign.lower()
114
+ tx.send(
115
+ packets.AckPacket(
116
+ from_call=our_call,
117
+ to_call=from_call,
118
+ msgNo=packet.msgNo,
119
+ ),
120
+ direct=True,
121
+ )
122
+
123
+ if got_ack:
124
+ if wait_response:
125
+ if got_response:
126
+ sys.exit(0)
127
+ else:
128
+ sys.exit(0)
129
+
130
+ try:
131
+ client_factory.create().client
132
+ except LoginError:
133
+ sys.exit(-1)
134
+
135
+ # Send a message
136
+ # then we setup a consumer to rx messages
137
+ # We should get an ack back as well as a new message
138
+ # we should bail after we get the ack and send an ack back for the
139
+ # message
140
+ if raw:
141
+ tx.send(
142
+ packets.Packet(from_call="", to_call="", raw=raw),
143
+ direct=True,
144
+ )
145
+ sys.exit(0)
146
+ else:
147
+ tx.send(
148
+ packets.MessagePacket(
149
+ from_call=aprs_login,
150
+ to_call=tocallsign,
151
+ message_text=command,
152
+ ),
153
+ direct=True,
154
+ )
155
+
156
+ if no_ack:
157
+ sys.exit(0)
158
+
159
+ try:
160
+ # This will register a packet consumer with aprslib
161
+ # When new packets come in the consumer will process
162
+ # the packet
163
+ aprs_client = client_factory.create().client
164
+ aprs_client.consumer(rx_packet, raw=False)
165
+ except aprslib.exceptions.ConnectionDrop:
166
+ LOG.error("Connection dropped, reconnecting")
167
+ time.sleep(5)
168
+ # Force the deletion of the client object connected to aprs
169
+ # This will cause a reconnect, next time client.get_client()
170
+ # is called
171
+ aprs_client.reset()
aprsd/cmds/server.py ADDED
@@ -0,0 +1,137 @@
1
+ import logging
2
+ import signal
3
+ import sys
4
+
5
+ import click
6
+ from oslo_config import cfg
7
+
8
+ import aprsd
9
+ from aprsd import cli_helper
10
+ from aprsd import main as aprsd_main
11
+ from aprsd import plugin, threads, utils
12
+ from aprsd.client import client_factory
13
+ from aprsd.main import cli
14
+ from aprsd.packets import collector as packet_collector
15
+ from aprsd.packets import seen_list
16
+ from aprsd.threads import keep_alive, log_monitor, registry, rx
17
+ from aprsd.threads import stats as stats_thread
18
+ from aprsd.threads import tx
19
+
20
+
21
+ CONF = cfg.CONF
22
+ LOG = logging.getLogger("APRSD")
23
+
24
+
25
+ # main() ###
26
+ @cli.command()
27
+ @cli_helper.add_options(cli_helper.common_options)
28
+ @click.option(
29
+ "-f",
30
+ "--flush",
31
+ "flush",
32
+ is_flag=True,
33
+ show_default=True,
34
+ default=False,
35
+ help="Flush out all old aged messages on disk.",
36
+ )
37
+ @click.pass_context
38
+ @cli_helper.process_standard_options
39
+ def server(ctx, flush):
40
+ """Start the aprsd server gateway process."""
41
+ signal.signal(signal.SIGINT, aprsd_main.signal_handler)
42
+ signal.signal(signal.SIGTERM, aprsd_main.signal_handler)
43
+
44
+ level, msg = utils._check_version()
45
+ if level:
46
+ LOG.warning(msg)
47
+ else:
48
+ LOG.info(msg)
49
+ LOG.info(f"APRSD Started version: {aprsd.__version__}")
50
+
51
+ # Initialize the client factory and create
52
+ # The correct client object ready for use
53
+ if not client_factory.is_client_enabled():
54
+ LOG.error("No Clients are enabled in config.")
55
+ sys.exit(-1)
56
+
57
+ # Creates the client object
58
+ LOG.info("Creating client connection")
59
+ aprs_client = client_factory.create()
60
+ LOG.info(aprs_client)
61
+
62
+ # Create the initial PM singleton and Register plugins
63
+ # We register plugins first here so we can register each
64
+ # plugins config options, so we can dump them all in the
65
+ # log file output.
66
+ LOG.info("Loading Plugin Manager and registering plugins")
67
+ plugin_manager = plugin.PluginManager()
68
+ plugin_manager.setup_plugins()
69
+
70
+ # Dump all the config options now.
71
+ CONF.log_opt_values(LOG, logging.DEBUG)
72
+ message_plugins = plugin_manager.get_message_plugins()
73
+ watchlist_plugins = plugin_manager.get_watchlist_plugins()
74
+ LOG.info("Message Plugins enabled and running:")
75
+ for p in message_plugins:
76
+ LOG.info(p)
77
+ LOG.info("Watchlist Plugins enabled and running:")
78
+ for p in watchlist_plugins:
79
+ LOG.info(p)
80
+
81
+ # Make sure we have 1 client transport enabled
82
+ if not client_factory.is_client_enabled():
83
+ LOG.error("No Clients are enabled in config.")
84
+ sys.exit(-1)
85
+
86
+ if not client_factory.is_client_configured():
87
+ LOG.error("APRS client is not properly configured in config file.")
88
+ sys.exit(-1)
89
+
90
+ if not CONF.enable_seen_list:
91
+ # just deregister the class from the packet collector
92
+ packet_collector.PacketCollector().unregister(seen_list.SeenList)
93
+
94
+ # Now load the msgTrack from disk if any
95
+ if flush:
96
+ LOG.debug("Flushing All packet tracking objects.")
97
+ packet_collector.PacketCollector().flush()
98
+ else:
99
+ # Try and load saved MsgTrack list
100
+ LOG.debug("Loading saved packet tracking data.")
101
+ packet_collector.PacketCollector().load()
102
+
103
+ # Now start all the main processing threads.
104
+
105
+ keepalive = keep_alive.KeepAliveThread()
106
+ keepalive.start()
107
+
108
+ stats_store_thread = stats_thread.APRSDStatsStoreThread()
109
+ stats_store_thread.start()
110
+
111
+ rx_thread = rx.APRSDPluginRXThread(
112
+ packet_queue=threads.packet_queue,
113
+ )
114
+ process_thread = rx.APRSDPluginProcessPacketThread(
115
+ packet_queue=threads.packet_queue,
116
+ )
117
+ rx_thread.start()
118
+ process_thread.start()
119
+
120
+ if CONF.enable_beacon:
121
+ LOG.info("Beacon Enabled. Starting Beacon thread.")
122
+ bcn_thread = tx.BeaconSendThread()
123
+ bcn_thread.start()
124
+
125
+ if CONF.aprs_registry.enabled:
126
+ LOG.info("Registry Enabled. Starting Registry thread.")
127
+ registry_thread = registry.APRSRegistryThread()
128
+ registry_thread.start()
129
+
130
+ if CONF.admin.web_enabled:
131
+ log_monitor_thread = log_monitor.LogMonitorThread()
132
+ log_monitor_thread.start()
133
+
134
+ rx_thread.join()
135
+ process_thread.join()
136
+
137
+ return 0