Update images.py

This commit is contained in:
thekiwismarthome
2026-02-13 15:06:11 +13:00
committed by GitHub
parent 5a7b8203f6
commit 0258bc8690
@@ -1,92 +1,109 @@
"""Config flow for Shopping List Manager.""" """Image handling utilities for Shopping List Manager."""
import voluptuous as vol import logging
from homeassistant import config_entries import os
from homeassistant.core import callback from pathlib import Path
from typing import Optional
from .const import DOMAIN _LOGGER = logging.getLogger(__name__)
class ShoppingListManagerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class ImageHandler:
"""Handle a config flow for Shopping List Manager.""" """Handle product images with URL and local file support."""
VERSION = 1 def __init__(self, hass, config_path: str):
"""Initialize image handler.
def __init__(self):
"""Initialize config flow."""
self._data = {}
async def async_step_user(self, user_input=None):
"""Handle the initial step."""
# Only allow one instance
if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
if user_input is not None: Args:
# Store initial list name hass: Home Assistant instance
self._data["initial_list_name"] = user_input.get("list_name", "Shopping List") config_path: Path to HA config directory
return await self.async_step_features() """
self.hass = hass
# Show setup form # Images stored in /config/www/shopping_list_manager/images/
return self.async_show_form( self._local_images_dir = Path(config_path) / "www" / "shopping_list_manager" / "images"
step_id="user", self._local_images_dir.mkdir(parents=True, exist_ok=True)
data_schema=vol.Schema({
vol.Optional("list_name", default="Shopping List"): str, _LOGGER.info("Image directory: %s", self._local_images_dir)
}),
description_placeholders={ def get_image_url(self, product_name: str, external_url: Optional[str] = None) -> str:
"version": "2.0.0", """Get image URL for a product.
}
) Priority:
1. External URL (if provided)
async def async_step_features(self, user_input=None): 2. Local file match
"""Configure optional features.""" 3. Placeholder
if user_input is not None:
self._data.update(user_input) Args:
return self.async_create_entry( product_name: Name of product to find image for
title="Shopping List Manager", external_url: Optional external image URL
data=self._data
) Returns:
Image URL (external, local, or placeholder)
return self.async_show_form( """
step_id="features", # Priority 1: Use external URL if provided
data_schema=vol.Schema({ if external_url:
vol.Optional("enable_price_tracking", default=True): bool, return external_url
vol.Optional("enable_image_search", default=True): bool,
vol.Optional("metric_units_only", default=True): bool, # Priority 2: Look for local file
}), local_url = self._find_local_image(product_name)
description_placeholders={ if local_url:
"features": "Configure optional features for your shopping lists" return local_url
}
) # Priority 3: Placeholder
return self._get_placeholder_url()
@staticmethod
@callback def _find_local_image(self, product_name: str) -> Optional[str]:
def async_get_options_flow(config_entry): """Find local image file for product.
"""Get the options flow for this handler."""
return OptionsFlowHandler(config_entry) Searches for files matching product name (case-insensitive).
Supports: .webp, .jpg, .jpeg, .png
class OptionsFlowHandler(config_entries.OptionsFlow): Args:
"""Handle options flow for Shopping List Manager.""" product_name: Product name to search for
def __init__(self, config_entry): Returns:
"""Initialize options flow.""" Local URL if found, None otherwise
self.config_entry = config_entry """
# Normalize product name for filename matching
async def async_step_init(self, user_input=None): normalized_name = product_name.lower().replace(" ", "_")
"""Manage the options."""
if user_input is not None: # Supported extensions
return self.async_create_entry(title="", data=user_input) extensions = [".webp", ".jpg", ".jpeg", ".png"]
return self.async_show_form( for ext in extensions:
step_id="init", # Check exact match
data_schema=vol.Schema({ image_file = self._local_images_dir / f"{normalized_name}{ext}"
vol.Optional( if image_file.exists():
"enable_price_tracking", return f"/local/shopping_list_manager/images/{normalized_name}{ext}"
default=self.config_entry.data.get("enable_price_tracking", True)
): bool, # Check for files starting with the product name
vol.Optional( for file in self._local_images_dir.glob(f"{normalized_name}*{ext}"):
"enable_image_search", return f"/local/shopping_list_manager/images/{file.name}"
default=self.config_entry.data.get("enable_image_search", True)
): bool, return None
})
) def _get_placeholder_url(self) -> str:
"""Get placeholder image URL.
Returns:
URL to placeholder image
"""
# Use a simple colored placeholder
# You can replace this with a real placeholder image later
return "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23f0f0f0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='Arial' font-size='16' fill='%23999'%3ENo Image%3C/text%3E%3C/svg%3E"
def list_available_images(self) -> list:
"""List all available local images.
Returns:
List of (filename, product_name_guess) tuples
"""
images = []
extensions = [".webp", ".jpg", ".jpeg", ".png"]
for ext in extensions:
for image_file in self._local_images_dir.glob(f"*{ext}"):
# Guess product name from filename
product_name = image_file.stem.replace("_", " ").title()
images.append((image_file.name, product_name))
return sorted(images)