Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions custom_components/hacs/brands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Brand icon endpoint for HACS update entities."""

from __future__ import annotations

from http import HTTPStatus
from pathlib import Path
import re

from aiohttp import web
from homeassistant.components.http import HomeAssistantView
from homeassistant.core import HomeAssistant

from .base import HacsBase
from .const import BRAND_ICON_CDN_URL, BRAND_ICON_URL
from .enums import HacsCategory

DOMAIN_RE = re.compile(r"^[a-z0-9_]+$")


def _read_brand_icon(path: Path) -> bytes | None:
"""Read a brand icon from disk."""
if not path.is_file():
return None
return path.read_bytes()


Comment on lines +22 to +26
class HacsBrandIconView(HomeAssistantView):
"""Serve installed integration brand icons with a CDN fallback."""

name = "api:hacs:brand_icon"
url = BRAND_ICON_URL
requires_auth = False

def __init__(self, hass: HomeAssistant, hacs: HacsBase) -> None:
"""Initialize the view."""
self.hass = hass
self.hacs = hacs

async def get(self, request: web.Request, domain: str) -> web.Response:
"""Return the local brand icon for an installed HACS integration."""
if not DOMAIN_RE.fullmatch(domain):
return web.Response(status=HTTPStatus.NOT_FOUND)

if (icon_path := self._brand_icon_path(domain)) is not None:
data = await self.hass.async_add_executor_job(_read_brand_icon, icon_path)
if data is not None:
return web.Response(body=data, content_type="image/png")

raise web.HTTPFound(BRAND_ICON_CDN_URL.format(domain=domain))

def _brand_icon_path(self, domain: str) -> Path | None:
"""Return the local brand icon path for an installed integration."""
for repository in self.hacs.repositories.list_downloaded:
if repository.data.category != HacsCategory.INTEGRATION:
continue
if repository.data.domain != domain or repository.content.path.local is None:
continue
return Path(repository.content.path.local) / "brand" / "icon.png"
return None
2 changes: 2 additions & 0 deletions custom_components/hacs/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
MINIMUM_HA_VERSION = "0.0.0"

URL_BASE = "/hacsfiles"
BRAND_ICON_URL = "/api/hacs/brands/{domain}/icon.png"
BRAND_ICON_CDN_URL = "https://brands.home-assistant.io/_/{domain}/icon.png"

TV = TypeVar("TV")

Expand Down
2 changes: 2 additions & 0 deletions custom_components/hacs/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
async_register_built_in_panel,
)

from .brands import HacsBrandIconView
from .const import DOMAIN, URL_BASE
from .hacs_frontend import VERSION as FE_VERSION, locate_dir
from .utils.workarounds import async_register_static_path
Expand All @@ -22,6 +23,7 @@

async def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None:
"""Register the frontend."""
hass.http.register_view(HacsBrandIconView(hass, hacs))

# Register frontend
if hacs.configuration.dev and (frontend_path := os.getenv("HACS_FRONTEND_DIR")):
Expand Down
4 changes: 2 additions & 2 deletions custom_components/hacs/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .base import HacsBase
from .const import DOMAIN
from .const import BRAND_ICON_URL, DOMAIN
from .entity import HacsRepositoryEntity
from .enums import HacsCategory, HacsDispatchEvent
from .exceptions import HacsException
Expand Down Expand Up @@ -76,7 +76,7 @@ def entity_picture(self) -> str | None:
):
return None

return f"https://brands.home-assistant.io/_/{self.repository.data.domain}/icon.png"
return BRAND_ICON_URL.format(domain=self.repository.data.domain)

async def async_install(self, version: str | None, backup: bool, **kwargs: Any) -> None:
"""Install an update."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/example/icon.png",
"entity_picture": "/api/hacs/brands/example/icon.png",
"friendly_name": "Proxy manifest update",
"in_progress": false,
"installed_version": "1.0.0",
Expand Down Expand Up @@ -126,7 +126,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"initial": {
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/example/icon.png",
"entity_picture": "/api/hacs/brands/example/icon.png",
"friendly_name": "Basic integration update",
"in_progress": false,
"installed_version": "1.0.0",
Expand All @@ -48,7 +48,7 @@
"updated": {
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/example/icon.png",
"entity_picture": "/api/hacs/brands/example/icon.png",
"friendly_name": "Basic integration update",
"in_progress": false,
"installed_version": "1.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"initial_state": {
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/example/icon.png",
"entity_picture": "/api/hacs/brands/example/icon.png",
"friendly_name": "Basic integration update",
"in_progress": false,
"installed_version": "1.0.0",
Expand All @@ -23,7 +23,7 @@
"updated_state": {
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/example/icon.png",
"entity_picture": "/api/hacs/brands/example/icon.png",
"friendly_name": "Basic integration update",
"in_progress": false,
"installed_version": "1.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/example/icon.png",
"entity_picture": "/api/hacs/brands/example/icon.png",
"friendly_name": "Proxy manifest update",
"in_progress": false,
"installed_version": "2.0.0",
Expand Down Expand Up @@ -141,7 +141,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"area_id": null,
"attributes": {
"auto_update": false,
"entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png",
"entity_picture": "/api/hacs/brands/hacs/icon.png",
"friendly_name": "HACS update",
"in_progress": false,
"installed_version": "0.0.0",
Expand Down
Loading
Loading