aliceblue11 commited on
Commit
925be92
·
verified ·
1 Parent(s): 07cd8bb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -853
app.py CHANGED
@@ -1,797 +1,59 @@
1
- """
2
- 이벤트 공지사항 생성기 - 완전 버전
3
- 그라디오 최신 버전 지원
4
- """
5
-
6
  import gradio as gr
7
- from datetime import datetime, timedelta
8
- from typing import List, Dict, Any
9
- import json
10
- import tempfile
11
- import os
12
-
13
- class EventGenerator:
14
- """이벤트 생성기 메인 클래스"""
15
-
16
- def __init__(self):
17
- self.monthly_data = {
18
- 1: {
19
- "holidays": ["신정", "설날", "대보름"],
20
- "special_days": ["새해", "신년", "다이어트의 달"],
21
- "seasons": ["겨울", "새해맞이", "신년다짐"],
22
- "trends": ["새해 계획", "다이어트", "정리정돈", "미니멀라이프"],
23
- "colors": ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7"]
24
- },
25
- 2: {
26
- "holidays": ["밸런타인데이", "정월대보름"],
27
- "special_days": ["초콜릿데이", "로즈데이"],
28
- "seasons": ["겨울", "입춘", "매화꽃"],
29
- "trends": ["러브", "로맨스", "셀프케어", "따뜻함"],
30
- "colors": ["#FF69B4", "#FFB6C1", "#DC143C", "#FFC0CB", "#8B0000"]
31
- },
32
- 3: {
33
- "holidays": ["삼일절", "화이트데이"],
34
- "special_days": ["여성의 날", "화이트데이"],
35
- "seasons": ["봄", "벚꽃", "춘분", "개화"],
36
- "trends": ["봄맞이", "새학기", "벚꽃놀이", "봄나들이"],
37
- "colors": ["#FFB6C1", "#98FB98", "#87CEEB", "#F0E68C", "#DDA0DD"]
38
- },
39
- 4: {
40
- "holidays": ["만우절", "식목일"],
41
- "special_days": ["블랙데이", "킹데이"],
42
- "seasons": ["봄", "벚꽃만개", "꽃구경"],
43
- "trends": ["벚꽃축제", "봄피크닉", "새학기적응", "아웃도어"],
44
- "colors": ["#FFB6C1", "#98FB98", "#F0E68C", "#DDA0DD", "#87CEEB"]
45
- },
46
- 5: {
47
- "holidays": ["어린이날", "어버이날", "스승의날", "부처님오신날"],
48
- "special_days": ["가정의 달", "로즈데이", "감사데이"],
49
- "seasons": ["봄", "신록", "야외활동"],
50
- "trends": ["가족사랑", "감사", "나들이", "어린이날선물"],
51
- "colors": ["#32CD32", "#FFB6C1", "#87CEEB", "#F0E68C", "#DDA0DD"]
52
- },
53
- 6: {
54
- "holidays": ["현충일", "단오"],
55
- "special_days": ["키스데이", "패밀리데이"],
56
- "seasons": ["초여름", "장마준비", "여름나기"],
57
- "trends": ["여름준비", "다이어트", "워터파크", "바캉스준비"],
58
- "colors": ["#00CED1", "#FFD700", "#FF6347", "#32CD32", "#FF69B4"]
59
- },
60
- 7: {
61
- "holidays": ["제헌절", "초복", "중복"],
62
- "special_days": ["실버데이", "썸머데이"],
63
- "seasons": ["여름", "장마", "휴가철"],
64
- "trends": ["여름휴가", "워터액티비티", "시원한음식", "휴가패션"],
65
- "colors": ["#00BFFF", "#FFD700", "#FF6347", "#32CD32", "#FF69B4"]
66
- },
67
- 8: {
68
- "holidays": ["광복절", "말복"],
69
- "special_days": ["그린데이", "썸머바캉스"],
70
- "seasons": ["여름", "휴가철", "더위절정"],
71
- "trends": ["여름휴가절정", "바다여행", "축제", "여름추억"],
72
- "colors": ["#00BFFF", "#FF6347", "#FFD700", "#32CD32", "#FF69B4"]
73
- },
74
- 9: {
75
- "holidays": ["추석", "추분"],
76
- "special_days": ["포토데이", "뮤직데이"],
77
- "seasons": ["가을", "추석연휴", "선선함"],
78
- "trends": ["추석준비", "가을패션", "독서의계절", "문화생활"],
79
- "colors": ["#FF8C00", "#DC143C", "#B8860B", "#CD853F", "#D2691E"]
80
- },
81
- 10: {
82
- "holidays": ["개천절", "한글날"],
83
- "special_days": ["와인데이", "커피데이"],
84
- "seasons": ["가을", "단풍", "쌀쌀함"],
85
- "trends": ["가을단풍", "독서", "카페문화", "가을나들이"],
86
- "colors": ["#FF8C00", "#DC143C", "#B8860B", "#8B4513", "#A0522D"]
87
- },
88
- 11: {
89
- "holidays": ["빼빼로데이", "수능"],
90
- "special_days": ["무비데이", "오렌지데이"],
91
- "seasons": ["늦가을", "쌀쌀함", "겨울준비"],
92
- "trends": ["빼빼로데이", "수능응원", "겨울준비", "연말준비"],
93
- "colors": ["#8B4513", "#A0522D", "#CD853F", "#D2691E", "#FF8C00"]
94
- },
95
- 12: {
96
- "holidays": ["크리스마스", "성탄절", "동지"],
97
- "special_days": ["허그데이", "키스데이"],
98
- "seasons": ["겨울", "연말", "크리스마스"],
99
- "trends": ["크리스마스", "연말파티", "선물", "한해마무리"],
100
- "colors": ["#DC143C", "#228B22", "#FFD700", "#800080", "#FF69B4"]
101
- }
102
- }
103
-
104
- self.event_templates = {
105
- "댓글 달기 이벤트": {
106
- "steps": ["해당 게시글 찾아가기", "감성적인 댓글 작성하기", "댓글 등록 완료"],
107
- "description": "지정된 게시글에 댓글을 달아주세요"
108
- },
109
- "게시글 작성 이벤트": {
110
- "steps": ["이벤트 주제 확인하기", "창의적인 게시글 작성하기", "해시태그 포함하여 업로드"],
111
- "description": "주제에 맞는 게시글을 작성해주세요"
112
- },
113
- "좋아요/공감 이벤트": {
114
- "steps": ["이벤트 게시글 확인하기", "좋아요 버튼 클릭하기", "추가 액션 완료하기"],
115
- "description": "마음에 드는 게시글에 좋아요를 눌러주세요"
116
- },
117
- "출석체크 이벤트": {
118
- "steps": ["매일 커뮤니티 접속하기", "출석체크 버튼 클릭하기", "연속 출석 달성하기"],
119
- "description": "매일 커뮤니티에 방문하여 출석체크를 해주세요"
120
- },
121
- "추천인 이벤트": {
122
- "steps": ["초대 링크 생성하기", "친구에게 링크 공유하기", "친구 가입 완료 확인하기"],
123
- "description": "친구를 초대하고 함께 이벤트에 참여해주세요"
124
- },
125
- "사진 업로드 이벤트": {
126
- "steps": ["테마에 맞는 사진 촬영하기", "사진 업로드하기", "설명글과 함께 공유하기"],
127
- "description": "테마에 맞는 사진을 업로드해주세요"
128
- },
129
- "퀴즈/설문 이벤트": {
130
- "steps": ["퀴즈 문제 확인하기", "정답 또는 의견 제출하기", "제출 완료 확인하기"],
131
- "description": "퀴즈를 풀거나 설문에 참여해주세요"
132
- }
133
- }
134
-
135
- def analyze_monthly_concepts(self, month: int, year: int = 2025) -> List[Dict[str, Any]]:
136
- """월별 컨셉 분석"""
137
-
138
- month_data = self.monthly_data.get(month, {})
139
- concepts = []
140
-
141
- # 컨셉 1: 주요 기념일 기반
142
- if month_data.get("holidays"):
143
- main_holiday = month_data["holidays"][0]
144
- concepts.append({
145
- "name": f"{main_holiday} 특별 이벤트",
146
- "theme": f"{main_holiday}를 테마로 한 감성 이벤트",
147
- "catchphrase": f"💕 {main_holiday}과 함께 특별한 추억을 만들어요!",
148
- "reason": f"{month}월의 대표 기념일인 {main_holiday}로 높은 관심과 참여도 예상",
149
- "colors": month_data.get("colors", ["#FF69B4"])[:3],
150
- "participation_score": 8.5,
151
- "participation_reason": "주요 기념일로 인한 높은 관심도와 시즌성",
152
- "event_style": "댓글 이벤트 + 인증샷 업로드",
153
- "competitive_edge": "시즌 특화 컨텐츠로 차별화",
154
- "target_appeal": "기념일 감성과 공감대 형성"
155
- })
156
-
157
- # 컨셉 2: 계절/트렌드 기반
158
- if month_data.get("trends"):
159
- trend_theme = month_data["trends"][0]
160
- concepts.append({
161
- "name": f"{trend_theme} 챌린지",
162
- "theme": f"최신 {trend_theme} 트렌드 참여형 이벤트",
163
- "catchphrase": f"✨ 지금 핫한 {trend_theme}! 함께 도전해요!",
164
- "reason": f"현재 인기 트렌드인 {trend_theme}로 젊은 층 어필",
165
- "colors": month_data.get("colors", ["#4ECDC4"])[1:4],
166
- "participation_score": 8.0,
167
- "participation_reason": "최신 트렌드로 인한 화제성과 참여욕구",
168
- "event_style": "챌린지 참여 + SNS 공유",
169
- "competitive_edge": "트렌드 선도적 이벤트",
170
- "target_appeal": "트렌드 민감층과 SNS 활용"
171
- })
172
-
173
- # 컨셉 3: 계절감 기반
174
- if month_data.get("seasons"):
175
- season_theme = month_data["seasons"][0]
176
- concepts.append({
177
- "name": f"{season_theme} 라이프 이벤트",
178
- "theme": f"{season_theme} 계절 맞이 라이프스타일 이벤트",
179
- "catchphrase": f"🌸 {season_theme}과 함께하는 일상의 소소한 행복!",
180
- "reason": f"{season_theme} 계절감으로 자연스러운 참여 유도",
181
- "colors": month_data.get("colors", ["#98FB98"])[2:5],
182
- "participation_score": 7.5,
183
- "participation_reason": "계절적 공감대와 일상 연관성",
184
- "event_style": "포토 챌린지 + 후기 공유",
185
- "competitive_edge": "계절별 맞춤 컨텐츠",
186
- "target_appeal": "일상 속 계절감과 감성"
187
- })
188
-
189
- # 컨셉 4: 커뮤니티 소통 기반
190
- concepts.append({
191
- "name": f"{month}월 우리들의 이야기",
192
- "theme": "커뮤니티 멤버 간 소통과 공감 이벤트",
193
- "catchphrase": f"💬 {month}월, 우리의 특별한 이야기를 들려주세요!",
194
- "reason": "커뮤니티 결속력 강화와 지속적 참여 유도",
195
- "colors": month_data.get("colors", ["#87CEEB"])[-3:],
196
- "participation_score": 7.0,
197
- "participation_reason": "커뮤니티 애착도와 소속감 기반 참여",
198
- "event_style": "스토리텔링 + 공감 이벤트",
199
- "competitive_edge": "진정성 있는 커뮤니티 소통",
200
- "target_appeal": "소속감과 공감대 형성"
201
- })
202
-
203
- # 컨셉 5: 스페셜 데이 기반
204
- if month_data.get("special_days"):
205
- special_day = month_data["special_days"][0]
206
- concepts.append({
207
- "name": f"{special_day} 스페셜 위크",
208
- "theme": f"{special_day} 맞이 특별 혜택 이벤트",
209
- "catchphrase": f"🎁 {special_day} 특별한 선물이 기다려요!",
210
- "reason": f"{special_day}의 특별함을 활용한 프리미엄 이벤트",
211
- "colors": month_data.get("colors", ["#FFB6C1"])[:3],
212
- "participation_score": 7.8,
213
- "participation_reason": "특별한 날에 대한 기대감과 혜택 관심",
214
- "event_style": "미션 완료 + 럭키박스",
215
- "competitive_edge": "특별 혜택과 깜짝 이벤트",
216
- "target_appeal": "특별함과 혜택에 대한 기대"
217
- })
218
-
219
- return concepts
220
-
221
- def generate_event_notice(self, concept_data: Dict, event_type: str, custom_event: str = None) -> str:
222
- """완성된 이벤트 공지사항 생성"""
223
-
224
- concept_name = concept_data.get("name", "특별 이벤트")
225
- catchphrase = concept_data.get("catchphrase", "✨ 특별한 이벤트에 참여하세요!")
226
- theme = concept_data.get("theme", "커뮤니티 이벤트")
227
-
228
- # 이벤트 기간 설정
229
- now = datetime.now()
230
- start_date = now.strftime("%Y.%m.%d")
231
- end_date = (now + timedelta(days=7)).strftime("%Y.%m.%d")
232
-
233
- # 템플릿 선택
234
- if custom_event and event_type == "직접 입력":
235
- template = {
236
- "description": custom_event,
237
- "steps": ["이벤트 내용 확인하기", "요구사항에 맞게 참여하기", "참여 완료 확인하기"]
238
- }
239
- else:
240
- template = self.event_templates.get(event_type, self.event_templates["댓글 달기 이벤트"])
241
-
242
- # 공지사항 생성
243
- notice = f"""{catchphrase}
244
-
245
- 🎉 {concept_name} 🎉
246
-
247
- 📅 이벤트 기간: {start_date} ~ {end_date} 23:59
248
-
249
- ========================
250
- ✨ EVENT
251
- {theme}을 테마로 한 특별한 이벤트에 참여하세요!
252
- 많은 분들의 적극적인 참여를 기다리고 있어요 💕
253
-
254
- 📅 이벤트 기간: {start_date} ~ {end_date}
255
- ========================
256
-
257
- 🎯 STEP 1
258
- {template["steps"][0]}
259
- * 이벤트 게시글을 꼼꼼히 확인해주세요!
260
-
261
- 🎯 STEP 2
262
- {template["steps"][1]}
263
- * 진심이 담긴 따뜻한 마음으로 참여해주세요
264
-
265
- 🎯 STEP 3
266
- {template["steps"][2]}
267
- * 모든 과정을 완료하시면 참여 완료입니다!
268
-
269
- =================
270
- 🎁 당첨혜택
271
- ✨ 1등 (1명): 스타벅스 5만원 기프트카드
272
- 🎉 2등 (3명): 베스킨라빈스 아이스크림 쿠폰
273
- 💝 3등 (10명): 편의점 5천원 상품권
274
- 🌟 참가상 (50명): 모바일 치킨 쿠폰
275
-
276
- 📋 추첨 방식: 참여자 중 무작위 추첨
277
- ========================
278
-
279
- 👥 이벤트 대상
280
- ✅ 커뮤니티 정회원 (가입 후 7일 경과)
281
- ✅ 만 18세 이상 성인
282
- ✅ 이벤트 기간 내 정상 참여자
283
-
284
- (*중복 참여, 어뷰징 계정 제외)
285
- ========================
286
-
287
- 📮 수령방법
288
- 1️⃣ 당첨자 발표: 이벤트 종료 후 3일 이내
289
- 2️⃣ 개별 메시지를 통한 당첨 안내
290
- 3️⃣ 본인 확인 후 7일 이내 회신 필수
291
- 4️⃣ 모바일 쿠폰/기프트카드 발송
292
-
293
- 📞 문의처: 커뮤니티 고객센터
294
- 🕐 수령 기한: 당첨 안내 후 30일 이내
295
- =========================
296
-
297
- ⚠️ 꼭 확인하세요!
298
- ※ 부적절한 내용의 댓글/게시글은 삭제될 수 있습니다
299
- ※ 중복 계정이나 어뷰징으로 의심되는 참여는 제외됩니다
300
- ※ 당첨자는 본인 확인을 위해 추가 정보 요청이 있을 수 있습니다
301
- ※ 상품은 현금으로 교환되지 않으며, 재판매가 불가합니다
302
- ※ 이벤트 내용은 운영진의 판단에 따라 변경될 수 있습니다
303
- ※ 문의사항은 고객센터를 통��� 연락해주세요
304
-
305
- ===========================
306
- 📞 고객센터: 1234-5678
307
- 🕐 운영시간: 평일 09:30~18:00 (점심시간 12:00~13:00)
308
- 💬 카카오톡: @event_community
309
- ※ 주말 및 공휴일 휴무
310
-
311
- 💝 많은 분들의 참여 부탁드려요! 감사합니다 💕"""
312
-
313
- return notice.strip()
314
-
315
- def count_text_stats(self, text: str) -> str:
316
- """텍스트 통계 계산"""
317
- total_chars = len(text)
318
- chars_no_space = len(text.replace(" ", "").replace("\n", ""))
319
- words = len(text.split())
320
- lines = len(text.split("\n"))
321
-
322
- return f"총 글자수: {total_chars:,}자 | 공백제외: {chars_no_space:,}자 | 단어수: {words:,}개 | 줄수: {lines:,}줄"
323
 
