Norcoo commited on
Commit
36ce68c
·
verified ·
1 Parent(s): 637fff5

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +103 -11
  2. requirements.txt +2 -0
app.py CHANGED
@@ -6,6 +6,8 @@ from datetime import datetime
6
  from pathlib import Path
7
  from PIL import Image
8
  import json
 
 
9
 
10
  # 环境变量
11
  ACCESS_PASSWORD = os.environ.get("ACCESS_PASSWORD", "changeme")
@@ -66,13 +68,14 @@ def generate_filename(original_filename):
66
  ext = ".png"
67
  return f"{timestamp}_{hash_suffix}{ext}"
68
 
69
- def generate_full_url(file_path):
70
- """生成完整的图片URL"""
71
- relative_path = f"/file={file_path}"
72
  if HF_USERNAME and HF_SPACE_NAME:
73
- return f"https://{HF_USERNAME}-{HF_SPACE_NAME}.hf.space{relative_path}"
74
  else:
75
- return relative_path
 
76
 
77
  def upload_images(images, description, password):
78
  """批量上传图片"""
@@ -126,7 +129,7 @@ def upload_images(images, description, password):
126
  conn.close()
127
 
128
  # 生成访问 URL
129
- full_url = generate_full_url(file_path)
130
 
131
  results.append({
132
  'id': image_id,
@@ -216,7 +219,7 @@ def get_image_list_html(password):
216
 
217
  for row in rows:
218
  upload_time_str = datetime.fromisoformat(row['upload_time']).strftime('%Y-%m-%d %H:%M:%S')
219
- full_url = generate_full_url(row['file_path'])
220
 
221
  html += f"""
222
  <tr>
@@ -269,7 +272,7 @@ def view_image_by_id(image_id, password):
269
  return "❌ 图片文件已损坏或丢失!", None, ""
270
 
271
  # 生成访问 URL
272
- full_url = generate_full_url(file_path)
273
 
274
  info_text = f"""## 📷 图片信息
275
 
@@ -390,7 +393,7 @@ def export_data(password):
390
  # 转换为 JSON
391
  data = []
392
  for row in rows:
393
- full_url = generate_full_url(row['file_path'])
394
  data.append({
395
  'id': row['id'],
396
  'filename': row['filename'],
@@ -414,6 +417,90 @@ def export_data(password):
414
  # 初始化数据库
415
  init_success = init_db()
416
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
  # 自定义CSS
418
  custom_css = """
419
  .compact-gallery .gallery {
@@ -426,7 +513,7 @@ custom_css = """
426
  """
427
 
428
  # 创建 Gradio 界面
429
- with gr.Blocks(title="私人图床服务", theme=gr.themes.Soft(), css=custom_css) as app:
430
  gr.Markdown("# 🖼️ 私人图床服务")
431
  gr.Markdown("⚠️ 请输入密码以使用此服务 | 支持批量上传 | 图片存储在服务器本地")
432
 
@@ -619,4 +706,9 @@ with gr.Blocks(title="私人图床服务", theme=gr.themes.Soft(), css=custom_cs
619
  """)
620
 
621
  if __name__ == "__main__":
622
- app.launch()
 
 
 
 
 
 
6
  from pathlib import Path
7
  from PIL import Image
8
  import json
9
+ from fastapi import FastAPI, Response
10
+ from fastapi.responses import FileResponse, JSONResponse
11
 
12
  # 环境变量
13
  ACCESS_PASSWORD = os.environ.get("ACCESS_PASSWORD", "changeme")
 
68
  ext = ".png"
69
  return f"{timestamp}_{hash_suffix}{ext}"
70
 
71
+ def generate_full_url(image_id):
72
+ """生成完整的图片URL(使用专用API端点)"""
73
+ api_path = f"/api/img/{image_id}"
74
  if HF_USERNAME and HF_SPACE_NAME:
75
+ return f"https://{HF_USERNAME}-{HF_SPACE_NAME}.hf.space{api_path}"
76
  else:
77
+ # 返回相对路径,用户访问时会自动补全域名
78
+ return api_path
79
 
80
  def upload_images(images, description, password):
81
  """批量上传图片"""
 
129
  conn.close()
130
 
131
  # 生成访问 URL
132
+ full_url = generate_full_url(image_id)
133
 
134
  results.append({
135
  'id': image_id,
 
219
 
220
  for row in rows:
221
  upload_time_str = datetime.fromisoformat(row['upload_time']).strftime('%Y-%m-%d %H:%M:%S')
222
+ full_url = generate_full_url(row['id'])
223
 
224
  html += f"""
225
  <tr>
 
272
  return "❌ 图片文件已损坏或丢失!", None, ""
273
 
274
  # 生成访问 URL
275
+ full_url = generate_full_url(row['id'])
276
 
277
  info_text = f"""## 📷 图片信息
278
 
 
393
  # 转换为 JSON
394
  data = []
395
  for row in rows:
396
+ full_url = generate_full_url(row['id'])
397
  data.append({
398
  'id': row['id'],
399
  'filename': row['filename'],
 
417
  # 初始化数据库
418
  init_success = init_db()
419
 
420
+ # 创建FastAPI app
421
+ fastapi_app = FastAPI()
422
+
423
+ # 添加图片访问API端点
424
+ @fastapi_app.get("/api/img/{image_id}")
425
+ async def get_image(image_id: int):
426
+ """通过ID获取图片"""
427
+ try:
428
+ conn = get_db_connection()
429
+ cursor = conn.cursor()
430
+ cursor.execute("SELECT * FROM images WHERE id = ?", (image_id,))
431
+ row = cursor.fetchone()
432
+ conn.close()
433
+
434
+ if not row:
435
+ return JSONResponse(
436
+ status_code=404,
437
+ content={"error": "Image not found"}
438
+ )
439
+
440
+ file_path = Path(row['file_path'])
441
+
442
+ if not file_path.exists():
443
+ return JSONResponse(
444
+ status_code=404,
445
+ content={"error": "Image file not found"}
446
+ )
447
+
448
+ # 返回图片文件
449
+ return FileResponse(
450
+ file_path,
451
+ media_type=row['mime_type'],
452
+ headers={
453
+ "Cache-Control": "public, max-age=31536000",
454
+ "Content-Disposition": f'inline; filename="{row["original_filename"]}"'
455
+ }
456
+ )
457
+
458
+ except Exception as e:
459
+ return JSONResponse(
460
+ status_code=500,
461
+ content={"error": str(e)}
462
+ )
463
+
464
+ # 添加图片信息API端点(可选,用于获取元数据)
465
+ @fastapi_app.get("/api/img/{image_id}/info")
466
+ async def get_image_info(image_id: int, password: str = None):
467
+ """获取图片信息(需要密码)"""
468
+ if not password or not check_password(password):
469
+ return JSONResponse(
470
+ status_code=401,
471
+ content={"error": "Unauthorized"}
472
+ )
473
+
474
+ try:
475
+ conn = get_db_connection()
476
+ cursor = conn.cursor()
477
+ cursor.execute("SELECT * FROM images WHERE id = ?", (image_id,))
478
+ row = cursor.fetchone()
479
+ conn.close()
480
+
481
+ if not row:
482
+ return JSONResponse(
483
+ status_code=404,
484
+ content={"error": "Image not found"}
485
+ )
486
+
487
+ return JSONResponse(content={
488
+ "id": row['id'],
489
+ "filename": row['filename'],
490
+ "original_filename": row['original_filename'],
491
+ "file_size": row['file_size'],
492
+ "mime_type": row['mime_type'],
493
+ "upload_time": row['upload_time'],
494
+ "description": row['description'],
495
+ "url": generate_full_url(row['id'])
496
+ })
497
+
498
+ except Exception as e:
499
+ return JSONResponse(
500
+ status_code=500,
501
+ content={"error": str(e)}
502
+ )
503
+
504
  # 自定义CSS
505
  custom_css = """
506
  .compact-gallery .gallery {
 
513
  """
514
 
515
  # 创建 Gradio 界面
516
+ with gr.Blocks(title="私人图床服务", theme=gr.themes.Soft(), css=custom_css) as gradio_app:
517
  gr.Markdown("# 🖼️ 私人图床服务")
518
  gr.Markdown("⚠️ 请输入密码以使用此服务 | 支持批量上传 | 图片存储在服务器本地")
519
 
 
706
  """)
707
 
708
  if __name__ == "__main__":
709
+ # 将Gradio app挂载到FastAPI
710
+ app = gr.mount_gradio_app(fastapi_app, gradio_app, path="/")
711
+
712
+ # 启动服务
713
+ import uvicorn
714
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt CHANGED
@@ -1,3 +1,5 @@
1
  gradio==4.44.0
2
  Pillow==10.4.0
 
 
3
 
 
1
  gradio==4.44.0
2
  Pillow==10.4.0
3
+ uvicorn[standard]>=0.24.0
4
+ fastapi>=0.104.0
5