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/conf/__init__.py ADDED
@@ -0,0 +1,56 @@
1
+ from oslo_config import cfg
2
+
3
+ from aprsd.conf import client, common, log, plugin_common, plugin_email
4
+
5
+
6
+ CONF = cfg.CONF
7
+
8
+ log.register_opts(CONF)
9
+ common.register_opts(CONF)
10
+ client.register_opts(CONF)
11
+
12
+ # plugins
13
+ plugin_common.register_opts(CONF)
14
+ plugin_email.register_opts(CONF)
15
+
16
+
17
+ def set_lib_defaults():
18
+ """Update default value for configuration options from other namespace.
19
+ Example, oslo lib config options. This is needed for
20
+ config generator tool to pick these default value changes.
21
+ https://docs.openstack.org/oslo.config/latest/cli/
22
+ generator.html#modifying-defaults-from-other-namespaces
23
+ """
24
+
25
+ # Update default value of oslo_log default_log_levels and
26
+ # logging_context_format_string config option.
27
+ set_log_defaults()
28
+
29
+
30
+ def set_log_defaults():
31
+ # log.set_defaults(default_log_levels=log.get_default_log_levels())
32
+ pass
33
+
34
+
35
+ def conf_to_dict():
36
+ """Convert the CONF options to a single level dictionary."""
37
+ entries = {}
38
+
39
+ def _sanitize(opt, value):
40
+ """Obfuscate values of options declared secret."""
41
+ return value if not opt.secret else "*" * 4
42
+
43
+ for opt_name in sorted(CONF._opts):
44
+ opt = CONF._get_opt_info(opt_name)["opt"]
45
+ val = str(_sanitize(opt, getattr(CONF, opt_name)))
46
+ entries[str(opt)] = val
47
+
48
+ for group_name in list(CONF._groups):
49
+ group_attr = CONF.GroupAttr(CONF, CONF._get_group(group_name))
50
+ for opt_name in sorted(CONF._groups[group_name]._opts):
51
+ opt = CONF._get_opt_info(opt_name, group_name)["opt"]
52
+ val = str(_sanitize(opt, getattr(group_attr, opt_name)))
53
+ gname_opt_name = f"{group_name}.{opt_name}"
54
+ entries[gname_opt_name] = val
55
+
56
+ return entries
aprsd/conf/client.py ADDED
@@ -0,0 +1,131 @@
1
+ """
2
+ The options for log setup
3
+ """
4
+
5
+ from oslo_config import cfg
6
+
7
+
8
+ DEFAULT_LOGIN = "NOCALL"
9
+
10
+ aprs_group = cfg.OptGroup(
11
+ name="aprs_network",
12
+ title="APRS-IS Network settings",
13
+ )
14
+
15
+ kiss_serial_group = cfg.OptGroup(
16
+ name="kiss_serial",
17
+ title="KISS Serial device connection",
18
+ )
19
+
20
+ kiss_tcp_group = cfg.OptGroup(
21
+ name="kiss_tcp",
22
+ title="KISS TCP/IP Device connection",
23
+ )
24
+
25
+ fake_client_group = cfg.OptGroup(
26
+ name="fake_client",
27
+ title="Fake Client settings",
28
+ )
29
+ aprs_opts = [
30
+ cfg.BoolOpt(
31
+ "enabled",
32
+ default=True,
33
+ help="Set enabled to False if there is no internet connectivity."
34
+ "This is useful for a direwolf KISS aprs connection only.",
35
+ ),
36
+ cfg.StrOpt(
37
+ "login",
38
+ default=DEFAULT_LOGIN,
39
+ help="APRS Username",
40
+ ),
41
+ cfg.StrOpt(
42
+ "password",
43
+ secret=True,
44
+ help="APRS Password "
45
+ "Get the passcode for your callsign here: "
46
+ "https://apps.magicbug.co.uk/passcode",
47
+ ),
48
+ cfg.HostAddressOpt(
49
+ "host",
50
+ default="noam.aprs2.net",
51
+ help="The APRS-IS hostname",
52
+ ),
53
+ cfg.PortOpt(
54
+ "port",
55
+ default=14580,
56
+ help="APRS-IS port",
57
+ ),
58
+ ]
59
+
60
+ kiss_serial_opts = [
61
+ cfg.BoolOpt(
62
+ "enabled",
63
+ default=False,
64
+ help="Enable Serial KISS interface connection.",
65
+ ),
66
+ cfg.StrOpt(
67
+ "device",
68
+ help="Serial Device file to use. /dev/ttyS0",
69
+ ),
70
+ cfg.IntOpt(
71
+ "baudrate",
72
+ default=9600,
73
+ help="The Serial device baud rate for communication",
74
+ ),
75
+ cfg.ListOpt(
76
+ "path",
77
+ default=["WIDE1-1", "WIDE2-1"],
78
+ help="The APRS path to use for wide area coverage.",
79
+ ),
80
+ ]
81
+
82
+ kiss_tcp_opts = [
83
+ cfg.BoolOpt(
84
+ "enabled",
85
+ default=False,
86
+ help="Enable Serial KISS interface connection.",
87
+ ),
88
+ cfg.HostAddressOpt(
89
+ "host",
90
+ help="The KISS TCP Host to connect to.",
91
+ ),
92
+ cfg.PortOpt(
93
+ "port",
94
+ default=8001,
95
+ help="The KISS TCP/IP network port",
96
+ ),
97
+ cfg.ListOpt(
98
+ "path",
99
+ default=["WIDE1-1", "WIDE2-1"],
100
+ help="The APRS path to use for wide area coverage.",
101
+ ),
102
+ ]
103
+
104
+ fake_client_opts = [
105
+ cfg.BoolOpt(
106
+ "enabled",
107
+ default=False,
108
+ help="Enable fake client connection.",
109
+ ),
110
+ ]
111
+
112
+
113
+ def register_opts(config):
114
+ config.register_group(aprs_group)
115
+ config.register_opts(aprs_opts, group=aprs_group)
116
+ config.register_group(kiss_serial_group)
117
+ config.register_group(kiss_tcp_group)
118
+ config.register_opts(kiss_serial_opts, group=kiss_serial_group)
119
+ config.register_opts(kiss_tcp_opts, group=kiss_tcp_group)
120
+
121
+ config.register_group(fake_client_group)
122
+ config.register_opts(fake_client_opts, group=fake_client_group)
123
+
124
+
125
+ def list_opts():
126
+ return {
127
+ aprs_group.name: aprs_opts,
128
+ kiss_serial_group.name: kiss_serial_opts,
129
+ kiss_tcp_group.name: kiss_tcp_opts,
130
+ fake_client_group.name: fake_client_opts,
131
+ }
aprsd/conf/common.py ADDED
@@ -0,0 +1,301 @@
1
+ from pathlib import Path
2
+
3
+ from oslo_config import cfg
4
+
5
+
6
+ home = str(Path.home())
7
+ DEFAULT_CONFIG_DIR = f"{home}/.config/aprsd/"
8
+ APRSD_DEFAULT_MAGIC_WORD = "CHANGEME!!!"
9
+
10
+ admin_group = cfg.OptGroup(
11
+ name="admin",
12
+ title="Admin web interface settings",
13
+ )
14
+ watch_list_group = cfg.OptGroup(
15
+ name="watch_list",
16
+ title="Watch List settings",
17
+ )
18
+ webchat_group = cfg.OptGroup(
19
+ name="webchat",
20
+ title="Settings specific to the webchat command",
21
+ )
22
+
23
+ registry_group = cfg.OptGroup(
24
+ name="aprs_registry",
25
+ title="APRS Registry settings",
26
+ )
27
+
28
+
29
+ aprsd_opts = [
30
+ cfg.StrOpt(
31
+ "callsign",
32
+ required=True,
33
+ help="Callsign to use for messages sent by APRSD",
34
+ ),
35
+ cfg.BoolOpt(
36
+ "enable_save",
37
+ default=True,
38
+ help="Enable saving of watch list, packet tracker between restarts.",
39
+ ),
40
+ cfg.StrOpt(
41
+ "save_location",
42
+ default=DEFAULT_CONFIG_DIR,
43
+ help="Save location for packet tracking files.",
44
+ ),
45
+ cfg.BoolOpt(
46
+ "trace_enabled",
47
+ default=False,
48
+ help="Enable code tracing",
49
+ ),
50
+ cfg.StrOpt(
51
+ "units",
52
+ default="imperial",
53
+ help="Units for display, imperial or metric",
54
+ ),
55
+ cfg.IntOpt(
56
+ "ack_rate_limit_period",
57
+ default=1,
58
+ help="The wait period in seconds per Ack packet being sent."
59
+ "1 means 1 ack packet per second allowed."
60
+ "2 means 1 pack packet every 2 seconds allowed",
61
+ ),
62
+ cfg.IntOpt(
63
+ "msg_rate_limit_period",
64
+ default=2,
65
+ help="Wait period in seconds per non AckPacket being sent."
66
+ "2 means 1 packet every 2 seconds allowed."
67
+ "5 means 1 pack packet every 5 seconds allowed",
68
+ ),
69
+ cfg.IntOpt(
70
+ "packet_dupe_timeout",
71
+ default=300,
72
+ help="The number of seconds before a packet is not considered a duplicate.",
73
+ ),
74
+ cfg.BoolOpt(
75
+ "enable_beacon",
76
+ default=False,
77
+ help="Enable sending of a GPS Beacon packet to locate this service. "
78
+ "Requires latitude and longitude to be set.",
79
+ ),
80
+ cfg.IntOpt(
81
+ "beacon_interval",
82
+ default=1800,
83
+ help="The number of seconds between beacon packets.",
84
+ ),
85
+ cfg.StrOpt(
86
+ "beacon_symbol",
87
+ default="/",
88
+ help="The symbol to use for the GPS Beacon packet. See: http://www.aprs.net/vm/DOS/SYMBOLS.HTM",
89
+ ),
90
+ cfg.StrOpt(
91
+ "latitude",
92
+ default=None,
93
+ help="Latitude for the GPS Beacon button. If not set, the button will not be enabled.",
94
+ ),
95
+ cfg.StrOpt(
96
+ "longitude",
97
+ default=None,
98
+ help="Longitude for the GPS Beacon button. If not set, the button will not be enabled.",
99
+ ),
100
+ cfg.StrOpt(
101
+ "log_packet_format",
102
+ choices=["compact", "multiline", "both"],
103
+ default="compact",
104
+ help="When logging packets 'compact' will use a single line formatted for each packet."
105
+ "'multiline' will use multiple lines for each packet and is the traditional format."
106
+ "both will log both compact and multiline.",
107
+ ),
108
+ cfg.IntOpt(
109
+ "default_packet_send_count",
110
+ default=3,
111
+ help="The number of times to send a non ack packet before giving up.",
112
+ ),
113
+ cfg.IntOpt(
114
+ "default_ack_send_count",
115
+ default=3,
116
+ help="The number of times to send an ack packet in response to recieving a packet.",
117
+ ),
118
+ cfg.IntOpt(
119
+ "packet_list_maxlen",
120
+ default=100,
121
+ help="The maximum number of packets to store in the packet list.",
122
+ ),
123
+ cfg.IntOpt(
124
+ "packet_list_stats_maxlen",
125
+ default=20,
126
+ help="The maximum number of packets to send in the stats dict for admin ui.",
127
+ ),
128
+ cfg.BoolOpt(
129
+ "enable_seen_list",
130
+ default=True,
131
+ help="Enable the Callsign seen list tracking feature. This allows aprsd to keep track of "
132
+ "callsigns that have been seen and when they were last seen.",
133
+ ),
134
+ cfg.BoolOpt(
135
+ "enable_packet_logging",
136
+ default=True,
137
+ help="Set this to False, to disable logging of packets to the log file.",
138
+ ),
139
+ ]
140
+
141
+ watch_list_opts = [
142
+ cfg.BoolOpt(
143
+ "enabled",
144
+ default=False,
145
+ help="Enable the watch list feature. Still have to enable "
146
+ "the correct plugin. Built-in plugin to use is "
147
+ "aprsd.plugins.notify.NotifyPlugin",
148
+ ),
149
+ cfg.ListOpt(
150
+ "callsigns",
151
+ help="Callsigns to watch for messsages",
152
+ ),
153
+ cfg.StrOpt(
154
+ "alert_callsign",
155
+ help="The Ham Callsign to send messages to for watch list alerts.",
156
+ ),
157
+ cfg.IntOpt(
158
+ "packet_keep_count",
159
+ default=10,
160
+ help="The number of packets to store.",
161
+ ),
162
+ cfg.IntOpt(
163
+ "alert_time_seconds",
164
+ default=3600,
165
+ help="Time to wait before alert is sent on new message for "
166
+ "users in callsigns.",
167
+ ),
168
+ ]
169
+
170
+ admin_opts = [
171
+ cfg.BoolOpt(
172
+ "web_enabled",
173
+ default=False,
174
+ help="Enable the Admin Web Interface",
175
+ ),
176
+ cfg.StrOpt(
177
+ "web_ip",
178
+ default="0.0.0.0",
179
+ help="The ip address to listen on",
180
+ ),
181
+ cfg.PortOpt(
182
+ "web_port",
183
+ default=8001,
184
+ help="The port to listen on",
185
+ ),
186
+ cfg.StrOpt(
187
+ "user",
188
+ default="admin",
189
+ help="The admin user for the admin web interface",
190
+ ),
191
+ cfg.StrOpt(
192
+ "password",
193
+ default="password",
194
+ secret=True,
195
+ help="Admin interface password",
196
+ ),
197
+ ]
198
+
199
+
200
+ enabled_plugins_opts = [
201
+ cfg.ListOpt(
202
+ "enabled_plugins",
203
+ default=[
204
+ "aprsd.plugins.email.EmailPlugin",
205
+ "aprsd.plugins.fortune.FortunePlugin",
206
+ "aprsd.plugins.location.LocationPlugin",
207
+ "aprsd.plugins.ping.PingPlugin",
208
+ "aprsd.plugins.time.TimePlugin",
209
+ "aprsd.plugins.weather.OWMWeatherPlugin",
210
+ "aprsd.plugins.version.VersionPlugin",
211
+ "aprsd.plugins.notify.NotifySeenPlugin",
212
+ ],
213
+ help="Comma separated list of enabled plugins for APRSD."
214
+ "To enable installed external plugins add them here."
215
+ "The full python path to the class name must be used",
216
+ ),
217
+ ]
218
+
219
+ webchat_opts = [
220
+ cfg.StrOpt(
221
+ "web_ip",
222
+ default="0.0.0.0",
223
+ help="The ip address to listen on",
224
+ ),
225
+ cfg.PortOpt(
226
+ "web_port",
227
+ default=8001,
228
+ help="The port to listen on",
229
+ ),
230
+ cfg.StrOpt(
231
+ "latitude",
232
+ default=None,
233
+ help="Latitude for the GPS Beacon button. If not set, the button will not be enabled.",
234
+ ),
235
+ cfg.StrOpt(
236
+ "longitude",
237
+ default=None,
238
+ help="Longitude for the GPS Beacon button. If not set, the button will not be enabled.",
239
+ ),
240
+ cfg.BoolOpt(
241
+ "disable_url_request_logging",
242
+ default=False,
243
+ help="Disable the logging of url requests in the webchat command.",
244
+ ),
245
+ ]
246
+
247
+ registry_opts = [
248
+ cfg.BoolOpt(
249
+ "enabled",
250
+ default=False,
251
+ help="Enable sending aprs registry information. This will let the "
252
+ "APRS registry know about your service and it's uptime. "
253
+ "No personal information is sent, just the callsign, uptime and description. "
254
+ "The service callsign is the callsign set in [DEFAULT] section.",
255
+ ),
256
+ cfg.StrOpt(
257
+ "description",
258
+ default=None,
259
+ help="Description of the service to send to the APRS registry. "
260
+ "This is what will show up in the APRS registry."
261
+ "If not set, the description will be the same as the callsign.",
262
+ ),
263
+ cfg.StrOpt(
264
+ "registry_url",
265
+ default="https://aprs.hemna.com/api/v1/registry",
266
+ help="The APRS registry domain name to send the information to.",
267
+ ),
268
+ cfg.StrOpt(
269
+ "service_website",
270
+ default=None,
271
+ help="The website for your APRS service to send to the APRS registry.",
272
+ ),
273
+ cfg.IntOpt(
274
+ "frequency_seconds",
275
+ default=3600,
276
+ help="The frequency in seconds to send the APRS registry information.",
277
+ ),
278
+ ]
279
+
280
+
281
+ def register_opts(config):
282
+ config.register_opts(aprsd_opts)
283
+ config.register_opts(enabled_plugins_opts)
284
+ config.register_group(admin_group)
285
+ config.register_opts(admin_opts, group=admin_group)
286
+ config.register_group(watch_list_group)
287
+ config.register_opts(watch_list_opts, group=watch_list_group)
288
+ config.register_group(webchat_group)
289
+ config.register_opts(webchat_opts, group=webchat_group)
290
+ config.register_group(registry_group)
291
+ config.register_opts(registry_opts, group=registry_group)
292
+
293
+
294
+ def list_opts():
295
+ return {
296
+ "DEFAULT": (aprsd_opts + enabled_plugins_opts),
297
+ admin_group.name: admin_opts,
298
+ watch_list_group.name: watch_list_opts,
299
+ webchat_group.name: webchat_opts,
300
+ registry_group.name: registry_opts,
301
+ }
aprsd/conf/log.py ADDED
@@ -0,0 +1,65 @@
1
+ """
2
+ The options for log setup
3
+ """
4
+ import logging
5
+
6
+ from oslo_config import cfg
7
+
8
+
9
+ LOG_LEVELS = {
10
+ "CRITICAL": logging.CRITICAL,
11
+ "ERROR": logging.ERROR,
12
+ "WARNING": logging.WARNING,
13
+ "INFO": logging.INFO,
14
+ "DEBUG": logging.DEBUG,
15
+ }
16
+
17
+ DEFAULT_DATE_FORMAT = "%m/%d/%Y %I:%M:%S %p"
18
+ DEFAULT_LOG_FORMAT = (
19
+ "[%(asctime)s] [%(threadName)-20.20s] [%(levelname)-5.5s]"
20
+ " %(message)s - [%(pathname)s:%(lineno)d]"
21
+ )
22
+
23
+ DEFAULT_LOG_FORMAT = (
24
+ "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
25
+ "<yellow>{thread.name: <18}</yellow> | "
26
+ "<level>{level: <8}</level> | "
27
+ "<level>{message}</level> | "
28
+ "<cyan>{name}</cyan>:<cyan>{function:}</cyan>:<magenta>{line:}</magenta>"
29
+ )
30
+
31
+ logging_group = cfg.OptGroup(
32
+ name="logging",
33
+ title="Logging options",
34
+ )
35
+ logging_opts = [
36
+ cfg.StrOpt(
37
+ "logfile",
38
+ default=None,
39
+ help="File to log to",
40
+ ),
41
+ cfg.StrOpt(
42
+ "logformat",
43
+ default=DEFAULT_LOG_FORMAT,
44
+ help="Log file format, unless rich_logging enabled.",
45
+ ),
46
+ cfg.StrOpt(
47
+ "log_level",
48
+ default="INFO",
49
+ choices=LOG_LEVELS.keys(),
50
+ help="Log level for logging of events.",
51
+ ),
52
+ ]
53
+
54
+
55
+ def register_opts(config):
56
+ config.register_group(logging_group)
57
+ config.register_opts(logging_opts, group=logging_group)
58
+
59
+
60
+ def list_opts():
61
+ return {
62
+ logging_group.name: (
63
+ logging_opts
64
+ ),
65
+ }
aprsd/conf/opts.py ADDED
@@ -0,0 +1,80 @@
1
+ # Copyright 2015 OpenStack Foundation
2
+ # All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+ # not use this file except in compliance with the License. You may obtain
6
+ # a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ """
17
+ This is the single point of entry to generate the sample configuration
18
+ file for Nova. It collects all the necessary info from the other modules
19
+ in this package. It is assumed that:
20
+
21
+ * every other module in this package has a 'list_opts' function which
22
+ return a dict where
23
+ * the keys are strings which are the group names
24
+ * the value of each key is a list of config options for that group
25
+ * the nova.conf package doesn't have further packages with config options
26
+ * this module is only used in the context of sample file generation
27
+ """
28
+
29
+ import collections
30
+ import importlib
31
+ import os
32
+ import pkgutil
33
+
34
+
35
+ LIST_OPTS_FUNC_NAME = "list_opts"
36
+
37
+
38
+ def _tupleize(dct):
39
+ """Take the dict of options and convert to the 2-tuple format."""
40
+ return [(key, val) for key, val in dct.items()]
41
+
42
+
43
+ def list_opts():
44
+ opts = collections.defaultdict(list)
45
+ module_names = _list_module_names()
46
+ imported_modules = _import_modules(module_names)
47
+ _append_config_options(imported_modules, opts)
48
+ return _tupleize(opts)
49
+
50
+
51
+ def _list_module_names():
52
+ module_names = []
53
+ package_path = os.path.dirname(os.path.abspath(__file__))
54
+ for _, modname, ispkg in pkgutil.iter_modules(path=[package_path]):
55
+ if modname == "opts" or ispkg:
56
+ continue
57
+ else:
58
+ module_names.append(modname)
59
+ return module_names
60
+
61
+
62
+ def _import_modules(module_names):
63
+ imported_modules = []
64
+ for modname in module_names:
65
+ mod = importlib.import_module("aprsd.conf." + modname)
66
+ if not hasattr(mod, LIST_OPTS_FUNC_NAME):
67
+ msg = "The module 'aprsd.conf.%s' should have a '%s' "\
68
+ "function which returns the config options." % \
69
+ (modname, LIST_OPTS_FUNC_NAME)
70
+ raise Exception(msg)
71
+ else:
72
+ imported_modules.append(mod)
73
+ return imported_modules
74
+
75
+
76
+ def _append_config_options(imported_modules, config_options):
77
+ for mod in imported_modules:
78
+ configs = mod.list_opts()
79
+ for key, val in configs.items():
80
+ config_options[key].extend(val)