mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Add intial property to imap_content event data (#100171)
* Add initial property to imap event data * Simplify loop Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * MyPy --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
86bccf769e
commit
e84a4661b0
@ -110,6 +110,15 @@ class ImapMessage:
|
||||
header_base[key] += header_instances # type: ignore[assignment]
|
||||
return header_base
|
||||
|
||||
@property
|
||||
def message_id(self) -> str | None:
|
||||
"""Get the message ID."""
|
||||
value: str
|
||||
for header, value in self.email_message.items():
|
||||
if header == "Message-ID":
|
||||
return value
|
||||
return None
|
||||
|
||||
@property
|
||||
def date(self) -> datetime | None:
|
||||
"""Get the date the email was sent."""
|
||||
@ -189,6 +198,7 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||
"""Initiate imap client."""
|
||||
self.imap_client = imap_client
|
||||
self.auth_errors: int = 0
|
||||
self._last_message_uid: str | None = None
|
||||
self._last_message_id: str | None = None
|
||||
self.custom_event_template = None
|
||||
_custom_event_template = entry.data.get(CONF_CUSTOM_EVENT_DATA_TEMPLATE)
|
||||
@ -209,16 +219,22 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||
if self.imap_client is None:
|
||||
self.imap_client = await connect_to_server(self.config_entry.data)
|
||||
|
||||
async def _async_process_event(self, last_message_id: str) -> None:
|
||||
async def _async_process_event(self, last_message_uid: str) -> None:
|
||||
"""Send a event for the last message if the last message was changed."""
|
||||
response = await self.imap_client.fetch(last_message_id, "BODY.PEEK[]")
|
||||
response = await self.imap_client.fetch(last_message_uid, "BODY.PEEK[]")
|
||||
if response.result == "OK":
|
||||
message = ImapMessage(response.lines[1])
|
||||
# Set `initial` to `False` if the last message is triggered again
|
||||
initial: bool = True
|
||||
if (message_id := message.message_id) == self._last_message_id:
|
||||
initial = False
|
||||
self._last_message_id = message_id
|
||||
data = {
|
||||
"server": self.config_entry.data[CONF_SERVER],
|
||||
"username": self.config_entry.data[CONF_USERNAME],
|
||||
"search": self.config_entry.data[CONF_SEARCH],
|
||||
"folder": self.config_entry.data[CONF_FOLDER],
|
||||
"initial": initial,
|
||||
"date": message.date,
|
||||
"text": message.text,
|
||||
"sender": message.sender,
|
||||
@ -231,18 +247,20 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||
data, parse_result=True
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"imap custom template (%s) for msgid %s rendered to: %s",
|
||||
"IMAP custom template (%s) for msguid %s (%s) rendered to: %s, initial: %s",
|
||||
self.custom_event_template,
|
||||
last_message_id,
|
||||
last_message_uid,
|
||||
message_id,
|
||||
data["custom"],
|
||||
initial,
|
||||
)
|
||||
except TemplateError as err:
|
||||
data["custom"] = None
|
||||
_LOGGER.error(
|
||||
"Error rendering imap custom template (%s) for msgid %s "
|
||||
"Error rendering IMAP custom template (%s) for msguid %s "
|
||||
"failed with message: %s",
|
||||
self.custom_event_template,
|
||||
last_message_id,
|
||||
last_message_uid,
|
||||
err,
|
||||
)
|
||||
data["text"] = message.text[
|
||||
@ -263,10 +281,12 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||
|
||||
self.hass.bus.fire(EVENT_IMAP, data)
|
||||
_LOGGER.debug(
|
||||
"Message with id %s processed, sender: %s, subject: %s",
|
||||
last_message_id,
|
||||
"Message with id %s (%s) processed, sender: %s, subject: %s, initial: %s",
|
||||
last_message_uid,
|
||||
message_id,
|
||||
message.sender,
|
||||
message.subject,
|
||||
initial,
|
||||
)
|
||||
|
||||
async def _async_fetch_number_of_messages(self) -> int | None:
|
||||
@ -282,20 +302,20 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||
f"Invalid response for search '{self.config_entry.data[CONF_SEARCH]}': {result} / {lines[0]}"
|
||||
)
|
||||
if not (count := len(message_ids := lines[0].split())):
|
||||
self._last_message_id = None
|
||||
self._last_message_uid = None
|
||||
return 0
|
||||
last_message_id = (
|
||||
last_message_uid = (
|
||||
str(message_ids[-1:][0], encoding=self.config_entry.data[CONF_CHARSET])
|
||||
if count
|
||||
else None
|
||||
)
|
||||
if (
|
||||
count
|
||||
and last_message_id is not None
|
||||
and self._last_message_id != last_message_id
|
||||
and last_message_uid is not None
|
||||
and self._last_message_uid != last_message_uid
|
||||
):
|
||||
self._last_message_id = last_message_id
|
||||
await self._async_process_event(last_message_id)
|
||||
self._last_message_uid = last_message_uid
|
||||
await self._async_process_event(last_message_uid)
|
||||
|
||||
return count
|
||||
|
||||
|
@ -22,6 +22,7 @@ TEST_MESSAGE_HEADERS2 = (
|
||||
b"To: notify@example.com\r\n"
|
||||
b"From: John Doe <john.doe@example.com>\r\n"
|
||||
b"Subject: Test subject\r\n"
|
||||
b"Message-ID: <N753P9hLvLw3lYGan11ji9WggPjxtLSpKvFOYgdnE@example.com>"
|
||||
)
|
||||
|
||||
TEST_MESSAGE_HEADERS3 = b""
|
||||
|
@ -512,6 +512,7 @@ async def test_reset_last_message(
|
||||
assert data["sender"] == "john.doe@example.com"
|
||||
assert data["subject"] == "Test subject"
|
||||
assert data["text"]
|
||||
assert data["initial"]
|
||||
assert (
|
||||
valid_date
|
||||
and isinstance(data["date"], datetime)
|
||||
@ -628,7 +629,7 @@ async def test_message_is_truncated(
|
||||
[
|
||||
("{{ subject }}", "Test subject", None),
|
||||
('{{ "@example.com" in sender }}', True, None),
|
||||
("{% bad template }}", None, "Error rendering imap custom template"),
|
||||
("{% bad template }}", None, "Error rendering IMAP custom template"),
|
||||
],
|
||||
ids=["subject_test", "sender_filter", "template_error"],
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user