324
- def create_app():
325
- """그라디오 생성"""
326
-
327
- generator = EventGenerator()
328
 
329
- # 커스텀 CSS
330
- custom_css = """
331
- .main-header {
332
- text-align: center;
333
- padding: 30px;
334
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
335
- color: white;
336
- border-radius: 15px;
337
- margin-bottom: 25px;
338
- box-shadow: 0 4px 15px rgba(0,0,0,0.1);
339
- }
340
- .input-section {
341
- background: #f8f9fa;
342
- padding: 25px;
343
- border-radius: 15px;
344
- box-shadow: 0 2px 10px rgba(0,0,0,0.05);
345
- margin-bottom: 20px;
346
- }
347
- .output-section {
348
- background: white;
349
- padding: 25px;
350
- border-radius: 15px;
351
- box-shadow: 0 2px 10px rgba(0,0,0,0.05);
352
- }
353
- .concept-card {
354
- background: linear-gradient(45deg, #e3f2fd, #f1f8e9);
355
- padding: 20px;
356
- border-radius: 12px;
357
- margin: 15px 0;
358
- border-left: 5px solid #2196f3;
359
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
360
- }
361
- .stats-box {
362
- background: #fff3cd;
363
- padding: 10px;
364
- border-radius: 8px;
365
- border: 1px solid #ffeaa7;
366
- margin-top: 10px;
367
  }
368
- """
369
 
