
    Pib<              
          d Z ddlZddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
  G d d      Zedk(  r# e       Z ed	        ed
        ed	        ed       ej                  d      ZeD ])  Z eded    ded    d        eded   dd  d       +  ed       ej%                  d      ZeD ]  Z eded    ded    d         ed       ej'                  d      ZeD ]  Z eded    ded    d         ed       ej)                         ZeD ]  Z eded    ded    ded    d         ed        ed        ed	       yy) ur   
정보 관리 시스템 - 검색 엔진
제이회장님의 AI 비서를 위한 토큰 효율적 검색 시스템
    N)datetime)Path)DictListOptionalTuplec                       e Zd ZdZddefdZdefdZdefdZdede	e
   fd	Zd
ede	e
   fdZddedede	e
   fdZdedee   fdZdedee
   fdZdedee   fdZddede	e
   fdZdedefdZy)MemorySearchEngineu+   메모리 검색 엔진 - index.json 활용Nmemory_pathc                     |t        t              j                  }t        |      | _        | j                  dz  | _        d| _        | j                          y)u	   초기화Nz
index.json)r   __file__parentr   
index_pathindex
load_index)selfr   s     >/home/jay/workspace/.worktrees/task-2117-dev1/memory/search.py__init__zMemorySearchEngine.__init__   sG    x.//K,**\9
    returnc                 n   	 | j                   j                         r<t        | j                   dd      5 }t        j                  |      | _        ddd       yt        d| j                           i i i d| _        y# 1 sw Y   yxY w# t        $ r#}t        d	|        i i i d| _        Y d}~yd}~ww xY w)
u   index.json 로드rutf-8encodingNTu#   ⚠️ index.json이 없습니다: )	documentskeywordsparticipantsFu   ❌ index.json 로드 실패: )r   existsopenjsonloadr   print	Exceptionr   fes      r   r   zMemorySearchEngine.load_index   s    	%%'$//3A .Q!%1DJ.;DOO;LMN+-2rR
.
  	21#67')r2NDJ	s:   2B A<B #B <BB B 	B4B//B4c                 R   	 t        j                         j                         dz   | j                  d<   t	        | j
                  dd      5 }t        j                  | j                  |dd       d	d	d	       y
# 1 sw Y   y
xY w# t        $ r}t        d|        Y d	}~yd	}~ww xY w)u   index.json 저장ZlastUpdatedwr   r   F   )ensure_asciiindentNTu   ❌ index.json 저장 실패: )
r   now	isoformatr   r    r   r!   dumpr$   r#   r%   s      r   
save_indexzMemorySearchEngine.save_index+   s    		(0(@(@(BS(HDJJ}%doosW= G		$**aeAFGG 	21#67	s6   A
B $A90B 9B>B B 	B&B!!B&keywordc                 d   g }| j                   s|S | j                   j                  di       }||v r||   }|D ]  }| j                   d   j                  |      }|s$|j                  ||j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  d	d      d
        |j                         D ]  \  }}|j	                         |j	                         v s'||k7  s-|D ]  }||D cg c]  }|d   	 c}vs| j                   d   j                  |      }|s:|j                  ||j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  d	d      d
         |S c c}w )u   
        키워드로 검색

        Args:
            keyword: 검색할 키워드

        Returns:
            검색 결과 리스트 (doc_id, title, summary, path)
        r   r   title   제목 없음summary pathdatetypeidr5   r7   r9   r:   r;   r=   r   getappenditemslower)	r   r3   resultsr   doc_idsdoc_iddockeyr   s	            r   search_by_keywordz$MemorySearchEngine.search_by_keyword8   s    zzN ::>>*b1 hw'G! jj-11&9NN"(%(WWWo%F'*wwy"'=$'GGFB$7$'GGFB$7$'GGFB$7	 %NN, 	LC}}#))+-#.% Fw%?!ag%??"jj599&A#NN*0-0WWWo-N/2wwy"/E,/GGFB,?,/GGFB,?,/GGFB,?!"			"  &@   F-
