-
Notifications
You must be signed in to change notification settings - Fork 68
/
FNplus.py
151 lines (124 loc) · 4.3 KB
/
FNplus.py
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
"""
cron: 25 7 */10 * *
new Env('Freenom 续期消息版');
"""
import argparse
import os
import re
import requests
# 登录地址
LOGIN_URL = "https://my.freenom.com/dologin.php"
# 域名状态地址
DOMAIN_STATUS_URL = "https://my.freenom.com/domains.php?a=renewals"
# 域名续期地址
RENEW_DOMAIN_URL = "https://my.freenom.com/domains.php?submitrenewals=true"
# token 正则
token_ptn = re.compile('name="token" value="(.*?)"', re.I)
# 域名信息正则
domain_info_ptn = re.compile(
r'<tr><td>(.*?)</td><td>[^<]+</td><td>[^<]+<span class="[^<]+>(\d+?).Days</span>[^&]+&domain=(\d+?)">.*?</tr>',
re.I,
)
# 登录状态正则
login_status_ptn = re.compile('<a href="logout.php">Logout</a>', re.I)
def qlnotify(desp):
cur_path = os.path.abspath(os.path.dirname(__file__))
if os.path.exists(f"{cur_path}/notify.py"):
try:
from notify import send # type: ignore
except Exception:
print("加载通知服务失败~")
else:
send("Freenom 续期", desp)
class FreeNom:
def __init__(self, username: str, password: str):
self._u = username
self._p = password
self._s = requests.session()
self._s.headers.update(
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/79.0.3945.130 Safari/537.36"
}
)
def _login(self) -> bool:
self._s.headers.update(
{
"content-type": "application/x-www-form-urlencoded",
"referer": "https://my.freenom.com/clientarea.php",
}
)
r = self._s.post(LOGIN_URL, data={"username": self._u, "password": self._p})
return r.status_code == 200
def renew(self) -> str:
msg = ""
# login
if not self._login():
msg = "login failed"
print(msg)
return msg
# check domain status
self._s.headers.update({"referer": "https://my.freenom.com/clientarea.php"})
r = self._s.get(DOMAIN_STATUS_URL)
# login status check
if not re.search(login_status_ptn, r.text):
msg = "get login status failed"
print(msg)
return msg
# page token
match = re.search(token_ptn, r.text)
if not match:
msg = "get page token failed"
print(msg)
return msg
token = match[1]
# domains
domains = re.findall(domain_info_ptn, r.text)
# renew domains
for domain, days, renewal_id in domains:
if int(days) < 14:
self._s.headers.update(
{
"referer": f"https://my.freenom.com/domains.php?a=renewdomain&domain={renewal_id}",
"content-type": "application/x-www-form-urlencoded",
}
)
r = self._s.post(
RENEW_DOMAIN_URL,
data={
"token": token,
"renewalid": renewal_id,
f"renewalperiod[{renewal_id}]": "12M",
"paymentmethod": "credit",
},
)
result = (
f"{domain} 续期成功"
if r.text.find("Order Confirmation") != -1
else f"{domain} 续期失败"
)
print(result)
msg += result + "\n"
result = f"{domain} 还有 {days} 天续期"
print(result)
msg += result + "\n"
return msg
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--username", type=str)
parser.add_argument("-p", "--password", type=str)
args = parser.parse_args()
username = args.username or os.getenv("FN_ID")
password = args.password or os.getenv("FN_PW")
if not username or not password:
print("你没有添加任何账户")
exit(1)
user_list = username.strip().split()
passwd_list = password.strip().split()
if len(user_list) != len(passwd_list):
print("账户与密码不匹配")
exit(1)
for i in range(len(user_list)):
freenom = FreeNom(user_list[i], passwd_list[i])
qlnotify(freenom.renew())
if __name__ == "__main__":
main()