podflow 2025.1.26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Podflow/__init__.py +137 -0
- Podflow/basic/__init__.py +2 -0
- Podflow/basic/file_save.py +21 -0
- Podflow/basic/folder_build.py +16 -0
- Podflow/basic/get_duration.py +18 -0
- Podflow/basic/get_file_list.py +57 -0
- Podflow/basic/get_html_dict.py +30 -0
- Podflow/basic/http_client.py +75 -0
- Podflow/basic/list_merge_tidy.py +15 -0
- Podflow/basic/qr_code.py +55 -0
- Podflow/basic/split_dict.py +14 -0
- Podflow/basic/time_format.py +16 -0
- Podflow/basic/time_stamp.py +61 -0
- Podflow/basic/vary_replace.py +11 -0
- Podflow/basic/write_log.py +43 -0
- Podflow/bilibili/__init__.py +2 -0
- Podflow/bilibili/build.py +201 -0
- Podflow/bilibili/get.py +477 -0
- Podflow/bilibili/login.py +307 -0
- Podflow/config/__init__.py +2 -0
- Podflow/config/build_original.py +41 -0
- Podflow/config/channge_icon.py +163 -0
- Podflow/config/correct_channelid.py +230 -0
- Podflow/config/correct_config.py +103 -0
- Podflow/config/get_channelid.py +22 -0
- Podflow/config/get_channelid_id.py +21 -0
- Podflow/config/get_config.py +34 -0
- Podflow/download/__init__.py +2 -0
- Podflow/download/convert_bytes.py +18 -0
- Podflow/download/delete_part.py +20 -0
- Podflow/download/dl_aideo_video.py +307 -0
- Podflow/download/show_progress.py +46 -0
- Podflow/download/wait_animation.py +34 -0
- Podflow/download/youtube_and_bilibili_download.py +30 -0
- Podflow/ffmpeg_judge.py +45 -0
- Podflow/httpfs/__init__.py +2 -0
- Podflow/httpfs/app_bottle.py +212 -0
- Podflow/httpfs/port_judge.py +21 -0
- Podflow/main.py +248 -0
- Podflow/makeup/__init__.py +2 -0
- Podflow/makeup/del_makeup_yt_format_fail.py +19 -0
- Podflow/makeup/make_up_file.py +51 -0
- Podflow/makeup/make_up_file_format_mod.py +96 -0
- Podflow/makeup/make_up_file_mod.py +30 -0
- Podflow/message/__init__.py +2 -0
- Podflow/message/backup_zip_save.py +45 -0
- Podflow/message/create_main_rss.py +44 -0
- Podflow/message/display_qrcode_and_url.py +36 -0
- Podflow/message/fail_message_initialize.py +165 -0
- Podflow/message/format_time.py +27 -0
- Podflow/message/get_original_rss.py +65 -0
- Podflow/message/get_video_format.py +111 -0
- Podflow/message/get_video_format_multithread.py +42 -0
- Podflow/message/get_youtube_and_bilibili_video_format.py +87 -0
- Podflow/message/media_format.py +195 -0
- Podflow/message/original_rss_fail_print.py +15 -0
- Podflow/message/rss_create_hash.py +26 -0
- Podflow/message/title_correction.py +30 -0
- Podflow/message/update_information_display.py +72 -0
- Podflow/message/update_youtube_bilibili_rss.py +116 -0
- Podflow/message/want_retry.py +21 -0
- Podflow/message/xml_item.py +83 -0
- Podflow/message/xml_original_item.py +92 -0
- Podflow/message/xml_rss.py +46 -0
- Podflow/netscape/__init__.py +2 -0
- Podflow/netscape/bulid_netscape.py +44 -0
- Podflow/netscape/get_cookie_dict.py +21 -0
- Podflow/parse_arguments.py +80 -0
- Podflow/remove/__init__.py +2 -0
- Podflow/remove/remove_dir.py +33 -0
- Podflow/remove/remove_file.py +23 -0
- Podflow/youtube/__init__.py +2 -0
- Podflow/youtube/build.py +287 -0
- Podflow/youtube/get.py +376 -0
- Podflow/youtube/login.py +39 -0
- podflow-2025.1.26.dist-info/METADATA +214 -0
- podflow-2025.1.26.dist-info/RECORD +80 -0
- podflow-2025.1.26.dist-info/WHEEL +5 -0
- podflow-2025.1.26.dist-info/entry_points.txt +6 -0
- podflow-2025.1.26.dist-info/top_level.txt +1 -0
@@ -0,0 +1,307 @@
|
|
1
|
+
# Podflow/bilibili/login.py
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
import binascii
|
5
|
+
import json
|
6
|
+
import os
|
7
|
+
import re
|
8
|
+
import time
|
9
|
+
from datetime import datetime
|
10
|
+
import requests
|
11
|
+
from Cryptodome.Cipher import PKCS1_OAEP
|
12
|
+
from Cryptodome.Hash import SHA256
|
13
|
+
from Cryptodome.PublicKey import RSA
|
14
|
+
from Podflow.basic.file_save import file_save
|
15
|
+
from Podflow.basic.http_client import http_client
|
16
|
+
from Podflow.basic.qr_code import qr_code
|
17
|
+
from Podflow.basic.time_stamp import time_stamp
|
18
|
+
from Podflow.basic.write_log import write_log
|
19
|
+
from Podflow.netscape.bulid_netscape import bulid_netscape
|
20
|
+
|
21
|
+
|
22
|
+
# 获取最新的img_key和sub_key模块
|
23
|
+
def getWbiKeys(bilibili_cookie=None):
|
24
|
+
bilibili_url = "https://api.bilibili.com/x/web-interface/nav"
|
25
|
+
if resp := http_client(
|
26
|
+
bilibili_url, "获取最新的img_key和sub_key", 10, 4, True, bilibili_cookie
|
27
|
+
):
|
28
|
+
resp.raise_for_status()
|
29
|
+
json_content = resp.json()
|
30
|
+
img_url: str = json_content["data"]["wbi_img"]["img_url"]
|
31
|
+
sub_url: str = json_content["data"]["wbi_img"]["sub_url"]
|
32
|
+
img_key = img_url.rsplit("/", 1)[1].split(".")[0]
|
33
|
+
sub_key = sub_url.rsplit("/", 1)[1].split(".")[0]
|
34
|
+
return img_key, sub_key
|
35
|
+
else:
|
36
|
+
return "", ""
|
37
|
+
|
38
|
+
|
39
|
+
# 申请哔哩哔哩二维码并获取token和URL模块
|
40
|
+
def bilibili_request_qr_code():
|
41
|
+
# 实际申请二维码的API请求
|
42
|
+
response = http_client(
|
43
|
+
"https://passport.bilibili.com/x/passport-login/web/qrcode/generate",
|
44
|
+
"申请BiliBili二维码",
|
45
|
+
3,
|
46
|
+
5,
|
47
|
+
True,
|
48
|
+
)
|
49
|
+
data = response.json()
|
50
|
+
return data["data"]["qrcode_key"], data["data"]["url"]
|
51
|
+
|
52
|
+
|
53
|
+
# 扫码登录哔哩哔哩并返回状态和cookie模块
|
54
|
+
def bilibili_scan_login(token):
|
55
|
+
# 发送GET请求
|
56
|
+
response = http_client(
|
57
|
+
"https://passport.bilibili.com/x/passport-login/web/qrcode/poll",
|
58
|
+
"",
|
59
|
+
1,
|
60
|
+
1,
|
61
|
+
True,
|
62
|
+
None,
|
63
|
+
{"qrcode_key": token},
|
64
|
+
)
|
65
|
+
if not response:
|
66
|
+
return None, None, None
|
67
|
+
data = response.json()
|
68
|
+
return data["data"]["code"], response.cookies, data["data"]["refresh_token"]
|
69
|
+
|
70
|
+
|
71
|
+
# 登陆哔哩哔哩模块
|
72
|
+
def bilibili_login():
|
73
|
+
buvid3_and_bnut = http_client(
|
74
|
+
"https://www.bilibili.com", "哔哩哔哩主页", 10, 4, True
|
75
|
+
).cookies.get_dict()
|
76
|
+
token, url = bilibili_request_qr_code()
|
77
|
+
print(f"{datetime.now().strftime('%H:%M:%S')}|请用BiliBili App扫描登录:")
|
78
|
+
upward = qr_code(url)
|
79
|
+
login_status_change = ""
|
80
|
+
time_print = f"{datetime.now().strftime('%H:%M:%S')}|BiliBili "
|
81
|
+
while True:
|
82
|
+
status, cookie, refresh_token = bilibili_scan_login(token)
|
83
|
+
if status == 86101:
|
84
|
+
login_status = "\033[0m未扫描\033[0m"
|
85
|
+
elif status == 86038:
|
86
|
+
login_status = "\033[31m二维码超时, 请重试\033[0m"
|
87
|
+
elif status == 86090:
|
88
|
+
login_status = "\033[32m扫描成功\033[0m"
|
89
|
+
elif status == 0:
|
90
|
+
login_status = "\033[32m登陆成功\033[0m"
|
91
|
+
else:
|
92
|
+
login_status = "\033[31m错误\033[0m"
|
93
|
+
if login_status_change != login_status:
|
94
|
+
if login_status == "":
|
95
|
+
print(f"{time_print}{login_status}".ljust(42), end="")
|
96
|
+
else:
|
97
|
+
print(f"\r{time_print}{login_status}".ljust(42), end="")
|
98
|
+
login_status_change = login_status
|
99
|
+
if status == 86038:
|
100
|
+
print("")
|
101
|
+
return status, refresh_token, upward
|
102
|
+
elif status == 0:
|
103
|
+
print("")
|
104
|
+
cookie["buvid3"] = buvid3_and_bnut.get("buvid3", "")
|
105
|
+
cookie["b_nut"] = buvid3_and_bnut.get("b_nut", "")
|
106
|
+
return cookie, refresh_token, upward
|
107
|
+
time.sleep(1)
|
108
|
+
|
109
|
+
|
110
|
+
# 保存哔哩哔哩登陆成功后的cookies模块
|
111
|
+
def save_bilibili_cookies():
|
112
|
+
bilibili_cookie, refresh_token, upward = bilibili_login()
|
113
|
+
if bilibili_cookie == 86038:
|
114
|
+
return {"cookie": None}, upward
|
115
|
+
bilibili_cookie = requests.utils.dict_from_cookiejar(bilibili_cookie)
|
116
|
+
bilibili_data = {"cookie": bilibili_cookie, "refresh_token": refresh_token}
|
117
|
+
bulid_netscape("yt_dlp_bilibili", bilibili_cookie)
|
118
|
+
return bilibili_data, upward
|
119
|
+
|
120
|
+
|
121
|
+
# 检查哔哩哔哩是否需要刷新模块
|
122
|
+
def judgment_bilibili_update(cookies):
|
123
|
+
url = "https://passport.bilibili.com/x/passport-login/web/cookie/info"
|
124
|
+
response = http_client(url, "BiliBili刷新判断", 3, 5, True, cookies)
|
125
|
+
response = response.json()
|
126
|
+
if response["code"] == 0:
|
127
|
+
return response["code"], response["data"]["refresh"]
|
128
|
+
else:
|
129
|
+
return response["code"], None
|
130
|
+
|
131
|
+
|
132
|
+
# 生成CorrespondPath模块
|
133
|
+
def getCorrespondPath(ts, key):
|
134
|
+
cipher = PKCS1_OAEP.new(key, SHA256)
|
135
|
+
encrypted = cipher.encrypt(f"refresh_{ts}".encode())
|
136
|
+
return binascii.b2a_hex(encrypted).decode()
|
137
|
+
|
138
|
+
|
139
|
+
def bilibili_cookie_update_data(
|
140
|
+
bilibili_cookie, new_bilibili_cookie, bilibili_data, new_refresh_token
|
141
|
+
):
|
142
|
+
new_bilibili_cookie["buvid3"] = bilibili_cookie["buvid3"]
|
143
|
+
new_bilibili_cookie["b_nut"] = bilibili_cookie["b_nut"]
|
144
|
+
bilibili_data["cookie"] = new_bilibili_cookie
|
145
|
+
bilibili_data["refresh_token"] = new_refresh_token
|
146
|
+
bulid_netscape("yt_dlp_bilibili", new_bilibili_cookie)
|
147
|
+
return bilibili_data
|
148
|
+
|
149
|
+
|
150
|
+
# 哔哩哔哩cookie刷新模块
|
151
|
+
def bilibili_cookie_update(bilibili_data):
|
152
|
+
bilibili_cookie = bilibili_data["cookie"]
|
153
|
+
# 获取refresh_csrf
|
154
|
+
key = RSA.importKey("""\
|
155
|
+
-----BEGIN PUBLIC KEY-----
|
156
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLgd2OAkcGVtoE3ThUREbio0Eg
|
157
|
+
Uc/prcajMKXvkCKFCWhJYJcLkcM2DKKcSeFpD/j6Boy538YXnR6VhcuUJOhH2x71
|
158
|
+
nzPjfdTcqMz7djHum0qSZA0AyCBDABUqCrfNgCiJ00Ra7GmRj+YCK1NJEuewlb40
|
159
|
+
JNrRuoEUXpabUzGB8QIDAQAB
|
160
|
+
-----END PUBLIC KEY-----""")
|
161
|
+
|
162
|
+
# 获取当前时间戳
|
163
|
+
ts = time_stamp()
|
164
|
+
# 获取refresh_csrf
|
165
|
+
refresh_csrf_response = http_client(
|
166
|
+
f"https://www.bilibili.com/correspond/1/{getCorrespondPath(ts, key)}",
|
167
|
+
"获取refresh_csrf",
|
168
|
+
3,
|
169
|
+
5,
|
170
|
+
True,
|
171
|
+
bilibili_cookie,
|
172
|
+
)
|
173
|
+
if refresh_csrf_match := re.search(
|
174
|
+
r'<div id="1-name">(.+?)</div>', refresh_csrf_response.text
|
175
|
+
):
|
176
|
+
refresh_csrf_value = refresh_csrf_match[1]
|
177
|
+
else:
|
178
|
+
return {"cookie": None}
|
179
|
+
# 更新bilibili_cookie
|
180
|
+
update_cookie_url = (
|
181
|
+
"https://passport.bilibili.com/x/passport-login/web/cookie/refresh"
|
182
|
+
)
|
183
|
+
update_cookie_data = {
|
184
|
+
"csrf": bilibili_cookie["bili_jct"],
|
185
|
+
"refresh_csrf": refresh_csrf_value,
|
186
|
+
"source": "main_web",
|
187
|
+
"refresh_token": bilibili_data["refresh_token"],
|
188
|
+
}
|
189
|
+
update_cookie_response = http_client(
|
190
|
+
update_cookie_url,
|
191
|
+
"更新BiliBili_cookie",
|
192
|
+
3,
|
193
|
+
5,
|
194
|
+
True,
|
195
|
+
bilibili_cookie,
|
196
|
+
update_cookie_data,
|
197
|
+
"post",
|
198
|
+
)
|
199
|
+
if update_cookie_response.json()["code"] != 0:
|
200
|
+
return {"cookie": None}
|
201
|
+
new_bilibili_cookie = requests.utils.dict_from_cookiejar(
|
202
|
+
update_cookie_response.cookies
|
203
|
+
)
|
204
|
+
new_refresh_token = update_cookie_response.json()["data"]["refresh_token"]
|
205
|
+
# 确认更新bilibili_cookie
|
206
|
+
confirm_cookie_url = (
|
207
|
+
"https://passport.bilibili.com/x/passport-login/web/confirm/refresh"
|
208
|
+
)
|
209
|
+
confirm_cookie_data = {
|
210
|
+
"csrf": new_bilibili_cookie["bili_jct"],
|
211
|
+
"refresh_token": bilibili_data["refresh_token"],
|
212
|
+
}
|
213
|
+
confirm_cookie_response = http_client(
|
214
|
+
confirm_cookie_url,
|
215
|
+
"确认更新BiliBili_cookie",
|
216
|
+
3,
|
217
|
+
5,
|
218
|
+
True,
|
219
|
+
new_bilibili_cookie,
|
220
|
+
confirm_cookie_data,
|
221
|
+
"post",
|
222
|
+
)
|
223
|
+
if confirm_cookie_response.json()["code"] == 0:
|
224
|
+
return bilibili_cookie_update_data(
|
225
|
+
bilibili_cookie,
|
226
|
+
new_bilibili_cookie,
|
227
|
+
bilibili_data,
|
228
|
+
new_refresh_token,
|
229
|
+
)
|
230
|
+
else:
|
231
|
+
return {"cookie": None}
|
232
|
+
|
233
|
+
|
234
|
+
def get_bilibili_data_success(bilibili_data, channelid_bilibili_ids):
|
235
|
+
print(
|
236
|
+
f"{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[32m获取cookie成功\033[0m"
|
237
|
+
)
|
238
|
+
img_key, sub_key = getWbiKeys()
|
239
|
+
bilibili_data["img_key"] = img_key
|
240
|
+
bilibili_data["sub_key"] = sub_key
|
241
|
+
bilibili_data["timestamp"] = time.time()
|
242
|
+
file_save(bilibili_data, "bilibili_data.json", "channel_data")
|
243
|
+
if not os.path.isfile("channel_data/yt_dlp_bilibili.txt"):
|
244
|
+
bulid_netscape("yt_dlp_bilibili", bilibili_data["cookie"])
|
245
|
+
return channelid_bilibili_ids, bilibili_data
|
246
|
+
|
247
|
+
|
248
|
+
def get_bilibili_data_state(bilibili_data, channelid_bilibili_ids):
|
249
|
+
bilibili_login_code, bilibili_login_refresh_token = judgment_bilibili_update(
|
250
|
+
bilibili_data["cookie"]
|
251
|
+
)
|
252
|
+
upward = 0
|
253
|
+
try_num = 0
|
254
|
+
while try_num < 2 and (
|
255
|
+
bilibili_login_code != 0 or bilibili_login_refresh_token is not False
|
256
|
+
):
|
257
|
+
if bilibili_login_code != 0:
|
258
|
+
if try_num == 0:
|
259
|
+
print(
|
260
|
+
f"{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[31m未登陆\033[0m"
|
261
|
+
)
|
262
|
+
else:
|
263
|
+
print(
|
264
|
+
f"\033[{upward + 3}F\033[{upward + 3}K{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[31m未登陆, 重试第\033[0m{try_num}\033[31m次\033[0m"
|
265
|
+
)
|
266
|
+
bilibili_data, upward = save_bilibili_cookies()
|
267
|
+
try_num += 1
|
268
|
+
else:
|
269
|
+
print(
|
270
|
+
f"{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[33m需刷新\033[0m"
|
271
|
+
)
|
272
|
+
bilibili_data = bilibili_cookie_update(bilibili_data)
|
273
|
+
if bilibili_data["cookie"]:
|
274
|
+
print(
|
275
|
+
f"{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[32m刷新成功\033[0m"
|
276
|
+
)
|
277
|
+
else:
|
278
|
+
print(
|
279
|
+
f"{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[31m刷新失败, 重新登陆\033[0m"
|
280
|
+
)
|
281
|
+
bilibili_login_code, bilibili_login_refresh_token = judgment_bilibili_update(
|
282
|
+
bilibili_data["cookie"]
|
283
|
+
)
|
284
|
+
if bilibili_login_code == 0 and bilibili_login_refresh_token is False:
|
285
|
+
return get_bilibili_data_success(bilibili_data, channelid_bilibili_ids)
|
286
|
+
write_log("BiliBili \033[31m获取cookie失败\033[0m")
|
287
|
+
return {}, {"cookie": None, "timestamp": 0.0}
|
288
|
+
|
289
|
+
|
290
|
+
# 登陆刷新哔哩哔哩并获取data
|
291
|
+
def get_bilibili_data(channelid_bilibili_ids):
|
292
|
+
if not channelid_bilibili_ids:
|
293
|
+
return {}, {"cookie": None, "timestamp": 0.0}
|
294
|
+
try:
|
295
|
+
with open("channel_data/bilibili_data.json", "r") as file:
|
296
|
+
bilibili_data = file.read()
|
297
|
+
bilibili_data = json.loads(bilibili_data)
|
298
|
+
except Exception:
|
299
|
+
bilibili_data = {"cookie": None, "timestamp": 0.0}
|
300
|
+
if time.time() - bilibili_data["timestamp"] - 60 * 60 > 0:
|
301
|
+
return get_bilibili_data_state(bilibili_data, channelid_bilibili_ids)
|
302
|
+
print(
|
303
|
+
f"{datetime.now().strftime('%H:%M:%S')}|BiliBili \033[33m获取cookie成功\033[0m"
|
304
|
+
)
|
305
|
+
if not os.path.isfile("channel_data/yt_dlp_bilibili.txt"):
|
306
|
+
bulid_netscape("yt_dlp_bilibili", bilibili_data["cookie"])
|
307
|
+
return channelid_bilibili_ids, bilibili_data
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Podflow/config/build_original.py
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
from Podflow import gVar, parse
|
5
|
+
from Podflow.config.get_config import get_config
|
6
|
+
from Podflow.basic.folder_build import folder_build
|
7
|
+
from Podflow.config.get_channelid import get_channelid
|
8
|
+
from Podflow.config.correct_config import correct_config
|
9
|
+
from Podflow.config.correct_channelid import correct_channelid
|
10
|
+
from Podflow.config.get_channelid_id import get_channelid_id
|
11
|
+
|
12
|
+
|
13
|
+
def build_original():
|
14
|
+
# 获取配置文件config
|
15
|
+
gVar.config = get_config(parse.config)
|
16
|
+
# 纠正配置信息config
|
17
|
+
correct_config()
|
18
|
+
# 从配置文件中获取YouTube的频道
|
19
|
+
gVar.channelid_youtube = get_channelid("youtube")
|
20
|
+
# 从配置文件中获取哔哩哔哩的频道
|
21
|
+
gVar.channelid_bilibili = get_channelid("bilibili")
|
22
|
+
# 构建文件夹channel_id
|
23
|
+
folder_build("channel_id")
|
24
|
+
# 构建文件夹channel_audiovisual
|
25
|
+
folder_build("channel_audiovisual")
|
26
|
+
# 构建文件夹channel_rss
|
27
|
+
folder_build("channel_rss")
|
28
|
+
# 构建文件夹channel_data
|
29
|
+
folder_build("channel_data")
|
30
|
+
# 修正channelid_youtube
|
31
|
+
gVar.channelid_youtube = correct_channelid(gVar.channelid_youtube, "youtube")
|
32
|
+
# 修正channelid_bilibili
|
33
|
+
gVar.channelid_bilibili = correct_channelid(gVar.channelid_bilibili, "bilibili")
|
34
|
+
# 读取youtube频道的id
|
35
|
+
gVar.channelid_youtube_ids = get_channelid_id(gVar.channelid_youtube, "youtube")
|
36
|
+
# 复制youtube频道id用于删除已抛弃的媒体文件夹
|
37
|
+
gVar.channelid_youtube_ids_original = gVar.channelid_youtube_ids.copy()
|
38
|
+
# 读取bilibili频道的id
|
39
|
+
gVar.channelid_bilibili_ids = get_channelid_id(gVar.channelid_bilibili, "bilibili")
|
40
|
+
# 复制bilibili频道id用于删除已抛弃的媒体文件夹
|
41
|
+
gVar.channelid_bilibili_ids_original = gVar.channelid_bilibili_ids.copy()
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# Podflow/config/channge_icon.py
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
from datetime import datetime, timedelta, timezone
|
5
|
+
from astral import LocationInfo
|
6
|
+
from astral.sun import sun
|
7
|
+
from Podflow.basic.http_client import http_client
|
8
|
+
from Podflow.basic.write_log import write_log
|
9
|
+
from Podflow import gVar, default_config
|
10
|
+
|
11
|
+
|
12
|
+
# 获取日出日落并判断昼夜模块
|
13
|
+
def http_day_and_night(latitude, longitude):
|
14
|
+
sun_url = "https://api.sunrise-sunset.org/json"
|
15
|
+
sun_data = {
|
16
|
+
"lat": latitude,
|
17
|
+
"lng": longitude,
|
18
|
+
"date": "today",
|
19
|
+
}
|
20
|
+
sunrise_sunset = http_client(sun_url, "获取日出日落", 3, 5, True, None, sun_data)
|
21
|
+
if not sunrise_sunset:
|
22
|
+
return None
|
23
|
+
try:
|
24
|
+
time_dict = sunrise_sunset.json()["results"]
|
25
|
+
sunrise = time_dict["sunrise"]
|
26
|
+
sunset = time_dict["sunset"]
|
27
|
+
except KeyError:
|
28
|
+
return None
|
29
|
+
# 获取当前时间, 并去除时区
|
30
|
+
now = datetime.now()
|
31
|
+
# 将日出和日落时间转换为datetime对象
|
32
|
+
today = now.date()
|
33
|
+
sunrise_time = datetime.strptime(sunrise, "%I:%M:%S %p")
|
34
|
+
sunrise_time = sunrise_time.replace(
|
35
|
+
year=today.year, month=today.month, day=today.day, tzinfo=timezone.utc
|
36
|
+
)
|
37
|
+
sunset_time = datetime.strptime(sunset, "%I:%M:%S %p")
|
38
|
+
sunset_time = sunset_time.replace(
|
39
|
+
year=today.year, month=today.month, day=today.day, tzinfo=timezone.utc
|
40
|
+
)
|
41
|
+
# 转换日出和日落时间为时间戳
|
42
|
+
sunrise_now = sunrise_time.timestamp()
|
43
|
+
sunset_now = sunset_time.timestamp()
|
44
|
+
today = now.timestamp()
|
45
|
+
# 计算昨天及明天日出和日落时间戳
|
46
|
+
sunrise_yesterday = sunrise_now - 3600 * 24
|
47
|
+
sunset_yesterday = sunset_now - 3600 * 24
|
48
|
+
sunrise_tommorrow = sunrise_now + 3600 * 24
|
49
|
+
sunset_tommorrow = sunset_now + 3600 * 24
|
50
|
+
if sunrise_now < sunset_now:
|
51
|
+
return (
|
52
|
+
"light"
|
53
|
+
if (
|
54
|
+
sunrise_now < today < sunset_now
|
55
|
+
or sunrise_yesterday < today < sunset_yesterday
|
56
|
+
or sunrise_tommorrow < today < sunset_tommorrow
|
57
|
+
)
|
58
|
+
else "dark"
|
59
|
+
)
|
60
|
+
if (
|
61
|
+
sunrise_now > today > sunset_now
|
62
|
+
or sunrise_yesterday > today > sunset_yesterday
|
63
|
+
or sunrise_tommorrow > today > sunset_tommorrow
|
64
|
+
):
|
65
|
+
return "dark"
|
66
|
+
else:
|
67
|
+
return "light"
|
68
|
+
|
69
|
+
|
70
|
+
# 根据经纬度判断昼夜模块
|
71
|
+
def judging_day_and_night(latitude, longitude):
|
72
|
+
# 创建一个 LocationInfo 对象, 只提供经纬度信息
|
73
|
+
location = LocationInfo("", "", "", latitude=latitude, longitude=longitude)
|
74
|
+
# 获取当前日期和时间, 并为其添加时区信息
|
75
|
+
now = datetime.now(timezone.utc)
|
76
|
+
yesterday = now - timedelta(days=1)
|
77
|
+
tommorrow = now + timedelta(days=1)
|
78
|
+
|
79
|
+
def sunrise_sunset(time):
|
80
|
+
# 创建一个 Sun 对象
|
81
|
+
sun_time = sun(location.observer, date=time)
|
82
|
+
# 计算日出和日落时间, 以及日落前和日出后的一小时
|
83
|
+
sunrise = sun_time["sunrise"]
|
84
|
+
sunset = sun_time["sunset"]
|
85
|
+
sunrise_minus_one_hour = sunrise # - timedelta(hours=1)
|
86
|
+
sunset_plus_one_hour = sunset # + timedelta(hours=1)
|
87
|
+
return sunrise_minus_one_hour, sunset_plus_one_hour
|
88
|
+
|
89
|
+
sunrise_now, sunset_now = sunrise_sunset(now)
|
90
|
+
sunrise_yesterday, sunset_yesterday = sunrise_sunset(yesterday)
|
91
|
+
sunrise_tommorrow, sunset_tommorrow = sunrise_sunset(tommorrow)
|
92
|
+
if sunrise_now < sunset_now:
|
93
|
+
return (
|
94
|
+
"light"
|
95
|
+
if (
|
96
|
+
sunrise_now < now < sunset_now
|
97
|
+
or sunrise_yesterday < now < sunset_yesterday
|
98
|
+
or sunrise_tommorrow < now < sunset_tommorrow
|
99
|
+
)
|
100
|
+
else "dark"
|
101
|
+
)
|
102
|
+
if (
|
103
|
+
sunrise_now > now > sunset_now
|
104
|
+
or sunrise_yesterday > now > sunset_yesterday
|
105
|
+
or sunrise_tommorrow > now > sunset_tommorrow
|
106
|
+
):
|
107
|
+
return "dark"
|
108
|
+
else:
|
109
|
+
return "light"
|
110
|
+
|
111
|
+
|
112
|
+
def ipinfo():
|
113
|
+
if response := http_client("https://ipinfo.io/json/", "", 1, 0):
|
114
|
+
data = response.json()
|
115
|
+
# 提取经度和纬度
|
116
|
+
coordinates = data["loc"].split(",")
|
117
|
+
return True, coordinates[0], coordinates[1]
|
118
|
+
else:
|
119
|
+
return False, None, None
|
120
|
+
|
121
|
+
|
122
|
+
def ipapi():
|
123
|
+
if response := http_client("http://ip-api.com/json/", "", 1, 0):
|
124
|
+
data = response.json()
|
125
|
+
# 提取经度和纬度
|
126
|
+
return True, data["lat"], data["lon"]
|
127
|
+
else:
|
128
|
+
return False, None, None
|
129
|
+
|
130
|
+
|
131
|
+
def freegeoip():
|
132
|
+
if response := http_client("https://freegeoip.app/json/", "", 1, 0):
|
133
|
+
data = response.json()
|
134
|
+
# 提取经度和纬度
|
135
|
+
return True, data["latitude"], data["longitude"]
|
136
|
+
else:
|
137
|
+
return False, None, None
|
138
|
+
|
139
|
+
|
140
|
+
# 根据日出日落修改封面(只适用原封面)模块
|
141
|
+
def channge_icon():
|
142
|
+
config = gVar.config
|
143
|
+
if config["icon"] != default_config["icon"]:
|
144
|
+
return
|
145
|
+
label = False
|
146
|
+
# 公网获取经纬度
|
147
|
+
label, latitude, longitude = ipinfo()
|
148
|
+
if label is False:
|
149
|
+
write_log("获取经纬度信息重试中...\033[97m1\033[0m")
|
150
|
+
label, latitude, longitude = ipapi()
|
151
|
+
if label is False:
|
152
|
+
write_log("获取经纬度信息重试中...\033[97m2\033[0m")
|
153
|
+
label, latitude, longitude = freegeoip()
|
154
|
+
if label is False:
|
155
|
+
write_log("获取经纬度信息失败")
|
156
|
+
if label:
|
157
|
+
picture_name = http_day_and_night(latitude, longitude)
|
158
|
+
if not picture_name:
|
159
|
+
write_log("获取日出日落失败, 将计算昼夜")
|
160
|
+
picture_name = judging_day_and_night(latitude, longitude)
|
161
|
+
config["icon"] = (
|
162
|
+
f"https://raw.githubusercontent.com/gruel-zxz/podflow/main/Podflow_{picture_name}.png"
|
163
|
+
)
|