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
3 changed files with 37 additions and 15 deletions
|
@ -110,6 +110,15 @@ class ImapMessage:
|
||||||
header_base[key] += header_instances # type: ignore[assignment]
|
header_base[key] += header_instances # type: ignore[assignment]
|
||||||
return header_base
|
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
|
@property
|
||||||
def date(self) -> datetime | None:
|
def date(self) -> datetime | None:
|
||||||
"""Get the date the email was sent."""
|
"""Get the date the email was sent."""
|
||||||
|
@ -189,6 +198,7 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||||
"""Initiate imap client."""
|
"""Initiate imap client."""
|
||||||
self.imap_client = imap_client
|
self.imap_client = imap_client
|
||||||
self.auth_errors: int = 0
|
self.auth_errors: int = 0
|
||||||
|
self._last_message_uid: str | None = None
|
||||||
self._last_message_id: str | None = None
|
self._last_message_id: str | None = None
|
||||||
self.custom_event_template = None
|
self.custom_event_template = None
|
||||||
_custom_event_template = entry.data.get(CONF_CUSTOM_EVENT_DATA_TEMPLATE)
|
_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:
|
if self.imap_client is None:
|
||||||
self.imap_client = await connect_to_server(self.config_entry.data)
|
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."""
|
"""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":
|
if response.result == "OK":
|
||||||
message = ImapMessage(response.lines[1])
|
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 = {
|
data = {
|
||||||
"server": self.config_entry.data[CONF_SERVER],
|
"server": self.config_entry.data[CONF_SERVER],
|
||||||
"username": self.config_entry.data[CONF_USERNAME],
|
"username": self.config_entry.data[CONF_USERNAME],
|
||||||
"search": self.config_entry.data[CONF_SEARCH],
|
"search": self.config_entry.data[CONF_SEARCH],
|
||||||
"folder": self.config_entry.data[CONF_FOLDER],
|
"folder": self.config_entry.data[CONF_FOLDER],
|
||||||
|
"initial": initial,
|
||||||
"date": message.date,
|
"date": message.date,
|
||||||
"text": message.text,
|
"text": message.text,
|
||||||
"sender": message.sender,
|
"sender": message.sender,
|
||||||
|
@ -231,18 +247,20 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||||
data, parse_result=True
|
data, parse_result=True
|
||||||
)
|
)
|
||||||
_LOGGER.debug(
|
_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,
|
self.custom_event_template,
|
||||||
last_message_id,
|
last_message_uid,
|
||||||
|
message_id,
|
||||||
data["custom"],
|
data["custom"],
|
||||||
|
initial,
|
||||||
)
|
)
|
||||||
except TemplateError as err:
|
except TemplateError as err:
|
||||||
data["custom"] = None
|
data["custom"] = None
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Error rendering imap custom template (%s) for msgid %s "
|
"Error rendering IMAP custom template (%s) for msguid %s "
|
||||||
"failed with message: %s",
|
"failed with message: %s",
|
||||||
self.custom_event_template,
|
self.custom_event_template,
|
||||||
last_message_id,
|
last_message_uid,
|
||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
data["text"] = message.text[
|
data["text"] = message.text[
|
||||||
|
@ -263,10 +281,12 @@ class ImapDataUpdateCoordinator(DataUpdateCoordinator[int | None]):
|
||||||
|
|
||||||
self.hass.bus.fire(EVENT_IMAP, data)
|
self.hass.bus.fire(EVENT_IMAP, data)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Message with id %s processed, sender: %s, subject: %s",
|
"Message with id %s (%s) processed, sender: %s, subject: %s, initial: %s",
|
||||||
last_message_id,
|
last_message_uid,
|
||||||
|
message_id,
|
||||||
message.sender,
|
message.sender,
|
||||||
message.subject,
|
message.subject,
|
||||||
|
initial,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _async_fetch_number_of_messages(self) -> int | None:
|
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]}"
|
f"Invalid response for search '{self.config_entry.data[CONF_SEARCH]}': {result} / {lines[0]}"
|
||||||
)
|
)
|
||||||
if not (count := len(message_ids := lines[0].split())):
|
if not (count := len(message_ids := lines[0].split())):
|
||||||
self._last_message_id = None
|
self._last_message_uid = None
|
||||||
return 0
|
return 0
|
||||||
last_message_id = (
|
last_message_uid = (
|
||||||
str(message_ids[-1:][0], encoding=self.config_entry.data[CONF_CHARSET])
|
str(message_ids[-1:][0], encoding=self.config_entry.data[CONF_CHARSET])
|
||||||
if count
|
if count
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
count
|
count
|
||||||
and last_message_id is not None
|
and last_message_uid is not None
|
||||||
and self._last_message_id != last_message_id
|
and self._last_message_uid != last_message_uid
|
||||||
):
|
):
|
||||||
self._last_message_id = last_message_id
|
self._last_message_uid = last_message_uid
|
||||||
await self._async_process_event(last_message_id)
|
await self._async_process_event(last_message_uid)
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ TEST_MESSAGE_HEADERS2 = (
|
||||||
b"To: notify@example.com\r\n"
|
b"To: notify@example.com\r\n"
|
||||||
b"From: John Doe <john.doe@example.com>\r\n"
|
b"From: John Doe <john.doe@example.com>\r\n"
|
||||||
b"Subject: Test subject\r\n"
|
b"Subject: Test subject\r\n"
|
||||||
|
b"Message-ID: <N753P9hLvLw3lYGan11ji9WggPjxtLSpKvFOYgdnE@example.com>"
|
||||||
)
|
)
|
||||||
|
|
||||||
TEST_MESSAGE_HEADERS3 = b""
|
TEST_MESSAGE_HEADERS3 = b""
|
||||||
|
|
|
@ -512,6 +512,7 @@ async def test_reset_last_message(
|
||||||
assert data["sender"] == "john.doe@example.com"
|
assert data["sender"] == "john.doe@example.com"
|
||||||
assert data["subject"] == "Test subject"
|
assert data["subject"] == "Test subject"
|
||||||
assert data["text"]
|
assert data["text"]
|
||||||
|
assert data["initial"]
|
||||||
assert (
|
assert (
|
||||||
valid_date
|
valid_date
|
||||||
and isinstance(data["date"], datetime)
|
and isinstance(data["date"], datetime)
|
||||||
|
@ -628,7 +629,7 @@ async def test_message_is_truncated(
|
||||||
[
|
[
|
||||||
("{{ subject }}", "Test subject", None),
|
("{{ subject }}", "Test subject", None),
|
||||||
('{{ "@example.com" in sender }}', True, 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"],
|
ids=["subject_test", "sender_filter", "template_error"],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue