Source code for ogu_api.models
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
__all__ = [
'UserProfile',
'ReputationPage',
'ActionResult',
'Message',
'RecentTransaction',
'ThreadSummary',
'Inbox',
'Post',
'Thread',
]
[docs]
@dataclass(frozen = True)
class UserProfile:
"""Parsed forum profile.
Returned by :meth:`UsersResource.get_by_username` and
:meth:`UsersResource.get_by_id`. Numeric fields default to ``0`` when the
profile page doesn't render them (e.g. brand-new accounts).
Attributes:
user_id: Numeric user id (the value shown in the ``#profileLink``
anchor).
username: Canonical-cased username.
reputation: Positive reputation count.
vouches: Vouch count.
credits: Current credits balance.
"""
user_id: int
username: str | None = None
reputation: int = 0
vouches: int = 0
credits: int = 0
[docs]
@dataclass(frozen = True)
class ReputationPage:
"""Parsed reputation modal for a target user.
Attributes:
values: Allowed reputation values, e.g. ``('-1', '0', '1')``. Empty
when the current account can't rep this target (yourself, or a
cooldown applies).
hidden: Hidden form fields needed to POST a reputation.
"""
values: tuple[str, ...] = ()
hidden: dict[str, Any] = field(default_factory = dict)
[docs]
@dataclass(frozen = True)
class ActionResult:
"""Generic result for state-changing operations.
Currently only used by helpers in user code. Most resource methods
return raw responses so callers can branch on body content.
"""
success: bool
message: str = ''
[docs]
@dataclass(frozen = True)
class Message:
"""A row in the PM inbox table.
Attributes:
username: Other party's username.
date: UTC unix timestamp of the message; ``0`` if the date column
couldn't be parsed.
message: Message preview text.
"""
username: str
date: int
message: str
[docs]
@dataclass(frozen = True)
class RecentTransaction:
"""A row in the public ``/credits.php?action=stats`` recently-sent table.
Attributes:
sender: Donor username.
recipient: Recipient username.
amount: Credits transferred.
date: UTC unix timestamp of the transaction; ``0`` on parse failure.
"""
sender: str
recipient: str
amount: int
date: int
[docs]
@dataclass(frozen = True)
class ThreadSummary:
"""A thread reference extracted from a feed / forum / search page.
Attributes:
title: Visible thread title.
link: URL path. Either ``/showthread.php?tid=N&...`` (numeric) or
``/Thread-Slug-...`` (rewritten). Pass to
:meth:`ThreadsResource.get_by_link` to fetch.
tid: Numeric thread id when one is recoverable from the link or
from a sibling anchor in the same row. ``None`` for explore
slug-only entries.
"""
title: str
link: str
tid: int | None = None
[docs]
@dataclass(frozen = True)
class Post:
"""A single post inside a thread.
Attributes:
pid: Post id.
author: Username of the poster.
author_id: Numeric user id of the poster, or ``None`` if it couldn't
be recovered from the post header.
body: Post body text only (signature stripped out, HTML reduced to
plain text).
date: UTC unix timestamp of the post; ``0`` on parse failure.
date_label: Original date string from the page (``'Yesterday'``,
``'2 hours ago'``, ``'05-06-2026, 04:23 PM'`` etc.) for display.
signature: The poster's signature text (empty if none).
"""
pid: int
author: str | None
author_id: int | None
body: str
date: int
date_label: str = ''
signature: str = ''
[docs]
@dataclass(frozen = True)
class Thread:
"""A parsed thread page.
Returned by :meth:`ThreadsResource.read`. Multi-page threads can be
fetched one page at a time; ``page`` and ``total_pages`` reflect the
current view.
Attributes:
tid: Thread id.
title: Thread subject (best-effort: from the page ``<title>`` tag,
stripped of the trailing ``" | OGU"`` suffix).
posts: Posts on the current page, in display order.
page: 1-indexed current page number.
total_pages: Total page count when discoverable, else ``1``.
"""
tid: int
title: str
posts: tuple[Post, ...]
page: int = 1
total_pages: int = 1
[docs]
@dataclass(frozen = True)
class Inbox:
"""Parsed inbox page.
Returned by :meth:`MessagesResource.inbox`. ``my_post_key`` is the form
CSRF token used by every state-changing call across the SDK; you can
cache it from a single inbox fetch and reuse across many sends.
Attributes:
messages: Inbox rows (newest first).
conversation_ids: Opaque conversation ids deduped from anchor hrefs.
my_post_key: CSRF token from the page; ``None`` if the inbox
failed to render (e.g. session expired).
"""
messages: tuple[Message, ...] = ()
conversation_ids: tuple[str, ...] = ()
my_post_key: str | None = None