dockerize!
This commit is contained in:
83
models.py
83
models.py
@@ -5,6 +5,20 @@ import re
|
||||
|
||||
|
||||
class EventType(Enum):
|
||||
"""Enumeration of possible Ingress event types.
|
||||
|
||||
Attributes:
|
||||
RESONATOR_DEPLOYED: A resonator was deployed on a portal.
|
||||
RESONATOR_DESTROYED: A resonator was destroyed on a portal.
|
||||
PORTAL_CAPTURED: A portal was captured by a faction.
|
||||
PORTAL_NEUTRALIZED: A portal was neutralized.
|
||||
PORTAL_UNDER_ATTACK: A portal is under attack.
|
||||
LINK_CREATED: A link was created between portals.
|
||||
LINK_DESTROYED: A link was destroyed.
|
||||
CONTROL_FIELD_CREATED: A control field was created.
|
||||
UNKNOWN: Unknown event type.
|
||||
"""
|
||||
|
||||
RESONATOR_DEPLOYED = "RESONATOR_DEPLOYED"
|
||||
RESONATOR_DESTROYED = "RESONATOR_DESTROYED"
|
||||
PORTAL_CAPTURED = "PORTAL_CAPTURED"
|
||||
@@ -30,6 +44,18 @@ EVENT_TYPE_KEYWORDS = {
|
||||
|
||||
@dataclass
|
||||
class Markup:
|
||||
"""Represents markup data within a plext message.
|
||||
|
||||
Attributes:
|
||||
type: The type of markup (e.g., "PLAYER", "PORTAL").
|
||||
plain: Plain text representation of the markup.
|
||||
team: Team affiliation (e.g., "RESISTANCE", "ENLIGHTENED").
|
||||
name: Name associated with the markup (e.g., player name, portal name).
|
||||
address: Address of the location (for portals).
|
||||
latE6: Latitude in microdegrees (E6 format).
|
||||
lngE6: Longitude in microdegrees (E6 format).
|
||||
"""
|
||||
|
||||
type: str
|
||||
plain: str
|
||||
team: str = ""
|
||||
@@ -41,6 +67,18 @@ class Markup:
|
||||
|
||||
@dataclass
|
||||
class Plext:
|
||||
"""Represents a plext (message) from the Ingress Intel API.
|
||||
|
||||
Attributes:
|
||||
id: Unique identifier for the plext.
|
||||
timestamp: Timestamp in milliseconds since epoch.
|
||||
text: The text content of the plext.
|
||||
team: Team affiliation (e.g., "RESISTANCE", "ENLIGHTENED").
|
||||
plext_type: Type of plext (e.g., "SYSTEM_BROADCAST", "PLAYER_GENERATED").
|
||||
categories: Category flags for the plext.
|
||||
markup: List of Markup objects containing structured data.
|
||||
"""
|
||||
|
||||
id: str
|
||||
timestamp: int
|
||||
text: str
|
||||
@@ -51,6 +89,15 @@ class Plext:
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, data: List[Any]) -> "Plext":
|
||||
"""Create a Plext instance from raw JSON data.
|
||||
|
||||
Args:
|
||||
data: Raw JSON data from the Ingress API. Expected format is a list
|
||||
where index 2 contains a dict with a "plext" key.
|
||||
|
||||
Returns:
|
||||
A new Plext instance populated with data from the JSON.
|
||||
"""
|
||||
plext_data = data[2]["plext"]
|
||||
markup_data = plext_data["markup"]
|
||||
|
||||
@@ -81,6 +128,12 @@ class Plext:
|
||||
)
|
||||
|
||||
def get_event_type(self) -> EventType:
|
||||
"""Determine the event type based on the plext text content.
|
||||
|
||||
Returns:
|
||||
The EventType that matches the plext text, or EventType.UNKNOWN if
|
||||
no match is found.
|
||||
"""
|
||||
for event_type, keywords in EVENT_TYPE_KEYWORDS.items():
|
||||
if all(keyword in self.text for keyword in keywords):
|
||||
# A special case for "captured", to avoid matching "destroyed"
|
||||
@@ -90,6 +143,14 @@ class Plext:
|
||||
return EventType.UNKNOWN
|
||||
|
||||
def get_player_name(self) -> str:
|
||||
"""Extract the player name from the plext.
|
||||
|
||||
First attempts to find the player name in the markup. If not found,
|
||||
attempts to extract it from the text using regex.
|
||||
|
||||
Returns:
|
||||
The player name if found, otherwise an empty string.
|
||||
"""
|
||||
for m in self.markup:
|
||||
if m.type == "PLAYER":
|
||||
return m.plain
|
||||
@@ -101,11 +162,23 @@ class Plext:
|
||||
return ""
|
||||
|
||||
def get_portal_name(self) -> str:
|
||||
"""Extract the portal name from the plext.
|
||||
|
||||
First attempts to find the portal name in the markup. If not found,
|
||||
attempts to extract it from the text using regex patterns for various
|
||||
event types.
|
||||
|
||||
Returns:
|
||||
The portal name if found, otherwise an empty string.
|
||||
"""
|
||||
for m in self.markup:
|
||||
if m.type == "PORTAL":
|
||||
return m.name
|
||||
# If portal name is not in markup, try to extract from text
|
||||
match = re.search(r"(?:deployed|destroyed|captured|linked from|created a Control Field @) (.+?) \(", self.text)
|
||||
match = re.search(
|
||||
r"(?:deployed|destroyed|captured|linked from|created a Control Field @) (.+?) \(",
|
||||
self.text,
|
||||
)
|
||||
if not match:
|
||||
match = re.search(r"Your Portal (.+?) is under attack by", self.text)
|
||||
if not match:
|
||||
@@ -115,6 +188,14 @@ class Plext:
|
||||
return ""
|
||||
|
||||
def get_event_coordinates(self) -> Optional[tuple[int, int]]:
|
||||
"""Extract the coordinates of the portal associated with this event.
|
||||
|
||||
Searches the markup for a PORTAL type entry and returns its coordinates.
|
||||
|
||||
Returns:
|
||||
A tuple of (latitude, longitude) in microdegrees (E6 format) if found,
|
||||
otherwise None.
|
||||
"""
|
||||
for m in self.markup:
|
||||
if m.type == "PORTAL":
|
||||
return m.latE6, m.lngE6
|
||||
|
||||
Reference in New Issue
Block a user