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/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"{home}/.config/aprsd/"
7
- APRSD_DEFAULT_MAGIC_WORD = "CHANGEME!!!"
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="watch_list",
11
- title="Watch List settings",
10
+ name='watch_list',
11
+ title='Watch List settings',
12
12
  )
13
13
 
14
14
  registry_group = cfg.OptGroup(
15
- name="aprs_registry",
16
- title="APRS Registry settings",
15
+ name='aprs_registry',
16
+ title='APRS Registry settings',
17
17
  )
18
18
 
19
19
  aprsd_opts = [
20
20
  cfg.StrOpt(
21
- "callsign",
21
+ 'callsign',
22
22
  required=True,
23
- help="Callsign to use for messages sent by APRSD",
23
+ help='Callsign to use for messages sent by APRSD',
24
24
  ),
25
25
  cfg.BoolOpt(
26
- "enable_save",
26
+ 'enable_save',
27
27
  default=True,
28
- help="Enable saving of watch list, packet tracker between restarts.",
28
+ help='Enable saving of watch list, packet tracker between restarts.',
29
29
  ),
30
30
  cfg.StrOpt(
31
- "save_location",
31
+ 'save_location',
32
32
  default=DEFAULT_CONFIG_DIR,
33
- help="Save location for packet tracking files.",
33
+ help='Save location for packet tracking files.',
34
34
  ),
35
35
  cfg.BoolOpt(
36
- "trace_enabled",
36
+ 'trace_enabled',
37
37
  default=False,
38
- help="Enable code tracing",
38
+ help='Enable code tracing',
39
39
  ),
40
40
  cfg.StrOpt(
41
- "units",
42
- default="imperial",
43
- help="Units for display, imperial or metric",
41
+ 'units',
42
+ default='imperial',
43
+ help='Units for display, imperial or metric',
44
44
  ),
45
45
  cfg.IntOpt(
46
- "ack_rate_limit_period",
46
+ 'ack_rate_limit_period',
47
47
  default=1,
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",
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
- "msg_rate_limit_period",
53
+ 'msg_rate_limit_period',
54
54
  default=2,
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",
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
- "packet_dupe_timeout",
60
+ 'packet_dupe_timeout',
61
61
  default=300,
62
- help="The number of seconds before a packet is not considered a duplicate.",
62
+ help='The number of seconds before a packet is not considered a duplicate.',
63
63
  ),
64
64
  cfg.BoolOpt(
65
- "enable_beacon",
65
+ 'enable_beacon',
66
66
  default=False,
67
- help="Enable sending of a GPS Beacon packet to locate this service. "
68
- "Requires latitude and longitude to be set.",
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
- "beacon_interval",
71
+ 'beacon_interval',
72
72
  default=1800,
73
- help="The number of seconds between beacon packets.",
73
+ help='The number of seconds between beacon packets.',
74
74
  ),
75
75
  cfg.StrOpt(
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",
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
- "latitude",
81
+ 'latitude',
82
82
  default=None,
83
- help="Latitude for the GPS Beacon button. If not set, the button will not be enabled.",
83
+ help='Latitude for the GPS Beacon button. If not set, the button will not be enabled.',
84
84
  ),
85
85
  cfg.StrOpt(
86
- "longitude",
86
+ 'longitude',
87
87
  default=None,
88
- help="Longitude for the GPS Beacon button. If not set, the button will not be enabled.",
88
+ help='Longitude for the GPS Beacon button. If not set, the button will not be enabled.',
89
89
  ),
90
90
  cfg.StrOpt(
91
- "log_packet_format",
92
- choices=["compact", "multiline", "both"],
93
- default="compact",
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
- "both will log both compact and multiline.",
96
+ 'both will log both compact and multiline.',
97
97
  ),
98
98
  cfg.IntOpt(
99
- "default_packet_send_count",
99
+ 'default_packet_send_count',
100
100
  default=3,
101
- help="The number of times to send a non ack packet before giving up.",
101
+ help='The number of times to send a non ack packet before giving up.',
102
102
  ),
103
103
  cfg.IntOpt(
104
- "default_ack_send_count",
104
+ 'default_ack_send_count',
105
105
  default=3,
106
- help="The number of times to send an ack packet in response to recieving a packet.",
106
+ help='The number of times to send an ack packet in response to recieving a packet.',
107
107
  ),
108
108
  cfg.IntOpt(
109
- "packet_list_maxlen",
109
+ 'packet_list_maxlen',
110
110
  default=100,
111
- help="The maximum number of packets to store in the packet list.",
111
+ help='The maximum number of packets to store in the packet list.',
112
112
  ),
113
113
  cfg.IntOpt(
114
- "packet_list_stats_maxlen",
114
+ 'packet_list_stats_maxlen',
115
115
  default=20,
116
- help="The maximum number of packets to send in the stats dict for admin ui.",
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
- "enable_seen_list",
119
+ 'enable_seen_list',
120
120
  default=True,
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.",
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
- "enable_packet_logging",
125
+ 'enable_packet_logging',
126
126
  default=True,
127
- help="Set this to False, to disable logging of packets to the log file.",
127
+ help='Set this to False, to disable logging of packets to the log file.',
128
128
  ),
129
129
  cfg.BoolOpt(
130
- "load_help_plugin",
130
+ 'load_help_plugin',
131
131
  default=True,
132
- help="Set this to False to disable the help plugin.",
132
+ help='Set this to False to disable the help plugin.',
133
133
  ),
134
134
  cfg.BoolOpt(
135
- "enable_sending_ack_packets",
135
+ 'enable_sending_ack_packets',
136
136
  default=True,
137
- help="Set this to False, to disable sending of ack packets. This will entirely stop"
138
- "APRSD from sending ack packets.",
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
- "enabled",
144
+ 'enabled',
145
145
  default=False,
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",
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
- "callsigns",
152
- help="Callsigns to watch for messsages",
151
+ 'callsigns',
152
+ help='Callsigns to watch for messsages',
153
153
  ),
154
154
  cfg.StrOpt(
155
- "alert_callsign",
156
- help="The Ham Callsign to send messages to for watch list alerts.",
155
+ 'alert_callsign',
156
+ help='The Ham Callsign to send messages to for watch list alerts.',
157
157
  ),
158
158
  cfg.IntOpt(
159
- "packet_keep_count",
159
+ 'packet_keep_count',
160
160
  default=10,
161
- help="The number of packets to store.",
161
+ help='The number of packets to store.',
162
162
  ),
163
163
  cfg.IntOpt(
164
- "alert_time_seconds",
164
+ 'alert_time_seconds',
165
165
  default=3600,
166
- help="Time to wait before alert is sent on new message for "
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
- "enabled_plugins",
173
+ 'enabled_plugins',
175
174
  default=[
176
- "aprsd.plugins.fortune.FortunePlugin",
177
- "aprsd.plugins.location.LocationPlugin",
178
- "aprsd.plugins.ping.PingPlugin",
179
- "aprsd.plugins.time.TimePlugin",
180
- "aprsd.plugins.weather.OWMWeatherPlugin",
181
- "aprsd.plugins.version.VersionPlugin",
182
- "aprsd.plugins.notify.NotifySeenPlugin",
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="Comma separated list of enabled plugins for APRSD."
185
- "To enable installed external plugins add them here."
186
- "The full python path to the class name must be used",
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
- "enabled",
191
+ 'enabled',
193
192
  default=False,
194
- help="Enable sending aprs registry information. This will let the "
193
+ help='Enable sending aprs registry information. This will let the '
195
194
  "APRS registry know about your service and it's uptime. "
196
- "No personal information is sent, just the callsign, uptime and description. "
197
- "The service callsign is the callsign set in [DEFAULT] section.",
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
- "description",
199
+ 'description',
201
200
  default=None,
202
- help="Description of the service to send to the APRS registry. "
203
- "This is what will show up in the APRS registry."
204
- "If not set, the description will be the same as the callsign.",
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
- "registry_url",
208
- default="https://aprs.hemna.com/api/v1/registry",
209
- help="The APRS registry domain name to send the information to.",
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
- "service_website",
211
+ 'service_website',
213
212
  default=None,
214
- help="The website for your APRS service to send to the APRS registry.",
213
+ help='The website for your APRS service to send to the APRS registry.',
215
214
  ),
216
215
  cfg.IntOpt(
217
- "frequency_seconds",
216
+ 'frequency_seconds',
218
217
  default=3600,
219
- help="The frequency in seconds to send the APRS registry information.",
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
- "DEFAULT": (aprsd_opts + enabled_plugins_opts),
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
- "CRITICAL": logging.CRITICAL,
11
- "ERROR": logging.ERROR,
12
- "WARNING": logging.WARNING,
13
- "INFO": logging.INFO,
14
- "DEBUG": logging.DEBUG,
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 = "%m/%d/%Y %I:%M:%S %p"
17
+ DEFAULT_DATE_FORMAT = '%m/%d/%Y %I:%M:%S %p'
18
18
  DEFAULT_LOG_FORMAT = (
19
- "[%(asctime)s] [%(threadName)-20.20s] [%(levelname)-5.5s]"
20
- " %(message)s - [%(pathname)s:%(lineno)d]"
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
- "<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>"
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="logging",
33
- title="Logging options",
32
+ name='logging',
33
+ title='Logging options',
34
34
  )
35
35
  logging_opts = [
36
36
  cfg.StrOpt(
37
- "logfile",
37
+ 'logfile',
38
38
  default=None,
39
- help="File to log to",
39
+ help='File to log to',
40
40
  ),
41
41
  cfg.StrOpt(
42
- "logformat",
42
+ 'logformat',
43
43
  default=DEFAULT_LOG_FORMAT,
44
- help="Log file format, unless rich_logging enabled.",
44
+ help='Log file format, unless rich_logging enabled.',
45
45
  ),
46
46
  cfg.StrOpt(
47
- "log_level",
48
- default="INFO",
47
+ 'log_level',
48
+ default='INFO',
49
49
  choices=LOG_LEVELS.keys(),
50
- help="Log level for logging of events.",
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
- "aprslib",
67
- "aprslib.parsing",
68
- "aprslib.exceptions",
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
- "sink": sys.stdout,
80
- "serialize": False,
81
- "format": CONF.logging.logformat,
82
- "colorize": True,
83
- "level": log_level,
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
- "sink": CONF.logging.logfile,
90
- "serialize": False,
91
- "format": CONF.logging.logformat,
92
- "colorize": False,
93
- "level": log_level,
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("DEBUG", color="<fg #BABABA>")
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("APRSD")
43
- CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
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("aprsd.extension")
72
- cli(auto_envvar_prefix="APRSD")
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("signal_handler: called")
78
+ click.echo('signal_handler: called')
79
79
  threads.APRSDThreadList().stop_all()
80
- if "subprocess" not in str(frame):
80
+ if 'subprocess' not in str(frame):
81
81
  LOG.info(
82
- "Ctrl+C, Sending all threads exit! Can take up to 10 seconds {}".format(
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"Failed to save data: {e}")
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="yellow")
111
+ click.secho(msg, fg='yellow')
112
112
  else:
113
- click.secho(msg, fg="green")
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 "oslo.config.opts" in all:
128
- for x in all["oslo.config.opts"]:
129
- if x.group == "oslo.config.opts":
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="oslo.config.opts")
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 "aprsd" in entry.name:
143
- args.append("--namespace")
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("oslo.config")
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("APRSD Version : ", fg="white"), nl=False)
169
- click.secho(f"{aprsd.__version__}", fg="yellow", bold=True)
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__ == "__main__":
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
- repr = (
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: