Spaces:
Runtime error
Runtime error
File size: 7,703 Bytes
c48780b c3a9e90 2cfdf65 c3a9e90 c48780b 7b7fd88 b0940a1 c48780b 49ec9dc c3a9e90 444fc48 49ec9dc 7b7fd88 c48780b 49ec9dc c3a9e90 49ec9dc c3a9e90 49ec9dc 7b7fd88 49ec9dc 444fc48 c48780b 444fc48 c80bb75 444fc48 49ec9dc c3a9e90 2cfdf65 c3a9e90 49ec9dc c3a9e90 49ec9dc b0940a1 49ec9dc 7b7fd88 2edcd19 49ec9dc c80bb75 49ec9dc c3a9e90 6659834 444fc48 c80bb75 b6dfa24 b0940a1 b6dfa24 444fc48 6659834 c3a9e90 49ec9dc c3a9e90 49ec9dc 6659834 49ec9dc c48780b c3a9e90 2473562 c3a9e90 c48780b 2473562 c48780b b08146f c3a9e90 c48780b 2473562 c48780b c3a9e90 b08146f 2473562 b08146f 2473562 c48780b b08146f c48780b 2473562 b08146f 2473562 c48780b 2473562 c3a9e90 2473562 b08146f 2473562 c3a9e90 2473562 c3a9e90 c48780b c3a9e90 49ec9dc c48780b c3a9e90 49ec9dc c48780b 49ec9dc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# img_bot.py
# βμ΄λ―Έμ§ μ²¨λΆ β μ€ν¨ μ URL μΆλ ₯β μκ²°ν
import os, io, re, random, asyncio, logging, subprocess, base64
from urllib.parse import urljoin, quote_plus
import discord
import requests
import replicate
from transformers import pipeline as transformers_pipeline
from gradio_client import Client
try:
from PIL import Image # WEBP β PNG λ³ν
PIL_OK = True
except Exception:
PIL_OK = False # Pillow λ―Έμ€μΉ μ λ³ν μλ΅
# ββββββββββββββββββ νκ²½ λ³μ ββββββββββββββββββ
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"
# ββββββββββββββββββ λ²μ νμ΄νλΌμΈ βββββββββββββ
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
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,
scales=3.5,
prompt=prompt_en,
seed=random.randint(0, 2**32 - 1),
api_name=GRADIO_API
)
try:
result = 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
# 리μ€νΈ κ²°κ³Ό β 첫 μμ
if isinstance(result, list):
result = result[0]
# βββββββββββββ μ΄λ―Έμ§ λ°μ΄ν° ν보 βββββββββββββ
data = None
remote_path = None # μ€ν¨ μ μ¬μ©μμκ² λ³΄μ¬μ€ URL
candidate_urls: list[str] = []
def add_remote(p: str):
url = urljoin(GRADIO_URL, f"/gradio_api/file={quote_plus(p)}")
candidate_urls.append(url)
return url
# dict κ²°κ³Ό
if isinstance(result, dict):
u = result.get("url")
if u:
if u.startswith("/"):
u = urljoin(GRADIO_URL, u)
candidate_urls.append(u)
remote_path = u
p = result.get("path")
if p:
remote_path = add_remote(p)
if os.path.isfile(p):
try:
with open(p, "rb") as f:
data = f.read()
except Exception:
pass
# str κ²°κ³Ό
elif isinstance(result, str):
s = result.strip()
if s.startswith("data:"):
try:
data = base64.b64decode(re.sub(r"^data:image/[^;]+;base64,", "", s))
except Exception as e:
logging.warning(f"base64 λμ½λ© μ€ν¨: {e}")
elif s.startswith("http"):
candidate_urls.append(s)
remote_path = s
else:
remote_path = add_remote(s)
if s.startswith("/"):
candidate_urls.append(urljoin(GRADIO_URL, s))
if os.path.isfile(s):
try:
with open(s, "rb") as f:
data = f.read()
except Exception:
pass
# URL λ€μ΄λ‘λ (ν€λ 무μ, 200 OK λ§ νμΈ)
for u in candidate_urls:
if data:
break
try:
r = requests.get(u, timeout=10)
if r.ok and r.content:
data = r.content
break
except Exception as e:
logging.warning(f"URL λ€μ΄λ‘λ μ€ν¨({u}): {e}")
# βββββββββββββ Discord μ μ‘ βββββββββββββ
if data:
if PIL_OK: # WEBP β PNG λ³ν
try:
buf = io.BytesIO()
Image.open(io.BytesIO(data)).convert("RGB").save(buf, format="PNG")
buf.seek(0)
await message.reply(files=[discord.File(buf, filename="image.png")])
return
except Exception as e:
logging.warning(f"PNG λ³ν μ€ν¨: {e}")
# λ³ν μ€ν¨ λλ Pillow μμ β μλ³Έ μ μ‘
await message.reply(files=[discord.File(io.BytesIO(data), filename="image.webp")])
return
# βββββββββββββ μ€ν¨ μ URL μΆλ ₯ βββββββββββββ
if remote_path:
await message.reply(content=remote_path)
else:
await message.reply("β οΈ μ΄λ―Έμ§λ₯Ό μ μ‘ν μ μμ΅λλ€.")
# ββββββββββββββββββ μ€ν ββββββββββββββββββββββββ
if __name__ == "__main__":
replicate.Client(api_token=REPL_TOKEN) # ꡬ쑰 μ μ§
ImageBot(intents=intents).run(TOKEN)
|