namec                 d   g }| j                   s|S | j                   j                  di       }||v r||   }|D ]  }| j                   d   j                  |      }|s$|j                  ||j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  d	d      d
        |j                         D ]  \  }}|j	                         |j	                         v s'||k7  s-|D ]  }||D cg c]  }|d   	 c}vs| j                   d   j                  |      }|s:|j                  ||j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  d	d      d
         |S c c}w )u   
        참여자로 검색

        Args:
            name: 참여자 이름

        Returns:
            검색 결과 리스트
        r   r   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   )	r   rJ   rC   r   rD   rE   rF   rG   r   s	            r   search_by_participantz(MemorySearchEngine.search_by_participanto   s    zzN zz~~nb9 <"4(G! jj-11&9NN"(%(WWWo%F'*wwy"'=$'GGFB$7$'GGFB$7$'GGFB$7	 )..0 	LCzz|syy{*sd{% Fw%?!ag%??"jj599&A#NN*0-0WWWo-N/2wwy"/E,/GGFB,?,/GGFB,?,/GGFB,?!"			"  &@rI   
start_dateend_datec                    g }| j                   s|S ||}| j                   d   j                         D ]  \  }}|j                  dd      }|s||cxk  r|k  s'n *|j                  ||j                  dd      |j                  dd      |j                  dd      ||j                  dd      d	        |j	                  d
 d       |S )u   
        날짜 범위로 검색

        Args:
            start_date: 시작 날짜 (YYYY-MM-DD)
            end_date: 종료 날짜 (YYYY-MM-DD), 없으면 start_date만 검색

        Returns:
            검색 결과 리스트
        r   r:   r8   r5   r6   r7   r9   r;   r<   c                     | d   S )Nr:    xs    r   <lambda>z3MemorySearchEngine.search_by_date.<locals>.<lambda>   s
    1V9 r   TrG   reverser   rA   r?   r@   sort)r   rM   rN   rC   rE   rF   doc_dates          r   search_by_datez!MemorySearchEngine.search_by_date   s     zzN !H  ::k288: 	KFCwwvr*H 5X5NN"(%(WWWo%F'*wwy"'=$'GGFB$7$,$'GGFB$7		$ 	,d;r   rE   c                     | j                   sy| j                   d   j                  |      }|r|j                  dd      S y)u   
        문서의 요약만 반환 (토큰 절약)

        Args:
            doc_id: 문서 ID

        Returns:
            요약 텍스트 (없으면 None)
        Nr   r7   r8   r   r?   )r   rE   rF   s      r   get_summaryzMemorySearchEngine.get_summary   s>     zzjj%))&1779b))r   c                 X    | j                   sy| j                   d   j                  |      S )u   
        문서의 전체 정보 반환

        Args:
            doc_id: 문서 ID

        Returns:
            문서 정보 딕셔너리
        Nr   r\   )r   rE   s     r   get_document_infoz$MemorySearchEngine.get_document_info   s(     zzzz+&**622r   c                 X   | j                   sy| j                   d   j                  |      }|sy|j                  dd      }|sy| j                  |z  }	 t        |dd      5 }|j	                         cddd       S # 1 sw Y   yxY w# t
        $ r}t        d|        Y d}~yd}~ww xY w)	u   
        문서 전체 읽기 (필요시에만 사용)

        Args:
            doc_id: 문서 ID

        Returns:
            문서 전체 텍스트
        Nr   r9   r8   r   r   r   u   ❌ 문서 읽기 실패: )r   r?   r   r    readr$   r#   )r   rE   rF   r9   	full_pathr&   r'   s          r   read_full_documentz%MemorySearchEngine.read_full_document   s     zzjj%))&1wwvr" $$t+		iw7  1vvx      	.qc23	s6   B "A<2	B <BB B 	B)B$$B)doc_typec                    g }| j                   s|S | j                   d   j                         D ]  \  }}||j                  d      |k(  s|j                  ||j                  dd      |j                  dd      |j                  dd      |j                  dd      |j                  dd      d	        |j	                  d
 d       |S )u   
        모든 문서 목록 반환

        Args:
            doc_type: 문서 타입 필터 (daily, meeting, project, template 등)

        Returns:
            문서 목록
        r   r;   r5   r6   r7   r8   r9   r:   r<   c                 &    | j                  dd      S )Nr:   r8   )r?   rR   s    r   rT   z7MemorySearchEngine.list_all_documents.<locals>.<lambda>.  s    155#4 r   TrU   rW   )r   rd   rC   rE   rF   s        r   list_all_documentsz%MemorySearchEngine.list_all_documents  s     zzN::k288: 	KFC3776?h#>$!$/!B#&779b#9 # 3 # 3 # 3		 	4dCr   doc_pathc                    	 | j                   |z  }|j                         st        d|        yt        |dd      5 }|j	                         }ddd       j                  d      st        d|        y|j                  dd	      }t        |      d
