Passed
Push — master ( c3d8b2...2edf0a )
by Leon
02:08
created

ck_euserv.EUserv.check()   F

Complexity

Conditions 14

Size

Total Lines 29
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 24
nop 3
dl 0
loc 29
rs 3.6
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like ck_euserv.EUserv.check() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
"""
3
:author @ZetaoYang
4
cron: 0 10 */7 * *
5
new Env('EUserv');
6
"""
7
8
import base64
9
import json
10
import re
11
import time
12
13
import requests
14
from bs4 import BeautifulSoup
15
16
from notify_mtr import send
17
from utils import get_data
18
19
#
20
# SPDX-FileCopyrightText: (c) 2020-2021 CokeMine & Its repository contributors
21
# SPDX-FileCopyrightText: (c) 2021 A beam of light
22
#
23
# SPDX-License-Identifier: GPL-3.0-or-later
24
#
25
26
"""
27
euserv auto-renew script
28
29
ChangeLog
30
31
v2021.09.30
32
- Captcha automatic recognition using TrueCaptcha API
33
- Email notification
34
- Add login failure retry mechanism
35
- reformat log info
36
37
v2021.11.06
38
- Receive renew PIN(6-digits) using mailparser parsed data download url
39
  workflow: auto-forward your EUserv PIN email to your mailparser inbox 
40
  -> parsing PIN via mailparser -> get PIN from mailparser
41
- Update kc2_security_password_get_token request
42
43
v2021.11.26
44
- Handle TrueCaptcha service exception
45
- Adjust TrueCaptcha constraint parameters for high availability.
46
  Plus, the CAPTCHA of EUserv is currently case-insensitive, so the above adjustment works.
47
48
v2021.12.15
49
- Implemented a simple localization system, log output localization
50
- Reformat code via black
51
52
"""
53
54
# default value is TrueCaptcha demo credential,
55
# you can use your own credential via set environment variables:
56
# userid and apikey
57
# demo: https://apitruecaptcha.org/demo
58
# demo2: https://apitruecaptcha.org/demo2
59
# demo apikey also has a limit of 100 times per day
60
# {
61
# 'error': '101.0 above free usage limit 100 per day and no balance',
62
# 'requestId': '7690c065-70e0-4757-839b-5fd8381e65c7'
63
# }
64
65
66
desp = ""  # 空值
67
68
# Simplified Chinese Translation
69
chs_locale = {
70
    ":": ":",
71
    ",": ",",
72
    ".": "。",
73
    "!": "!",
74
    "...": "......",
75
    "~": "~",
76
    "Login retried the @@@ time": "登录重试第 @@@ 次",
77
    "You are using the demo apikey": "你正在使用演示版 apikey",
78
    "There is no guarantee that demo apikey will work in the future": "无法保证演示版 apikey 在将来也能使用",
79
    "You are using your own apikey": "你正在使用自己的 apikey",
80
    "Service Exception": "服务异常",
81
    "Returned JSON": "返回的 JSON",
82
    "Failed to find parsed results": "找不到解析结果",
83
    "Performing CAPTCHA recognition": "进行验证码识别",
84
    "The recognized CAPTCHA is": "识别的验证码是",
85
    "current date": "当前日期",
86
    "api usage count": "api 使用次数",
87
    "CAPTCHA Verification passed": "CAPTCHA 验证通过",
88
    "CAPTCHA Verification failed": "CAPTCHA 验证失败",
89
    "PIN": "PIN",
90
    "ServerID": "服务器 ID",
91
    "Renew Failed": "续期失败",
92
    "ALL Work Done": "所有工作都已完成",
93
    "Enjoy": "使用愉快",
94
    "EUserv Renewal Logs": "EUserv 续期日志",
95
    "push failed": "推送失败",
96
    "push successfully": "推送成功",
97
    "Server Chan": "Server 酱",
98
    "Checking": "正在检查",
99
    "You have not added any accounts": "你没有添加任何账户",
100
    "The number of usernames and passwords do not match": "用户名和密码的数量不匹配",
101
    "The number of mailparser_dl_url_ids and usernames do not match": "mailparser 下载链接 id 和用户名的数量不匹配",
102
    "Renewing the @@@ account": "正在续期第 @@@ 个账号",
103
    "The @@@ account login failed": "第 @@@ 个账号登录失败",
104
    "please check the login information": "请检查登录信息",
105
    "renewals are being attempted": "正在尝试续期",
106
    "The @@@ account is detected": "检测到第 @@@ 个账号",
107
    "with @@@ VPS": "有 @@@ 台 VPS",
108
    "renew Error": "续期错误",
109
    "has been successfully renewed": "已成功续期",
110
    "does not need to be renewed": "不需要续期",
111
}
112
113
# Traditional Chinese Translation
114
cht_locale = {
115
    ":": ":",
116
    ",": ",",
117
    ".": "。",
118
    "!": "!",
119
    "...": "......",
120
    "~": "~",
121
    "Login retried the @@@ time": "登錄重試第 @@@ 次",
122
    "You are using the demo apikey": "你正在使用演示版 apikey",
123
    "There is no guarantee that demo apikey will work in the future": "無法保證演示版 apikey 在將來也能使用",
124
    "You are using your own apikey": "你正在使用你自己的 apikey",
125
    "Service Exception": "服務異常",
126
    "Returned JSON": "返回的 JSON",
127
    "Failed to find parsed results": "找不到解析結果",
128
    "Performing CAPTCHA recognition": "進行驗證碼識別",
129
    "The recognized CAPTCHA is": "識別的驗證碼是",
130
    "current date": "當前日期",
131
    "api usage count": "api 已使用次數",
132
    "CAPTCHA Verification passed": "CAPTCHA 驗證通過",
133
    "CAPTCHA Verification failed": "CAPTCHA 驗證失敗",
134
    "PIN": "PIN",
135
    "ServerID": "伺服器 ID",
136
    "Renew Failed": "續期失敗",
137
    "ALL Work Done": "所有工作都已完成",
138
    "Enjoy": "使用愉快",
139
    "EUserv Renewal Logs": "EUserv 續期日誌",
140
    "push failed": "推送失敗",
141
    "push successfully": "推送成功",
142
    "Server Chan": "Server 醬",
143
    "Checking": "正在檢查",
144
    "You have not added any accounts": "你沒有新增任何賬戶",
145
    "The number of usernames and passwords do not match": "使用者名稱和密碼的數量不匹配",
146
    "The number of mailparser_dl_url_ids and usernames do not match": "mailparser 下載連結 id 和使用者名稱的數量不匹配",
147
    "Renewing the @@@ account": "正在續期第 @@@ 個賬號",
148
    "The @@@ account login failed": "第 @@@ 個賬號登入失敗",
149
    "please check the login information": "請檢查登入資訊",
150
    "renewals are being attempted": "正在嘗試續期",
151
    "The @@@ account is detected": "檢測到第 @@@ 個賬號",
152
    "with @@@ VPS": "有 @@@ 臺 VPS",
153
    "renew Error": "續期錯誤",
154
    "has been successfully renewed": "已成功續期",
155
    "does not need to be renewed": "不需要續期",
156
}
157
158
# Localization
159
log_lang_options = {
160
    "en": lambda x: x,
161
    "chs": lambda x: chs_locale.get(x, x),
162
    "cht": lambda x: cht_locale.get(x, x),
163
}
164
165
# Language Options: en/chs/cht, or leave it blank
166
log_lang = "chs"
167
168
ordinal = lambda n: "{}{}".format(
169
    n,
170
    "tsnrhtdd"[(n / 10 % 10 != 1) * (n % 10 < 4) * n % 10 :: 4],
171
)
172
173
174
def log(info: str):
175
    global desp
