fantos's picture
Update app.py
b6dfa24 verified
raw
history blame
5.77 kB
# img_bot.py
import discord, os, io, re, random, asyncio, logging, requests, replicate, subprocess
from transformers import pipeline as transformers_pipeline
from gradio_client import Client, handle_file
# ── ν™˜κ²½ λ³€μˆ˜ ────────────────────────────────────────────────
TOKEN = os.getenv("DISCORD_TOKEN")
CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID"))
REPL_TOKEN = (os.getenv("OPENAI_API_KEY") or "").strip()
HF_TOKEN = (os.getenv("HF_TOKEN") or "").strip()
if not TOKEN or not CHANNEL_ID:
raise RuntimeError("DISCORD_TOKEN κ³Ό DISCORD_CHANNEL_ID ν™˜κ²½ λ³€μˆ˜λ₯Ό λͺ¨λ‘ μ§€μ •ν•˜μ„Έμš”.")
if not REPL_TOKEN:
raise RuntimeError("OPENAI_API_KEY 에 Replicate Personal Access Token 값을 λ„£μ–΄μ£Όμ„Έμš”.")
os.environ["REPLICATE_API_TOKEN"] = REPL_TOKEN # ꡬ쑰 μœ μ§€ (Replicate λ―Έμ‚¬μš©)
# ── Gradio μ„œλ²„ ─────────────────────────────────────────────
GRADIO_URL = "http://211.233.58.201:7971"
GRADIO_API = "/process_and_save_image"
DUMMY_IMG = "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
# ── λ²ˆμ—­ νŒŒμ΄ν”„λΌμΈ (CPU) ───────────────────────────────────
translator = transformers_pipeline(
"translation",
model="Helsinki-NLP/opus-mt-ko-en",
device=-1,
**({"token": HF_TOKEN} if HF_TOKEN else {})
)
async def ko2en_async(text: str) -> str:
"""ν•œκΈ€ 포함 μ‹œ 별도 μ“°λ ˆλ“œμ—μ„œ μ˜μ–΄ λ²ˆμ—­."""
if not re.search(r"[κ°€-힣]", text):
return text
loop = asyncio.get_running_loop()
try:
return await loop.run_in_executor(
None,
lambda: translator(text, max_length=256, num_beams=1)[0]["translation_text"].strip()
)
except Exception as e:
logging.warning(f"λ²ˆμ—­ μ‹€νŒ¨, 원문 μ‚¬μš©: {e}")
return text
# ── λ‘œκΉ… ────────────────────────────────────────────────────
logging.basicConfig(level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[logging.StreamHandler()])
# ── Discord μΈν…νŠΈ ──────────────────────────────────────────
intents = discord.Intents.default()
intents.message_content = True # Portalμ—μ„œλ„ Message-Content Intent ON
class ImageBot(discord.Client):
async def on_ready(self):
logging.info(f"Logged in as {self.user} (id={self.user.id})")
try:
subprocess.Popen(["python", "web.py"])
logging.info("web.py server has been started.")
except Exception as e:
logging.warning(f"web.py μ‹€ν–‰ μ‹€νŒ¨: {e}")
async def on_message(self, message: discord.Message):
if message.author.id == self.user.id or message.channel.id != CHANNEL_ID:
return
prompt_raw = message.content.strip()
if not prompt_raw:
return
prompt_en = await ko2en_async(prompt_raw)
await message.channel.typing()
# ── Gradio 호좜 ────────────────────────────────────
def generate_image():
client = Client(GRADIO_URL)
return client.predict(
height=768,
width=768,
steps=30, # inference_steps β†’ steps
scales=3.5, # guidance β†’ scales
prompt=prompt_en,
seed=random.randint(0, 2**32 - 1),
api_name=GRADIO_API
)[0] # dict(path|url|…)
try:
img_info = await asyncio.get_running_loop().run_in_executor(None, generate_image)
except Exception as e:
logging.error(f"Gradio API error: {e}")
await message.reply("⚠️ 이미지 생성 μ‹€νŒ¨!")
return
# ── Discord 전솑 ──────────────────────────────────
files = []
try:
if isinstance(img_info, str): # 경우 1: λ¬Έμžμ—΄ 경둜/URL
data = requests.get(img_info).content if img_info.startswith("http") else open(img_info, "rb").read()
files.append(discord.File(io.BytesIO(data), filename="generated.webp"))
elif isinstance(img_info, dict): # 경우 2: dict(path|url)
if img_info.get("path"):
data = open(img_info["path"], "rb").read()
elif img_info.get("url"):
data = requests.get(img_info["url"]).content
else:
data = None
if data:
files.append(discord.File(io.BytesIO(data), filename="generated.webp"))
except Exception as e:
logging.warning(f"이미지 처리 μ‹€νŒ¨: {e}")
await message.reply(
files=files if files else None,
content=None if files else "⚠️ 이미지λ₯Ό 전솑할 수 μ—†μŠ΅λ‹ˆλ‹€."
)
# ── μ‹€ν–‰ ────────────────────────────────────────────────────
if __name__ == "__main__":
replicate.Client(api_token=REPL_TOKEN) # ꡬ쑰 μœ μ§€(μ‚¬μš© μ•ˆ 함)
ImageBot(intents=intents).run(TOKEN)