tuning ui and adding adaptive themeing to extension
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"""SQLAlchemy base model."""
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
||||
|
||||
@@ -10,8 +10,29 @@ class Base(DeclarativeBase):
|
||||
pass
|
||||
|
||||
|
||||
class TimestampMixin:
|
||||
"""Mixin for created_at and updated_at timestamps."""
|
||||
def utcnow():
|
||||
"""Return current UTC time as timezone-aware datetime."""
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(default=func.now(), onupdate=func.now())
|
||||
|
||||
def format_datetime(dt):
|
||||
"""Format datetime as ISO string with UTC marker for API responses.
|
||||
|
||||
If the datetime is naive (no timezone), assumes UTC and appends Z.
|
||||
This ensures JavaScript Date() correctly interprets the timezone.
|
||||
"""
|
||||
if not dt:
|
||||
return None
|
||||
# If naive (no timezone), assume UTC and append Z
|
||||
if dt.tzinfo is None:
|
||||
return dt.isoformat() + "Z"
|
||||
return dt.isoformat()
|
||||
|
||||
|
||||
class TimestampMixin:
|
||||
"""Mixin for created_at and updated_at timestamps.
|
||||
|
||||
Uses UTC timestamps for consistency. Frontend should convert to local time.
|
||||
"""
|
||||
created_at: Mapped[datetime] = mapped_column(default=utcnow)
|
||||
updated_at: Mapped[datetime] = mapped_column(default=utcnow, onupdate=utcnow)
|
||||
|
||||
@@ -6,7 +6,7 @@ from sqlalchemy import String, Integer, Text, ForeignKey, BigInteger
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.models.base import Base, TimestampMixin
|
||||
from app.models.base import Base, TimestampMixin, format_datetime
|
||||
|
||||
|
||||
class DownloadStatus:
|
||||
@@ -79,10 +79,10 @@ class Download(Base, TimestampMixin):
|
||||
"error_message": self.error_message,
|
||||
"file_count": self.file_count,
|
||||
"total_size": self.total_size,
|
||||
"started_at": self.started_at.isoformat() if self.started_at else None,
|
||||
"completed_at": self.completed_at.isoformat() if self.completed_at else None,
|
||||
"started_at": format_datetime(self.started_at),
|
||||
"completed_at": format_datetime(self.completed_at),
|
||||
"metadata": self.metadata_,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"created_at": format_datetime(self.created_at),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from sqlalchemy import String, Boolean, Integer, Text, ForeignKey, UniqueConstra
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.models.base import Base, TimestampMixin
|
||||
from app.models.base import Base, TimestampMixin, format_datetime
|
||||
|
||||
|
||||
class Source(Base, TimestampMixin):
|
||||
@@ -55,12 +55,12 @@ class Source(Base, TimestampMixin):
|
||||
"url": self.url,
|
||||
"enabled": self.enabled,
|
||||
"check_interval": self.check_interval,
|
||||
"last_check": self.last_check.isoformat() if self.last_check else None,
|
||||
"last_success": self.last_success.isoformat() if self.last_success else None,
|
||||
"last_check": format_datetime(self.last_check),
|
||||
"last_success": format_datetime(self.last_success),
|
||||
"error_count": self.error_count,
|
||||
"metadata": self.metadata_,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
"created_at": format_datetime(self.created_at),
|
||||
"updated_at": format_datetime(self.updated_at),
|
||||
}
|
||||
if include_subscription and self.subscription:
|
||||
result["subscription_name"] = self.subscription.name
|
||||
|
||||
@@ -6,7 +6,7 @@ from sqlalchemy import String, Boolean, Integer, Text
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.models.base import Base, TimestampMixin
|
||||
from app.models.base import Base, TimestampMixin, format_datetime
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.models.source import Source
|
||||
@@ -64,8 +64,8 @@ class Subscription(Base, TimestampMixin):
|
||||
"metadata": self.metadata_,
|
||||
"platform_count": self.platform_count,
|
||||
"enabled_source_count": self.enabled_source_count,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
"created_at": format_datetime(self.created_at),
|
||||
"updated_at": format_datetime(self.updated_at),
|
||||
}
|
||||
if include_sources and self.sources:
|
||||
result["sources"] = [s.to_dict(include_subscription=False) for s in self.sources]
|
||||
|
||||
Reference in New Issue
Block a user