File size: 6,416 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
"""

bilibili_api.login_func



登录功能相关

"""

import enum
import threading
from typing import Tuple, Union

from . import login
from .utils.utils import get_api
from .exceptions import LoginError
import urllib.parse
from .utils.picture import Picture
from .utils.credential import Credential

API = get_api("login")


class QrCodeLoginEvents(enum.Enum):
    """

    二维码登录状态枚举



    + SCAN: 未扫描二维码

    + CONF: 未确认登录

    + TIMEOUT: 二维码过期

    + DONE: 成功

    """

    SCAN = "scan"
    CONF = "confirm"
    TIMEOUT = "timeout"
    DONE = "done"


def get_qrcode() -> Tuple[Picture, str]:
    """

    获取二维码及登录密钥(后面有用)



    Returns:

        Tuple[Picture, str]: 第一项是二维码图片地址(本地缓存)和登录密钥。登录密钥需要保存。

    """
    login_data = login.update_qrcode_data()
    login_key = login_data["qrcode_key"]
    img = login.make_qrcode(login_data["url"])
    return (Picture.from_file(img), login_key)


def check_qrcode_events(login_key: str) -> Tuple[QrCodeLoginEvents, Union[str, Credential]]:
    """

    检查登录状态。(建议频率 1s,这个 API 也有风控!)



    Args:

        login_key (str): 登录密钥(get_qrcode 的返回值第二项)



    Returns:

        Tuple[QrCodeLoginEvents, str|Credential]: 状态(第一项)和信息(第二项)(如果成功登录信息为凭据类)

    """
    events = login.login_with_key(login_key)

    if events["code"] == 86101:
        return QrCodeLoginEvents.SCAN, events["message"]
    elif events["code"] == 86090:
        return QrCodeLoginEvents.CONF, events["message"]
    elif events["code"] == 86038:
        return QrCodeLoginEvents.TIMEOUT, events["message"]
    elif events["code"] == 0:
        url: str = events["data"]["url"]
        cookies_list = url.split("?")[1].split("&")
        sessdata = ""
        bili_jct = ""
        dede = ""
        for cookie in cookies_list:
            if cookie[:8] == "SESSDATA":
                sessdata = cookie[9:]
            if cookie[:8] == "bili_jct":
                bili_jct = cookie[9:]
            if cookie[:11].upper() == "DEDEUSERID=":
                dede = cookie[11:]
        c = Credential(sessdata, bili_jct, dedeuserid=dede)
        return QrCodeLoginEvents.DONE, c
    else:
        raise LoginError(events["message"])


def get_tv_qrcode() -> Tuple[Picture, str]:
    """

    获取 TV 端登录二维码及登录密钥(后面有用)



    Returns:

        Tuple[Picture, str]: 第一项是二维码图片地址(本地缓存)和登录密钥。登录密钥需要保存。

    """
    qrcode_data = login.update_tv_qrcode_data()
    qrcode_url = qrcode_data["url"]
    auth_code = qrcode_data["auth_code"]
    img = login.make_qrcode(qrcode_url)
    return (Picture.from_file(img), auth_code)


def check_tv_qrcode_events(auth_code: str) -> Tuple[QrCodeLoginEvents, Union[str, Credential]]:
    """

    检查登录状态。



    Args:

        auth_code (str): 登录密钥



    Returns:

        Tuple[QrCodeLoginEvents, str|Credential]: 状态(第一项)和信息(第二项)(如果成功登录信息为凭据类)

    """
    events = login.verify_tv_login_status(auth_code=auth_code)

    if events["code"] == 86039:
        return QrCodeLoginEvents.SCAN, events["message"]
    elif events["code"] == 86038:
        return QrCodeLoginEvents.TIMEOUT, events["message"]
    elif events["code"] == 0:
        c = login.parse_tv_resp(events["data"])
        return QrCodeLoginEvents.DONE, c
    else:
        raise LoginError(events["message"])


def start_geetest_server() -> "ServerThreadModel":
    """

    验证码服务打开服务器



    Returns:

        ServerThread: 服务进程,将自动开启



    返回值内函数及属性:

        (继承:threading.Thread)

        - url   (str)     : 验证码服务地址

        - start (Callable): 开启进程

        - stop  (Callable): 结束进程



    ``` python

    print(start_geetest_server().url)

    ```

    """
    return login.start_server()  # type: ignore


def close_geetest_server() -> None:
    """

    关闭极验验证服务(打开极验验证服务后务必关闭掉它,否则会卡住)

    """
    return login.close_server()


def done_geetest() -> bool:
    """

    检查是否完成了极验验证。



    如果没有完成极验验证码就开始短信登录发送短信,那么可能会让你的项目卡住。



    Returns:

        bool: 是否完成极验验证

    """
    result = login.get_result()
    if result != -1:
        return True
    else:
        return False


def safecenter_start_geetest_server() -> "ServerThreadModel":
    """

    登录验证专用函数:验证码服务打开服务器



    Returns:

        ServerThread: 服务进程,将自动开启



    返回值内函数及属性:

        (继承:threading.Thread)

        - url   (str)     : 验证码服务地址

        - start (Callable): 开启进程

        - stop  (Callable): 结束进程



    ``` python

    print(start_geetest_server().url)

    ```

    """
    return login.safecenter_start_server()  # type: ignore


def safecenter_close_geetest_server() -> None:
    """

    登录验证专用函数:关闭极验验证服务(打开极验验证服务后务必关闭掉它,否则会卡住)

    """
    return login.safecenter_close_server()


def safecenter_done_geetest() -> bool:
    """

    登录验证专用函数:检查是否完成了极验验证。



    如果没有完成极验验证码就开始短信登录发送短信,那么可能会让你的项目卡住。



    Returns:

        bool: 是否完成极验验证

    """
    result = login.safecenter_get_result()
    if result != -1:
        return True
    else:
        return False


COUNTRIES_LIST = login.get_countries_list()
countries_list = COUNTRIES_LIST


class ServerThreadModel(threading.Thread):
    """

    A simple model for bilibili_api.utils.captcha._start_server.ServerThread.

    """

    url: str

    def __init__(self, *args, **kwargs):
        ...

    def stop(self):
        """Stop the server and this thread nicely"""