176
    desp = desp + info + "\n"
177
178
179
class EUserv:
180
    def __init__(self, check_items):
181
        self.check_items = check_items
182
        self.BASE_URL = "https://support.euserv.com/index.iphp"
183
        self.UA = (
184
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
185
            "Chrome/96.0.4664.110 Safari/537.36"
186
        )
187
        self.CHECK_CAPTCHA_SOLVER_USAGE = True
188
        self.MAILPARSER_DOWNLOAD_BASE_URL = "https://files.mailparser.io/d/"
189
        self.WAITING_TIME_OF_PIN = 15
190
191
    def captcha_solver(
192
        self, captcha_image_url: str, session: requests.session, userid, apikey
193
    ) -> dict:
194
        """
195
        TrueCaptcha API doc: https://apitruecaptcha.org/api
196
        Free to use 100 requests per day.
197
        -- response::
198
        {
199
            "result": "", ==> Or "result": 0
200
            "conf": 0.85,
201
            "usage": 0,
202
            "requestId": "ed0006e5-69f0-4617-b698-97dc054f9022",
203
            "version": "dev2"
204
        }
205
        """
206
        response = session.get(captcha_image_url)
207
        encoded_string = base64.b64encode(response.content)
208
        url = "https://api.apitruecaptcha.org/one/gettext"