370
- with gr.Blocks(
371
- title="🎉 AI 이벤트 공지사항 생성기",
372
- theme=gr.themes.Soft(),
373
- css=custom_css
374
- ) as demo:
375
-
376
- # 헤더
377
- with gr.Column(elem_classes="main-header"):
378
- gr.Markdown("""
379
- # 🎉 AI 이벤트 공지사항 생성기
380
- ### 실시간 트렌드 분석으로 완벽한 이벤트 기획을 도와드립니다
381
- #### 20-40대 여성 타겟 커뮤니티 이벤트 전문 생성기
382
- """)
383
-
384
- with gr.Row():
385
- # 좌측: 입력 영역
386
- with gr.Column(scale=1, elem_classes="input-section"):
387
- gr.Markdown("## ⚙️ 기본 설정")
388
-
389
- with gr.Row():
390
- year_input = gr.Number(
391
- value=2025,
392
- label="📅 연도",
393
- minimum=2024,
394
- maximum=2030,
395
- step=1
396
- )
397
-
398
- month_input = gr.Dropdown(
399
- choices=[f"{i}월" for i in range(1, 13)],
400
- label="📅 이벤트 월 선택",
401
- value=f"{datetime.now().month}월"
402
- )
403
-
404
- analyze_btn = gr.Button(
405
- "🧠 AI 컨셉 분석 시작",
406
- variant="secondary",
407
- size="lg"
408
- )
409
-
410
- # 컨셉 선택 영역
411
- with gr.Group(visible=False) as concept_group:
412
- gr.Markdown("### 🎨 추천 컨셉 선택")
413
-
414
- concept_selector = gr.Dropdown(
415
- label="컨셉을 선택해주세요",
416
- interactive=True
417
- )
418
-
419
- concept_preview = gr.Textbox(
420
- label="📊 선택된 컨셉 미리보기",
421
- lines=8,
422
- interactive=False
423
- )
424
-
425
- gr.Markdown("## 🎯 이벤트 설정")
426
-
427
- event_type_selector = gr.Dropdown(
428
- choices=[
429
- "댓글 달기 이벤트",
430
- "게시글 작성 이벤트",
431
- "좋아요/공감 이벤트",
432
- "출석체크 이벤트",
433
- "추천인 이벤트",
434
- "사진 업로드 이벤트",
435
- "퀴즈/설문 이벤트",
436
- "직접 입력"
437
- ],
438
- label="🎯 이벤트 유형 선택",
439
- value="댓글 달기 이벤트"
440
- )
441
-
442
- custom_event_input = gr.Textbox(
443
- label="✏️ 커스텀 이벤트 설명",
444
- placeholder="'직접 입력' 선택시 원하는 이벤트 내용을 자세히 설명해주세요",
445
- visible=False,
446
- lines=4
447
- )
448
-
449
- generate_btn = gr.Button(
450
- "✨ 완성된 공지사항 생성하기",
451
- variant="primary",
452
- size="lg",
453
- visible=False
454
- )
455
-
456
- # 우측: 결과 출력 영역
457
- with gr.Column(scale=2, elem_classes="output-section"):
458
-
459
- with gr.Tabs() as tabs:
460
-
461
- with gr.TabItem("🧠 AI 컨셉 분석"):
462
- concept_analysis_output = gr.Markdown(
463
- value="👆 먼저 좌측에서 연도와 월을 선택한 후 'AI 컨셉 분석 시작' 버튼을 클릭해주세요",
464
- elem_classes="concept-card"
465
- )
466
-
467
- with gr.TabItem("📝 완성된 공지사항"):
468
- final_notice_output = gr.Textbox(
469
- label="생성된 이벤트 공지사항",
470
- lines=35,
471
- placeholder="컨셉 선택 후 '완성된 공지사항 생성하기' 버튼을 클릭하면 결과가 나타납니다",
472
- show_copy_button=True,
473
- max_lines=50
474
- )
475
-
476
- # 통계 및 버튼
477
- with gr.Row():
478
- text_stats_output = gr.Textbox(
479
- label="📊 텍스트 통계",
480
- lines=1,
481
- interactive=False,
482
- visible=False,
483
- elem_classes="stats-box"
484
- )
485
-
486
- with gr.Row():
487
- download_btn = gr.DownloadButton(
488
- "💾 텍스트 파일로 다운로드",
489
- size="sm",
490
- variant="secondary",
491
- visible=False
492
- )
493
- regenerate_btn = gr.Button(
494
- "🔄 다시 생성하기",
495
- size="sm",
496
- visible=False
497
- )
498
-
499
- with gr.TabItem("🎨 컨셉 상세정보"):
500
- concept_details_output = gr.JSON(
501
- label="선택된 컨셉의 상세 정보",
502
- visible=False
503
- )
504
-
505
- # 상태 관리
506
- concepts_state = gr.State([])
507
- selected_concept_state = gr.State(None)
508
-
509
- # 이벤트 핸들러 함수들
510
- def handle_concept_analysis(year, month):
511
- """AI 컨셉 분석 처리"""
512
- try:
513
- month_num = int(month.replace('월', ''))
514
- concepts = generator.analyze_monthly_concepts(month_num, year)
515
-
516
- concept_choices = [f"{concept['name']} - {concept['theme']}" for concept in concepts]
517
-
518
- # 분석 결과 마크다운 생성
519
- analysis_md = f"# 🎯 {year}년 {month} AI 분석 결과\n\n"
520
- analysis_md += f"**분석 완료:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
521
- analysis_md += f"**총 {len(concepts)}개 컨셉 추천**\n\n"
522
-
523
- for i, concept in enumerate(concepts, 1):
524
- colors_display = " ".join([f"`{color}`" for color in concept['colors'][:3]])
525
-
526
- analysis_md += f"""
527
- ## {i}. {concept['name']}
528
- **🏷️ 테마:** {concept['theme']}
529
- **🎯 타겟 어필:** {concept['target_appeal']}
530
- **⭐ 예상 참여도:** {concept['participation_score']}/10점
531
- **🎪 추천 이벤트:** {concept['event_style']}
532
- **🎨 색상 팔레트:** {colors_display}
533
- **💡 선정 이유:** {concept['reason']}
534
-
535
- ---
536
- """
537
-
538
- return (
539
- gr.update(visible=True), # concept_group
540
- gr.update(choices=concept_choices, value=concept_choices[0] if concept_choices else None), # concept_selector
541
- gr.update(visible=True), # generate_btn
542
- analysis_md, # concept_analysis_output
543
- concepts # concepts_state
544
- )
545
-
546
- except Exception as e:
547
- error_message = f"❌ 컨셉 분석 중 오류가 발생했습니다: {str(e)}"
548
- return (
549
- gr.update(visible=False),
550
- gr.update(choices=[], value=None),
551
- gr.update(visible=False),
552
- error_message,
553
- []
554
- )
555
-
556
- def handle_concept_selection(selected_concept_name, concepts_data):
557
- """컨셉 선택 처리"""
558
- try:
559
- if selected_concept_name and concepts_data:
560
- selected_idx = next(i for i, c in enumerate(concepts_data)
561
- if f"{c['name']} - {c['theme']}" == selected_concept_name)
562
- selected_concept = concepts_data[selected_idx]
563
-
564
- # 미리보기 텍스트 생성
565
- preview_text = f"""🎨 컨셉명: {selected_concept['name']}
566
-
567
- 🏷️ 테마: {selected_concept['theme']}
568
-
569
- 💬 캐치프레이즈: {selected_concept['catchphrase']}
570
-
571
- 🎯 타겟 어필: {selected_concept['target_appeal']}
572
-
573
- ⭐ 예상 참여도: {selected_concept['participation_score']}/10점
574
- 📊 참여 근거: {selected_concept['participation_reason']}
575
-
576
- 🎪 추천 이벤트: {selected_concept['event_style']}
577
-
578
- 🎨 색상 팔레트: {', '.join(selected_concept['colors'][:3])}
579
-
580
- 💡 차별화 포인트: {selected_concept['competitive_edge']}"""
581
-
582
- return preview_text, selected_concept, gr.update(value=selected_concept, visible=True)
583
- return "", None, gr.update(visible=False)
584
- except Exception as e:
585
- return f"❌ 컨셉 선택 오류: {str(e)}", None, gr.update(visible=False)
586
-
587
- def handle_event_type_change(event_type):
588
- """이벤트 유형 변경 처리"""
589
- return gr.update(visible=(event_type == "직접 입력"))
590
-
591
- def handle_final_generation(year, month, selected_concept, event_type, custom_event):
592
- """최종 공지사항 생성 처리"""
593
- try:
594
- if not selected_concept:
595
- return (
596
- "❌ 먼저 컨셉을 선택해주세요!",
597
- gr.update(visible=False),
598
- gr.update(visible=False),
599
- gr.update(visible=False),
600
- ""
601
- )
602
-
603
- # 공지사항 생성
604
- notice = generator.generate_event_notice(
605
- concept_data=selected_concept,
606
- event_type=event_type,
607
- custom_event=custom_event
608
- )
609
-
610
- # 텍스트 통계
611
- stats = generator.count_text_stats(notice)
612
-
613
- # 다운로드 파일 준비
614
- def prepare_download():
615
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
616
- filename = f"event_notice_{timestamp}.txt"
617
-
618
- temp_file = tempfile.NamedTemporaryFile(
619
- mode='w',
620
- suffix='.txt',
621
- delete=False,
622
- encoding='utf-8'
623
- )
624
- temp_file.write(notice)
625
- temp_file.close()
626
-
627
- return temp_file.name
628
-
629
- return (
630
- notice, # final_notice_output
631
- gr.update(visible=True, value=stats), # text_stats_output
632
- gr.update(visible=True), # download_btn
633
- gr.update(visible=True), # regenerate_btn
634
- prepare_download() # 다운로드 파일
635
- )
636
-
637
- except Exception as e:
638
- error_message = f"❌ 공지사항 생성 중 오류가 발생했습니다: {str(e)}"
639
- return (
640
- error_message,
641
- gr.update(visible=False),
642
- gr.update(visible=False),
643
- gr.update(visible=False),
644
- ""
645
- )
646
-
647
- def handle_regeneration(year, month, selected_concept, event_type, custom_event):
648
- """공지사항 재생성"""
649
- return handle_final_generation(year, month, selected_concept, event_type, custom_event)
650
-
651
- # 이벤트 바인딩
652
- analyze_btn.click(
653
- handle_concept_analysis,
654
- inputs=[year_input, month_input],
655
- outputs=[concept_group, concept_selector, generate_btn, concept_analysis_output, concepts_state]
656
- )
657
-
658
- concept_selector.change(
659
- handle_concept_selection,
660
- inputs=[concept_selector, concepts_state],
661
- outputs=[concept_preview, selected_concept_state, concept_details_output]
662
- )
663
-
664
- event_type_selector.change(
665
- handle_event_type_change,
666
- inputs=[event_type_selector],
667
- outputs=[custom_event_input]
668
- )
669
-
670
- generate_btn.click(
671
- handle_final_generation,
672
- inputs=[year_input, month_input, selected_concept_state, event_type_selector, custom_event_input],
673
- outputs=[final_notice_output, text_stats_output, download_btn, regenerate_btn, download_btn]
674
- )
675
-
676
- regenerate_btn.click(
677
- handle_regeneration,
678
- inputs=[year_input, month_input, selected_concept_state, event_type_selector, custom_event_input],
679
- outputs=[final_notice_output, text_stats_output, download_btn, regenerate_btn, download_btn]
680
- )
681
 
