Add post date to info line
This commit is contained in:
parent
e22cde2a27
commit
8467c0696b
@ -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."""
|
||||||
|
|
||||||
|
|||||||
@ -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]:
|
||||||
|
|||||||
@ -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]:
|
||||||
|
|||||||
@ -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]:
|
||||||
|
|||||||
@ -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]:
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user