209
210
        # Since "case": "mixed", "mode": "human"
211
        # can sometimes cause internal errors in the truecaptcha server.
212
        # So a more relaxed constraint(lower/upper & default) is used here.
213
        # Plus, the CAPTCHA of EUserv is currently case-insensitive, so the below adjustment works.
214
        data = {
215
            "userid": userid,
216
            "apikey": apikey,
217
            # case sensitivity of text (upper | lower| mixed)
218
            "case": "lower",
219
            # use human or AI (human | default)
220
            "mode": "default",
221
            "data": str(encoded_string)[2:-1],
222
        }
223
        r = requests.post(url=url, json=data)
224
        j = json.loads(r.text)
225
        return j
226
227
    def handle_captcha_solved_result(self, solved: dict) -> str:
228
        """Since CAPTCHA sometimes appears as a very simple binary arithmetic expression.
229
        But since recognition sometimes doesn't show the result of the calculation directly,
230
        that's what this function is for.
231
        """
232
        if "result" in solved:
233
            solved_result = solved["result"]
234
            if isinstance(solved_result, str):
235
                if "RESULT  IS" in solved_result:
236
                    log(
237
                        "[Captcha Solver] {}{}".format(
238
                            log_lang_options.get(log_lang, lambda x: x)(
239
                                "You are using the demo apikey"
240
                            ),
241
                            log_lang_options.get(log_lang, lambda x: x)("."),
242
                        )
243
                    )
244
                    print(
245
                        "{}{}".format(
246
                            log_lang_options.get(log_lang, lambda x: x)(
247
                                "There is no guarantee that demo apikey will work in the future"
248
                            ),
249
                            log_lang_options.get(log_lang, lambda x: x)("!"),
250
                        )
251
                    )
252
                    # because using demo apikey
253
                    text = re.findall(r"RESULT  IS . (.*) .", solved_result)[0]
254
                else:
255
                    # using your own apikey
256
                    log(
257
                        "[Captcha Solver] {}{}".format(
258
                            log_lang_options.get(log_lang, lambda x: x)(
259
                                "You are using your own apikey"
260
                            ),
261
                            log_lang_options.get(log_lang, lambda x: x)("."),
262
                        )
263
                    )
264
                    text = solved_result
265
                operators = ["X", "x", "+", "-"]
266
                if any(x in text for x in operators):
267
                    for operator in operators:
268
                        operator_pos = text.find(operator)
269
                        if operator == "x" or operator == "X":
270
                            operator = "*"
271
                        if operator_pos != -1:
272
                            left_part = text[:operator_pos]
273
                            right_part = text[operator_pos + 1 :]
274
                            if left_part.isdigit() and right_part.isdigit():
275
                                return eval(
276
                                    "{left} {operator} {right}".format(
277
                                        left=left_part,
278
                                        operator=operator,
279
                                        right=right_part,
280
                                    )
281
                                )
