fantos commited on
Commit
49ec9dc
Β·
verified Β·
1 Parent(s): 1b947fd

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -0
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # img_bot.py
2
+ import discord, os, io, re, asyncio, logging, requests, replicate, subprocess
3
+ from transformers import pipeline as transformers_pipeline # λ²ˆμ—­ νŒŒμ΄ν”„λΌμΈ
4
+
5
+ # ── ν™˜κ²½ λ³€μˆ˜ ────────────────────────────────────────────────
6
+ TOKEN = os.getenv("DISCORD_TOKEN") # Discord 봇 토큰
7
+ CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID")) # κ°μ‹œν•  채널 ID
8
+ REPL_TOKEN = (os.getenv("OPENAI_API_KEY") or "").strip() # Replicate 토큰(동일 λ³€μˆ˜ μ‚¬μš©)
9
+ HF_TOKEN = (os.getenv("HF_TOKEN") or "").strip() # Hugging Face Personal Access Token
10
+
11
+ if not TOKEN or not CHANNEL_ID:
12
+ raise RuntimeError("DISCORD_TOKEN κ³Ό DISCORD_CHANNEL_ID ν™˜κ²½ λ³€μˆ˜λ₯Ό λͺ¨λ‘ μ§€μ •ν•˜μ„Έμš”.")
13
+
14
+ if not REPL_TOKEN:
15
+ raise RuntimeError(
16
+ "OPENAI_API_KEY ν™˜κ²½ λ³€μˆ˜μ— Replicate Personal Access Token 값을 λ„£μ–΄μ£Όμ„Έμš”."
17
+ )
18
+
19
+ # Replicate λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ°Έμ‘°ν•˜λ„λ‘ 토큰 μ£Όμž…
20
+ os.environ["REPLICATE_API_TOKEN"] = REPL_TOKEN
21
+
22
+ # ── λͺ¨λΈ ────────────────────────────────────────────────────
23
+ MODEL = (
24
+ "bytedance/sdxl-lightning-4step:"
25
+ "6f7a773af6fc3e8de9d5a3c00be77c17308914bf67772726aff83496ba1e3bbe"
26
+ )
27
+
28
+ # ── λ²ˆμ—­ νŒŒμ΄ν”„λΌμΈ (CPU) ───────────────────────────────────
29
+ translator_kwargs = {"device": -1}
30
+ if HF_TOKEN:
31
+ translator_kwargs["token"] = HF_TOKEN # 인증 토큰 전달
32
+
33
+ translator = transformers_pipeline(
34
+ "translation",
35
+ model="Helsinki-NLP/opus-mt-ko-en",
36
+ **translator_kwargs
37
+ )
38
+
39
+ def ko2en(text: str) -> str:
40
+ """ν•œκΈ€ 포함 μ‹œ μ˜μ–΄ λ²ˆμ—­, κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ 원문 λ°˜ν™˜."""
41
+ if re.search(r"[κ°€-힣]", text):
42
+ try:
43
+ return translator(text, max_length=512)[0]["translation_text"].strip()
44
+ except Exception as e:
45
+ logging.warning(f"λ²ˆμ—­ μ‹€νŒ¨, 원문 μ‚¬μš©: {e}")
46
+ return text
47
+
48
+ # ── λ‘œκΉ… ────────────────────────────────────────────────────
49
+ logging.basicConfig(
50
+ level=logging.INFO,
51
+ format="%(asctime)s [%(levelname)s] %(message)s",
52
+ handlers=[logging.StreamHandler()]
53
+ )
54
+
55
+ # ── Discord μ„€μ • ────────────────────────────────────────────
56
+ intents = discord.Intents.default()
57
+ intents.message_content = True # λ©”μ‹œμ§€ μ½˜ν…μΈ  읽기
58
+
59
+ class ImageBot(discord.Client):
60
+ async def on_ready(self):
61
+ logging.info(f"Logged in as {self.user} (id={self.user.id})")
62
+ # web.py 병렬 μ‹€ν–‰
63
+ try:
64
+ subprocess.Popen(["python", "web.py"])
65
+ logging.info("web.py server has been started.")
66
+ except Exception as e:
67
+ logging.warning(f"web.py μ‹€ν–‰ μ‹€νŒ¨: {e}")
68
+
69
+ async def on_message(self, message: discord.Message):
70
+ # 봇 μžμ‹ μ˜ λ©”μ‹œμ§€ ν˜Ήμ€ λŒ€μƒ μ•„λ‹Œ 채널 β†’ λ¬΄μ‹œ
71
+ if message.author.id == self.user.id or message.channel.id != CHANNEL_ID:
72
+ return
73
+
74
+ prompt = message.content.strip()
75
+ if not prompt:
76
+ return
77
+
78
+ prompt_en = ko2en(prompt) # ν•œκΈ€μ΄λ©΄ μ˜μ–΄λ‘œ λ³€ν™˜
79
+ await message.channel.typing()
80
+
81
+ # ── Replicate 호좜 ──────────────────────────────────
82
+ def run_replicate():
83
+ return list(replicate.run(MODEL, input={"prompt": prompt_en}))
84
+
85
+ try:
86
+ images = await asyncio.get_running_loop().run_in_executor(None, run_replicate)
87
+ except Exception as e:
88
+ logging.error(f"Replicate error: {e}")
89
+ await message.reply("⚠️ 이미지 생성 μ‹€νŒ¨!")
90
+ return
91
+
92
+ # ── 이미지 Discord 전솑 ─────────────────────────────
93
+ files = []
94
+ for idx, item in enumerate(images):
95
+ try:
96
+ data = item.read() if hasattr(item, "read") else requests.get(item).content
97
+ files.append(discord.File(io.BytesIO(data), filename=f"img_{idx}.png"))
98
+ except Exception as e:
99
+ logging.warning(f"[IMG {idx}] 처리 μ‹€νŒ¨: {e}")
100
+
101
+ await message.reply(
102
+ files=files if files else None,
103
+ content=None if files else "⚠️ 이미지λ₯Ό 전솑할 수 μ—†μŠ΅λ‹ˆλ‹€."
104
+ )
105
+
106
+ # ── μ‹€ν–‰ ────────────────────────────────────────────────────
107
+ if __name__ == "__main__":
108
+ replicate.Client(api_token=REPL_TOKEN) # Replicate 인증
109
+ ImageBot(intents=intents).run(TOKEN)