682
- return demo
683
-
684
- def main():
685
- """메인 실행 함수"""
686
- print("🎉 이벤트 공지사항 생성기를 시작합니다...")
687
- print("📚 그라디오 최신 버전으로 실행 중...")
688
 
689
- try:
690
- # 애플리케이션 생성
691
- demo = create_app()
692
-
693
- # 서버 실행
694
- print("🚀 서버를 시작합니다...")
695
- demo.launch(
696
- server_name="0.0.0.0",
697
- server_port=7860,
698
- share=True,
699
- show_tips=True,
700
- show_error=True
701
- )
702
-
703
- except Exception as e:
704
- print(f"❌ 애플리케이션 시작 중 오류 발생: {e}")
705
- import traceback
706
- traceback.print_exc()
707
-
708
- if __name__ == "__main__":
709
- main()"""
710
- 이벤트 공지사항 생성기 - 기본 버전 (MVP)
711
- """
712
 
713
- import gradio as gr
714
- from datetime import datetime
715
- from typing import List, Dict, Any
716
-
717
- class BasicEventGenerator:
718
- """기본 이벤트 생성기"""
719
 
720
- def __init__(self):
721
- self.monthly_data = {
722
- 1: {"holidays": ["신정", "설날"], "trends": ["새해 계획", "다이어트"], "colors": ["#FF6B6B", "#4ECDC4", "#45B7D1"]},
723
- 2: {"holidays": ["밸런타인데이"], "trends": ["러브", "로맨스"], "colors": ["#FF69B4", "#FFB6C1", "#DC143C"]},
724
- 3: {"holidays": ["삼일절", "화이트데이"], "trends": ["봄맞이", "벚꽃놀이"], "colors": ["#FFB6C1", "#98FB98", "#87CEEB"]},
725
- 4: {"holidays": ["만우절"], "trends": ["벚꽃축제", "봄피크닉"], "colors": ["#98FB98", "#F0E68C", "#DDA0DD"]},
726
- 5: {"holidays": ["어린이날", "어버이날"], "trends": ["가족사랑", "나들이"], "colors": ["#32CD32", "#FFB6C1", "#87CEEB"]},
727
- 6: {"holidays": ["현충일"], "trends": ["여름준비", "바캉스준비"], "colors": ["#00CED1", "#FFD700", "#FF6347"]},
728
- 7: {"holidays": ["제헌절"], "trends": ["여름휴가", "바다여행"], "colors": ["#00BFFF", "#FFD700", "#FF6347"]},
729
- 8: {"holidays": ["광복절"], "trends": ["여름휴가절정", "축제"], "colors": ["#00BFFF", "#FF6347", "#FFD700"]},
730
- 9: {"holidays": ["추석"], "trends": ["추석준비", "가을패션"], "colors": ["#FF8C00", "#DC143C", "#B8860B"]},
731
- 10: {"holidays": ["개천절", "한글날"], "trends": ["가을단풍", "독서"], "colors": ["#FF8C00", "#DC143C", "#B8860B"]},
732
- 11: {"holidays": ["빼빼로데이"], "trends": ["빼빼로데이", "겨울준비"], "colors": ["#8B4513", "#A0522D", "#CD853F"]},
733
- 12: {"holidays": ["크리스마스"], "trends": ["크리스마스", "연말파티"], "colors": ["#DC143C", "#228B22", "#FFD700"]}
734
- }
735
 