282
                            else:
283
                                # Because these symbols("X", "x", "+", "-") do not appear at the same time,
284
                                # it just contains an arithmetic symbol.
285
                                return text
286
                else:
287
                    return text
288
            else:
289
                print(
290
                    "[Captcha Solver] {}{} {}".format(
291
                        log_lang_options.get(log_lang, lambda x: x)("Returned JSON"),
292
                        log_lang_options.get(log_lang, lambda x: x)(":"),
293
                        solved,
294
                    )
295
                )
296
                log(
297
                    "[Captcha Solver] {}{}".format(
298
                        log_lang_options.get(log_lang, lambda x: x)(
299
                            "Service Exception"
300
                        ),
301
                        log_lang_options.get(log_lang, lambda x: x)("!"),
302
                    )
303
                )
304
                raise ValueError("[Captcha Solver] Service Exception!")
305
        else:
306
            print(
307
                "[Captcha Solver] {}{} {}".format(
308
                    log_lang_options.get(log_lang, lambda x: x)("Returned JSON"),
309
                    log_lang_options.get(log_lang, lambda x: x)(":"),
310
                    solved,
311
                )
312
            )
313
            log(
314
                "[Captcha Solver] {}{}".format(
315
                    log_lang_options.get(log_lang, lambda x: x)(
316
                        "Failed to find parsed results"
317
                    ),
318
                    log_lang_options.get(log_lang, lambda x: x)("!"),
319
                )
320
            )
321
            raise KeyError("[Captcha Solver] Failed to find parsed results!")
322
323
    def get_captcha_solver_usage(self, userid: str, apikey: str) -> dict:
324
        url = "https://api.apitruecaptcha.org/one/getusage"
325
326
        params = {
327
            "username": userid,
328
            "apikey": apikey,
329
        }
330
        r = requests.get(url=url, params=params)
331
        j = json.loads(r.text)
332
        return j
333
334
    def get_pin_from_mailparser(self, url_id: str) -> str:
335
        """
336
        response format:
337
        [
338
        {
339
            "id": "83b95f50f6202fb03950afbe00975eab",
340
            "received_at": "2021-11-06 02:30:07",  ==> up to mailparser account timezone setting, here is UTC 0000.
341
            "processed_at": "2021-11-06 02:30:07",
342
            "pin": "123456"
343
        }
344
        ]
345
        """
346
        response = requests.get(
347
            f"{self.MAILPARSER_DOWNLOAD_BASE_URL}{url_id}",
348
            # Mailparser parsed data download using Basic Authentication.
349
            # auth=("<your mailparser username>", "<your mailparser password>")
350
        )
351
        pin = response.json()[0]["pin"]
352
        return pin
353
354
    def login(
355
        self,
356
        username: str,
357
        password: str,
358
        userid: str,
359
        apikey: str,
360
    ) -> tuple:
361
        headers = {"user-agent": self.UA, "origin": "https://www.euserv.com"}
362
        url = self.BASE_URL
363
        captcha_image_url = "https://support.euserv.com/securimage_show.php"
364
        session = requests.Session()
365
366
        sess = session.get(url, headers=headers)
367
        sess_id = re.findall("PHPSESSID=(\\w{10,100});", str(sess.headers))[0]
368
        # visit png
369
        logo_png_url = "https://support.euserv.com/pic/logo_small.png"
370
        session.get(logo_png_url, headers=headers)
371
372
        login_data = {
373
            "email": username,
374
            "password": password,
375
            "form_selected_language": "en",
376
            "Submit": "Login",
377
            "subaction": "login",
378
            "sess_id": sess_id,
379
        }
380
        f = session.post(url, headers=headers, data=login_data)
381
        f.raise_for_status()
382
383
        if (
384
            f.text.find("Hello") == -1
385
            and f.text.find("Confirm or change your customer data here") == -1
386
        ):
387
            if (
388
                f.text.find(
389
                    "To finish the login process please solve the following captcha."
390
                )
391
                == -1
392
            ):
393
                return "-1", session
