Add post date to info line

This commit is contained in:
pax 2026-04-05 21:15:22 -05:00
parent e22cde2a27
commit 8467c0696b
6 changed files with 40 additions and 6 deletions

View File

@ -25,6 +25,7 @@ class Post:
source: str | None source: str | None
width: int = 0 width: int = 0
height: int = 0 height: int = 0
created_at: str = "" # YYYY-MM-DD
tag_categories: dict[str, list[str]] = field(default_factory=dict) tag_categories: dict[str, list[str]] = field(default_factory=dict)
@property @property
@ -32,6 +33,29 @@ class Post:
return self.tags.split() return self.tags.split()
def _parse_date(raw) -> str:
"""Normalize various booru date formats to YYYY-MM-DD."""
if not raw:
return ""
if isinstance(raw, dict):
raw = raw.get("s", 0)
if isinstance(raw, (int, float)):
from datetime import datetime, timezone
return datetime.fromtimestamp(raw, tz=timezone.utc).strftime("%Y-%m-%d")
s = str(raw)
# ISO 8601
if len(s) >= 10 and s[4] == '-' and s[7] == '-':
return s[:10]
# Gelbooru style: "Thu Jun 06 08:16:14 -0500 2024"
from datetime import datetime
for fmt in ("%a %b %d %H:%M:%S %z %Y",):
try:
return datetime.strptime(s, fmt).strftime("%Y-%m-%d")
except ValueError:
pass
return ""
class BooruClient(ABC): class BooruClient(ABC):
"""Base class for booru API clients.""" """Base class for booru API clients."""

View File

@ -5,7 +5,7 @@ from __future__ import annotations
import logging import logging
from ..config import DEFAULT_PAGE_SIZE from ..config import DEFAULT_PAGE_SIZE
from .base import BooruClient, Post from .base import BooruClient, Post, _parse_date
log = logging.getLogger("booru") log = logging.getLogger("booru")
@ -54,6 +54,7 @@ class DanbooruClient(BooruClient):
source=item.get("source"), source=item.get("source"),
width=item.get("image_width", 0), width=item.get("image_width", 0),
height=item.get("image_height", 0), height=item.get("image_height", 0),
created_at=_parse_date(item.get("created_at")),
tag_categories=self._extract_tag_categories(item), tag_categories=self._extract_tag_categories(item),
) )
) )
@ -85,6 +86,7 @@ class DanbooruClient(BooruClient):
source=item.get("source"), source=item.get("source"),
width=item.get("image_width", 0), width=item.get("image_width", 0),
height=item.get("image_height", 0), height=item.get("image_height", 0),
created_at=_parse_date(item.get("created_at")),
) )
async def autocomplete(self, query: str, limit: int = 10) -> list[str]: async def autocomplete(self, query: str, limit: int = 10) -> list[str]:

View File

@ -7,7 +7,7 @@ import logging
import httpx import httpx
from ..config import DEFAULT_PAGE_SIZE, USER_AGENT from ..config import DEFAULT_PAGE_SIZE, USER_AGENT
from .base import BooruClient, Post from .base import BooruClient, Post, _parse_date
log = logging.getLogger("booru") log = logging.getLogger("booru")
@ -74,6 +74,7 @@ class E621Client(BooruClient):
source=self._get_source(item), source=self._get_source(item),
width=self._get_nested(item, "file", "width") or 0, width=self._get_nested(item, "file", "width") or 0,
height=self._get_nested(item, "file", "height") or 0, height=self._get_nested(item, "file", "height") or 0,
created_at=_parse_date(item.get("created_at")),
tag_categories=self._extract_tag_categories(item), tag_categories=self._extract_tag_categories(item),
) )
) )
@ -107,6 +108,7 @@ class E621Client(BooruClient):
source=self._get_source(item), source=self._get_source(item),
width=self._get_nested(item, "file", "width") or 0, width=self._get_nested(item, "file", "width") or 0,
height=self._get_nested(item, "file", "height") or 0, height=self._get_nested(item, "file", "height") or 0,
created_at=_parse_date(item.get("created_at")),
) )
async def autocomplete(self, query: str, limit: int = 10) -> list[str]: async def autocomplete(self, query: str, limit: int = 10) -> list[str]:

View File