736
- def analyze_month_concepts(self, month: int) -> List[Dict[str, Any]]:
737
- """월별 간단한 컨셉 분석"""
738
-
739
- month_data = self.monthly_data.get(month, {})
740
- concepts = []
741
-
742
- # 컨셉 1: 기념일 기반
743
- if month_data.get("holidays"):
744
- holiday = month_data["holidays"][0]
745
- concepts.append({
746
- "name": f"{holiday} 특별 이벤트",
747
- "theme": f"{holiday}를 테마로 한 이벤트",
748
- "score": 8.5,
749
- "colors": month_data.get("colors", ["#FF69B4"])
750
- })
751
-
752
- # 컨셉 2: 트렌드 기반
753
- if month_data.get("trends"):
754
- trend = month_data["trends"][0]
755
- concepts.append({
756
- "name": f"{trend} 챌린지",
757
- "theme": f"{trend} 트렌드 이벤트",
758
- "score": 7.8,
759
- "colors": month_data.get("colors", ["#87CEEB"])
760
- })
761
-
762
- # 컨셉 3: 커뮤니티 기반
763
- concepts.append({
764
- "name": f"{month}월 소통 이벤트",
765
- "theme": "커뮤니티 멤버 소통 이벤트",
766
- "score": 7.0,
767
- "colors": month_data.get("colors", ["#98FB98"])
768
- })
769
-
770
- return concepts
771
 
772
- def generate_notice(self, concept: Dict, event_type: str) -> str:
773
- """기본 공지사항 생성"""
774
-
775
- now = datetime.now()
776
- start_date = f"{now.year}.{now.month}.{now.day}"
777
- end_date = f"{now.year}.{now.month}.{now.day + 7}"
778
-
779
- notice = f"""
780
- 💕 {concept['name']}에 참여하세요!
781
 
782
- 🎉 {concept['name']} 🎉
783
 
784
  📅 이벤트 기간: {start_date} ~ {end_date} 23:59
785
 
786
  ========================
787
  ✨ EVENT
788
- {concept['theme']}을 테마로 한 특별한 이벤트입니다!
789
- 많은 분들의 적극적인 참여를 기다리고 있어요 💕
790
  ========================
791
 
792
  🎯 참여 방법
793
- 1️⃣ 이벤트 게시글 확인하기
794
- 2️⃣ {event_type} 참여하기
795
  3️⃣ 참여 완료!
796
 
797
  =================
@@ -804,147 +66,116 @@ class BasicEventGenerator:
804
  ========================
805
 
806
  👥 이벤트 대상
807
- ✅ 커뮤니티 정회원
808
  ✅ 만 18세 이상
809
  ✅ 이벤트 기간 내 참여자
810
  ========================
811
 
812
  ⚠️ 주의사항
813
  ※ 부적절한 참여는 제외됩니다
814
- ※ 중복 계정 참여 불가
815
  ※ 당첨자는 본인 확인 필요
816
 
817
  ===========================
818
  📞 문의: 1234-5678
819
  💬 카카오톡: @event_community
820
 
821
- 💝 많은 참여 부탁드려요! 감사합니다 💕
822
- """
823
-
824
- return notice.strip()
825
 
