aprsd 4.0.2__py3-none-any.whl → 4.1.1__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/cli_helper.py +36 -35
- aprsd/client/base.py +14 -11
- aprsd/client/drivers/aprsis.py +87 -35
- aprsd/client/drivers/kiss.py +28 -5
- aprsd/client/kiss.py +1 -0
- aprsd/cmds/listen.py +84 -91
- aprsd/cmds/send_message.py +30 -28
- aprsd/cmds/server.py +29 -64
- aprsd/conf/common.py +100 -101
- aprsd/conf/log.py +32 -22
- aprsd/log/log.py +31 -18
- aprsd/main.py +22 -22
- aprsd/packets/__init__.py +6 -0
- aprsd/packets/core.py +5 -2
- aprsd/packets/filter.py +58 -0
- aprsd/packets/filters/__init__.py +0 -0
- aprsd/packets/filters/dupe_filter.py +68 -0
- aprsd/packets/filters/packet_type.py +53 -0
- aprsd/packets/packet_list.py +33 -27
- aprsd/plugin.py +52 -52
- aprsd/plugin_utils.py +20 -21
- aprsd/plugins/weather.py +110 -109
- aprsd/threads/__init__.py +1 -2
- aprsd/threads/rx.py +83 -75
- aprsd/threads/service.py +42 -0
- aprsd/threads/stats.py +4 -9
- aprsd/utils/objectstore.py +12 -13
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/METADATA +22 -20
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/RECORD +34 -29
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/WHEEL +1 -1
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/AUTHORS +0 -0
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/LICENSE +0 -0
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/entry_points.txt +0 -0
- {aprsd-4.0.2.dist-info → aprsd-4.1.1.dist-info}/top_level.txt +0 -0
aprsd/conf/common.py
CHANGED
@@ -3,220 +3,219 @@ from pathlib import Path
|
|
3
3
|
from oslo_config import cfg
|
4
4
|
|
5
5
|
home = str(Path.home())
|
6
|
-
DEFAULT_CONFIG_DIR = f
|
7
|
-
APRSD_DEFAULT_MAGIC_WORD =
|
6
|
+
DEFAULT_CONFIG_DIR = f'{home}/.config/aprsd/'
|
7
|
+
APRSD_DEFAULT_MAGIC_WORD = 'CHANGEME!!!'
|
8
8
|
|
9
9
|
watch_list_group = cfg.OptGroup(
|
10
|
-
name=
|
11
|
-
title=
|
10
|
+
name='watch_list',
|
11
|
+
title='Watch List settings',
|
12
12
|
)
|
13
13
|
|
14
14
|
registry_group = cfg.OptGroup(
|
15
|
-
name=
|
16
|
-
title=
|
15
|
+
name='aprs_registry',
|
16
|
+
title='APRS Registry settings',
|
17
17
|
)
|
18
18
|
|
19
19
|
aprsd_opts = [
|
20
20
|
cfg.StrOpt(
|
21
|
-
|
21
|
+
'callsign',
|
22
22
|
required=True,
|
23
|
-
help=
|
23
|
+
help='Callsign to use for messages sent by APRSD',
|
24
24
|
),
|
25
25
|
cfg.BoolOpt(
|
26
|
-
|
26
|
+
'enable_save',
|
27
27
|
default=True,
|
28
|
-
help=
|
28
|
+
help='Enable saving of watch list, packet tracker between restarts.',
|
29
29
|
),
|
30
30
|
cfg.StrOpt(
|
31
|
-
|
31
|
+
'save_location',
|
32
32
|
default=DEFAULT_CONFIG_DIR,
|
33
|
-
help=
|
33
|
+
help='Save location for packet tracking files.',
|
34
34
|
),
|
35
35
|
cfg.BoolOpt(
|
36
|
-
|
36
|
+
'trace_enabled',
|
37
37
|
default=False,
|
38
|
-
help=
|
38
|
+
help='Enable code tracing',
|
39
39
|
),
|
40
40
|
cfg.StrOpt(
|
41
|
-
|
42
|
-
default=
|
43
|
-
help=
|
41
|
+
'units',
|
42
|
+
default='imperial',
|
43
|
+
help='Units for display, imperial or metric',
|
44
44
|
),
|
45
45
|
cfg.IntOpt(
|
46
|
-
|
46
|
+
'ack_rate_limit_period',
|
47
47
|
default=1,
|
48
|
-
help=
|
49
|
-
|
50
|
-
|
48
|
+
help='The wait period in seconds per Ack packet being sent.'
|
49
|
+
'1 means 1 ack packet per second allowed.'
|
50
|
+
'2 means 1 pack packet every 2 seconds allowed',
|
51
51
|
),
|
52
52
|
cfg.IntOpt(
|
53
|
-
|
53
|
+
'msg_rate_limit_period',
|
54
54
|
default=2,
|
55
|
-
help=
|
56
|
-
|
57
|
-
|
55
|
+
help='Wait period in seconds per non AckPacket being sent.'
|
56
|
+
'2 means 1 packet every 2 seconds allowed.'
|
57
|
+
'5 means 1 pack packet every 5 seconds allowed',
|
58
58
|
),
|
59
59
|
cfg.IntOpt(
|
60
|
-
|
60
|
+
'packet_dupe_timeout',
|
61
61
|
default=300,
|
62
|
-
help=
|
62
|
+
help='The number of seconds before a packet is not considered a duplicate.',
|
63
63
|
),
|
64
64
|
cfg.BoolOpt(
|
65
|
-
|
65
|
+
'enable_beacon',
|
66
66
|
default=False,
|
67
|
-
help=
|
68
|
-
|
67
|
+
help='Enable sending of a GPS Beacon packet to locate this service. '
|
68
|
+
'Requires latitude and longitude to be set.',
|
69
69
|
),
|
70
70
|
cfg.IntOpt(
|
71
|
-
|
71
|
+
'beacon_interval',
|
72
72
|
default=1800,
|
73
|
-
help=
|
73
|
+
help='The number of seconds between beacon packets.',
|
74
74
|
),
|
75
75
|
cfg.StrOpt(
|
76
|
-
|
77
|
-
default=
|
78
|
-
help=
|
76
|
+
'beacon_symbol',
|
77
|
+
default='/',
|
78
|
+
help='The symbol to use for the GPS Beacon packet. See: http://www.aprs.net/vm/DOS/SYMBOLS.HTM',
|
79
79
|
),
|
80
80
|
cfg.StrOpt(
|
81
|
-
|
81
|
+
'latitude',
|
82
82
|
default=None,
|
83
|
-
help=
|
83
|
+
help='Latitude for the GPS Beacon button. If not set, the button will not be enabled.',
|
84
84
|
),
|
85
85
|
cfg.StrOpt(
|
86
|
-
|
86
|
+
'longitude',
|
87
87
|
default=None,
|
88
|
-
help=
|
88
|
+
help='Longitude for the GPS Beacon button. If not set, the button will not be enabled.',
|
89
89
|
),
|
90
90
|
cfg.StrOpt(
|
91
|
-
|
92
|
-
choices=[
|
93
|
-
default=
|
91
|
+
'log_packet_format',
|
92
|
+
choices=['compact', 'multiline', 'both'],
|
93
|
+
default='compact',
|
94
94
|
help="When logging packets 'compact' will use a single line formatted for each packet."
|
95
95
|
"'multiline' will use multiple lines for each packet and is the traditional format."
|
96
|
-
|
96
|
+
'both will log both compact and multiline.',
|
97
97
|
),
|
98
98
|
cfg.IntOpt(
|
99
|
-
|
99
|
+
'default_packet_send_count',
|
100
100
|
default=3,
|
101
|
-
help=
|
101
|
+
help='The number of times to send a non ack packet before giving up.',
|
102
102
|
),
|
103
103
|
cfg.IntOpt(
|
104
|
-
|
104
|
+
'default_ack_send_count',
|
105
105
|
default=3,
|
106
|
-
help=
|
106
|
+
help='The number of times to send an ack packet in response to recieving a packet.',
|
107
107
|
),
|
108
108
|
cfg.IntOpt(
|
109
|
-
|
109
|
+
'packet_list_maxlen',
|
110
110
|
default=100,
|
111
|
-
help=
|
111
|
+
help='The maximum number of packets to store in the packet list.',
|
112
112
|
),
|
113
113
|
cfg.IntOpt(
|
114
|
-
|
114
|
+
'packet_list_stats_maxlen',
|
115
115
|
default=20,
|
116
|
-
help=
|
116
|
+
help='The maximum number of packets to send in the stats dict for admin ui. -1 means no max.',
|
117
117
|
),
|
118
118
|
cfg.BoolOpt(
|
119
|
-
|
119
|
+
'enable_seen_list',
|
120
120
|
default=True,
|
121
|
-
help=
|
122
|
-
|
121
|
+
help='Enable the Callsign seen list tracking feature. This allows aprsd to keep track of '
|
122
|
+
'callsigns that have been seen and when they were last seen.',
|
123
123
|
),
|
124
124
|
cfg.BoolOpt(
|
125
|
-
|
125
|
+
'enable_packet_logging',
|
126
126
|
default=True,
|
127
|
-
help=
|
127
|
+
help='Set this to False, to disable logging of packets to the log file.',
|
128
128
|
),
|
129
129
|
cfg.BoolOpt(
|
130
|
-
|
130
|
+
'load_help_plugin',
|
131
131
|
default=True,
|
132
|
-
help=
|
132
|
+
help='Set this to False to disable the help plugin.',
|
133
133
|
),
|
134
134
|
cfg.BoolOpt(
|
135
|
-
|
135
|
+
'enable_sending_ack_packets',
|
136
136
|
default=True,
|
137
|
-
help=
|
138
|
-
|
137
|
+
help='Set this to False, to disable sending of ack packets. This will entirely stop'
|
138
|
+
'APRSD from sending ack packets.',
|
139
139
|
),
|
140
140
|
]
|
141
141
|
|
142
142
|
watch_list_opts = [
|
143
143
|
cfg.BoolOpt(
|
144
|
-
|
144
|
+
'enabled',
|
145
145
|
default=False,
|
146
|
-
help=
|
147
|
-
|
148
|
-
|
146
|
+
help='Enable the watch list feature. Still have to enable '
|
147
|
+
'the correct plugin. Built-in plugin to use is '
|
148
|
+
'aprsd.plugins.notify.NotifyPlugin',
|
149
149
|
),
|
150
150
|
cfg.ListOpt(
|
151
|
-
|
152
|
-
help=
|
151
|
+
'callsigns',
|
152
|
+
help='Callsigns to watch for messsages',
|
153
153
|
),
|
154
154
|
cfg.StrOpt(
|
155
|
-
|
156
|
-
help=
|
155
|
+
'alert_callsign',
|
156
|
+
help='The Ham Callsign to send messages to for watch list alerts.',
|
157
157
|
),
|
158
158
|
cfg.IntOpt(
|
159
|
-
|
159
|
+
'packet_keep_count',
|
160
160
|
default=10,
|
161
|
-
help=
|
161
|
+
help='The number of packets to store.',
|
162
162
|
),
|
163
163
|
cfg.IntOpt(
|
164
|
-
|
164
|
+
'alert_time_seconds',
|
165
165
|
default=3600,
|
166
|
-
help=
|
167
|
-
"users in callsigns.",
|
166
|
+
help='Time to wait before alert is sent on new message for users in callsigns.',
|
168
167
|
),
|
169
168
|
]
|
170
169
|
|
171
170
|
|
172
171
|
enabled_plugins_opts = [
|
173
172
|
cfg.ListOpt(
|
174
|
-
|
173
|
+
'enabled_plugins',
|
175
174
|
default=[
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
175
|
+
'aprsd.plugins.fortune.FortunePlugin',
|
176
|
+
'aprsd.plugins.location.LocationPlugin',
|
177
|
+
'aprsd.plugins.ping.PingPlugin',
|
178
|
+
'aprsd.plugins.time.TimePlugin',
|
179
|
+
'aprsd.plugins.weather.OWMWeatherPlugin',
|
180
|
+
'aprsd.plugins.version.VersionPlugin',
|
181
|
+
'aprsd.plugins.notify.NotifySeenPlugin',
|
183
182
|
],
|
184
|
-
help=
|
185
|
-
|
186
|
-
|
183
|
+
help='Comma separated list of enabled plugins for APRSD.'
|
184
|
+
'To enable installed external plugins add them here.'
|
185
|
+
'The full python path to the class name must be used',
|
187
186
|
),
|
188
187
|
]
|
189
188
|
|
190
189
|
registry_opts = [
|
191
190
|
cfg.BoolOpt(
|
192
|
-
|
191
|
+
'enabled',
|
193
192
|
default=False,
|
194
|
-
help=
|
193
|
+
help='Enable sending aprs registry information. This will let the '
|
195
194
|
"APRS registry know about your service and it's uptime. "
|
196
|
-
|
197
|
-
|
195
|
+
'No personal information is sent, just the callsign, uptime and description. '
|
196
|
+
'The service callsign is the callsign set in [DEFAULT] section.',
|
198
197
|
),
|
199
198
|
cfg.StrOpt(
|
200
|
-
|
199
|
+
'description',
|
201
200
|
default=None,
|
202
|
-
help=
|
203
|
-
|
204
|
-
|
201
|
+
help='Description of the service to send to the APRS registry. '
|
202
|
+
'This is what will show up in the APRS registry.'
|
203
|
+
'If not set, the description will be the same as the callsign.',
|
205
204
|
),
|
206
205
|
cfg.StrOpt(
|
207
|
-
|
208
|
-
default=
|
209
|
-
help=
|
206
|
+
'registry_url',
|
207
|
+
default='https://aprs.hemna.com/api/v1/registry',
|
208
|
+
help='The APRS registry domain name to send the information to.',
|
210
209
|
),
|
211
210
|
cfg.StrOpt(
|
212
|
-
|
211
|
+
'service_website',
|
213
212
|
default=None,
|
214
|
-
help=
|
213
|
+
help='The website for your APRS service to send to the APRS registry.',
|
215
214
|
),
|
216
215
|
cfg.IntOpt(
|
217
|
-
|
216
|
+
'frequency_seconds',
|
218
217
|
default=3600,
|
219
|
-
help=
|
218
|
+
help='The frequency in seconds to send the APRS registry information.',
|
220
219
|
),
|
221
220
|
]
|
222
221
|
|
@@ -232,7 +231,7 @@ def register_opts(config):
|
|
232
231
|
|
233
232
|
def list_opts():
|
234
233
|
return {
|
235
|
-
|
234
|
+
'DEFAULT': (aprsd_opts + enabled_plugins_opts),
|
236
235
|
watch_list_group.name: watch_list_opts,
|
237
236
|
registry_group.name: registry_opts,
|
238
237
|
}
|
aprsd/conf/log.py
CHANGED
@@ -7,47 +7,57 @@ import logging
|
|
7
7
|
from oslo_config import cfg
|
8
8
|
|
9
9
|
LOG_LEVELS = {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
'CRITICAL': logging.CRITICAL,
|
11
|
+
'ERROR': logging.ERROR,
|
12
|
+
'WARNING': logging.WARNING,
|
13
|
+
'INFO': logging.INFO,
|
14
|
+
'DEBUG': logging.DEBUG,
|
15
15
|
}
|
16
16
|
|
17
|
-
DEFAULT_DATE_FORMAT =
|
17
|
+
DEFAULT_DATE_FORMAT = '%m/%d/%Y %I:%M:%S %p'
|
18
18
|
DEFAULT_LOG_FORMAT = (
|
19
|
-
|
20
|
-
|
19
|
+
'[%(asctime)s] [%(threadName)-20.20s] [%(levelname)-5.5s]'
|
20
|
+
' %(message)s - [%(pathname)s:%(lineno)d]'
|
21
21
|
)
|
22
22
|
|
23
23
|
DEFAULT_LOG_FORMAT = (
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
29
|
)
|
30
30
|
|
31
31
|
logging_group = cfg.OptGroup(
|
32
|
-
name=
|
33
|
-
title=
|
32
|
+
name='logging',
|
33
|
+
title='Logging options',
|
34
34
|
)
|
35
35
|
logging_opts = [
|
36
36
|
cfg.StrOpt(
|
37
|
-
|
37
|
+
'logfile',
|
38
38
|
default=None,
|
39
|
-
help=
|
39
|
+
help='File to log to',
|
40
40
|
),
|
41
41
|
cfg.StrOpt(
|
42
|
-
|
42
|
+
'logformat',
|
43
43
|
default=DEFAULT_LOG_FORMAT,
|
44
|
-
help=
|
44
|
+
help='Log file format, unless rich_logging enabled.',
|
45
45
|
),
|
46
46
|
cfg.StrOpt(
|
47
|
-
|
48
|
-
default=
|
47
|
+
'log_level',
|
48
|
+
default='INFO',
|
49
49
|
choices=LOG_LEVELS.keys(),
|
50
|
-
help=
|
50
|
+
help='Log level for logging of events.',
|
51
|
+
),
|
52
|
+
cfg.BoolOpt(
|
53
|
+
'enable_color',
|
54
|
+
default=True,
|
55
|
+
help='Enable ANSI color codes in logging',
|
56
|
+
),
|
57
|
+
cfg.BoolOpt(
|
58
|
+
'enable_console_stdout',
|
59
|
+
default=True,
|
60
|
+
help='Enable logging to the console/stdout.',
|
51
61
|
),
|
52
62
|
]
|
53
63
|
|
aprsd/log/log.py
CHANGED
@@ -63,37 +63,50 @@ def setup_logging(loglevel=None, quiet=False):
|
|
63
63
|
|
64
64
|
# We don't really want to see the aprslib parsing debug output.
|
65
65
|
disable_list = [
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
'aprslib',
|
67
|
+
'aprslib.parsing',
|
68
|
+
'aprslib.exceptions',
|
69
69
|
]
|
70
70
|
|
71
|
+
chardet_list = [
|
72
|
+
'chardet',
|
73
|
+
'chardet.charsetprober',
|
74
|
+
'chardet.eucjpprober',
|
75
|
+
]
|
76
|
+
|
77
|
+
for name in chardet_list:
|
78
|
+
disable = logging.getLogger(name)
|
79
|
+
disable.setLevel(logging.ERROR)
|
80
|
+
|
71
81
|
# remove every other logger's handlers
|
72
82
|
# and propagate to root logger
|
73
83
|
for name in logging.root.manager.loggerDict.keys():
|
74
84
|
logging.getLogger(name).handlers = []
|
75
85
|
logging.getLogger(name).propagate = name not in disable_list
|
76
86
|
|
77
|
-
handlers = [
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
87
|
+
handlers = []
|
88
|
+
if CONF.logging.enable_console_stdout:
|
89
|
+
handlers.append(
|
90
|
+
{
|
91
|
+
'sink': sys.stdout,
|
92
|
+
'serialize': False,
|
93
|
+
'format': CONF.logging.logformat,
|
94
|
+
'colorize': CONF.logging.enable_color,
|
95
|
+
'level': log_level,
|
96
|
+
},
|
97
|
+
)
|
98
|
+
|
86
99
|
if CONF.logging.logfile:
|
87
100
|
handlers.append(
|
88
101
|
{
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
102
|
+
'sink': CONF.logging.logfile,
|
103
|
+
'serialize': False,
|
104
|
+
'format': CONF.logging.logformat,
|
105
|
+
'colorize': False,
|
106
|
+
'level': log_level,
|
94
107
|
},
|
95
108
|
)
|
96
109
|
|
97
110
|
# configure loguru
|
98
111
|
logger.configure(handlers=handlers)
|
99
|
-
logger.level(
|
112
|
+
logger.level('DEBUG', color='<fg #BABABA>')
|
aprsd/main.py
CHANGED
@@ -39,8 +39,8 @@ from aprsd.stats import collector
|
|
39
39
|
# setup the global logger
|
40
40
|
# log.basicConfig(level=log.DEBUG) # level=10
|
41
41
|
CONF = cfg.CONF
|
42
|
-
LOG = logging.getLogger(
|
43
|
-
CONTEXT_SETTINGS = dict(help_option_names=[
|
42
|
+
LOG = logging.getLogger('APRSD')
|
43
|
+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
44
44
|
flask_enabled = False
|
45
45
|
|
46
46
|
|
@@ -68,18 +68,18 @@ def main():
|
|
68
68
|
# First import all the possible commands for the CLI
|
69
69
|
# The commands themselves live in the cmds directory
|
70
70
|
load_commands()
|
71
|
-
utils.load_entry_points(
|
72
|
-
cli(auto_envvar_prefix=
|
71
|
+
utils.load_entry_points('aprsd.extension')
|
72
|
+
cli(auto_envvar_prefix='APRSD')
|
73
73
|
|
74
74
|
|
75
75
|
def signal_handler(sig, frame):
|
76
76
|
global flask_enabled
|
77
77
|
|
78
|
-
click.echo(
|
78
|
+
click.echo('signal_handler: called')
|
79
79
|
threads.APRSDThreadList().stop_all()
|
80
|
-
if
|
80
|
+
if 'subprocess' not in str(frame):
|
81
81
|
LOG.info(
|
82
|
-
|
82
|
+
'Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}'.format(
|
83
83
|
datetime.datetime.now(),
|
84
84
|
),
|
85
85
|
)
|
@@ -91,7 +91,7 @@ def signal_handler(sig, frame):
|
|
91
91
|
packets.PacketList().save()
|
92
92
|
collector.Collector().collect()
|
93
93
|
except Exception as e:
|
94
|
-
LOG.error(f
|
94
|
+
LOG.error(f'Failed to save data: {e}')
|
95
95
|
sys.exit(0)
|
96
96
|
# signal.signal(signal.SIGTERM, sys.exit(0))
|
97
97
|
# sys.exit(0)
|
@@ -108,9 +108,9 @@ def check_version(ctx):
|
|
108
108
|
"""Check this version against the latest in pypi.org."""
|
109
109
|
level, msg = utils._check_version()
|
110
110
|
if level:
|
111
|
-
click.secho(msg, fg=
|
111
|
+
click.secho(msg, fg='yellow')
|
112
112
|
else:
|
113
|
-
click.secho(msg, fg=
|
113
|
+
click.secho(msg, fg='green')
|
114
114
|
|
115
115
|
|
116
116
|
@cli.command()
|
@@ -124,12 +124,12 @@ def sample_config(ctx):
|
|
124
124
|
if sys.version_info < (3, 10):
|
125
125
|
all = imp.entry_points()
|
126
126
|
selected = []
|
127
|
-
if
|
128
|
-
for x in all[
|
129
|
-
if x.group ==
|
127
|
+
if 'oslo.config.opts' in all:
|
128
|
+
for x in all['oslo.config.opts']:
|
129
|
+
if x.group == 'oslo.config.opts':
|
130
130
|
selected.append(x)
|
131
131
|
else:
|
132
|
-
selected = imp.entry_points(group=
|
132
|
+
selected = imp.entry_points(group='oslo.config.opts')
|
133
133
|
|
134
134
|
return selected
|
135
135
|
|
@@ -139,23 +139,23 @@ def sample_config(ctx):
|
|
139
139
|
# selected = imp.entry_points(group="oslo.config.opts")
|
140
140
|
selected = _get_selected_entry_points()
|
141
141
|
for entry in selected:
|
142
|
-
if
|
143
|
-
args.append(
|
142
|
+
if 'aprsd' in entry.name:
|
143
|
+
args.append('--namespace')
|
144
144
|
args.append(entry.name)
|
145
145
|
|
146
146
|
return args
|
147
147
|
|
148
148
|
args = get_namespaces()
|
149
|
-
config_version = metadata_version(
|
149
|
+
config_version = metadata_version('oslo.config')
|
150
150
|
logging.basicConfig(level=logging.WARN)
|
151
151
|
conf = cfg.ConfigOpts()
|
152
152
|
generator.register_cli_opts(conf)
|
153
153
|
try:
|
154
154
|
conf(args, version=config_version)
|
155
|
-
except cfg.RequiredOptError:
|
155
|
+
except cfg.RequiredOptError as ex:
|
156
156
|
conf.print_help()
|
157
157
|
if not sys.argv[1:]:
|
158
|
-
raise SystemExit
|
158
|
+
raise SystemExit from ex
|
159
159
|
raise
|
160
160
|
generator.generate(conf)
|
161
161
|
return
|
@@ -165,9 +165,9 @@ def sample_config(ctx):
|
|
165
165
|
@click.pass_context
|
166
166
|
def version(ctx):
|
167
167
|
"""Show the APRSD version."""
|
168
|
-
click.echo(click.style(
|
169
|
-
click.secho(f
|
168
|
+
click.echo(click.style('APRSD Version : ', fg='white'), nl=False)
|
169
|
+
click.secho(f'{aprsd.__version__}', fg='yellow', bold=True)
|
170
170
|
|
171
171
|
|
172
|
-
if __name__ ==
|
172
|
+
if __name__ == '__main__':
|
173
173
|
main()
|
aprsd/packets/__init__.py
CHANGED
@@ -15,6 +15,8 @@ from aprsd.packets.core import ( # noqa: F401
|
|
15
15
|
WeatherPacket,
|
16
16
|
factory,
|
17
17
|
)
|
18
|
+
from aprsd.packets.filter import PacketFilter
|
19
|
+
from aprsd.packets.filters.dupe_filter import DupePacketFilter
|
18
20
|
from aprsd.packets.packet_list import PacketList # noqa: F401
|
19
21
|
from aprsd.packets.seen_list import SeenList # noqa: F401
|
20
22
|
from aprsd.packets.tracker import PacketTrack # noqa: F401
|
@@ -26,5 +28,9 @@ collector.PacketCollector().register(SeenList)
|
|
26
28
|
collector.PacketCollector().register(PacketTrack)
|
27
29
|
collector.PacketCollector().register(WatchList)
|
28
30
|
|
31
|
+
# Register all the packet filters for normal processing
|
32
|
+
# For specific commands you can deregister these if you don't want them.
|
33
|
+
PacketFilter().register(DupePacketFilter)
|
34
|
+
|
29
35
|
|
30
36
|
NULL_MESSAGE = -1
|
aprsd/packets/core.py
CHANGED
@@ -106,6 +106,8 @@ class Packet:
|
|
106
106
|
last_send_time: float = field(repr=False, default=0, compare=False, hash=False)
|
107
107
|
# Was the packet acked?
|
108
108
|
acked: bool = field(repr=False, default=False, compare=False, hash=False)
|
109
|
+
# Was the packet previously processed (for dupe checking)
|
110
|
+
processed: bool = field(repr=False, default=False, compare=False, hash=False)
|
109
111
|
|
110
112
|
# Do we allow this packet to be saved to send later?
|
111
113
|
allow_delay: bool = field(repr=False, default=True, compare=False, hash=False)
|
@@ -186,12 +188,11 @@ class Packet:
|
|
186
188
|
|
187
189
|
def __repr__(self) -> str:
|
188
190
|
"""Build the repr version of the packet."""
|
189
|
-
|
191
|
+
return (
|
190
192
|
f"{self.__class__.__name__}:"
|
191
193
|
f" From: {self.from_call} "
|
192
194
|
f" To: {self.to_call}"
|
193
195
|
)
|
194
|
-
return repr
|
195
196
|
|
196
197
|
|
197
198
|
@dataclass_json
|
@@ -694,6 +695,8 @@ class UnknownPacket:
|
|
694
695
|
path: List[str] = field(default_factory=list, compare=False, hash=False)
|
695
696
|
packet_type: Optional[str] = field(default=None)
|
696
697
|
via: Optional[str] = field(default=None, compare=False, hash=False)
|
698
|
+
# Was the packet previously processed (for dupe checking)
|
699
|
+
processed: bool = field(repr=False, default=False, compare=False, hash=False)
|
697
700
|
|
698
701
|
@property
|
699
702
|
def key(self) -> str:
|