394
            else:
395
                log(
396
                    "[Captcha Solver] {}{}".format(
397
                        log_lang_options.get(log_lang, lambda x: x)(
398
                            "Performing CAPTCHA recognition"
399
                        ),
400
                        log_lang_options.get(log_lang, lambda x: x)("..."),
401
                    )
402
                )
403
                solved_result = self.captcha_solver(
404
                    captcha_image_url, session, userid, apikey
405
                )
406
                try:
407
                    captcha_code = self.handle_captcha_solved_result(solved_result)
408
                    log(
409
                        "[Captcha Solver] {}{} {}".format(
410
                            log_lang_options.get(log_lang, lambda x: x)(
411
                                "The recognized CAPTCHA is"
412
                            ),
413
                            log_lang_options.get(log_lang, lambda x: x)(":"),
414
                            captcha_code,
415
                        )
416
                    )
417
418
                    if self.CHECK_CAPTCHA_SOLVER_USAGE:
419
                        usage = self.get_captcha_solver_usage(userid, apikey)
420
                        log(
421
                            "[Captcha Solver] {} {} {}{} {}".format(
422
                                log_lang_options.get(log_lang, lambda x: x)(
423
                                    "current date"
424
                                ),
425
                                usage[0]["date"],
426
                                log_lang_options.get(log_lang, lambda x: x)(
427
                                    "api usage count"
428
                                ),
429
                                log_lang_options.get(log_lang, lambda x: x)(":"),
430
                                usage[0]["count"],
431
                            )
432
                        )
433
434
                    f2 = session.post(
435
                        url,
436
                        headers=headers,
437
                        data={
438
                            "subaction": "login",
439
                            "sess_id": sess_id,
440
                            "captcha_code": captcha_code,
441
                        },
442
                    )
443
                    if (
444
                        f2.text.find(
445
                            "To finish the login process please solve the following captcha."
446
                        )
447
                        == -1
448
                    ):
449
                        log(
450
                            "[Captcha Solver] {}".format(
451
                                log_lang_options.get(log_lang, lambda x: x)(
452
                                    "CAPTCHA Verification passed"
453
                                )
454
                            )
455
                        )
456
                        return sess_id, session
457
                    else:
458
                        log(
459
                            "[Captcha Solver] {}".format(
460
                                log_lang_options.get(log_lang, lambda x: x)(
461
                                    "CAPTCHA Verification failed"
462
                                )
463
                            )
464
                        )
465
                        return "-1", session
466
                except (KeyError, ValueError):
467
                    return "-1", session
468
        else:
469
            return sess_id, session
470
471
    def get_servers(self, sess_id: str, session: requests.session) -> dict:
472
        d = {}
473
        url = f"{self.BASE_URL}?sess_id=" + sess_id
474
        headers = {"user-agent": self.UA, "origin": "https://www.euserv.com"}
475
        f = session.get(url=url, headers=headers)
476
        f.raise_for_status()
477
        soup = BeautifulSoup(f.text, "html.parser")
478
        for tr in soup.select(
479
            "#kc2_order_customer_orders_tab_content_1 .kc2_order_table.kc2_content_table tr"
480
        ):
481
            server_id = tr.select(".td-z1-sp1-kc")
482
            if not len(server_id) == 1:
483
                continue
484
            flag = (
485
                True
486
                if tr.select(".td-z1-sp2-kc .kc2_order_action_container")[0]
487
                .get_text()
488
                .find("Contract extension possible from")
489
                == -1
490
                else False
491
            )
492
            d[server_id[0].get_text()] = flag
493
        return d
494
495
    def renew(
496
        self,
497
        sess_id: str,
498
        session: requests.session,
499
        order_id: str,
500
        mailparser_dl_url_id: str,
501
    ) -> bool:
502
        url = self.BASE_URL
503
        headers = {
504
            "user-agent": self.UA,
505
            "Host": "support.euserv.com",
506
            "origin": "https://support.euserv.com",
507
            "Referer": self.BASE_URL,
508
        }
