updated apps

This commit is contained in:
2026-07-14 23:57:03 -04:00
parent 6cc7212cef
commit 010e828e9c
797 changed files with 45153 additions and 4246 deletions
@@ -104,12 +104,23 @@ class AmazonShipper(Shipper):
days = self.config.get(CONF_AMAZON_DAYS, DEFAULT_AMAZON_DAYS)
domain = self.config.get(CONF_AMAZON_DOMAIN)
if sensor_type in [AMAZON_PACKAGES, AMAZON_ORDER]:
param = "count" if sensor_type == AMAZON_PACKAGES else "order"
result = await self._parse_amazon_emails(
account, param, fwds, days, domain, cache, forwarding_header
if sensor_type == AMAZON_PACKAGES:
count = await self._parse_amazon_emails(
account, "count", fwds, days, domain, cache, forwarding_header
)
return {sensor_type: result}
orders = await self._parse_amazon_emails(
account, "order", fwds, days, domain, cache, forwarding_header
)
return {
AMAZON_PACKAGES: count,
AMAZON_ORDER: orders,
}
if sensor_type == AMAZON_ORDER:
result = await self._parse_amazon_emails(
account, "order", fwds, days, domain, cache, forwarding_header
)
return {AMAZON_ORDER: result}
if sensor_type == AMAZON_HUB:
return await self._amazon_hub(account, fwds, cache, forwarding_header)
@@ -199,7 +210,17 @@ class AmazonShipper(Shipper):
if param == "count":
return final_count
return list(context["all_shipped_orders"])
return [
order_id
for order_id in context["all_shipped_orders"]
if context["packages_arriving_today"].get(order_id, 0)
> context["delivered_packages"].get(order_id, 0)
or (
context["packages_arriving_today"].get(order_id, 0) == 0
and context["delivered_packages"].get(order_id, 0) == 0
)
]
async def _process_amazon_email(
self,
@@ -297,7 +297,14 @@ class GenericShipper(Shipper):
tracking = set(sensor_res.get(ATTR_TRACKING, []))
if sensor.endswith("_delivered"):
shippers[prefix]["delivered"].update(tracking)
# ATTR_TRACKING on _delivered sensors holds only TODAY's
# deliveries (so the sensor resets at midnight); dedup must
# use the extended-window list or packages delivered on a
# previous day are never subtracted from _delivering.
extended = sensor_res.get("pre_filtered_tracking")
shippers[prefix]["delivered"].update(
tracking if extended is None else set(extended)
)
elif sensor.endswith(("_delivering", "_exception")):
shippers[prefix]["delivering"].update(tracking)
shippers[prefix]["update_targets"].append((sensor, sensor_res))
@@ -662,7 +669,11 @@ class GenericShipper(Shipper):
msg_parts = (await email_fetch(account, eid, "(RFC822)"))[1]
for response_part in msg_parts:
if isinstance(response_part, (bytes, bytearray)):
if generic_delivery_image_extraction(
# The extraction does blocking file I/O (the image
# write) and CPU-heavy email parsing — run the whole
# sync function off the event loop.
if await self.hass.async_add_executor_job(
generic_delivery_image_extraction,
response_part,
s_config["image_path"],
s_config["image_name"],
@@ -27,6 +27,7 @@ from custom_components.mail_and_packages.const import (
CONF_FORWARDING_HEADER,
CONF_GENERATE_GRID,
CONF_GENERATE_MP4,
CONF_USPS_PLACEHOLDER,
DEFAULT_CUSTOM_IMG_FILE,
SENSOR_DATA,
)
@@ -103,32 +104,17 @@ class USPSShipper(Shipper):
images = await self._process_usps_images(all_msg_content, images)
image_count = len(images)
if image_count > 0:
await self._generate_mail_image(
images,
config["image_output_path"],
config["image_name"],
config["gif_duration"],
images_delete,
)
elif image_count == 0:
await self._copy_nomail_image(
config["image_output_path"],
config["image_name"],
config["custom_img"],
# Generate filtered list for GIF/MP4/Grid
gif_images = images.copy()
if not config.get("usps_placeholder", True):
placeholder_str = str(
Path(__file__).parent.parent / "image-no-mailpieces700.jpg"
)
if placeholder_str in gif_images:
gif_images.remove(placeholder_str)
if config["gen_mp4"]:
await self._generate_mp4_video(
config["image_output_path"],
config["image_name"],
)
if config["gen_grid"]:
await self._generate_grid_image(
config["image_output_path"],
config["image_name"],
image_count,
)
# Generate camera media
await self._create_camera_media(gif_images, config, images_delete)
return {
ATTR_COUNT: image_count,
@@ -159,6 +145,40 @@ class USPSShipper(Shipper):
return res
async def _create_camera_media(
self,
gif_images: list,
config: dict,
images_delete: list,
):
"""Create camera media (GIF, MP4, and Grid)."""
if len(gif_images) > 0:
await self._generate_mail_image(
gif_images,
config["image_output_path"],
config["image_name"],
config["gif_duration"],
images_delete,
)
else:
await self._copy_nomail_image(
config["image_output_path"],
config["image_name"],
config["custom_img"],
)
if config["gen_mp4"]:
await self._generate_mp4_video(
config["image_output_path"],
config["image_name"],
)
if config["gen_grid"]:
await self._generate_grid_image(
config["image_output_path"],
config["image_name"],
len(gif_images),
)
async def _generate_mp4_video(self, path: str, name: str):
"""Generate MP4 video from images."""
await self.hass.async_add_executor_job(_generate_mp4, path, name)
@@ -260,6 +280,7 @@ class USPSShipper(Shipper):
"custom_img": self.config.get(CONF_CUSTOM_IMG_FILE)
or DEFAULT_CUSTOM_IMG_FILE,
"gen_grid": self.config.get(CONF_GENERATE_GRID),
"usps_placeholder": self.config.get(CONF_USPS_PLACEHOLDER, True),
}
async def _search_informed_delivery(self, account: IMAP4_SSL) -> tuple: