Update app.py
Browse files
app.py
CHANGED
@@ -53,12 +53,14 @@ class SimpleDB:
|
|
53 |
def save_reflection(self, name, reflection, sentiment, timestamp=None):
|
54 |
if timestamp is None:
|
55 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
56 |
reflection_data = {
|
|
|
57 |
"name": name,
|
58 |
"reflection": reflection,
|
59 |
-
"sentiment": sentiment
|
60 |
-
"timestamp": timestamp
|
61 |
}
|
|
|
62 |
self.reflections.append(reflection_data)
|
63 |
self._save_json(self.reflections_path, self.reflections)
|
64 |
return True
|
@@ -86,7 +88,7 @@ class SimpleDB:
|
|
86 |
return False
|
87 |
|
88 |
def get_all_reflections(self):
|
89 |
-
return self.reflections
|
90 |
|
91 |
def get_all_wishes(self):
|
92 |
return self.wishes
|
@@ -392,7 +394,7 @@ def create_interface():
|
|
392 |
with gr.Tabs(selected=0) as tabs:
|
393 |
# 입장 탭 (축원 포함)
|
394 |
with gr.TabItem("입장") as tab_entrance:
|
395 |
-
# 첫 화면
|
396 |
welcome_section = gr.Column(visible=True)
|
397 |
with welcome_section:
|
398 |
gr.Markdown(WELCOME_MESSAGE)
|
@@ -401,17 +403,18 @@ def create_interface():
|
|
401 |
placeholder="이름을 입력해주세요",
|
402 |
interactive=True
|
403 |
)
|
404 |
-
|
405 |
-
|
|
|
406 |
story_section = gr.Column(visible=False)
|
407 |
with story_section:
|
408 |
gr.Markdown(ONCHEON_STORY)
|
409 |
-
|
410 |
-
|
411 |
-
# 축원
|
412 |
blessing_section = gr.Column(visible=False)
|
413 |
with blessing_section:
|
414 |
-
gr.Markdown("###
|
415 |
gr.Markdown("'명짐 복짐 짊어지고 안가태평하시기를 비도발원 축원 드립니다'")
|
416 |
baseline_audio = gr.Audio(
|
417 |
label="축원 문장 녹음하기",
|
@@ -419,9 +422,21 @@ def create_interface():
|
|
419 |
type="numpy",
|
420 |
streaming=False
|
421 |
)
|
422 |
-
set_baseline_btn = gr.Button("
|
423 |
baseline_status = gr.Markdown("")
|
424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
# 청신 탭
|
426 |
with gr.TabItem("청신") as tab_listen:
|
427 |
gr.Markdown("## 청신 - 소리로 정화하기")
|
@@ -451,9 +466,10 @@ def create_interface():
|
|
451 |
reflections_display = gr.Dataframe(
|
452 |
headers=["시간", "감상", "감정 분석"],
|
453 |
label="기록된 감상들",
|
454 |
-
value=[],
|
455 |
interactive=False,
|
456 |
-
wrap=True
|
|
|
457 |
)
|
458 |
|
459 |
# 기원 탭
|
@@ -519,10 +535,49 @@ def create_interface():
|
|
519 |
)
|
520 |
|
521 |
# 이벤트 핸들러들
|
522 |
-
def
|
523 |
if not name.strip():
|
524 |
-
return
|
525 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
|
527 |
def handle_start():
|
528 |
return gr.update(visible=False), gr.update(visible=True)
|
@@ -570,6 +625,43 @@ def create_interface():
|
|
570 |
print(f"Error saving reflection: {e}")
|
571 |
return state, state.get("reflections", [])
|
572 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
def handle_save_wish(text, state):
|
574 |
if not text.strip():
|
575 |
return "소원을 입력해주세요.", []
|
@@ -637,7 +729,27 @@ def create_interface():
|
|
637 |
inputs=[final_reflection, state],
|
638 |
outputs=[baseline_status, wishes_display]
|
639 |
)
|
640 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
641 |
return app
|
642 |
|
643 |
if __name__ == "__main__":
|
|
|
53 |
def save_reflection(self, name, reflection, sentiment, timestamp=None):
|
54 |
if timestamp is None:
|
55 |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
56 |
+
|
57 |
reflection_data = {
|
58 |
+
"timestamp": timestamp,
|
59 |
"name": name,
|
60 |
"reflection": reflection,
|
61 |
+
"sentiment": sentiment
|
|
|
62 |
}
|
63 |
+
|
64 |
self.reflections.append(reflection_data)
|
65 |
self._save_json(self.reflections_path, self.reflections)
|
66 |
return True
|
|
|
88 |
return False
|
89 |
|
90 |
def get_all_reflections(self):
|
91 |
+
return sorted(self.reflections, key=lambda x: x["timestamp"], reverse=True)
|
92 |
|
93 |
def get_all_wishes(self):
|
94 |
return self.wishes
|
|
|
394 |
with gr.Tabs(selected=0) as tabs:
|
395 |
# 입장 탭 (축원 포함)
|
396 |
with gr.TabItem("입장") as tab_entrance:
|
397 |
+
# 1단계: 첫 화면
|
398 |
welcome_section = gr.Column(visible=True)
|
399 |
with welcome_section:
|
400 |
gr.Markdown(WELCOME_MESSAGE)
|
|
|
403 |
placeholder="이름을 입력해주세요",
|
404 |
interactive=True
|
405 |
)
|
406 |
+
name_submit_btn = gr.Button("굿판 시작하기", variant="primary")
|
407 |
+
|
408 |
+
# 2단계: 세계관 설명
|
409 |
story_section = gr.Column(visible=False)
|
410 |
with story_section:
|
411 |
gr.Markdown(ONCHEON_STORY)
|
412 |
+
continue_btn = gr.Button("준비하기", variant="primary")
|
413 |
+
|
414 |
+
# 3단계: 축원 의식
|
415 |
blessing_section = gr.Column(visible=False)
|
416 |
with blessing_section:
|
417 |
+
gr.Markdown("### 축원의식을 시작하겠습니다")
|
418 |
gr.Markdown("'명짐 복짐 짊어지고 안가태평하시기를 비도발원 축원 드립니다'")
|
419 |
baseline_audio = gr.Audio(
|
420 |
label="축원 문장 녹음하기",
|
|
|
422 |
type="numpy",
|
423 |
streaming=False
|
424 |
)
|
425 |
+
set_baseline_btn = gr.Button("축원 마치기", variant="primary")
|
426 |
baseline_status = gr.Markdown("")
|
427 |
|
428 |
+
# 4단계: 굿판 입장 안내
|
429 |
+
entry_guide_section = gr.Column(visible=False)
|
430 |
+
with entry_guide_section:
|
431 |
+
gr.Markdown("## 굿판으로 입장하기")
|
432 |
+
gr.Markdown("""
|
433 |
+
* 청신 탭으로 이동해 주세요.
|
434 |
+
* 부산광역시 동래구 온천장역에서 시작하면 더욱 깊은 경험을 시작할 수 있습니다.
|
435 |
+
* (본격적인 경험을 시작하기에 앞서 이동을 권장드립니다)
|
436 |
+
""")
|
437 |
+
enter_btn = gr.Button("청신 의식 시작하기", variant="primary")
|
438 |
+
|
439 |
+
|
440 |
# 청신 탭
|
441 |
with gr.TabItem("청신") as tab_listen:
|
442 |
gr.Markdown("## 청신 - 소리로 정화하기")
|
|
|
466 |
reflections_display = gr.Dataframe(
|
467 |
headers=["시간", "감상", "감정 분석"],
|
468 |
label="기록된 감상들",
|
469 |
+
value=[], # 초기값은 빈 리스트
|
470 |
interactive=False,
|
471 |
+
wrap=True,
|
472 |
+
row_count=(5, "dynamic") # 동적으로 행 수 조정
|
473 |
)
|
474 |
|
475 |
# 기원 탭
|
|
|
535 |
)
|
536 |
|
537 |
# 이벤트 핸들러들
|
538 |
+
def handle_name_submit(name, state):
|
539 |
if not name.strip():
|
540 |
+
return (
|
541 |
+
gr.update(visible=True),
|
542 |
+
gr.update(visible=False),
|
543 |
+
gr.update(visible=False),
|
544 |
+
gr.update(visible=False),
|
545 |
+
state
|
546 |
+
)
|
547 |
+
state = safe_state_update(state, {"user_name": name})
|
548 |
+
return (
|
549 |
+
gr.update(visible=False),
|
550 |
+
gr.update(visible=True),
|
551 |
+
gr.update(visible=False),
|
552 |
+
gr.update(visible=False),
|
553 |
+
state
|
554 |
+
)
|
555 |
+
|
556 |
+
def handle_continue():
|
557 |
+
return (
|
558 |
+
gr.update(visible=False),
|
559 |
+
gr.update(visible=False),
|
560 |
+
gr.update(visible=True),
|
561 |
+
gr.update(visible=False)
|
562 |
+
)
|
563 |
+
|
564 |
+
def handle_blessing_complete(audio, state):
|
565 |
+
if audio is None:
|
566 |
+
return state, "음성을 먼저 녹음해주세요.", gr.update(visible=True), gr.update(visible=False)
|
567 |
+
|
568 |
+
try:
|
569 |
+
# ... (기존 음성 처리 코드)
|
570 |
+
return (
|
571 |
+
state,
|
572 |
+
"축원이 완료되었습니다.",
|
573 |
+
gr.update(visible=False),
|
574 |
+
gr.update(visible=True)
|
575 |
+
)
|
576 |
+
except Exception as e:
|
577 |
+
return state, f"오류가 발생했습니다: {str(e)}", gr.update(visible=True), gr.update(visible=False)
|
578 |
+
|
579 |
+
def handle_enter():
|
580 |
+
return gr.update(selected=1) # 청신 탭으로 이동
|
581 |
|
582 |
def handle_start():
|
583 |
return gr.update(visible=False), gr.update(visible=True)
|
|
|
625 |
print(f"Error saving reflection: {e}")
|
626 |
return state, state.get("reflections", [])
|
627 |
|
628 |
+
def save_reflection_fixed(text, state):
|
629 |
+
if not text.strip():
|
630 |
+
return state, []
|
631 |
+
|
632 |
+
try:
|
633 |
+
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
634 |
+
name = state.get("user_name", "익명")
|
635 |
+
|
636 |
+
if text_analyzer:
|
637 |
+
sentiment = text_analyzer(text)[0]
|
638 |
+
sentiment_text = f"{sentiment['label']} ({sentiment['score']:.2f})"
|
639 |
+
else:
|
640 |
+
sentiment_text = "분석 불가"
|
641 |
+
|
642 |
+
# DB에 저장
|
643 |
+
db.save_reflection(name, text, sentiment_text)
|
644 |
+
|
645 |
+
# 화면에 표시할 데이터 형식으로 변환
|
646 |
+
display_data = []
|
647 |
+
all_reflections = db.get_all_reflections()
|
648 |
+
for ref in all_reflections:
|
649 |
+
display_data.append([
|
650 |
+
ref["timestamp"],
|
651 |
+
ref["reflection"],
|
652 |
+
ref["sentiment"]
|
653 |
+
])
|
654 |
+
|
655 |
+
# 상태 업데이트
|
656 |
+
state = safe_state_update(state, {"reflections": display_data})
|
657 |
+
|
658 |
+
return state, display_data
|
659 |
+
|
660 |
+
except Exception as e:
|
661 |
+
print(f"Error saving reflection: {e}")
|
662 |
+
return state, []
|
663 |
+
|
664 |
+
|
665 |
def handle_save_wish(text, state):
|
666 |
if not text.strip():
|
667 |
return "소원을 입력해주세요.", []
|
|
|
729 |
inputs=[final_reflection, state],
|
730 |
outputs=[baseline_status, wishes_display]
|
731 |
)
|
732 |
+
name_submit_btn.click(
|
733 |
+
fn=handle_name_submit,
|
734 |
+
inputs=[name_input, state],
|
735 |
+
outputs=[welcome_section, story_section, blessing_section, entry_guide_section, state]
|
736 |
+
)
|
737 |
+
|
738 |
+
continue_btn.click(
|
739 |
+
fn=handle_continue,
|
740 |
+
outputs=[story_section, welcome_section, blessing_section, entry_guide_section]
|
741 |
+
)
|
742 |
+
|
743 |
+
set_baseline_btn.click(
|
744 |
+
fn=handle_blessing_complete,
|
745 |
+
inputs=[baseline_audio, state],
|
746 |
+
outputs=[state, baseline_status, blessing_section, entry_guide_section]
|
747 |
+
)
|
748 |
+
|
749 |
+
enter_btn.click(
|
750 |
+
fn=handle_enter,
|
751 |
+
outputs=[tabs]
|
752 |
+
)
|
753 |
return app
|
754 |
|
755 |
if __name__ == "__main__":
|