|
1 | 1 | from datetime import datetime |
2 | 2 | from enum import StrEnum |
3 | 3 | from typing import TYPE_CHECKING, Any, Self, TypedDict |
| 4 | +from urllib.parse import urlparse |
4 | 5 | from uuid import UUID |
5 | 6 |
|
6 | 7 | from sqlalchemy import ( |
@@ -147,10 +148,31 @@ class Organization(RateLimitGroupMixin, RecordModel): |
147 | 148 |
|
148 | 149 | name: Mapped[str] = mapped_column(String, nullable=False, index=True) |
149 | 150 | slug: Mapped[str] = mapped_column(CITEXT, nullable=False, unique=True) |
150 | | - avatar_url: Mapped[str | None] = mapped_column(String, nullable=True) |
| 151 | + _avatar_url: Mapped[str | None] = mapped_column( |
| 152 | + String, name="avatar_url", nullable=True |
| 153 | + ) |
151 | 154 |
|
152 | 155 | email: Mapped[str | None] = mapped_column(String, nullable=True, default=None) |
153 | 156 | website: Mapped[str | None] = mapped_column(String, nullable=True, default=None) |
| 157 | + |
| 158 | + @property |
| 159 | + def avatar_url(self) -> str | None: |
| 160 | + if self._avatar_url: |
| 161 | + return self._avatar_url |
| 162 | + |
| 163 | + if not self.website or not settings.LOGO_DEV_PUBLISHABLE_KEY: |
| 164 | + return None |
| 165 | + |
| 166 | + parsed = urlparse(self.website) |
| 167 | + domain = parsed.netloc or parsed.path |
| 168 | + domain = domain.lower().removeprefix("www.") |
| 169 | + |
| 170 | + return f"https://img.logo.dev/{domain}?size=64&retina=true&token={settings.LOGO_DEV_PUBLISHABLE_KEY}&fallback=404" |
| 171 | + |
| 172 | + @avatar_url.setter |
| 173 | + def avatar_url(self, value: str | None) -> None: |
| 174 | + self._avatar_url = value |
| 175 | + |
154 | 176 | socials: Mapped[list[OrganizationSocials]] = mapped_column( |
155 | 177 | JSONB, nullable=False, default=list |
156 | 178 | ) |
|
0 commit comments