wikidot.module.site_member のソースコード

"""
Wikidotサイトのメンバーを扱うモジュール

このモジュールは、Wikidotサイトのメンバーに関連するクラスや機能を提供する。
メンバーの情報取得や権限変更などの操作が可能。
"""

from dataclasses import dataclass
from datetime import datetime
from typing import TYPE_CHECKING

from bs4 import BeautifulSoup

from ..common.exceptions import (
    TargetErrorException,
    WikidotStatusCodeException,
)
from ..util.parser import odate as odate_parser
from ..util.parser import user as user_parser

if TYPE_CHECKING:
    from .site import Site
    from .user import AbstractUser


[ドキュメント] @dataclass class SiteMember: """ Wikidotサイトのメンバーを表すクラス サイトのメンバー情報を保持し、権限変更などの操作機能を提供する。 Attributes ---------- site : Site メンバーが所属するサイト user : AbstractUser メンバーユーザー joined_at : datetime | None サイトへの参加日時(取得できない場合はNone) """ site: "Site" user: "AbstractUser" joined_at: datetime | None @staticmethod def _parse(site: "Site", html: BeautifulSoup) -> list["SiteMember"]: """ メンバーリストページのHTMLからメンバー情報を抽出する内部メソッド Parameters ---------- site : Site メンバーが所属するサイト html : BeautifulSoup 解析対象のHTML Returns ------- list[SiteMember] 抽出されたメンバーのリスト """ members: list["SiteMember"] = [] for row in html.select("table tr"): tds = row.select("td") user_elem = tds[0].select_one(".printuser") if user_elem is None: continue user = user_parser(site.client, user_elem) # tdsが2つあったら加入日時がある if len(tds) == 2: joined_at_elem = tds[1].select_one(".odate") if joined_at_elem is None: joined_at = None else: joined_at = odate_parser(joined_at_elem) else: joined_at = None members.append(SiteMember(site, user, joined_at)) return members
[ドキュメント] @staticmethod def get(site: "Site", group: str | None = None) -> list["SiteMember"]: """ サイトのメンバーリストを取得する 指定したグループ(管理者、モデレーターなど)のメンバー一覧を取得する。 Parameters ---------- site : Site メンバーリストを取得するサイト group : str | None, default None 取得するメンバーのグループ("admins", "moderators", または "" で全メンバー) Returns ------- list[SiteMember] メンバーのリスト Raises ------ ValueError 無効なグループが指定された場合 """ if group is None: group = "" if group not in ["admins", "moderators", ""]: raise ValueError("Invalid group") members: list["SiteMember"] = [] first_response = site.amc_request( [ { "moduleName": "membership/MembersListModule", "page": 1, "group": group, } ] )[0] first_body = first_response.json()["body"] first_html = BeautifulSoup(first_body, "lxml") members.extend(SiteMember._parse(site, first_html)) pager = first_html.select_one("div.pager") if pager is None: return members last_page = int(pager.select("a")[-2].text) if last_page == 1: return members responses = site.amc_request( [ { "moduleName": "membership/MembersListModule", "page": page, "group": group, } for page in range(2, last_page + 1) ] ) for response in responses: body = response.json()["body"] html = BeautifulSoup(body, "lxml") members.extend(SiteMember._parse(site, html)) return members
def _change_group(self, event: str): """ メンバーのグループ(権限)を変更する内部メソッド モデレーターや管理者への昇格、または降格を行う共通メソッド。 Parameters ---------- event : str 変更イベント("toModerators", "removeModerator", "toAdmins", "removeAdmin") Raises ------ ValueError 無効なイベントが指定された場合 ForbiddenException 権限不足の場合 TargetErrorException ユーザーが既に指定された権限を持っている、または持っていない場合 WikidotStatusCodeException その他のエラーが発生した場合 """ if event not in [ "toModerators", "removeModerator", "toAdmins", "removeAdmin", ]: raise ValueError("Invalid event") try: self.site.amc_request( [ { "action": "ManageSiteMembershipAction", "event": event, "user_id": self.user.id, "moduleName": "", } ] ) except WikidotStatusCodeException as e: if e.status_code == "not_already": raise TargetErrorException(f"User is not moderator/admin: {self.user.name}") from e if e.status_code in ("already_admin", "already_moderator"): raise TargetErrorException( f"User is already {e.status_code.removeprefix('already_')}: {self.user.name}" ) from e raise e
[ドキュメント] def to_moderator(self): """ メンバーをモデレーターに昇格させる Raises ------ ForbiddenException 権限不足の場合 TargetErrorException ユーザーが既にモデレーターである場合 WikidotStatusCodeException その他のエラーが発生した場合 """ self._change_group("toModerators")
[ドキュメント] def remove_moderator(self): """ メンバーのモデレーター権限を削除する Raises ------ ForbiddenException 権限不足の場合 TargetErrorException ユーザーがモデレーターでない場合 WikidotStatusCodeException その他のエラーが発生した場合 """ self._change_group("removeModerator")
[ドキュメント] def to_admin(self): """ メンバーを管理者に昇格させる Raises ------ ForbiddenException 権限不足の場合 TargetErrorException ユーザーが既に管理者である場合 WikidotStatusCodeException その他のエラーが発生した場合 """ self._change_group("toAdmins")
[ドキュメント] def remove_admin(self): """ メンバーの管理者権限を削除する Raises ------ ForbiddenException 権限不足の場合 TargetErrorException ユーザーが管理者でない場合 WikidotStatusCodeException その他のエラーが発生した場合 """ self._change_group("removeAdmin")