1
0
mirror of https://github.com/craigerl/aprsd.git synced 2025-07-31 12:52:24 -04:00

Make Packet objects hashable

This patch makes the packet key a property of the Packet object and
makes packet objects comparable and hashable.
This commit is contained in:
Hemna 2023-10-03 16:01:43 -04:00
parent 59cec1317d
commit 544600a96b
4 changed files with 38 additions and 46 deletions

View File

@ -1,6 +1,6 @@
from aprsd.packets.core import ( # noqa: F401 from aprsd.packets.core import ( # noqa: F401
AckPacket, GPSPacket, MessagePacket, MicEPacket, Packet, PathPacket, AckPacket, GPSPacket, MessagePacket, MicEPacket, Packet, RejectPacket,
RejectPacket, StatusPacket, WeatherPacket, StatusPacket, WeatherPacket,
) )
from aprsd.packets.packet_list import PacketList # noqa: F401 from aprsd.packets.packet_list import PacketList # noqa: F401
from aprsd.packets.seen_list import SeenList # noqa: F401 from aprsd.packets.seen_list import SeenList # noqa: F401

View File

@ -47,26 +47,28 @@ def _init_msgNo(): # noqa: N802
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class Packet(metaclass=abc.ABCMeta): class Packet(metaclass=abc.ABCMeta):
from_call: str from_call: str = field(default=None)
to_call: str to_call: str = field(default=None)
addresse: str = None addresse: str = field(default=None)
format: str = None format: str = field(default=None)
msgNo: str = field(default_factory=_init_msgNo) # noqa: N815 msgNo: str = field(default_factory=_init_msgNo) # noqa: N815
packet_type: str = None packet_type: str = field(default=None)
timestamp: float = field(default_factory=_init_timestamp) timestamp: float = field(default_factory=_init_timestamp, compare=False, hash=False)
# Holds the raw text string to be sent over the wire # Holds the raw text string to be sent over the wire
# or holds the raw string from input packet # or holds the raw string from input packet
raw: str = None raw: str = field(default=None, compare=False, hash=False)
raw_dict: dict = field(repr=False, default_factory=lambda: {}, compare=False) raw_dict: dict = field(repr=False, default_factory=lambda: {}, compare=False, hash=False)
# Built by calling prepare(). raw needs this built first. # Built by calling prepare(). raw needs this built first.
payload: str = None payload: str = field(default=None)
# Fields related to sending packets out # Fields related to sending packets out
send_count: int = field(repr=False, default=0) send_count: int = field(repr=False, default=0, compare=False, hash=False)
retry_count: int = field(repr=False, default=3) retry_count: int = field(repr=False, default=3, compare=False, hash=False)
last_send_time: datetime.timedelta = field(repr=False, default=None) last_send_time: datetime.timedelta = field(repr=False, default=None, compare=False, hash=False)
# Do we allow this packet to be saved to send later? # Do we allow this packet to be saved to send later?
allow_delay: bool = field(repr=False, default=True) allow_delay: bool = field(repr=False, default=True, compare=False, hash=False)
path: List[str] = field(default_factory=list, compare=False, hash=False)
via: str = field(default=None, compare=False, hash=False)
def __post__init__(self): def __post__init__(self):
LOG.warning(f"POST INIT {self}") LOG.warning(f"POST INIT {self}")
@ -89,6 +91,7 @@ class Packet(metaclass=abc.ABCMeta):
else: else:
return default return default
@property
def key(self): def key(self):
"""Build a key for finding this packet in a dict.""" """Build a key for finding this packet in a dict."""
return f"{self.from_call}:{self.addresse}:{self.msgNo}" return f"{self.from_call}:{self.addresse}:{self.msgNo}"
@ -263,17 +266,8 @@ class Packet(metaclass=abc.ABCMeta):
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class PathPacket(Packet): class AckPacket(Packet):
path: List[str] = field(default_factory=list, compare=False) response: str = field(default=None)
via: str = None
def _build_payload(self):
raise NotImplementedError
@dataclass(unsafe_hash=True)
class AckPacket(PathPacket):
response: str = None
def __post__init__(self): def __post__init__(self):
if self.response: if self.response:
@ -284,8 +278,8 @@ class AckPacket(PathPacket):
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class RejectPacket(PathPacket): class RejectPacket(Packet):
response: str = None response: str = field(default=None)
def __post__init__(self): def __post__init__(self):
if self.response: if self.response:
@ -296,8 +290,8 @@ class RejectPacket(PathPacket):
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class MessagePacket(PathPacket): class MessagePacket(Packet):
message_text: str = None message_text: str = field(default=None)
def _filter_for_send(self) -> str: def _filter_for_send(self) -> str:
"""Filter and format message string for FCC.""" """Filter and format message string for FCC."""
@ -318,23 +312,23 @@ class MessagePacket(PathPacket):
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class StatusPacket(PathPacket): class StatusPacket(Packet):
status: str = None status: str = field(default=None)
messagecapable: bool = False messagecapable: bool = field(default=False)
comment: str = None comment: str = field(default=None)
def _build_payload(self): def _build_payload(self):
raise NotImplementedError raise NotImplementedError
@dataclass(unsafe_hash=True) @dataclass(unsafe_hash=True)
class GPSPacket(PathPacket): class GPSPacket(Packet):
latitude: float = 0.00 latitude: float = field(default=0.00)
longitude: float = 0.00 longitude: float = field(default=0.00)
altitude: float = 0.00 altitude: float = field(default=0.00)
rng: float = 0.00 rng: float = field(default=0.00)
posambiguity: int = 0 posambiguity: int = field(default=0)
comment: str = None comment: str = field(default=None)
symbol: str = field(default="l") symbol: str = field(default="l")
symbol_table: str = field(default="/") symbol_table: str = field(default="/")

View File

@ -48,8 +48,7 @@ class PacketList(MutableMapping):
self._add(packet) self._add(packet)
def _add(self, packet): def _add(self, packet):
key = packet.key() self[packet.key] = packet
self[key] = packet
@property @property
def maxlen(self): def maxlen(self):
@ -57,8 +56,7 @@ class PacketList(MutableMapping):
@wrapt.synchronized(lock) @wrapt.synchronized(lock)
def find(self, packet): def find(self, packet):
key = packet.key() return self.get(packet.key)
return self.get(key)
def __getitem__(self, key): def __getitem__(self, key):
# self.d.move_to_end(key) # self.d.move_to_end(key)

View File

@ -93,7 +93,7 @@ class APRSDPluginRXThread(APRSDRXThread):
pkt_list = packets.PacketList() pkt_list = packets.PacketList()
try: try:
# Find the packet in the list of already seen packets # Find the packet in the list of already seen packets
# Based on the packet.key() # Based on the packet.key
found = pkt_list.find(packet) found = pkt_list.find(packet)
except KeyError: except KeyError:
found = False found = False