Update app.py
Browse files
app.py
CHANGED
|
@@ -291,6 +291,7 @@ def analyze_voice(audio_data, state):
|
|
| 291 |
|
| 292 |
|
| 293 |
def generate_detailed_prompt(text, emotions, text_sentiment):
|
|
|
|
| 294 |
emotion_colors = {
|
| 295 |
"기쁨/열정": "밝은 노랑과 따뜻한 주황색",
|
| 296 |
"분노/강조": "강렬한 빨강과 짙은 검정",
|
|
@@ -313,8 +314,29 @@ def generate_detailed_prompt(text, emotions, text_sentiment):
|
|
| 313 |
"차분/진지": "균형잡힌 수직선과 안정적인 구조"
|
| 314 |
}
|
| 315 |
|
| 316 |
-
|
| 317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
prompt += "korean traditional patterns, ethereal atmosphere, sacred geometry, "
|
| 319 |
prompt += "flowing energy, mystical aura, no human figures, no faces, "
|
| 320 |
prompt += "digital art, high detail, luminescent effects. "
|
|
@@ -779,7 +801,7 @@ def create_interface():
|
|
| 779 |
initial_state = {
|
| 780 |
"user_name": "",
|
| 781 |
"baseline_features": None,
|
| 782 |
-
"reflections": [],
|
| 783 |
"wish": None,
|
| 784 |
"final_prompt": "",
|
| 785 |
"image_path": None,
|
|
@@ -1638,17 +1660,35 @@ def create_interface():
|
|
| 1638 |
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 1639 |
name = state.get("user_name", "익명")
|
| 1640 |
|
|
|
|
| 1641 |
if text_analyzer:
|
| 1642 |
sentiment = text_analyzer(text)[0]
|
| 1643 |
sentiment_text = f"{sentiment['label']} ({sentiment['score']:.2f})"
|
| 1644 |
else:
|
| 1645 |
sentiment_text = "분석 불가"
|
| 1646 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1647 |
# DB에 저장
|
| 1648 |
db.save_reflection(name, text, sentiment_text)
|
| 1649 |
|
| 1650 |
-
#
|
| 1651 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1652 |
|
| 1653 |
except Exception as e:
|
| 1654 |
print(f"Error saving reflection: {e}")
|
|
@@ -1697,57 +1737,46 @@ def create_interface():
|
|
| 1697 |
|
| 1698 |
def safe_analyze_voice(audio_data, state):
|
| 1699 |
if audio_data is None:
|
| 1700 |
-
return
|
| 1701 |
-
state,
|
| 1702 |
-
"음성을 먼저 녹음해주세요.",
|
| 1703 |
-
"",
|
| 1704 |
-
"",
|
| 1705 |
-
"",
|
| 1706 |
-
"분석 준비 중..."
|
| 1707 |
-
)
|
| 1708 |
|
| 1709 |
try:
|
| 1710 |
-
# 상태 업데이트
|
| 1711 |
status_msg = "음성 분석 중..."
|
| 1712 |
-
|
| 1713 |
-
# 음성 데이터 전처리
|
| 1714 |
sr, y = audio_data
|
|
|
|
| 1715 |
if len(y) == 0:
|
| 1716 |
-
return
|
| 1717 |
-
state,
|
| 1718 |
-
"음성이 감지되지 않았습니다.",
|
| 1719 |
-
"",
|
| 1720 |
-
"",
|
| 1721 |
-
"",
|
| 1722 |
-
"분석 실패"
|
| 1723 |
-
)
|
| 1724 |
|
| 1725 |
-
|
| 1726 |
acoustic_features = calculate_baseline_features((sr, y))
|
| 1727 |
-
|
| 1728 |
-
|
| 1729 |
new_state, text, voice_result, text_result, prompt = analyze_voice(audio_data, state)
|
| 1730 |
-
|
| 1731 |
-
|
| 1732 |
-
|
| 1733 |
-
|
| 1734 |
-
|
| 1735 |
-
|
| 1736 |
-
|
| 1737 |
-
|
| 1738 |
-
|
| 1739 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1740 |
|
| 1741 |
except Exception as e:
|
| 1742 |
print(f"Voice analysis error: {str(e)}")
|
| 1743 |
-
return
|
| 1744 |
-
|
| 1745 |
-
"음성 분석 중 오류가 발생했습니다. 다시 시도해주세요.",
|
| 1746 |
-
"",
|
| 1747 |
-
"",
|
| 1748 |
-
"",
|
| 1749 |
-
"분석 실패"
|
| 1750 |
-
)
|
| 1751 |
# 이벤트 연결
|
| 1752 |
name_submit_btn.click(
|
| 1753 |
fn=handle_name_submit,
|
|
|
|
| 291 |
|
| 292 |
|
| 293 |
def generate_detailed_prompt(text, emotions, text_sentiment):
|
| 294 |
+
# 기존 감정 매핑 유지
|
| 295 |
emotion_colors = {
|
| 296 |
"기쁨/열정": "밝은 노랑과 따뜻한 주황색",
|
| 297 |
"분노/강조": "강렬한 빨강과 짙은 검정",
|
|
|
|
| 314 |
"차분/진지": "균형잡힌 수직선과 안정적인 구조"
|
| 315 |
}
|
| 316 |
|
| 317 |
+
# 텍스트에서 주요 감정 키워드 추출
|
| 318 |
+
text_emotions = text_sentiment["label"].lower().split(", ")
|
| 319 |
+
emotion_keywords = set()
|
| 320 |
+
for emotion in text_emotions:
|
| 321 |
+
for key in emotion_colors.keys():
|
| 322 |
+
if emotion in key.lower():
|
| 323 |
+
emotion_keywords.add(key)
|
| 324 |
+
|
| 325 |
+
# 기본 프롬프트 구성
|
| 326 |
+
prompt = f"minimalistic abstract art, "
|
| 327 |
+
|
| 328 |
+
# 주요 감정 색상과 요소 통합
|
| 329 |
+
colors = []
|
| 330 |
+
elements = []
|
| 331 |
+
for emotion in emotion_keywords:
|
| 332 |
+
if emotion in emotion_colors:
|
| 333 |
+
colors.append(emotion_colors[emotion])
|
| 334 |
+
elements.append(abstract_elements[emotion])
|
| 335 |
+
|
| 336 |
+
prompt += f"{', '.join(colors) if colors else emotion_colors[emotions['primary']]} color scheme, "
|
| 337 |
+
prompt += f"{', '.join(elements) if elements else abstract_elements[emotions['primary']]}, "
|
| 338 |
+
|
| 339 |
+
# 기본 요소 추가
|
| 340 |
prompt += "korean traditional patterns, ethereal atmosphere, sacred geometry, "
|
| 341 |
prompt += "flowing energy, mystical aura, no human figures, no faces, "
|
| 342 |
prompt += "digital art, high detail, luminescent effects. "
|
|
|
|
| 801 |
initial_state = {
|
| 802 |
"user_name": "",
|
| 803 |
"baseline_features": None,
|
| 804 |
+
"reflections": [], # 여기에 사용자의 모든 기록을 누적
|
| 805 |
"wish": None,
|
| 806 |
"final_prompt": "",
|
| 807 |
"image_path": None,
|
|
|
|
| 1660 |
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
| 1661 |
name = state.get("user_name", "익명")
|
| 1662 |
|
| 1663 |
+
# 감정 분석
|
| 1664 |
if text_analyzer:
|
| 1665 |
sentiment = text_analyzer(text)[0]
|
| 1666 |
sentiment_text = f"{sentiment['label']} ({sentiment['score']:.2f})"
|
| 1667 |
else:
|
| 1668 |
sentiment_text = "분석 불가"
|
| 1669 |
|
| 1670 |
+
# 현재 사용자의 기존 reflections 가져오기
|
| 1671 |
+
if "reflections" not in state:
|
| 1672 |
+
state["reflections"] = []
|
| 1673 |
+
|
| 1674 |
+
# 새로운 reflection 추가
|
| 1675 |
+
new_reflection = {
|
| 1676 |
+
"timestamp": current_time,
|
| 1677 |
+
"text": text,
|
| 1678 |
+
"sentiment": sentiment_text
|
| 1679 |
+
}
|
| 1680 |
+
state["reflections"].append(new_reflection)
|
| 1681 |
+
|
| 1682 |
# DB에 저장
|
| 1683 |
db.save_reflection(name, text, sentiment_text)
|
| 1684 |
|
| 1685 |
+
# 화면에 표시할 데이터 생성 (현재 사용자의 모든 기록)
|
| 1686 |
+
display_data = [
|
| 1687 |
+
[r["timestamp"], r["text"], r["sentiment"]]
|
| 1688 |
+
for r in state["reflections"]
|
| 1689 |
+
]
|
| 1690 |
+
|
| 1691 |
+
return state, display_data
|
| 1692 |
|
| 1693 |
except Exception as e:
|
| 1694 |
print(f"Error saving reflection: {e}")
|
|
|
|
| 1737 |
|
| 1738 |
def safe_analyze_voice(audio_data, state):
|
| 1739 |
if audio_data is None:
|
| 1740 |
+
return state, "음성을 먼저 녹음해주세요.", "", "", "", "분석 준비 중..."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1741 |
|
| 1742 |
try:
|
|
|
|
| 1743 |
status_msg = "음성 분석 중..."
|
|
|
|
|
|
|
| 1744 |
sr, y = audio_data
|
| 1745 |
+
|
| 1746 |
if len(y) == 0:
|
| 1747 |
+
return state, "음성이 감지되지 않았습니다.", "", "", "", "분석 실패"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1748 |
|
| 1749 |
+
# 음성 특성 분석
|
| 1750 |
acoustic_features = calculate_baseline_features((sr, y))
|
| 1751 |
+
|
| 1752 |
+
# 기존 분석 함수 호출
|
| 1753 |
new_state, text, voice_result, text_result, prompt = analyze_voice(audio_data, state)
|
| 1754 |
+
|
| 1755 |
+
# 청신 단계의 누적된 기록들을 프롬프트에 통합
|
| 1756 |
+
if "reflections" in new_state:
|
| 1757 |
+
accumulated_emotions = []
|
| 1758 |
+
accumulated_texts = []
|
| 1759 |
+
|
| 1760 |
+
for reflection in new_state["reflections"]:
|
| 1761 |
+
accumulated_texts.append(reflection["text"])
|
| 1762 |
+
if "sentiment" in reflection:
|
| 1763 |
+
accumulated_emotions.append(reflection["sentiment"])
|
| 1764 |
+
|
| 1765 |
+
# 프롬프트 생성 시 누적된 감정과 텍스트 반영
|
| 1766 |
+
enhanced_prompt = generate_detailed_prompt(
|
| 1767 |
+
text=f"{text} || Previous reflections: {' | '.join(accumulated_texts)}",
|
| 1768 |
+
emotions=map_acoustic_to_emotion(acoustic_features, new_state.get("baseline_features")),
|
| 1769 |
+
text_sentiment={"label": ", ".join(accumulated_emotions), "score": 1.0}
|
| 1770 |
+
)
|
| 1771 |
+
|
| 1772 |
+
return new_state, text, voice_result, text_result, enhanced_prompt, "분석 완료"
|
| 1773 |
+
|
| 1774 |
+
return new_state, text, voice_result, text_result, prompt, "분석 완료"
|
| 1775 |
|
| 1776 |
except Exception as e:
|
| 1777 |
print(f"Voice analysis error: {str(e)}")
|
| 1778 |
+
return state, "음성 분석 중 오류가 발생했습니다.", "", "", "", "분석 실패"
|
| 1779 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1780 |
# 이벤트 연결
|
| 1781 |
name_submit_btn.click(
|
| 1782 |
fn=handle_name_submit,
|