Source code for ogu_api.resources.users
from __future__ import annotations
import tls_client.response
from ..errors import OGUParseError
from ..models import UserProfile
from ._base import ResourceBase
__all__ = ['UsersResource']
[docs]
class UsersResource(ResourceBase):
"""Profile lookup by username or numeric user id.
The high-level ``get_by_*`` methods return a :class:`~ogu_api.UserProfile`
dataclass with parsed integer fields. The ``get_page_*`` variants return
the raw ``tls_client.response.Response`` so callers can feed the HTML to
the static ``extract_*`` parsers themselves.
"""
[docs]
async def get_by_username(self, username: str) -> UserProfile:
"""Fetch a user's profile by username.
Hits the slug-rewritten URL ``/{username}``.
Args:
username: Forum username (case-insensitive).
Returns:
Parsed :class:`~ogu_api.UserProfile`.
Raises:
OGUParseError: The page rendered, but no ``user_id`` could be
extracted (usually a banned, deleted, or non-existent user).
OGUNotFoundError: Profile page returned 404.
Example:
>>> user = await client.users.get_by_username('forgivenforget')
>>> print(user.user_id, user.credits, user.reputation)
"""
response = await self._http.get(f'/{username}')
return self._parse_profile(response.text)
[docs]
async def get_by_id(self, user_id: str | int) -> UserProfile:
"""Fetch a user's profile by numeric user id.
Hits ``/member.php?action=profile&uid={user_id}``.
Args:
user_id: Numeric user id (the value shown by
:meth:`extract_user_id`).
Returns:
Parsed :class:`~ogu_api.UserProfile`.
Raises:
OGUParseError: The page rendered, but no ``user_id`` could be
extracted.
"""
response = await self._http.get(f'/member.php?action=profile&uid={user_id}')
return self._parse_profile(response.text)
[docs]
async def get_page_by_username(self, username: str) -> tls_client.response.Response:
"""Fetch the raw profile-page response by username (no parsing)."""
return await self._http.get(f'/{username}')
[docs]
async def get_page_by_id(self, user_id: str | int) -> tls_client.response.Response:
"""Fetch the raw profile-page response by uid (no parsing)."""
return await self._http.get(f'/member.php?action=profile&uid={user_id}')
@classmethod
def _parse_profile(cls, page_html: str) -> UserProfile:
raw_user_id = cls.extract_user_id(page_html)
if raw_user_id is None:
raise OGUParseError('Could not extract user_id from profile page')
return UserProfile(
user_id = _to_int(raw_user_id),
username = cls.extract_username(page_html),
reputation = _to_int(cls.extract_reputation(page_html)),
vouches = _to_int(cls.extract_vouches(page_html)),
credits = _to_int(cls.extract_credits(page_html)),
)
def _to_int(value: str | None) -> int:
if value is None:
return 0
cleaned = value.replace(',', '').strip()
if cleaned.startswith(('-', '+')):
sign, body = cleaned[0], cleaned[1:]
else:
sign, body = '', cleaned
if not body.isdigit():
return 0
return int(sign + body)