826
  def create_interface():
827
  """그라디오 인터페이스 생성"""
828
 
829
- generator = BasicEventGenerator()
830
-
831
  with gr.Blocks(title="이벤트 공지사항 생성기") as demo:
832
 
833
- gr.Markdown("""
834
- # 🎉 이벤트 공지사항 생성기
835
- ### 간편하게 이벤트 공지사항을 만들어보세요!
836
- """)
837
 
838
  with gr.Row():
839
  with gr.Column():
840
- gr.Markdown("## ⚙️ 설정")
841
 
842
- month_input = gr.Dropdown(
843
  choices=[f"{i}월" for i in range(1, 13)],
844
- label="📅 이벤트 월",
845
- value=f"{datetime.now().month}월"
846
- )
847
-
848
- event_type_input = gr.Dropdown(
849
- choices=["댓글 달기", "게시글 작성", "좋아요 누르기", "출석체크"],
850
- label="🎯 이벤트 유형",
851
- value="댓글 달기"
852
  )
853
 
854
- analyze_btn = gr.Button("🧠 컨셉 분석하기", variant="secondary")
855
 
856
  concept_dropdown = gr.Dropdown(
857
- label="🎨 컨셉 선택",
858
  visible=False
859
  )
860
 
861
- generate_btn = gr.Button("✨ 공지사항 생성하기", variant="primary", visible=False)
 
 
 
 
 
 
862
 
863
  with gr.Column():
864
- gr.Markdown("## 📝 결과")
865
 
866
- concept_result = gr.Textbox(
867
- label="컨셉 분석 결과",
868
- lines=8,
869
  placeholder="먼저 '컨셉 분석하기' 버튼을 클릭하세요"
870
  )
871
 
872
- final_result = gr.Textbox(
873
  label="생성된 공지사항",
874
  lines=20,
875
- placeholder="컨셉을 선택하고 '공지사항 생성하기' 버튼을 클릭하세요",
876
- show_copy_button=True
877
  )
878
 
879
  # 상태 변수
880
  concepts_state = gr.State([])
881
- selected_concept_state = gr.State(None)
882
 
883
  def handle_analyze(month):
884
- """컨셉 분석 처리"""
885
- try:
886
- month_num = int(month.replace('월', ''))
887
- concepts = generator.analyze_month_concepts(month_num)
888
-
889
- # 결과 텍스트 생성
890
- result_text = f"# {month} 추천 컨셉\n\n"
891
- concept_choices = []
892
-
893
- for i, concept in enumerate(concepts, 1):
894
- result_text += f"## {i}. {concept['name']}\n"
895
- result_text += f"- 테마: {concept['theme']}\n"
896
- result_text += f"- 예상 점수: {concept['score']}/10점\n\n"
897
-
898
- concept_choices.append(concept['name'])
899
-
900
- return (
901
- result_text,
902
- gr.update(visible=True, choices=concept_choices, value=concept_choices[0]),
903
- gr.update(visible=True),
904
- concepts
905
- )
906
- except Exception as e:
907
- return f"❌ 오류: {str(e)}", gr.update(visible=False), gr.update(visible=False), []
908
-
909
- def handle_concept_select(concept_name, concepts):
910
- """컨셉 선택 처리"""
911
- if concept_name and concepts:
912
- selected = next((c for c in concepts if c['name'] == concept_name), None)
913
- return selected
914
- return None
915
 
916
  def handle_generate(concept, event_type):
917
- """공지사항 생성 처리"""
918
- if concept:
919
- notice = generator.generate_notice(concept, event_type)
920
- return notice
921
- return "❌ 컨셉을 먼저 선택해주세요!"
922
 
923
  # 이벤트 연결
924
  analyze_btn.click(
925
  handle_analyze,
926
- inputs=[month_input],
927
- outputs=[concept_result, concept_dropdown, generate_btn, concepts_state]
928
  )
929
 
930
  concept_dropdown.change(
931
- handle_concept_select,
932
  inputs=[concept_dropdown, concepts_state],
933
  outputs=[selected_concept_state]
934
  )
935
 
936
  generate_btn.click(
937
  handle_generate,
938
- inputs=[selected_concept_state, event_type_input],
939
- outputs=[final_result]
940
  )
941
 
942
  return demo
943
 
944
  if __name__ == "__main__":
945
  demo = create_interface()
946
- demo.launch(
947
- server_name="0.0.0.0",
948
- server_port=7860,
949
- share=True
950
- )
 
 
 
 
 
 
1
  import gradio as gr
2
+ from datetime import datetime
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ def analyze_concepts(month):
5
+ """간단한 월별 컨셉 분석"""
 
 
6
 
