podflow 20250404.8__tar.gz → 20250405__tar.gz
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-20250404.8 → podflow-20250405}/PKG-INFO +1 -1
- {podflow-20250404.8 → podflow-20250405}/podflow/__init__.py +0 -1
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/time_print.py +1 -4
- {podflow-20250404.8 → podflow-20250405}/podflow/download/dl_aideo_video.py +18 -21
- {podflow-20250404.8 → podflow-20250405}/podflow/httpfs/app_bottle.py +16 -1
- {podflow-20250404.8 → podflow-20250405}/podflow/main_podcast.py +22 -6
- {podflow-20250404.8 → podflow-20250405}/podflow/message/fail_message_initialize.py +2 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/templates/index.html +48 -33
- {podflow-20250404.8 → podflow-20250405}/podflow.egg-info/PKG-INFO +1 -1
- {podflow-20250404.8 → podflow-20250405}/setup.py +1 -1
- {podflow-20250404.8 → podflow-20250405}/MANIFEST.in +0 -0
- {podflow-20250404.8 → podflow-20250405}/README.md +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/file_save.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/folder_build.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/get_duration.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/get_file_list.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/get_html_dict.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/http_client.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/list_merge_tidy.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/qr_code.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/split_dict.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/time_format.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/time_stamp.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/vary_replace.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/basic/write_log.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/bilibili/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/bilibili/build.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/bilibili/get.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/bilibili/login.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/build_original.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/channge_icon.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/correct_channelid.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/correct_config.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/get_channelid.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/get_channelid_id.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/config/get_config.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download/convert_bytes.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download/delete_part.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download/show_progress.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download/wait_animation.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download/youtube_and_bilibili_download.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/download_and_build.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/ffmpeg_judge.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/httpfs/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/httpfs/browser.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/httpfs/get_channelid.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/httpfs/port_judge.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/httpfs/to_html.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/main.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/main_upload.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/makeup/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/makeup/del_makeup_format_fail.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/makeup/make_up_file.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/makeup/make_up_file_format_mod.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/makeup/make_up_file_mod.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/backup_zip_save.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/create_main_rss.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/display_qrcode_and_url.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/format_time.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/get_media_name.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/get_original_rss.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/get_video_format.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/get_video_format_multithread.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/get_youtube_and_bilibili_video_format.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/media_format.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/original_rss_fail_print.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/rss_create_hash.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/save_rss.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/title_correction.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/update_information_display.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/update_youtube_bilibili_rss.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/want_retry.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/xml_item.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/xml_original_item.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/message/xml_rss.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/netscape/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/netscape/bulid_netscape.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/netscape/get_cookie_dict.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/parse_arguments.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/remove/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/remove/remove_dir.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/remove/remove_file.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/repair/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/repair/reverse_log.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/add_upload.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/build_hash.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/get_upload_original.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/linked_client.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/linked_server.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/login.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/time_key.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/update_upload.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/upload/upload_server.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/youtube/__init__.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/youtube/build.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/youtube/get.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow/youtube/login.py +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow.egg-info/SOURCES.txt +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow.egg-info/dependency_links.txt +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow.egg-info/entry_points.txt +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow.egg-info/requires.txt +0 -0
- {podflow-20250404.8 → podflow-20250405}/podflow.egg-info/top_level.txt +0 -0
- {podflow-20250404.8 → podflow-20250405}/setup.cfg +0 -0
@@ -35,8 +35,5 @@ def time_print(text, Top=False, NoEnter=False, Time=True, Url=""):
|
|
35
35
|
gVar.index_message["enter"] = True
|
36
36
|
if Url:
|
37
37
|
gVar.index_message["podflow"].append(
|
38
|
-
f'<a href="{Url}"><span class="ansi-url">{Url}</span></a>'
|
38
|
+
f'<a href="{Url}" target="_blank"><span class="ansi-url">{Url}</span></a>'
|
39
39
|
)
|
40
|
-
gVar.text_message.append(
|
41
|
-
[text, Top, NoEnter]
|
42
|
-
)
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
4
|
import os
|
5
|
+
import re
|
5
6
|
import ffmpeg
|
6
7
|
import yt_dlp
|
7
8
|
from podflow import gVar
|
@@ -68,22 +69,22 @@ def download_video(
|
|
68
69
|
ydl.download([f"{video_website}"]) # 下载指定视频链接的视频
|
69
70
|
return None, None
|
70
71
|
except Exception as download_video_error:
|
71
|
-
fail_info = fail_message_initialize(download_video_error, video_url).replace(
|
72
|
+
fail_info = fail_message_initialize(download_video_error, video_url).replace(
|
73
|
+
"\n", ""
|
74
|
+
)
|
72
75
|
remove_info = ""
|
73
|
-
if
|
74
|
-
""
|
75
|
-
"
|
76
|
-
|
77
|
-
"
|
78
|
-
|
79
|
-
"\033[31m响应超时\033[0m",
|
80
|
-
] and "www.youtube.com" in video_website:
|
76
|
+
if (
|
77
|
+
fail_info == ""
|
78
|
+
or re.search(r"请求拒绝|数据不完整|传输中断|请求超时|响应超时", fail_info)
|
79
|
+
) and "www.youtube.com" in video_website:
|
80
|
+
if fail_info != "":
|
81
|
+
remove_info = "|"
|
81
82
|
if os.path.isfile(outtmpl):
|
82
83
|
os.remove(outtmpl)
|
83
|
-
remove_info
|
84
|
+
remove_info += "已删除失败文件"
|
84
85
|
elif os.path.isfile(outtmpl + ".part"):
|
85
86
|
os.remove(outtmpl + ".part")
|
86
|
-
remove_info
|
87
|
+
remove_info += "已删除部分失败文件"
|
87
88
|
write_log(
|
88
89
|
f"{video_write_log} \033[31m下载失败\033[0m",
|
89
90
|
None,
|
@@ -124,15 +125,12 @@ def dl_full_video(
|
|
124
125
|
f"channel_audiovisual/{output_dir}/{video_url}{sesuffix}.{output_format}"
|
125
126
|
) # 获取已下载视频的实际时长
|
126
127
|
if (
|
127
|
-
duration_video is not None
|
128
|
-
and abs(id_duration - duration_video) <= 1
|
128
|
+
duration_video is not None and abs(id_duration - duration_video) <= 1
|
129
129
|
): # 检查实际时长与预计时长是否一致
|
130
130
|
return None, None
|
131
131
|
if duration_video:
|
132
132
|
fail_info = f"不完整({id_duration}|{duration_video}"
|
133
|
-
write_log(
|
134
|
-
f"{video_write_log} \033[31m下载失败\033[0m\n错误信息: {fail_info})"
|
135
|
-
)
|
133
|
+
write_log(f"{video_write_log} \033[31m下载失败\033[0m\n错误信息: {fail_info})")
|
136
134
|
os.remove(
|
137
135
|
f"channel_audiovisual/{output_dir}/{video_url}{sesuffix}.{output_format}"
|
138
136
|
) # 删除不完整的视频
|
@@ -176,7 +174,9 @@ def dl_retry_video(
|
|
176
174
|
cookies = "channel_data/yt_dlp_youtube.txt"
|
177
175
|
video_id_count += 1
|
178
176
|
if cookies:
|
179
|
-
write_log(
|
177
|
+
write_log(
|
178
|
+
f"{video_write_log} 第\033[34m{video_id_count}\033[0m次重新下载 🍪"
|
179
|
+
)
|
180
180
|
else:
|
181
181
|
write_log(f"{video_write_log} 第\033[34m{video_id_count}\033[0m次重新下载")
|
182
182
|
video_id_failed, _ = dl_full_video(
|
@@ -298,10 +298,7 @@ def dl_aideo_video(
|
|
298
298
|
audio, video, output_file, vcodec="copy", acodec="copy"
|
299
299
|
)
|
300
300
|
ffmpeg.run(stream, quiet=True)
|
301
|
-
time_print(
|
302
|
-
" \033[32m合成成功\033[0m",
|
303
|
-
Time=False
|
304
|
-
)
|
301
|
+
time_print(" \033[32m合成成功\033[0m", Time=False)
|
305
302
|
# 删除临时文件
|
306
303
|
os.remove(f"channel_audiovisual/{output_dir}/{video_url}.part.mp4")
|
307
304
|
os.remove(f"channel_audiovisual/{output_dir}/{video_url}.part.m4a")
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
import os
|
5
5
|
import hashlib
|
6
|
+
import mimetypes
|
6
7
|
import pkg_resources
|
7
8
|
from datetime import datetime
|
8
9
|
import cherrypy
|
@@ -203,7 +204,21 @@ class bottle_app:
|
|
203
204
|
# 如果文件存在, 返回文件
|
204
205
|
if os.path.exists(filename): # 如果文件存在, 返回文件
|
205
206
|
self.print_out(filename, 200)
|
206
|
-
|
207
|
+
# 设置正确的 Content-Type 头部
|
208
|
+
content_type, _ = mimetypes.guess_type(filename)
|
209
|
+
# 如果无法自动猜测出正确的 Content-Type,手动指定
|
210
|
+
if not content_type:
|
211
|
+
if filename.endswith(".xml"):
|
212
|
+
content_type = "application/xml"
|
213
|
+
elif filename.endswith(".m4a"):
|
214
|
+
content_type = "audio/mp4"
|
215
|
+
elif filename.endswith(".mp4"):
|
216
|
+
content_type = "video/mp4"
|
217
|
+
else:
|
218
|
+
content_type = "application/octet-stream" # 默认文件类型
|
219
|
+
|
220
|
+
# 返回静态文件并附加正确的 Content-Type
|
221
|
+
return static_file(filename, root=".", mimetype=content_type)
|
207
222
|
else: # 如果文件不存在, 返回 404 错误
|
208
223
|
self.print_out(filename, 404)
|
209
224
|
abort(404, "File not found")
|
@@ -210,7 +210,27 @@ def main_podcast():
|
|
210
210
|
update_upload()
|
211
211
|
else:
|
212
212
|
time_print("频道无更新内容")
|
213
|
-
|
213
|
+
# 清空变量内数据
|
214
|
+
gVar.channelid_youtube_ids_update.clear() # 需更新的YouTube频道字典
|
215
|
+
gVar.youtube_content_ytid_update.clear() # 需下载YouTube视频字典
|
216
|
+
gVar.youtube_content_ytid_backward_update.clear() # 向后更新需下载YouTube视频字典
|
217
|
+
gVar.channelid_youtube_rss.clear() # YouTube频道最新Rss Response字典
|
218
|
+
gVar.channelid_bilibili_ids_update.clear() # 需更新的哔哩哔哩频道字典
|
219
|
+
gVar.bilibili_content_bvid_update.clear() # 需下载哔哩哔哩视频字典
|
220
|
+
gVar.channelid_bilibili_rss.clear() # 哔哩哔哩频道最新Rss Response字典
|
221
|
+
gVar.bilibili_content_bvid_backward_update.clear() # 向后更新需下载哔哩哔哩视频字典
|
222
|
+
gVar.video_id_failed.clear() # YouTube&哔哩哔哩视频下载失败列表
|
223
|
+
gVar.video_id_update_format.clear() # YouTube&哔哩哔哩视频下载的详细信息字典
|
224
|
+
gVar.hash_rss_original = "" # 原始rss哈希值文本
|
225
|
+
gVar.xmls_original.clear() # 原始xml信息字典
|
226
|
+
gVar.xmls_original_fail.clear() # 未获取原始xml频道列表
|
227
|
+
gVar.youtube_xml_get_tree.clear() # YouTube频道简介和图标字典
|
228
|
+
gVar.all_youtube_content_ytid.clear() # 所有YouTube视频id字典
|
229
|
+
gVar.all_bilibili_content_bvid.clear() # 所有哔哩哔哩视频id字典
|
230
|
+
gVar.all_items.clear() # 更新后所有item明细列表
|
231
|
+
gVar.overall_rss = "" # 更新后的rss文本
|
232
|
+
gVar.make_up_file_format.clear() # 补全缺失媒体字典
|
233
|
+
gVar.make_up_file_format_fail.clear() # 补全缺失媒体失败字典
|
214
234
|
# 将需要更新转为否
|
215
235
|
gVar.update_generate_rss = False
|
216
236
|
if parse.update_num != -1:
|
@@ -232,9 +252,5 @@ def main_podcast():
|
|
232
252
|
# 延时
|
233
253
|
time.sleep(parse.time_delay)
|
234
254
|
# 关闭CherryPy服务器
|
235
|
-
cherrypy.engine.exit()
|
236
255
|
time_print("Podflow运行结束")
|
237
|
-
|
238
|
-
from podflow.basic.file_save import file_save
|
239
|
-
file_save(gVar.text_message, "text.json")
|
240
|
-
file_save(gVar.index_message, "index.json")
|
256
|
+
cherrypy.engine.exit()
|
@@ -169,4 +169,6 @@ def fail_message_initialize(message_error, video_url):
|
|
169
169
|
elif mode == "regexp" and re.search(fail_info, fail_message):
|
170
170
|
fail_message = re.sub(rf"{fail_info}", field, fail_message)
|
171
171
|
break
|
172
|
+
if fail_message[0] == "\n":
|
173
|
+
fail_message = fail_message[1:]
|
172
174
|
return fail_message
|
@@ -151,6 +151,9 @@
|
|
151
151
|
overflow-x: auto; /* 当内容超出宽度时显示水平滚动条(可选) */
|
152
152
|
overflow-y: auto;
|
153
153
|
font-family: 'Courier New', Courier, monospace; /* 添加字体 */
|
154
|
+
word-break: break-word;
|
155
|
+
overflow-wrap: break-word;
|
156
|
+
white-space: pre-wrap; /* 保留换行并允许自动换行 */
|
154
157
|
}
|
155
158
|
textarea {
|
156
159
|
height: 350px;
|
@@ -222,6 +225,11 @@
|
|
222
225
|
nav {
|
223
226
|
position: fixed;
|
224
227
|
}
|
228
|
+
/* 确保页面宽度不会超出视口 */
|
229
|
+
body, html {
|
230
|
+
width: 100%;
|
231
|
+
overflow-x: hidden;
|
232
|
+
}
|
225
233
|
}
|
226
234
|
.message {
|
227
235
|
padding: 0px;
|
@@ -312,9 +320,17 @@
|
|
312
320
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
313
321
|
if (node.classList.contains('qrcode-container')) {
|
314
322
|
generateQRCodeForNode(node);
|
323
|
+
// 在生成二维码后,检查是否需要滚动
|
324
|
+
if (!userScrolled && container.scrollHeight - container.scrollTop <= container.clientHeight + 10) {
|
325
|
+
container.scrollTop = container.scrollHeight;
|
326
|
+
}
|
315
327
|
} else {
|
316
328
|
const childContainers = node.querySelectorAll('.qrcode-container');
|
317
329
|
childContainers.forEach(generateQRCodeForNode);
|
330
|
+
// 在生成二维码后,检查是否需要滚动
|
331
|
+
if (!userScrolled && container.scrollHeight - container.scrollTop <= container.clientHeight + 10) {
|
332
|
+
container.scrollTop = container.scrollHeight;
|
333
|
+
}
|
318
334
|
}
|
319
335
|
}
|
320
336
|
});
|
@@ -343,6 +359,7 @@
|
|
343
359
|
|
344
360
|
// 监听 messageArea 内动态新增的二维码容器
|
345
361
|
observeQRCodes(messageArea);
|
362
|
+
observeQRCodes(messageHttp); // Also observe for messageHttp
|
346
363
|
|
347
364
|
// 菜单切换函数
|
348
365
|
function toggleMenu() {
|
@@ -381,8 +398,8 @@
|
|
381
398
|
// 监听滚动事件,检测用户是否手动滚动
|
382
399
|
function onUserScroll(event) {
|
383
400
|
const element = event.target;
|
384
|
-
//
|
385
|
-
const nearBottom = element.scrollHeight - element.scrollTop <= element.clientHeight +
|
401
|
+
// 判断是否接近底部,增加一定的容差值
|
402
|
+
const nearBottom = element.scrollHeight - element.scrollTop <= element.clientHeight + 20;
|
386
403
|
userScrolled = !nearBottom;
|
387
404
|
}
|
388
405
|
|
@@ -404,56 +421,54 @@
|
|
404
421
|
.catch(error => console.error('获取消息失败:', error));
|
405
422
|
}
|
406
423
|
|
424
|
+
function createMessageElement(message) {
|
425
|
+
const p = document.createElement('p');
|
426
|
+
p.innerHTML = message;
|
427
|
+
p.className = 'message';
|
428
|
+
return p;
|
429
|
+
}
|
430
|
+
|
407
431
|
function appendMessages(container, newMessages, oldMessages) {
|
408
432
|
// 判断当前是否在底部
|
409
|
-
const
|
410
|
-
|
411
|
-
//
|
433
|
+
const wasAtBottom = container.scrollHeight - container.scrollTop <= container.clientHeight + 10;
|
434
|
+
|
435
|
+
// 当两数组长度相等且有内容时,只比较最后一项
|
412
436
|
if (newMessages.length === oldMessages.length && newMessages.length > 0) {
|
413
437
|
const lastNewMessage = newMessages[newMessages.length - 1];
|
414
438
|
const lastOldMessage = oldMessages[oldMessages.length - 1];
|
415
439
|
if (lastNewMessage !== lastOldMessage) {
|
416
|
-
const p =
|
417
|
-
p.innerHTML = lastNewMessage;
|
418
|
-
p.className = 'message'; // 添加 CSS 类名
|
419
|
-
|
420
|
-
// 获取容器的最后一个子元素
|
440
|
+
const p = createMessageElement(lastNewMessage);
|
421
441
|
const lastChild = container.lastElementChild;
|
422
|
-
// 如果容器有子元素,则替换最后一个
|
423
442
|
if (lastChild) {
|
424
443
|
container.replaceChild(p, lastChild);
|
425
444
|
} else {
|
426
|
-
// 如果容器为空,则直接添加
|
427
445
|
container.appendChild(p);
|
428
446
|
}
|
429
447
|
}
|
430
448
|
} else {
|
431
|
-
// 如果 newMessages
|
449
|
+
// 如果 newMessages 与 oldMessages 数量不一致
|
450
|
+
// 先替换容器中最后一项为 newMessages 中对应位置的消息(若 oldMessages 存在数据)
|
451
|
+
if (oldMessages.length > 0) {
|
452
|
+
const replaceIndex = oldMessages.length - 1;
|
453
|
+
const p = createMessageElement(newMessages[replaceIndex]);
|
454
|
+
const lastChild = container.lastElementChild;
|
455
|
+
if (lastChild) {
|
456
|
+
container.replaceChild(p, lastChild);
|
457
|
+
} else {
|
458
|
+
container.appendChild(p);
|
459
|
+
}
|
460
|
+
}
|
461
|
+
// 再追加从 oldMessages.length 开始的后续消息
|
432
462
|
newMessages.slice(oldMessages.length).forEach(msg => {
|
433
|
-
|
434
|
-
p.innerHTML = msg;
|
435
|
-
p.className = 'message'; // 添加 CSS 类名
|
436
|
-
container.appendChild(p);
|
463
|
+
container.appendChild(createMessageElement(msg));
|
437
464
|
});
|
438
465
|
}
|
439
|
-
|
440
|
-
//
|
441
|
-
|
442
|
-
const child = container.children[container.children.length - (i + 1)];
|
443
|
-
if (child && newMessages.length > i) {
|
444
|
-
const newMessage = newMessages[newMessages.length - (i + 1)];
|
445
|
-
const p = document.createElement('p');
|
446
|
-
p.innerHTML = newMessage;
|
447
|
-
p.className = 'message'; // 添加 CSS 类名
|
448
|
-
container.replaceChild(p, child);
|
449
|
-
}
|
450
|
-
}
|
451
|
-
|
452
|
-
// 如果用户没有主动滚动,才自动滚动到底部
|
453
|
-
if (!userScrolled) {
|
466
|
+
|
467
|
+
// 如果之前在底部且用户没有主动滚动,则自动滚动到底部
|
468
|
+
if (wasAtBottom && !userScrolled) {
|
454
469
|
container.scrollTop = container.scrollHeight;
|
455
470
|
}
|
456
|
-
}
|
471
|
+
}
|
457
472
|
|
458
473
|
function startMessagePolling() {
|
459
474
|
getMessages();
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{podflow-20250404.8 → podflow-20250405}/podflow/message/get_youtube_and_bilibili_video_format.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|