1+ import asyncio
2+ import traceback
13from datetime import datetime , date
24from pathlib import Path
35from typing import List , Tuple , Dict
46from collections import Counter
57
68from src .four_pillars .entities .schemas import FourPillar , FourPillarDetail , PillarInfo
79from src .four_pillars .entities .enums import FiveElements , TenGods
10+ from src .hcx_client .client import HCXClient
11+ from src .hcx_client .common .utils import HCXUtils
12+ from src .hcx_client .common .parser import Parser
813
914
1015class FourPillarsCalculator :
@@ -19,7 +24,6 @@ def __init__(self):
1924 self ._init_five_elements_mapping ()
2025 self ._init_ten_gods_mapping ()
2126
22-
2327 def _init_five_elements_mapping (self ):
2428 """천간과 지지의 오행 매핑 초기화"""
2529 # 천간 오행 매핑
@@ -344,26 +348,18 @@ def _get_pillar_detail(self, pillar: str, day_stem: str) -> PillarInfo:
344348 heavenly_stem = pillar [0 ] # 천간
345349 earthly_branch = pillar [1 ] # 지지
346350
347- # 천간의 십신과 오행
351+ # 천간의 십신
348352 heavenly_stem_ten_god = self ._get_ten_god (day_stem , heavenly_stem )
349- heavenly_stem_element = self .jikkan_five_elements .get (
350- heavenly_stem , FiveElements .EARTH
351- )
352353
353354 # 지지의 십신 (지지의 숨겨진 천간을 기준으로 계산)
354355 hidden_stem = self ._get_hidden_stem (earthly_branch )
355356 earthly_branch_ten_god = self ._get_ten_god (day_stem , hidden_stem )
356- earthly_branch_element = self .jyunishi_five_elements .get (
357- earthly_branch , FiveElements .EARTH
358- )
359357
360358 return PillarInfo (
361359 stem = heavenly_stem ,
362360 branch = earthly_branch ,
363361 stem_ten_god = heavenly_stem_ten_god ,
364362 branch_ten_god = earthly_branch_ten_god ,
365- stem_element = heavenly_stem_element ,
366- branch_element = earthly_branch_element ,
367363 )
368364
369365 def _get_hidden_stem (self , earthly_branch : str ) -> str :
@@ -385,6 +381,24 @@ def _get_hidden_stem(self, earthly_branch: str) -> str:
385381 }
386382 return hidden_stems .get (earthly_branch , "甲" )
387383
384+ def _normalize_element (self , element : str ) -> FiveElements :
385+ """오행 문자열을 FiveElements enum으로 정규화"""
386+ # 기존 형식: "화(火)", "목(木)" 등을 처리
387+ element_mapping = {
388+ "화(火)" : FiveElements .FIRE ,
389+ "목(木)" : FiveElements .WOOD ,
390+ "토(土)" : FiveElements .EARTH ,
391+ "금(金)" : FiveElements .METAL ,
392+ "수(水)" : FiveElements .WATER ,
393+ }
394+
395+ normalized = element_mapping .get (element )
396+ if normalized is None :
397+ # 기본값으로 EARTH 반환
398+ return FiveElements .EARTH
399+
400+ return normalized
401+
388402 def calculate_four_pillars (self , birth_date : datetime ) -> FourPillar :
389403 """사주 계산 메인 함수"""
390404 year = birth_date .year
@@ -413,7 +427,9 @@ def calculate_four_pillars(self, birth_date: datetime) -> FourPillar:
413427
414428 return result
415429
416- def calculate_four_pillars_detailed (self , birth_date : datetime ) -> FourPillarDetail :
430+ async def calculate_four_pillars_detailed (
431+ self , birth_date : datetime
432+ ) -> FourPillarDetail :
417433 """십신 정보를 포함한 상세한 사주 계산"""
418434 # 기본 사주 계산
419435 basic_result = self .calculate_four_pillars (birth_date )
@@ -451,15 +467,75 @@ def calculate_four_pillars_detailed(self, birth_date: datetime) -> FourPillarDet
451467 strong_element = strong_elements [0 ] if strong_elements else FiveElements .EARTH
452468 weak_element = weak_elements [0 ] if weak_elements else FiveElements .WOOD
453469
454- # 종합 설명 생성
455- description = "근심과 즐거움이 상반하니 세월의 흐름을 잘 읽어보시게"
456-
457- return FourPillarDetail (
470+ # FourPillarDetail 객체 생성 (임시 description으로)
471+ four_pillar_detail = FourPillarDetail (
458472 strong_element = strong_element ,
459473 weak_element = weak_element ,
460- description = description ,
474+ description = "" , # 임시값
461475 year_pillar_detail = year_pillar_detail ,
462476 month_pillar_detail = month_pillar_detail ,
463477 day_pillar_detail = day_pillar_detail ,
464478 time_pillar_detail = time_pillar_detail ,
465479 )
480+
481+ # HCX API 호출하여 사주 설명 생성
482+ description = await self ._generate_four_pillar_description (
483+ four_pillar_detail , strong_element
484+ )
485+
486+ # description 업데이트
487+ four_pillar_detail .description = description
488+
489+ return four_pillar_detail
490+
491+ async def _generate_four_pillar_description (
492+ self , four_pillar_detail : FourPillarDetail , strong_element : FiveElements
493+ ) -> str :
494+ """HCX API를 호출하여 사주 설명을 생성합니다."""
495+ try :
496+ hcx_client = HCXClient ()
497+
498+ # FourPillarDetail에서 사주 정보 추출
499+ year_pillar = ""
500+ month_pillar = ""
501+ day_pillar = ""
502+ time_pillar = ""
503+
504+ if four_pillar_detail .year_pillar_detail :
505+ year_pillar = f"{ four_pillar_detail .year_pillar_detail .stem } { four_pillar_detail .year_pillar_detail .branch } "
506+
507+ if four_pillar_detail .month_pillar_detail :
508+ month_pillar = f"{ four_pillar_detail .month_pillar_detail .stem } { four_pillar_detail .month_pillar_detail .branch } "
509+
510+ if four_pillar_detail .day_pillar_detail :
511+ day_pillar = f"{ four_pillar_detail .day_pillar_detail .stem } { four_pillar_detail .day_pillar_detail .branch } "
512+
513+ if four_pillar_detail .time_pillar_detail :
514+ time_pillar = f"{ four_pillar_detail .time_pillar_detail .stem } { four_pillar_detail .time_pillar_detail .branch } "
515+
516+ # 사주 정보 준비
517+ four_pillar_data = {
518+ "year_pillar" : year_pillar ,
519+ "month_pillar" : month_pillar ,
520+ "day_pillar" : day_pillar ,
521+ "time_pillar" : time_pillar ,
522+ "strong_element" : strong_element .value ,
523+ }
524+
525+ # HCXUtils를 사용하여 프롬프트 가져오기
526+ system_prompt , user_prompt_template = HCXUtils .get_prompt_pair (
527+ "fortune.yaml" , "four_pillar"
528+ )
529+
530+ user_prompt = user_prompt_template .format (** four_pillar_data )
531+
532+ # HCX API 호출
533+ response = await hcx_client .call_completion (
534+ system_prompt = system_prompt , user_prompt = user_prompt
535+ )
536+
537+ return response .strip ()
538+
539+ except Exception as e :
540+ # API 호출 실패 시 기본 설명 반환
541+ return "근심과 즐거움이 상반하니 세월의 흐름을 잘 읽어보시게"
0 commit comments