Browse Source

add text2zip api

tomoya 1 day ago
parent
commit
b36069de98

+ 3 - 1
backend/app/app/api/api_v1/api.py

@@ -4,6 +4,7 @@ from app.api.api_v1.endpoints import  login, users, utils, videos, images, reput
 from app.api.api_v1.endpoints import ytviewspayment, payment, simplepayment
 from app.api.api_v1.endpoints import ecpay
 from app.api.api_v1.endpoints import heartbeat
+from app.api.api_v1.endpoints import text2zip
 
 api_router = APIRouter()
 api_router.include_router(login.router, tags=["login"])
@@ -17,4 +18,5 @@ api_router.include_router(ytviewspayment.router, prefix="/payment", tags=["yt vi
 api_router.include_router(payment.router, prefix="/payment", tags=["payment"])
 api_router.include_router(simplepayment.router, prefix="/payment", tags=["simple payment"])
 api_router.include_router(ecpay.router, prefix="/ecpay", tags=["ecpay"])
-api_router.include_router(heartbeat.router, prefix="/heartbeat", tags=["heartbeat"])
+api_router.include_router(heartbeat.router, prefix="/heartbeat", tags=["heartbeat"])
+api_router.include_router(text2zip.router, prefix="/text2zip", tags=["text2zip"] )

+ 133 - 0
backend/app/app/api/api_v1/endpoints/text2zip.py

@@ -0,0 +1,133 @@
+from typing import Any, List, Optional
+from datetime import datetime
+from fastapi import APIRouter, Body, Depends, HTTPException, Form, status, Response
+from fastapi.encoders import jsonable_encoder
+from pydantic.networks import EmailStr, HttpUrl
+from sqlalchemy.orm import Session
+from fastapi.responses import FileResponse
+import app.crud as crud
+import app.models as models
+import app.schemas as schemas 
+from app.api import deps
+from app.core.config import settings
+from app.core.ecpay_payment_sdk import ECPayPaymentSdk
+from app.utils import send_new_account_email
+from pydantic import BaseModel
+import requests
+from random import choice
+import string
+import json
+import os
+import PIL.Image
+from gradio_client import Client
+from openai import OpenAI
+import webuiapi
+import datetime
+from pathlib import Path
+import openpyxl as px
+import tempfile
+import shutil
+import PIL
+import re
+
+router = APIRouter()
+
+
+
+def gen_prompt(content:str):
+    client = OpenAI(api_key='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')
+
+    completion = client.chat.completions.create(
+        model="gpt-4o-mini",
+        messages=[
+            {"role": "assistant", "content": "You are a helpful image genaration prompt engineer. \
+             You will convert the following inputs into English prompts for image generation AI and respond accordingly. \
+             Do not start with 'Create an image. \
+             Keep it within 50 words"},
+            {
+                "role": "user",
+                "content": content
+            }
+        ]
+    )
+    return completion.choices[0].message.content
+
+def gen_flux_image(prompt):
+    client = Client("http://192.168.192.83:7860/")
+    result = client.predict(
+        model_id="models/FLUX.1-schnell",
+        prompt=prompt,
+        width=1280,
+        height=720,
+        seed=-1,
+        steps=4,
+        guidance_scale=3.5,
+        add_sampling_metadata=True,
+        api_name="/generate"
+    )
+    with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as t:
+        PIL.Image.open(result[0]).convert("RGB").save(t.name,"jpeg")
+        return t.name
+
+def gen_sd_image(prompt):
+    api = webuiapi.WebUIApi(host='192.168.192.38', port=7860)
+    api.util_set_model('sd3_medium')
+    result = api.txt2img(prompt=prompt,
+                    negative_prompt="",
+                    seed=-1,
+                    cfg_scale=4,
+                    sampler_name='Euler',
+                    scheduler='Automatic',
+                    steps=40,
+                    width=1280,
+                    height=720,
+                    )
+    with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg') as t:
+        result.image.save(t, "jpeg")
+    return t.name
+
+punctuation = r"[.,!?;:。 、!?,;:]"
+
+
+
+@router.post('/gen-zip')
+def generate_zip(
+      *,
+    current_user: models.User = Depends(deps.get_current_active_user),
+    model:Optional[str], 
+    texts:List[str]):
+
+    if not model:
+        model = 'sd3'
+    wb = px.Workbook()
+    ws = wb.active
+    ws.title = 'script'
+    ws['A1'] = '大標'
+    ws['B1'] = '字幕'
+    ws['C1'] = '素材'
+    with tempfile.TemporaryDirectory() as td:
+        dir = Path(f'{td}/{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}')
+        dir.mkdir(exist_ok=False)
+        texts = [text for text in texts if text]
+        for i, text in enumerate(texts):
+            print(f'{i+1}/{len(texts)}')
+            prompt = gen_prompt(text)
+            if model=='flux':
+                img_path = Path(gen_flux_image(prompt))
+
+            elif model=='sd3':
+                img_path = Path(gen_sd_image(prompt))
+            print("before", str(img_path))
+            img_path = img_path.rename(dir/(f'{i+1:02}'+img_path.suffix))
+            print("after", str(img_path))
+            ws['B'+ str(i+2)] = re.sub(punctuation, r"\\", text)
+            ws['C'+ str(i+2)] = img_path.name
+        excel_path = Path(dir/'script.xlsx')
+        wb.save(excel_path)
+        output_dir = '/tmp'
+        shutil.make_archive(f'{output_dir}/{dir.name}', format='zip', root_dir=td)
+        def remove_zip():
+            if os.path.exists(f'{output_dir}/{dir.name}.zip'):
+                os.remove(f'{output_dir}/{dir.name}.zip')
+    return FileResponse(f'{output_dir}/{dir.name}.zip', background=remove_zip)
+

+ 1 - 9
backend/app/prestart.sh

@@ -7,12 +7,4 @@ python /app/app/backend_pre_start.py
 # alembic upgrade head
 
 # Create initial data in DB
-python /app/app/initial_data.py
-
-if [ ! -e BACKEND_ZIP_STORAGE ]; then
-    mkdir BACKEND_ZIP_STORAGE
-fi
-
-if [ ! -e BACKEND_VIDEOS_STORAGE ]; then
-    mkdir BACKEND_VIDEOS_STORAGE
-fi
+python /app/app/initial_data.py

+ 3 - 0
backend/app/pyproject.toml

@@ -32,6 +32,9 @@ pandas = "^2.0.0"
 openpyxl = "^3.1.0"
 chardet = "^5.1.0"
 gradio_client = "^1.3.0"
+openai = "^1.59.4"
+gradio_client
+webuiapi
 
 [tool.poetry.dev-dependencies]
 mypy = "^0.991"