k  rt        d|        yddl}	 |j                  |d         }d|v r%t        |d   d      r|d   j                         |d<   |j                  d      }	|	st        d|        yd}
d|v ru|j                  d      }|j                  d|dz         }|dk(  r|j                  d|      }||kD  r3||| j                         }
|
j!                  dd      j                         }
||j                  dd      |j                  dd      |j                  d|      |j                  dg       |j                  dg       |
|j                  dg       d}d| j"                  vri | j"                  d<   || j"                  d   |	<   d| j"                  vri | j"                  d<   |j                  dg       D ][  }|| j"                  d   vrg | j"                  d   |<   |	| j"                  d   |   vs;| j"                  d   |   j%                  |	       ] d| j"                  vri | j"                  d<   |j                  dg       D ][  }|| j"                  d   vrg | j"                  d   |<   |	| j"                  d   |   vs;| j"                  d   |   j%                  |	       ] d| j"                  vrdi d | j"                  d<   t        | j"                  d         | j"                  d   d!<   i }| j"                  d   j'                         D ],  }|j                  dd"      }|j                  |d      dz   ||<   . || j"                  d   d#<   | j)                         S # 1 sw Y   xY w# t        $ r}t        d|        Y d}~yd}~ww xY w# t        $ r}t        d$|        Y d}~yd}~ww xY w)%u   
        문서에서 메타데이터 추출하여 index.json 업데이트

        Args:
            doc_path: 문서 경로 (memory/ 기준 상대 경로)

        Returns:
            성공 여부
        u   ⚠️ 문서가 없습니다: Fr   r   r   Nz---u$   ⚠️ frontmatter가 없습니다: r,      u"   ⚠️ frontmatter 형식 오류: r      r:   r0   u   ⚠️ YAML 파싱 오류: r=   u   ⚠️ id가 없습니다: r8   u   ## 📋 1분 요약z##   r;   r5   r   r   related)r9   r;   r:   r5   r   r   r7   rn   r   stats)totalDocumentsbyTyperp   unknownrq   u#   ❌ 인덱스 업데이트 실패: )r   r   r#   r    ra   
startswithsplitlenyaml	safe_loadhasattrr0   r$   r?   findstripreplacer   r@   valuesr2   )r   rh   rb   r&   contentpartsrv   metadatar'   rE   r7   summary_startsummary_end	doc_entryr3   participantby_typerF   rd   s                      r   update_index_from_documentz-MemorySearchEngine.update_index_from_document2  s[   f	((83I##%7	{CD iw7 #1&&(# %%e,<XJGH MM%+E5zA~:8*EF>>%(3X%'(62BK*P'/'7'A'A'CHV$ \\$'F3H:>? G$/ '-B C%ll41CD"$"),,um"DK.%mK@FFHG%oo.CRHNNPG ! VR0 VR0!gx8$LLR8 (^R @"#<<	26	I $**,*,

;'.7DJJ{#F+ +)+

:&#<<
B7 C$**Z"8868DJJz*73J!7!@@JJz*73::6B	C TZZ/-/

>*'||NB? Kdjj&@@>@DJJ~.{;N!;K!HHJJ~.{;BB6J	K djj(9:b&I

7#47

;8O4PDJJw 01Gzz+.557 A77695$+KK!$<q$@!A -4DJJw) ??$$s# #*  3A378L  	7s;<	s~   -P" P" O1'P" 7.P" &P" +=O> (!P" 
E>P" 	BP" CP" 1O;6P" >	PPP" PP" "	Q+P>>Q)N)__name__
__module____qualname____doc__strr   boolr   r2   r   r   rH   rL   rZ   r   r]   r_   rc   rg   r   rQ   r   r   r
   r
      s    5C D  D 5 5d 5n5# 5$t* 5n) ) )tDz )V# (3- $3 3 3 # >3 $t* Bp3 p4 pr   r
   __main__z<============================================================u   🔍 검색 시스템 테스트u+   
1️⃣ 키워드 검색: 'Boris Workflow'zBoris Workflowz  - r5   z (r:   )u       요약: r7   d   z...u-   
2️⃣ 참여자 검색: '메인 관리자'u   메인 관리자u"   
3️⃣ 날짜 검색: 2025-02-26z
2025-02-26u   
4️⃣ 모든 문서 목록z  - [r;   z] z=
============================================================u"   ✅ 검색 시스템 준비 완료)r   r!   osr   pathlibr   typingr   r   r   r   r
   r   enginer#   rH   rC   r   rL   rZ   rg   rQ   r   r   <module>r      s  
  	   . .T Tp z!F	(O	
+,	(O 

89&&'78G 6QwZL1V9+Q/0Qy\$3/0456
 

:;**+=>G 1QwZL1V9+Q/01 

/0##L1G 1QwZL1V9+Q/01 

*+'')G ?ai[1W:,b61=>? 
/	
./	(OE r   