File size: 6,328 Bytes
0aee47a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
"""

bilibili_api.vote



投票相关操作。



需要 vote_id,获取 vote_id: https://nemo2011.github.io/bilibili-api/#/vote_id

"""
from enum import Enum
from typing import Union, Optional

from .utils.utils import get_api
from .utils.picture import Picture
from .utils.credential import Credential
from .utils.network import Api

API = get_api("vote")


class VoteType(Enum):
    """

    投票类型枚举类



    + TEXT: 文字投票

    + IMAGE: 图片投票

    """

    TEXT = 0
    IMAGE = 1


class VoteChoices:
    """

    投票选项类

    """

    def __init__(self) -> None:
        self.choices = []

    def add_choice(

        self, desc: str, image: Optional[Union[str, Picture]] = None

    ) -> "VoteChoices":
        """

        往 VoteChoices 添加选项



        Args:

            desc (str): 选项描述



            image (str, Picture, optional): 选项的图片链接,用于图片投票。支持 Picture 类. Defaults to None.

        """
        if isinstance(image, Picture):
            image = image.url
        self.choices.append({"desc": desc, "img_url": image})
        return self

    def remove_choice(self, index: int) -> "VoteChoices":
        """

        从 VoteChoices 移除选项



        Args:

            index (int): 选项索引

        """
        self.choices.remove(index)
        return self

    def get_choices(self) -> dict:
        """

        获取 VoteChoices 的 choices



        Returns:

            dict: choices

        """
        results = {}
        for i in range(len(self.choices)):
            choice_key_name = f"info[options][{i}]"
            results[f"{choice_key_name}[desc]"] = self.choices[i]["desc"]
            results[f"{choice_key_name}[img_url]"] = self.choices[i]["img_url"]
        return results


class Vote:
    """

    投票类



    Attributes:

        vote_id (int): vote_id, 获取:https://nemo2011.github.io/bilibili-api/#/vote_id



        credential (Credential): 凭据类

    """

    def __init__(self, vote_id: int, credential: Credential = Credential()) -> None:
        """

        Args:

            vote_id (int): vote_id, 获取:https://nemo2011.github.io/bilibili-api/#/vote_id



            credential (Credential): 凭据类,非必要.

        """
        self.__vote_id = vote_id
        self.credential = credential
        self.title: Optional[str] = None

    def get_vote_id(self) -> int:
        return self.__vote_id

    def get_info_sync(self) -> dict:
        """

        获取投票详情



        Returns:

            dict: 调用 API 返回的结果

        """
        api = API["info"]["vote_info"]
        params = {"vote_id": self.get_vote_id()}
        info = Api(**api, params=params).result_sync
        self.title = info["info"]["title"]  # 为 dynmaic.BuildDnamic.add_vote 缓存 title
        return info

    async def get_info(self) -> dict:
        """

        获取投票详情



        Returns:

            dict: 调用 API 返回的结果

        """
        api = API["info"]["vote_info"]
        params = {"vote_id": self.get_vote_id()}
        info = await Api(**api).update_params(**params).result
        self.title = info["info"]["title"]  # 为 dynmaic.BuildDnamic.add_vote 缓存 title
        return info

    async def get_title(self) -> str:
        """

        快速获取投票标题



        Returns:

            str: 投票标题

        """
        if self.title is None:
            return (await self.get_info())["info"]["title"]
        return self.title

    async def update_vote(

        self,

        title: str,

        _type: VoteType,

        choice_cnt: int,

        duration: int,

        choices: VoteChoices,

        desc: Optional[str] = None,

    ) -> dict:
        """

        更新投票内容



        Args:

            vote_id (int): vote_id



            title (str): 投票标题



            _type (VoteType): 投票类型



            choice_cnt (int): 最多几项



            duration (int): 投票持续秒数 常用: 三天:259200 七天:604800 三十天:2592000



            choices (VoteChoices): 投票选项



            credential (Credential): Credential 枚举类



            desc (Optional[str], optional): 投票描述. Defaults to None.



        Returns:

            dict: 调用 API 返回的结果

        """
        self.credential.raise_for_no_sessdata()
        api = API["operate"]["update"]
        data = {
            "info[title]": title,
            "info[desc]": desc,
            "info[type]": _type.value,
            "info[choice_cnt]": choice_cnt,
            "info[duration]": duration,
            "info[vote_id]": self.get_vote_id(),
        }
        data.update(choices.get_choices())
        if choice_cnt > len(choices.choices):
            raise ValueError("choice_cnt 大于 choices 选项数")
        return await Api(**api, credential=self.credential).update_data(**data).result


async def create_vote(

    title: str,

    _type: VoteType,

    choice_cnt: int,

    duration: int,

    choices: VoteChoices,

    credential: Credential,

    desc: Optional[str] = None,

) -> Vote:
    """

    创建投票



    Args:

        title (str): 投票标题



        _type (VoteType): 投票类型



        choice_cnt (int): 最多几项



        duration (int): 投票持续秒数 常用: 三天:259200 七天:604800 三十天:2592000



        choices (VoteChoices): 投票选项



        credential (Credential): Credential



        desc (Optional[str], optional): 投票描述. Defaults to None.



    Returns:

        Vote: Vote 类

    """
    api = API["operate"]["create"]
    data = {
        "info[title]": title,
        "info[desc]": desc,
        "info[type]": _type.value,
        "info[choice_cnt]": choice_cnt,
        "info[duration]": duration,
    }
    data.update(choices.get_choices())
    if choice_cnt > len(choices.choices):
        raise ValueError("choice_cnt 大于 choices 选项数")
    vote_id = (await Api(**api, credential=credential).update_data(**data).result)[
        "vote_id"
    ]
    return Vote(vote_id=vote_id, credential=credential)