509
        data = {
510
            "Submit": "Extend contract",
511
            "sess_id": sess_id,
512
            "ord_no": order_id,
513
            "subaction": "choose_order",
514
            "choose_order_subaction": "show_contract_details",
515
        }
516
        session.post(url, headers=headers, data=data)
517
518
        # pop up 'Security Check' window, it will trigger 'send PIN' automatically.
519
        session.post(
520
            url,
521
            headers=headers,
522
            data={
523
                "sess_id": sess_id,
524
                "subaction": "show_kc2_security_password_dialog",
525
                "prefix": "kc2_customer_contract_details_extend_contract_",
526
                "type": "1",
527
            },
528
        )
529
530
        # # trigger 'Send new PIN to your Email-Address' (optional),
531
        # new_pin = session.post(url, headers=headers, data={
532
        #     "sess_id": sess_id,
533
        #     "subaction": "kc2_security_password_send_pin",
534
        #     "ident": f"kc2_customer_contract_details_extend_contract_{order_id}"
535
        # })
536
        # if not json.loads(new_pin.text)["rc"] == "100":
537
        #     print("new PIN Not Sended")
538
        #     return False
539
540
        # sleep WAITING_TIME_OF_PIN seconds waiting for mailparser email parsed PIN
541
        time.sleep(self.WAITING_TIME_OF_PIN)
542
        pin = self.get_pin_from_mailparser(mailparser_dl_url_id)
543
        log(
544
            "[MailParser] {}{} {}".format(
545
                log_lang_options.get(log_lang, lambda x: x)("PIN"),
546
                log_lang_options.get(log_lang, lambda x: x)(":"),
547
                pin,
548
            )
549
        )
550
551
        # using PIN instead of password to get token
552
        data = {
553
            "auth": pin,
554
            "sess_id": sess_id,
555
            "subaction": "kc2_security_password_get_token",
556
            "prefix": "kc2_customer_contract_details_extend_contract_",
557
            "type": 1,
558
            "ident": f"kc2_customer_contract_details_extend_contract_{order_id}",
559
        }
560
        f = session.post(url, headers=headers, data=data)
561
        f.raise_for_status()
562
        if not json.loads(f.text)["rs"] == "success":
563
            return False
564
        token = json.loads(f.text)["token"]["value"]
565
        data = {
566
            "sess_id": sess_id,
567
            "ord_id": order_id,
568
            "subaction": "kc2_customer_contract_details_extend_contract_term",
569
            "token": token,
570
        }
571
        session.post(url, headers=headers, data=data)
572
        time.sleep(5)
573
        return True
574
575
    def check(self, sess_id: str, session: requests.session):
576
        print(
577
            "{}{}".format(
578
                log_lang_options.get(log_lang, lambda x: x)("Checking"),
579
                log_lang_options.get(log_lang, lambda x: x)("..."),
580
            )
581
        )
582
        d = self.get_servers(sess_id, session)
583
        flag = True
584
        for key, val in d.items():
585
            if val:
586
                flag = False
587
                log(
588
                    "[EUserv] {}{} {} {}{}".format(
589
                        log_lang_options.get(log_lang, lambda x: x)("ServerID"),
590
                        log_lang_options.get(log_lang, lambda x: x)(":"),
591
                        key,
592
                        log_lang_options.get(log_lang, lambda x: x)("Renew Failed"),
593
                        log_lang_options.get(log_lang, lambda x: x)("!"),
594
                    )
595
                )
596
597
        if flag:
598
            log(
599
                "[EUserv] {}{} {}{}".format(
600
                    log_lang_options.get(log_lang, lambda x: x)("ALL Work Done"),
601
                    log_lang_options.get(log_lang, lambda x: x)("!"),
602
                    log_lang_options.get(log_lang, lambda x: x)("Enjoy"),
603
                    log_lang_options.get(log_lang, lambda x: x)("~"),
604
                )
605
            )
606
607
    def main(self):
608
        i = 0
609
        for check_item in self.check_items:
