jscmp4 commited on
Commit
97d9fdc
·
verified ·
1 Parent(s): f6550ed

add e hentai

Browse files
Files changed (1) hide show
  1. app.py +148 -38
app.py CHANGED
@@ -5,7 +5,8 @@ import yaml
5
  import logging
6
  import io
7
  import re
8
- import img2pdf # 直接导入库,手动操作
 
9
  from jmcomic import create_option, JmcomicException
10
 
11
  # 定义下载目录
@@ -174,49 +175,158 @@ def run_batch_download(album_ids_str, auth_type, cookies_input, username_input,
174
  else:
175
  yield success_files, f"🎉 全部处理完毕!\n成功: {len(success_files)} / {total_count}", "全部完成"
176
 
177
- # --- 界面 (保持不变) ---
178
- with gr.Blocks(title="JMComic 批量下载器") as demo:
179
- gr.Markdown("## 🚀 JMComic 批量下载器 (修复版)")
180
- gr.Markdown("一行一个 ID,下载完一个才会开始下一个,稳定防崩。")
 
 
 
 
 
 
181
 
182
- with gr.Row():
183
- inp_ids = gr.Textbox(label="输入本子 ID 列表 (回车分隔)", placeholder="123456\n234567", lines=5)
 
 
 
 
 
 
 
184
 
185
- with gr.Row():
186
- auth_select = gr.Radio(
187
- ["使用账号密码 (推荐)", "使用 Cookies (手动)"],
188
- label="登录方式",
189
- value="使用账号密码 (推荐)"
190
- )
 
191
 
192
- with gr.Group(visible=True) as group_user:
193
- with gr.Row():
194
- inp_user = gr.Textbox(label="用户名", placeholder="输入账号")
195
- inp_pass = gr.Textbox(label="密码", type="password", placeholder="输入你的密码")
196
-
197
- with gr.Group(visible=False) as group_cookie:
198
- inp_cookie = gr.Textbox(label="Cookies", placeholder="key=value...")
199
 
200
- def toggle_auth(choice):
201
- if choice == "使用账号密码 (推荐)":
202
- return gr.update(visible=True), gr.update(visible=False)
203
- else:
204
- return gr.update(visible=False), gr.update(visible=True)
205
- auth_select.change(fn=toggle_auth, inputs=auth_select, outputs=[group_user, group_cookie])
206
 
207
- btn_run = gr.Button("🚀 批量下载", variant="primary")
208
-
209
- with gr.Row():
210
- out_badge = gr.Label(value="等待指令", label="总体进度")
211
- out_log = gr.Textbox(label="实时日志", lines=6)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
- out_files = gr.File(label="下载结果", file_count="multiple")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
 
215
- btn_run.click(
216
- fn=run_batch_download,
217
- inputs=[inp_ids, auth_select, inp_cookie, inp_user, inp_pass],
218
- outputs=[out_files, out_log, out_badge]
219
- )
220
 
221
  if __name__ == "__main__":
222
- demo.launch()
 
5
  import logging
6
  import io
7
  import re
8
+ import img2pdf
9
+ import subprocess # 新增:用于调用 gallery-dl
10
  from jmcomic import create_option, JmcomicException
11
 
12
  # 定义下载目录
 
175
  else:
176
  yield success_files, f"🎉 全部处理完毕!\n成功: {len(success_files)} / {total_count}", "全部完成"
177
 
178
+ # --- 新增:E-Hentai 下载核心逻辑 ---
179
+ def run_eh_download(eh_url, cookies_str):
180
+ """
181
+ eh_url: E站画廊链接 (e-hentai.org 或 exhentai.org)
182
+ cookies_str: 浏览器导出的 cookies (Netscape格式 或 key=value)
183
+ """
184
+ # 1. 检查参数
185
+ if not eh_url:
186
+ yield None, "❌ 请输入画廊链接", "参数缺失"
187
+ return
188
 
189
+ # 2. 目录准备
190
+ # 定义 EH 下载的临时目录
191
+ eh_base_dir = os.path.join(BASE_DIR, "eh_temp")
192
+ if os.path.exists(eh_base_dir):
193
+ try:
194
+ shutil.rmtree(eh_base_dir)
195
+ except:
196
+ pass
197
+ os.makedirs(eh_base_dir, exist_ok=True)
198
 
199
+ # PDF 输出目录
200
+ pdf_final_dir = os.path.join(BASE_DIR, "final_pdfs")
201
+ os.makedirs(pdf_final_dir, exist_ok=True)
202
+
203
+ # 3. 处理 Cookies
204
+ # gallery-dl 最好使用 cookies.txt 文件
205
+ cookie_file_path = os.path.join(BASE_DIR, "eh_cookies.txt")
206
 
207
+ # 简单的 Cookie 写入逻辑
208
+ with open(cookie_file_path, "w", encoding="utf-8") as f:
209
+ # 如果用户输入的是 key=value; 格式,这里可能需要转换,
210
+ # gallery-dl Netscape 格式支持最好。
211
+ # 建议让用户直接粘贴 Netscape 格式 (EditThisCookie 插件导出)
212
+ f.write(cookies_str)
 
213
 
214
+ yield None, "🚀 正在启动 gallery-dl 解析...", "开始解析"
 
 
 
 
 
215
 
216
+ # 4. 构建 gallery-dl 命令
217
+ # 格式: gallery-dl -d "目录" --cookies "cookie文件" "URL"
218
+ cmd = [
219
+ "gallery-dl",
220
+ "--directory", eh_base_dir,
221
+ "--cookies", cookie_file_path,
222
+ eh_url
223
+ ]
224
+
225
+ # 5. 执行下载
226
+ try:
227
+ process = subprocess.Popen(
228
+ cmd,
229
+ stdout=subprocess.PIPE,
230
+ stderr=subprocess.STDOUT,
231
+ text=True
232
+ )
233
+
234
+ # 实时捕获日志
235
+ logs = ""
236
+ for line in process.stdout:
237
+ logs += line
238
+ # 简单的进度反馈
239
+ if "Example" in line or "http" in line:
240
+ yield None, f"📥 正在下载: \n{line.strip()}", "下载中"
241
+
242
+ process.wait()
243
+
244
+ if process.returncode != 0:
245
+ yield None, f"❌ 下载失败,请检查 Cookies 是否过期或链接是否有效。\n日志:\n{logs[-500:]}", "下载失败"
246
+ return
247
+
248
+ except Exception as e:
249
+ yield None, f"❌ 调用 gallery-dl 出错: {e}", "系统错误"
250
+ return
251
+
252
+ # 6. 寻找下载好的文件夹
253
+ # gallery-dl 会在 eh_base_dir 下自动创建 "E-Hentai/画廊名" 的结构
254
+ # 我们需要找到包含图片的那个最底层文件夹
255
+ target_img_dir = None
256
+ for root, dirs, files in os.walk(eh_base_dir):
257
+ # 如果当前文件夹里有图片,就是它了
258
+ has_img = any(f.lower().endswith(('.jpg', '.png', '.jpeg')) for f in files)
259
+ if has_img:
260
+ target_img_dir = root
261
+ break
262
 
263
+ if not target_img_dir:
264
+ yield None, "❌ 未找到下载的图片,可能是权限不足 (Sad Panda) 或下载被中断。", "未找到图片"
265
+ return
266
+
267
+ # 获取画廊标题作为文件名
268
+ folder_name = os.path.basename(target_img_dir)
269
+ safe_title = sanitize_filename(folder_name)
270
+ final_pdf_name = f"[EH] {safe_title}.pdf"
271
+ final_pdf_path = os.path.join(pdf_final_dir, final_pdf_name)
272
+
273
+ # 7. 合并 PDF (复用你现有的函数)
274
+ yield None, "🔨 图片下载完成,正在合并 PDF...", "正在合并"
275
+ try:
276
+ manual_merge_pdf(target_img_dir, final_pdf_path)
277
+ except Exception as e:
278
+ yield None, f"❌ 合并 PDF 失败: {e}", "合并失败"
279
+ return
280
+
281
+ yield [final_pdf_path], f"✅ 处理完成!\n文件: {final_pdf_name}", "完成"
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+ # --- 界面部分 (在原有 Blocks 中新增 Tab) ---
290
+ with gr.Blocks(title="超级漫画下载器") as demo:
291
+ gr.Markdown("## 🚀 超级漫画下载器 (JMComic + E-Hentai)")
292
+
293
+ with gr.Tabs():
294
+ # === Tab 1: JMComic (你原有的代码) ===
295
+ with gr.TabItem("JMComic (ID下载)"):
296
+ # 这里放你原来的 JMComic 界面代码...
297
+ # (inp_ids, auth_select, btn_run 等等...)
298
+ # 为了节省篇幅,这里省略,保持你原样即可
299
+ gr.Markdown("这里是你原来的 JM 界面...")
300
+
301
+ # === Tab 2: E-Hentai (新增) ===
302
+ with gr.TabItem("E-Hentai (链接下载)"):
303
+ gr.Markdown("输入 E站/EX站 画廊链接。**必须提供 Cookies** 才能下载原始画质或 EX 站内容。")
304
+
305
+ with gr.Row():
306
+ inp_eh_url = gr.Textbox(label="画廊链接 (URL)", placeholder="https://e-hentai.org/g/12345/xxxx/")
307
+
308
+ with gr.Row():
309
+ # 提示用户如何获取 Cookies
310
+ inp_eh_cookies = gr.Textbox(
311
+ label="Cookies (Netscape 格式)",
312
+ placeholder="# Netscape HTTP Cookie File\n.e-hentai.org ...",
313
+ lines=5,
314
+ info="推荐使用 Chrome 插件 'Get cookies.txt LOCALLY' 导出并在粘贴至此。"
315
+ )
316
+
317
+ btn_eh_run = gr.Button("🚀 下载并转 PDF", variant="primary")
318
+
319
+ with gr.Row():
320
+ out_eh_badge = gr.Label(value="等待指令", label="状态")
321
+ out_eh_log = gr.Textbox(label="运行日志", lines=3)
322
+
323
+ out_eh_files = gr.File(label="下载结果")
324
 
325
+ btn_eh_run.click(
326
+ fn=run_eh_download,
327
+ inputs=[inp_eh_url, inp_eh_cookies],
328
+ outputs=[out_eh_files, out_eh_log, out_eh_badge]
329
+ )
330
 
331
  if __name__ == "__main__":
332
+ demo.queue().launch() # 建议加上 queue()