@ -5,7 +5,7 @@ from __future__ import annotations
import logging import logging
from ..config import DEFAULT_PAGE_SIZE from ..config import DEFAULT_PAGE_SIZE
from .base import BooruClient, Post from .base import BooruClient, Post, _parse_date
log = logging.getLogger("booru") log = logging.getLogger("booru")
@ -72,6 +72,7 @@ class GelbooruClient(BooruClient):
source=item.get("source"), source=item.get("source"),
width=item.get("width", 0), width=item.get("width", 0),
height=item.get("height", 0), height=item.get("height", 0),
created_at=_parse_date(item.get("created_at")),
) )
) )
return posts return posts
@ -116,6 +117,7 @@ class GelbooruClient(BooruClient):
source=item.get("source"), source=item.get("source"),
width=item.get("width", 0), width=item.get("width", 0),
height=item.get("height", 0), height=item.get("height", 0),
created_at=_parse_date(item.get("created_at")),
) )
async def autocomplete(self, query: str, limit: int = 10) -> list[str]: async def autocomplete(self, query: str, limit: int = 10) -> list[str]:

View File

@ -5,7 +5,7 @@ from __future__ import annotations
import logging import logging
from ..config import DEFAULT_PAGE_SIZE from ..config import DEFAULT_PAGE_SIZE
from .base import BooruClient, Post from .base import BooruClient, Post, _parse_date
log = logging.getLogger("booru") log = logging.getLogger("booru")
@ -48,6 +48,7 @@ class MoebooruClient(BooruClient):
source=item.get("source"), source=item.get("source"),
width=item.get("width", 0), width=item.get("width", 0),
height=item.get("height", 0), height=item.get("height", 0),
created_at=_parse_date(item.get("created_at")),
) )
) )
return posts return posts
@ -83,6 +84,7 @@ class MoebooruClient(BooruClient):
source=item.get("source"), source=item.get("source"),
width=item.get("width", 0), width=item.get("width", 0),
height=item.get("height", 0), height=item.get("height", 0),
created_at=_parse_date(item.get("created_at")),
) )
async def autocomplete(self, query: str, limit: int = 10) -> list[str]: async def autocomplete(self, query: str, limit: int = 10) -> list[str]:

View File

@ -995,6 +995,7 @@ class BooruApp(QMainWindow):
post = self._posts[index] post = self._posts[index]
self._status.showMessage( self._status.showMessage(
f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}] {Path(post.file_url.split('?')[0]).suffix.lstrip('.').upper() if post.file_url else ''}" f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}] {Path(post.file_url.split('?')[0]).suffix.lstrip('.').upper() if post.file_url else ''}"
+ (f" {post.created_at}" if post.created_at else "")
) )
if self._info_panel.isVisible(): if self._info_panel.isVisible():
self._info_panel.set_post(post) self._info_panel.set_post(post)
@ -1015,7 +1016,8 @@ class BooruApp(QMainWindow):
self._prefetch_pause.clear() # pause prefetch self._prefetch_pause.clear() # pause prefetch
try: try:
path = await download_image(post.file_url, progress_callback=_progress) path = await download_image(post.file_url, progress_callback=_progress)
info = f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}] {Path(post.file_url.split('?')[0]).suffix.lstrip('.').upper() if post.file_url else ''}" info = (f"#{post.id} {post.width}x{post.height} score:{post.score} [{post.rating}] {Path(post.file_url.split('?')[0]).suffix.lstrip('.').upper() if post.file_url else ''}"
+ (f" {post.created_at}" if post.created_at else ""))
self._signals.image_done.emit(str(path), info) self._signals.image_done.emit(str(path), info)
except Exception as e: except Exception as e:
log.error(f"Image download failed: {e}") log.error(f"Image download failed: {e}")
@ -1217,7 +1219,7 @@ class BooruApp(QMainWindow):
source=meta.get("source"), tag_categories=meta.get("tag_categories", {}), source=meta.get("source"), tag_categories=meta.get("tag_categories", {}),
) )
self._info_panel.set_post(p) self._info_panel.set_post(p)
info = f"#{p.id} score:{p.score} [{p.rating}] {Path(path).suffix.lstrip('.').upper()}" info = f"#{p.id} score:{p.score} [{p.rating}] {Path(path).suffix.lstrip('.').upper()}" + (f" {p.created_at}" if p.created_at else "")
self._status.showMessage(info) self._status.showMessage(info)
def _on_library_selected(self, path: str) -> None: def _on_library_selected(self, path: str) -> None: