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.
- aprsd/__init__.py +6 -4
- aprsd/cli_helper.py +151 -0
- aprsd/client/__init__.py +13 -0
- aprsd/client/aprsis.py +132 -0
- aprsd/client/base.py +105 -0
- aprsd/client/drivers/__init__.py +0 -0
- aprsd/client/drivers/aprsis.py +228 -0
- aprsd/client/drivers/fake.py +73 -0
- aprsd/client/drivers/kiss.py +119 -0
- aprsd/client/factory.py +88 -0
- aprsd/client/fake.py +48 -0
- aprsd/client/kiss.py +103 -0
- aprsd/client/stats.py +38 -0
- aprsd/cmds/__init__.py +0 -0
- aprsd/cmds/completion.py +22 -0
- aprsd/cmds/dev.py +162 -0
- aprsd/cmds/fetch_stats.py +156 -0
- aprsd/cmds/healthcheck.py +86 -0
- aprsd/cmds/list_plugins.py +319 -0
- aprsd/cmds/listen.py +231 -0
- aprsd/cmds/send_message.py +171 -0
- aprsd/cmds/server.py +137 -0
- aprsd/cmds/webchat.py +674 -0
- aprsd/conf/__init__.py +56 -0
- aprsd/conf/client.py +131 -0
- aprsd/conf/common.py +301 -0
- aprsd/conf/log.py +65 -0
- aprsd/conf/opts.py +80 -0
- aprsd/conf/plugin_common.py +182 -0
- aprsd/conf/plugin_email.py +105 -0
- aprsd/exception.py +13 -0
- aprsd/log/__init__.py +0 -0
- aprsd/log/log.py +138 -0
- aprsd/main.py +104 -867
- aprsd/packets/__init__.py +20 -0
- aprsd/packets/collector.py +79 -0
- aprsd/packets/core.py +823 -0
- aprsd/packets/log.py +161 -0
- aprsd/packets/packet_list.py +110 -0
- aprsd/packets/seen_list.py +49 -0
- aprsd/packets/tracker.py +103 -0
- aprsd/packets/watch_list.py +119 -0
- aprsd/plugin.py +474 -284
- aprsd/plugin_utils.py +86 -0
- aprsd/plugins/__init__.py +0 -0
- aprsd/plugins/email.py +709 -0
- aprsd/plugins/fortune.py +61 -0
- aprsd/plugins/location.py +179 -0
- aprsd/plugins/notify.py +61 -0
- aprsd/plugins/ping.py +31 -0
- aprsd/plugins/time.py +115 -0
- aprsd/plugins/version.py +31 -0
- aprsd/plugins/weather.py +405 -0
- aprsd/stats/__init__.py +20 -0
- aprsd/stats/app.py +49 -0
- aprsd/stats/collector.py +37 -0
- aprsd/threads/__init__.py +11 -0
- aprsd/threads/aprsd.py +119 -0
- aprsd/threads/keep_alive.py +131 -0
- aprsd/threads/log_monitor.py +121 -0
- aprsd/threads/registry.py +56 -0
- aprsd/threads/rx.py +354 -0
- aprsd/threads/stats.py +44 -0
- aprsd/threads/tx.py +255 -0
- aprsd/utils/__init__.py +218 -0
- aprsd/utils/counter.py +51 -0
- aprsd/utils/json.py +80 -0
- aprsd/utils/objectstore.py +123 -0
- aprsd/utils/ring_buffer.py +40 -0
- aprsd/utils/trace.py +180 -0
- aprsd/web/__init__.py +0 -0
- aprsd/web/admin/__init__.py +0 -0
- aprsd/web/admin/static/css/index.css +84 -0
- aprsd/web/admin/static/css/prism.css +4 -0
- aprsd/web/admin/static/css/tabs.css +35 -0
- aprsd/web/admin/static/images/Untitled.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-16-0.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-16-1.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-64-0.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-64-1.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-64-2.png +0 -0
- aprsd/web/admin/static/js/charts.js +235 -0
- aprsd/web/admin/static/js/echarts.js +465 -0
- aprsd/web/admin/static/js/logs.js +26 -0
- aprsd/web/admin/static/js/main.js +231 -0
- aprsd/web/admin/static/js/prism.js +12 -0
- aprsd/web/admin/static/js/send-message.js +114 -0
- aprsd/web/admin/static/js/tabs.js +28 -0
- aprsd/web/admin/templates/index.html +196 -0
- aprsd/web/chat/static/css/chat.css +115 -0
- aprsd/web/chat/static/css/index.css +66 -0
- aprsd/web/chat/static/css/style.css.map +1 -0
- aprsd/web/chat/static/css/tabs.css +41 -0
- aprsd/web/chat/static/css/upstream/bootstrap.min.css +6 -0
- aprsd/web/chat/static/css/upstream/font.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/google-fonts.css +23 -0
- aprsd/web/chat/static/css/upstream/jquery-ui.css +1311 -0
- aprsd/web/chat/static/css/upstream/jquery.toast.css +28 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff2 +0 -0
- aprsd/web/chat/static/images/Untitled.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-16-0.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-16-1.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-64-0.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-64-1.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-64-2.png +0 -0
- aprsd/web/chat/static/images/globe.svg +3 -0
- aprsd/web/chat/static/js/gps.js +84 -0
- aprsd/web/chat/static/js/main.js +45 -0
- aprsd/web/chat/static/js/send-message.js +585 -0
- aprsd/web/chat/static/js/tabs.js +28 -0
- aprsd/web/chat/static/js/upstream/bootstrap.bundle.min.js +7 -0
- aprsd/web/chat/static/js/upstream/jquery-3.7.1.min.js +2 -0
- aprsd/web/chat/static/js/upstream/jquery-ui.min.js +13 -0
- aprsd/web/chat/static/js/upstream/jquery.toast.js +374 -0
- aprsd/web/chat/static/js/upstream/semantic.min.js +11 -0
- aprsd/web/chat/static/js/upstream/socket.io.min.js +7 -0
- aprsd/web/chat/templates/index.html +139 -0
- aprsd/wsgi.py +315 -0
- aprsd-3.4.2.dist-info/AUTHORS +13 -0
- aprsd-3.4.2.dist-info/LICENSE +175 -0
- aprsd-3.4.2.dist-info/METADATA +793 -0
- aprsd-3.4.2.dist-info/RECORD +133 -0
- {aprsd-1.0.0.dist-info → aprsd-3.4.2.dist-info}/WHEEL +1 -1
- aprsd-3.4.2.dist-info/entry_points.txt +8 -0
- aprsd/fake_aprs.py +0 -83
- aprsd/utils.py +0 -166
- aprsd-1.0.0.dist-info/AUTHORS +0 -6
- aprsd-1.0.0.dist-info/METADATA +0 -181
- aprsd-1.0.0.dist-info/RECORD +0 -13
- aprsd-1.0.0.dist-info/entry_points.txt +0 -4
- aprsd-1.0.0.dist-info/pbr.json +0 -1
- /aprsd/{fuzzyclock.py → utils/fuzzyclock.py} +0 -0
- {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)
|