610
            username = check_item.get("username")
611
            password = check_item.get("password")
612
            userid = check_item.get("userid")
613
            apikey = check_item.get("apikey")
614
            mailparser_dl_url_id = check_item.get("mailparser_dl_url_id")
615
            log("*" * 12)
616
            log(
617
                "[EUserv] {}{}".format(
618
                    log_lang_options.get(log_lang, lambda x: x)(
619
                        "Renewing the @@@ account"
620
                    ).replace("@@@", ordinal(i + 1)),
621
                    log_lang_options.get(log_lang, lambda x: x)("..."),
622
                )
623
            )
624
            sessid, s = self.login(username, password, userid, apikey)
625
            if sessid == "-1":
626
                log(
627
                    "[EUserv] {}{} {}{}".format(
628
                        log_lang_options.get(log_lang, lambda x: x)(
629
                            "The @@@ account login failed"
630
                        ).replace("@@@", ordinal(i + 1)),
631
                        log_lang_options.get(log_lang, lambda x: x)(","),
632
                        log_lang_options.get(log_lang, lambda x: x)(
633
                            "please check the login information"
634
                        ),
635
                        log_lang_options.get(log_lang, lambda x: x)("."),
636
                    )
637
                )
638
                continue
639
            SERVERS = self.get_servers(sessid, s)
640
            log(
641
                "[EUserv] {} {}{} {}{}".format(
642
                    log_lang_options.get(log_lang, lambda x: x)(
643
                        "The @@@ account is detected"
644
                    ).replace("@@@", ordinal(i + 1)),
645
                    log_lang_options.get(log_lang, lambda x: x)("with @@@ VPS").replace(
646
                        "@@@", str(len(SERVERS))
647
                    ),
648
                    log_lang_options.get(log_lang, lambda x: x)(","),
649
                    log_lang_options.get(log_lang, lambda x: x)(
650
                        "renewals are being attempted"
651
                    ),
652
                    log_lang_options.get(log_lang, lambda x: x)("..."),
653
                )
654
            )
655
            for k, v in SERVERS.items():
656
                if v:
657
                    if not self.renew(sessid, s, k, mailparser_dl_url_id):
658
                        log(
659
                            "[EUserv] {}{} {} {}{}".format(
660
                                log_lang_options.get(log_lang, lambda x: x)("ServerID"),
661
                                log_lang_options.get(log_lang, lambda x: x)(":"),
662
                                k,
663
                                log_lang_options.get(log_lang, lambda x: x)(
664
                                    "renew Error"
665
                                ),
666
                                log_lang_options.get(log_lang, lambda x: x)("!"),
667
                            )
668
                        )
669
                    else:
670
                        log(
671
                            "[EUserv] {}{} {} {}{}".format(
672
                                log_lang_options.get(log_lang, lambda x: x)("ServerID"),
673
                                log_lang_options.get(log_lang, lambda x: x)(":"),
674
                                k,
675
                                log_lang_options.get(log_lang, lambda x: x)(
676
                                    "has been successfully renewed"
677
                                ),
678
                                log_lang_options.get(log_lang, lambda x: x)("!"),
679
                            )
680
                        )
681
                else:
682
                    log(
683
                        "[EUserv] {}{} {} {}{}".format(
684
                            log_lang_options.get(log_lang, lambda x: x)("ServerID"),
685
                            log_lang_options.get(log_lang, lambda x: x)(":"),
686
                            k,
687
                            log_lang_options.get(log_lang, lambda x: x)(
688
                                "does not need to be renewed"
689
                            ),
690
                            log_lang_options.get(log_lang, lambda x: x)("."),
691
                        )
692
                    )
693
            time.sleep(15)
694
            self.check(sessid, s)
695
            time.sleep(5)
696
            i += 1
697
        return desp
698
699
700
if __name__ == "__main__":
701
    data = get_data()
702
    _check_items = data.get("EUSERV", [])
703
    res = EUserv(check_items=_check_items).main()
704
    send("EUserv", res)
705