7
+ concepts = {
8
+ "1월": ["신년 다짐 이벤트", "겨울 감성 이벤트", "새해 소망 이벤트"],
9
+ "2월": ["밸런타인 이벤트", "사랑 고백 이벤트", "겨울 마무리 이벤트"],
10
+ "3월": ["봄맞이 이벤트", "새학기 이벤트", "벚꽃 축제 이벤트"],
11
+ "4월": ["꽃구경 이벤트", "봄나들이 이벤트", "새싹 키우기 이벤트"],
12
+ "5월": ["가정의 달 이벤트", "어린이날 이벤트", "어버이날 이벤트"],
13
+ "6월": ["여름준비 이벤트", "현충일 추모 이벤트", "장마 대비 이벤트"],
14
+ "7월": ["여름휴가 이벤트", "바다 여행 이벤트", "시원한 음식 이벤트"],
15
+ "8월": ["휴가철 이벤트", "광복절 이벤트", "여름 추억 이벤트"],
16
+ "9월": ["추석 이벤트", "가을 시작 이벤트", "독서의 계절 이벤트"],
17
+ "10월": ["가을 단풍 이벤트", "한글날 이벤트", "가을 나들이 이벤트"],
18
+ "11월": ["빼빼로데이 이벤트", "수능 응원 이벤트", "겨울 준비 이벤트"],
19
+ "12월": ["크리스마스 이벤트", "연말 파티 이벤트", "한해 마무리 이벤트"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
 
21
 
22
+ month_concepts = concepts.get(month, ["기본 이벤트"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ result = f"# {month} 추천 컨셉\n\n"
25
+ for i, concept in enumerate(month_concepts, 1):
26
+ result += f"## {i}. {concept}\n"
27
+ result += f"- 20-40대 여성 타겟\n"
28
+ result += f"- 예상 참여도: 높음\n\n"
 
29
 
30
+ return result, month_concepts
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ def generate_notice(concept, event_type):
33
+ """기본 공지사항 생성"""
 
 
 
 
34
 
35
+ if not concept:
36
+ return "먼저 컨셉을 선택해주세요."
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
+ now = datetime.now()
39
+ start_date = now.strftime("%Y.%m.%d")
40
+ end_date = f"{now.year}.{now.month}.{now.day + 7}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ notice = f"""💕 {concept}에 참여하세요!
 
 
 
 
 
 
 
 
43
 
44
+ 🎉 {concept} 🎉
45
 
46
  📅 이벤트 기간: {start_date} ~ {end_date} 23:59
47
 
48
  ========================
49
  ✨ EVENT
50
+ 특별한 {concept}을 준비했어요!
51
+ 많은 분들의 적극적인 참여를 기다리고 있습니다 💕
52
  ========================
53
 
54
  🎯 참여 방법
55
+ 1️⃣ 이벤트 내용 확인하기
56
+ 2️⃣ {event_type} 참여하기
57
  3️⃣ 참여 완료!
58
 
59
  =================
 
66
  ========================
67
 
68
  👥 이벤트 대상
69
+ ✅ 커뮤니티 회원
70
  ✅ 만 18세 이상
71
  ✅ 이벤트 기간 내 참여자
72
  ========================
73
 
74
  ⚠️ 주의사항
75
  ※ 부적절한 참여는 제외됩니다
76
+ ※ 중복 참여 불가
77
  ※ 당첨자는 본인 확인 필요
78
 
79
  ===========================
80
  📞 문의: 1234-5678
81
  💬 카카오톡: @event_community
82
 
83
+ 💝 많은 참여 부탁드려요! 감사합니다 💕"""
84
+
85
+ return notice
 
86
 
87
  def create_interface():
88
  """그라디오 인터페이스 생성"""
89
 
 
 
90
  with gr.Blocks(title="이벤트 공지사항 생성기") as demo:
91
 
92
+ gr.Markdown("# 🎉 이벤트 공지사항 생성기")
93
+ gr.Markdown("### 간편하게 이벤트 공지사항을 만들어보세요!")
 
 
94
 
95
  with gr.Row():
96
  with gr.Column():
97
+ gr.Markdown("## 설정")
98
 
99
+ month_dropdown = gr.Dropdown(
100
  choices=[f"{i}월" for i in range(1, 13)],
101
+ label="이벤트 월 선택",
102
+ value="1월"
 
 
 
 
 
 
103
  )
104
 
105
+ analyze_btn = gr.Button("컨셉 분석하기", variant="primary")
106
 
107
  concept_dropdown = gr.Dropdown(
108
+ label="컨셉 선택",
109
  visible=False
110
  )
111
 
112
+ event_type_dropdown = gr.Dropdown(
113
+ choices=["댓글 달기", "게시글 작성", "좋아요 누르기", "사진 업로드"],
114
+ label="이벤트 유형",
115
+ value="댓글 달기"
116
+ )
117
+
118
+ generate_btn = gr.Button("공지사항 생성하기", variant="secondary", visible=False)
119
 
120
  with gr.Column():
121
+ gr.Markdown("## 결과")
122
 
123
+ concept_output = gr.Textbox(
124
+ label="분석 결과",
125
+ lines=10,
126
  placeholder="먼저 '컨셉 분석하기' 버튼을 클릭하세요"
127
  )
128
 
129
+ notice_output = gr.Textbox(
130
  label="생성된 공지사항",
131
  lines=20,
132
+ placeholder="컨셉을 선택하고 '공지사항 생성하기' 버튼을 클릭하세요"
 
133
  )
134
 
135
  # 상태 변수
136
  concepts_state = gr.State([])
137
+ selected_concept_state = gr.State("")
138
 
139
  def handle_analyze(month):
140
+ """분석 처리"""
141
+ result, concepts = analyze_concepts(month)
142
+ return (
143
+ result,
144
+ gr.update(choices=concepts, visible=True, value=concepts[0]),
145
+ gr.update(visible=True),
146
+ concepts
147
+ )
148
+
149
+ def handle_concept_change(concept, concepts):
150
+ """컨셉 변경 처리"""
151
+ return concept
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  def handle_generate(concept, event_type):
154
+ """생성 처리"""
155
+ notice = generate_notice(concept, event_type)
156
+ return notice
 
 
157
 
158
  # 이벤트 연결
159
  analyze_btn.click(
160
  handle_analyze,
161
+ inputs=[month_dropdown],
162
+ outputs=[concept_output, concept_dropdown, generate_btn, concepts_state]
163
  )
164
 
165
  concept_dropdown.change(
166
+ handle_concept_change,
167
  inputs=[concept_dropdown, concepts_state],
168
  outputs=[selected_concept_state]
169
  )
170
 
171
  generate_btn.click(
172
  handle_generate,
173
+ inputs=[selected_concept_state, event_type_dropdown],
174
+ outputs=[notice_output]
175
  )
176
 
177
  return demo
178
 
179
  if __name__ == "__main__":
180
  demo = create_interface()
181
+ demo.launch()