a
    �‰•já6  ã                   @   s¼   d Z ddlZddlZddlZddlZej ej e¡¡Z	ej 
e	dd¡Ze d¡Zdd„ Zdd	d
„Zdd„ Zd dd„Zdd„ Zd!dd„Zdd„ Zdd„ Zd"dd„Zdd„ Zedkr¸eƒ  dS )#u|  
AI æ¼«å‰§ Â· å‰§æœ¬å¯¼å…¥å™¨
=====================
æŠŠå°�è¯´/å‰§æœ¬æ–‡æœ¬ï¼š
  1) æŒ‰ã€Œç¬¬Xç« /å›ž/èŠ‚ã€�æ‹†åˆ†ç« èŠ‚
  2) æ¯�ç« æŒ‰ç›®æ ‡å­—æ•°æ‹†æˆ�è‹¥å¹²ã€Œé›†ã€�
  3) ç”¨ LLM æ��å�–äººç‰©/åœºæ™¯/é�“å…·ç­‰èµ„äº§ï¼ˆæ—  key æ—¶é€€åŒ–ä¸ºè§„åˆ™æ��å�–ï¼‰
  4) ç”Ÿæˆ�å�¯å¯¼å…¥ç”»å¸ƒçš„ JSONï¼ˆ{cards, view}ï¼‰

ç”¨æ³•:
  python3 aicomic-import.py å°�è¯´.txt                 # é»˜è®¤è¾“å‡º aicomic-import.json
  python3 aicomic-import.py å°�è¯´.txt -o out.json     # æŒ‡å®šè¾“å‡º
  python3 aicomic-import.py å°�è¯´.txt --target 1500   # æ¯�é›†ç›®æ ‡å­—æ•°
  python3 aicomic-import.py å°�è¯´.txt --no-llm        # å�ªç”¨è§„åˆ™ï¼Œä¸�è°ƒ AI
é    NZmanjuzapi_config.jsonuÏ   ^\s*(ç¬¬\s*[0-9ä¸€äºŒä¸‰å››äº”å…­ä¸ƒå…«ä¹�å��ç™¾å�ƒé›¶ä¸¤]+\s*[ç« å›žèŠ‚å�·]|æ¥”å­�|åº�ç« |åº�è¨€|å¼•å­�|å°¾å£°|ç•ªå¤–|ç»ˆç« |å�Žè®°|å¤§ç»“å±€|(?:CHAPTER|Chapter)\s+[0-9IVXLC]+)[\s:ï¼šã€�.ï¼Ž]*([^\n]{0,30})?c                 C   sÞ   |   d¡}g }d}g }|D ]z}t | ¡ ¡}|rŠ|durR| |d |¡ ¡ dœ¡ | d¡ ¡ | d¡rzd| d¡ ¡  nd  ¡ }g }q| |¡ q|dur¸| |d |¡ ¡ dœ¡ |sÌd|  ¡ dœg}d	d
„ |D ƒ}|S )uO   æŒ‰ç« èŠ‚æ ‡é¢˜æ‹†ç« ã€‚æ— æ ‡é¢˜æ—¶æ•´ç¯‡ç®—ä¸€ç« ã€‚è¿”å›ž [{title, content}]Ú
N)ÚtitleÚcontentr   é   ú Ú u   æ­£æ–‡c                 S   s   g | ]}|d    ¡ r|‘qS )r   ©Ústrip©Ú.0Úc© r   ú(/Users/cheyod/AIGC/DSH/aicomic-import.pyÚ
<listcomp>6   ó    z"split_chapters.<locals>.<listcomp>)ÚsplitÚHEAD_REÚmatchr	   ÚappendÚjoinÚgroup)ÚtextÚlinesÚchaptersZ	cur_titleÚcurÚlnÚmr   r   r   Úsplit_chapters#   s$    
2r   éÜ  c                 C   s°   dd„ t  d| ¡D ƒ}|s,dd„ |  ¡ D ƒ}g g d  }}}|D ]@}|rj||krj| d |¡¡ g d }}| |¡ |t|ƒ7 }q@|r–| d |¡¡ |p®|  ¡ r¬|  ¡ gS g S )uG   æŒ‰æ®µè�½è¾¹ç•ŒæŠŠä¸€ç« æ‹†æˆ�è‹¥å¹²é›†ï¼Œæ¯�é›†ç›®æ ‡ target_chars å­—c                 S   s   g | ]}|  ¡ r|  ¡ ‘qS r   r   ©r   Úpr   r   r   r   =   r   z"split_episodes.<locals>.<listcomp>z\n\s*\nc                 S   s   g | ]}|  ¡ r|  ¡ ‘qS r   r   r   r   r   r   r   ?   r   r   r   )Úrer   Ú
splitlinesr   r   Úlenr	   )r   Útarget_charsZparasÚepisodesr   Zcurlenr    r   r   r   Úsplit_episodes;   s    

r&   c               	   C   s.  i } t j t¡r>zt ttdd�¡} W n ty<   i } Y n0 g }|  d¡rt| 	d|  dd¡| d |  dd¡d	œ¡ t j
 d
¡rš| 	ddt j
d
 dd	œ¡ t j d¡}t j |¡�r*z`t|dd�D ]N}| d
¡rÂ| dd¡d  ¡  tdƒ¡ tdƒ¡}|rÂ| 	dd|dd	œ¡ qÂW n t�y(   Y n0 |S )Núutf-8©ÚencodingZapi_keyZagnesZbase_urlzhttps://apihub.agnes-ai.com/v1Z	llm_modelzagnes-2.5-flash)ÚnameÚbaseÚkeyÚmodelZDEEPSEEK_API_KEYZdeepseekzhttps://api.deepseek.com/v1zdeepseek-chatz~/.dsh/.credentials.yamlú:é   é"   é'   )ÚosÚpathÚexistsÚCONFIG_PATHÚjsonÚloadÚopenÚ	ExceptionÚgetr   ÚenvironÚ
expanduserÚ
startswithr   r	   Úchr)ZcfgÚ	providersZcredr   Úkr   r   r   Ú_load_llm_configM   s>    

þ
þ
(þrA   éÄ	  c                 C   s6  dd l }g }| D �]}t |d d|dœd|dœg|ddœ¡ d¡}|jj|d	  d
¡d |dd|d  dœd�}zb|jj|dd��>}	t |	 	¡  
d¡¡}
|
d d d d W  d   ƒ W   S 1 sÈ0    Y  W q t�y } z.| d|d t|ƒd d… f ¡ W Y d }~qd }~0 0 qtdd |¡ ƒ‚d S )Nr   r-   Úsystem)Úroler   Úuserg333333Ó?)r-   ZmessagesÚ
max_tokensZtemperaturer'   r+   ú/z/chat/completionszapplication/jsonzBearer r,   )zContent-TypeZAuthorization)ÚdataZheaderséx   )ZtimeoutÚchoicesÚmessager   z%s: %sr*   é–   u   LLM å…¨éƒ¨ä¸�å�¯ç”¨: z | )Zurllib.requestr6   ÚdumpsÚencodeZrequestZRequestÚrstripZurlopenÚloadsÚreadÚdecoder9   r   ÚstrÚRuntimeErrorr   )r?   rC   rE   rF   ZurllibZerrsr    ÚbodyZreqÚrÚdÚer   r   r   Ú	_llm_chatl   s2    
ÿüü
þÿ<:rY   c                 C   sÌ   |   ¡ } |  tdƒd ¡rVt dtdƒd  d d| ¡} t dtdƒd  d d| ¡} zt | ¡W S  tyt   Y n0 |  d¡|  	d	¡ }}|d
krÈ||krÈzt | ||d … ¡W S  tyÆ   Y n0 dS )u,   ä»Ž LLM å›žå¤�é‡Œå®½å®¹åœ°æŠ å‡º JSON å¯¹è±¡é`   é   ú^z
[a-zA-Z]*
r   r   ú$ú{ú}r   r/   N)
r	   r=   r>   r!   Úsubr6   rP   r9   ÚfindÚrfind)r   ÚsrX   r   r   r   Ú_extract_json‚   s    rd   éà.  c              
   C   s\  g }| D ]8}|d d|t t| ƒdƒ … }| |d d | ¡ qd |¡dd… }d}d	| d
 }t|||ƒ}	t|	ƒpzi }
|
 dg ¡ |
 dg ¡ |
 dg ¡ |
 dd¡ t|
 d¡t	ƒ�rXg }|
d D ]„}t|t
ƒ�r&| d¡�r&| t|d ƒ ¡ t| dd¡ƒ ¡ t| dd¡ƒ ¡ dœ¡ qÊt|tƒrÊ| ¡ rÊ| | ¡ dddœ¡ qÊ||
d< |
S )uS   LLM æ��å�–èµ„äº§ï¼Œè¿”å›ž {'title','characters':[...],'scenes':[...],'props':[...]}r   Nr/   r   r   z

i`ê  u±   ä½ æ˜¯èµ„æ·±ç½‘æ–‡ç¼–è¾‘ä¸Žæ¼«å‰§åˆ¶ä½œäººã€‚è¯·é€šè¯»ä¸‹é�¢å°�è¯´èŠ‚é€‰ï¼Œæ��å�–åˆ¶ä½œæ¼«å‰§æ‰€éœ€çš„ç»“æž„åŒ–ä¿¡æ�¯ã€‚å�ªè¾“å‡ºä¸€ä¸ª JSON å¯¹è±¡ï¼Œä¸�è¦�ä»»ä½•å…¶ä»–æ–‡å­—ã€‚u   å°�è¯´èŠ‚é€‰ï¼š
u»  

è¯·è¾“å‡º JSONï¼Œå­—æ®µå¦‚ä¸‹ï¼š
{
  "title": "å°�è¯´/å‰§æœ¬å��",
  "characters": [{"name": "è§’è‰²å��", "role": "ä¸»è§’/é…�è§’/å��æ´¾ç­‰", "description": "å¤–è²Œä¸Žæ€§æ ¼ï¼Œ20å­—å†…"}],
  "scenes": ["åœºæ™¯å��ï¼Œå¦‚ï¼šæž—åºœå¤§é—¨Â·æ¸…æ™¨"],
  "props": ["å…³é”®é�“å…·å��ï¼Œå¦‚ï¼šæœ¨å‰‘"]
}
è¦�æ±‚ï¼šcharacters æœ€å¤š12ä¸ªä¸»è¦�è§’è‰²ï¼›scenes æœ€å¤š15ä¸ªï¼›props æœ€å¤š10ä¸ªã€‚è§’è‰²å��å¿…é¡»ä»Žæ–‡ä¸­å‡ºçŽ°çš„äººå��æ��å�–ï¼Œä¸�è¦�ç¼–é€ ã€‚Ú
charactersÚscenesÚpropsõ   æœªå‘½å��å‰§æœ¬r*   rD   r   Údescription©r*   rD   rj   )Úmaxr#   r   r   rY   rd   Ú
setdefaultÚ
isinstancer:   ÚlistÚdictrS   r	   )r   r?   Zsample_charsÚpartsr   ÚheadÚcontextrC   rE   ÚrawrW   Zfixedr   r   r   Úextract_assets_llm•   s2    
þ
ru   c           
      C   s@  d  dd„ | D ƒ¡}i }t d|¡D ]6}| d¡}t|ƒdkr$|dvr$| |d¡d ||< q$d	d
„ | ¡ D ƒdd… }g }t d|¡D ](}| d¡ ¡ }|r†||vr†| |¡ q†g }t d|¡D ](}| d¡ ¡ }	|	rÀ|	|vrÀ| |	¡ qÀtt	j
ƒdk�rtj t	j
d ¡ dd¡d nddd
„ |D ƒ|dd… |dd… dœS )uU   è§„åˆ™å…œåº•ï¼šå¯¹è¯�å½’å±ž+è¯�é¢‘æ��äººç‰©ï¼›åœ°ç‚¹å�Žç¼€æ��åœºæ™¯ï¼›é‡�è¯�æ��é�“å…·r   c                 s   s   | ]}|d  V  qdS )r   Nr   r
   r   r   r   Ú	<genexpr>½   r   z+extract_assets_heuristic.<locals>.<genexpr>ui   ([\u4e00-\u9fa5]{1,4})(?:è¯´|é�“|é—®|å–Š|ç­”|å¿ƒæƒ³|ä½Žè¯­|å�¹|å–�|æƒŠ|æ€’é�“|ç¬‘é�“|æ²‰å£°é�“|æ·¡æ·¡é�“)r/   r   )u   ä»–è¯´u   å¥¹è¯´u   ä¼—äººu   å¤§å®¶u   å…¶ä¸­r   c                 S   s   g | ]\}}|d kr|‘qS )r[   r   )r   Únr   r   r   r   r   Ã   r   z,extract_assets_heuristic.<locals>.<listcomp>Né   uÑ   (?:æ�¥åˆ°|èµ°è¿›|å›žåˆ°|ç¦»å¼€|ç«™åœ¨|ä½�äºŽ|åœ¨|èµ¶å¾€|é€ƒåˆ°)([^ï¼Œã€‚ï¼�ï¼Ÿï¼›]{0,10}?)(?:çš„)?(?:å±±|åŸŽ|åºœ|æ®¿|å®«|é™¢|é•‡|æ�‘|æ´ž|æž—|è°·|å¡”|æ¥¼|é˜�|æ²³|æ¹–|é—¨|åº™|åŽ…|æˆ¿|å±‹|å ¡|è�¥|å¯¨|å ‚|åœº|åœ°)u®   (?:ä¸€æŠŠ|ä¸€æŸ„|ä¸€æžš|ä¸€é¢—|ä¸€åŒ…|ä¸€ä»¶|ä¸€ç“¶|ä¸€å�·|ä¸€å�—|ä¸€é¡¶|ä¸€èº«|ä¸€æ ¹|ä¸€å†Œ|ä¸€é¡µ|ä¸€ä¸ª|ä¸€å�ª|ä¸€æ”¯|ä¸€å¼ |ä¸€æ�¡|ä¸€ç›�|ä¸€ä»½)([^ï¼Œã€‚ï¼�ï¼Ÿ\s]{1,6})Ú.ri   c                 S   s   g | ]}|d d dœ‘qS )r   rk   r   )r   rw   r   r   r   r   Ð   r   é   é
   )r   rf   rg   rh   )r   r!   Úfinditerr   r#   r:   Úitemsr	   r   ÚsysÚargvr2   r3   ÚbasenameÚrsplit)
r   ZfullÚcharsr   rw   Únamesrg   rc   rh   r    r   r   r   Úextract_assets_heuristic»   s,    
0

ür„   c                    s   g }dg‰‡fdd„‰ ‡ fdd„}‡ fdd„}‡ fdd	„}‡ fd
d„}t dd„ | ¡ D ƒƒ}	| |ddd| t|ƒ|	t| dg ¡ƒt| dg ¡ƒt| dg ¡ƒf ƒ¡ t| dg ¡ƒD ]"\}
}| |dd|
d  |ƒ¡ q¶d}t|ƒD ]Ò\}}| |g ¡}| ||dd|d t|ƒd dd„ tt|ƒƒD ƒ¡f ƒ¡ t|ƒD ]p\}}d|d |d f }| ¡  	dd¡d d… t|ƒdk�r‚dnd }| ||d d|d   |d!| ƒ¡ �q>|d"7 }qæd#d d$d„ | dg ¡D ƒ¡ d% d d&d„ | dg ¡D ƒ¡ }| ||dd'|ƒ¡ |d(d(dd)œd*œS )+Niè  c                      s    ˆ d  d7  < dt ˆ d ƒ S )Nr   r/   r   )rS   r   )Úuidr   r   ÚcidÛ   s    zbuild_canvas_json.<locals>.cidc                    s   ˆ ƒ d| |dd|idœS )NÚnoter   r   ©ÚidÚtypeÚxÚyZstatusrH   r   )r‹   rŒ   r   ©r†   r   r   r‡   ß   s    zbuild_canvas_json.<locals>.notec                    s"   ˆ ƒ d| |d||g ddddœdœS )NÚscener   r   )ÚeprŽ   ZcharIdsÚpromptr   Zmoverˆ   r   )r‹   rŒ   r�   Ú	scene_txtr�   r   r   rŽ   â   s
    ÿÿz build_canvas_json.<locals>.scenec                    s2   ˆ ƒ d| |d|  dd¡|  dd¡dddddœd	œS )
NÚcharr   r*   u   è§’è‰²rj   r   uD   ç”±å‰§æœ¬å¯¼å…¥æ��å�–ï¼Œè¯·è¡¥å……å¤–è²Œ/æœ�è£…/ç‰¹å¾�ä»¥é”�å®šå½¢è±¡)r*   Z
appearanceZoutfitZfeatureZrefImgZrefNoterˆ   )r:   )r‹   rŒ   r   r�   r   r   r’   ç   s    þÿzbuild_canvas_json.<locals>.charc                    s   ˆ ƒ d| |d||dœdœS )NÚtoolr   )r   rU   rˆ   r   )r‹   rŒ   ÚtÚbr�   r   r   r“   í   s    ÿzbuild_canvas_json.<locals>.toolc                 s   s   | ]}t |ƒV  qd S )N©r#   )r   Úvr   r   r   rv   ñ   r   z$build_canvas_json.<locals>.<genexpr>é(   uD  ðŸ“– å‰§æœ¬å¯¼å…¥æ€»è§ˆ

ã€Š%sã€‹
ç« èŠ‚ï¼š%d ç« 
é›†æ•°ï¼š%d é›†
äººç‰©ï¼š%d ä½�
åœºæ™¯ï¼š%d ä¸ª
é�“å…·ï¼š%d ä»¶

â–  å·¦ä¾§ï¼šè§’è‰²èµ„äº§åº“ï¼ˆç‚¹ã€Œï¼‹è§’è‰²å�¡ã€�å�¯è¡¥å……ï¼‰
â–  ä¸­é—´ï¼šæ¯�ç« ä¸€åˆ—ï¼Œæ¯�é›†ä¸€å¼ åœºæ™¯å�¡
â–  å�³ä¸Šï¼šåœºæ™¯/é�“å…·æ¸…å�•
â–  é€�ä¸ªåœºæ™¯å�¡å¡«å†™å�°è¯�/è¿�é•œå�Žç‚¹ã€ŒðŸŽ¨ ç”Ÿå›¾ã€�rf   rg   rh   i  i,  i  u   ðŸ“š %s

å…±æ‹†ä¸º %d é›†ï¼š
%sr   r   c                 s   s   | ]}d |d  V  qdS )u   Â· ç¬¬%dé›†r/   Nr   )r   Újr   r   r   rv   ü   r   u   %s Â· ç¬¬%dé›†r/   r   é<   u   â€¦r   i@  u   ï¼ˆæœªæ‹†é•œï¼‰i0  u   ã€�åœºæ™¯ã€‘
c                 s   s   | ]}d | V  qdS ©u   Â· Nr   )r   rc   r   r   r   rv     r   u   

ã€�é�“å…·ã€‘
c                 s   s   | ]}d | V  qdS r›   r   r   r   r   r   rv     r   u   ðŸ§° åœºæ™¯ / é�“å…·èµ„äº§r   )ZtxZtyÚz©ÚcardsÚview)
ÚsumÚvaluesr   r#   r:   Ú	enumerater   Úranger	   Úreplace)r   r   Úepisodes_mapÚassetsrž   r‡   rŽ   r’   r“   Z	total_epsÚir   r‹   ZciÚchZepsr™   r�   Zep_titler‘   rU   r   )r†   r…   r   Úbuild_canvas_json×   s:    
*ÿþ&ÿ
.(
@r©   Tc           	         sÂ   t | ƒ}i ‰ t|ƒD ]\}}t|d |ƒˆ |< qd }|rhtƒ }|rhzt||ƒ}W n tyf   d }Y n0 |d u rxt|ƒ}t| dd¡|ˆ |ƒ}d| dd¡‡ fdd„t|ƒD ƒ||d |d d	œS )
Nr   r   ri   Tc                    s&   g | ]\}}|d  t ˆ | ƒdœ‘qS )r   )r   r%   r–   )r   r§   r   ©r¥   r   r   r     r   zrun_import.<locals>.<listcomp>rž   rŸ   )Úokr   r   r¦   rž   rŸ   )	r   r¢   r&   rA   ru   r9   r„   r©   r:   )	r   r$   Úuse_llmr   r§   r¨   r¦   r?   Zcanvasr   rª   r   Ú
run_import  s,    

úr­   c                  C   sØ  t jdd … } | s$ttƒ t  d¡ | d }d}d}d}d| v rR| |  d¡d  }d| v rpt| |  d¡d  ƒ}d| v r|d	}tj 	|¡sžtd
| ƒ t  d¡ t
|dd� ¡ }t|||d�}t
|ddd��0}tj|d |d dœ|d	dd� W d   ƒ n1 �s0    Y  tdƒ td|d ƒ tdt|d ƒdtdd„ |d D ƒƒƒ tdt|d  dg ¡ƒdd  d!d„ |d  dg ¡D ƒ¡d d"… ƒ td#t|d  d$g ¡ƒd%t|d  d&g ¡ƒƒ td'tj |¡ƒ td(ƒ d S ))Nr/   r   zaicomic-import.jsonr   Tz-oz--targetz--no-llmFu   æ–‡ä»¶ä¸�å­˜åœ¨: %sr'   r(   )r$   r¬   Úwrž   rŸ   r�   r   )Zensure_asciiÚindentu   âœ… å¯¼å…¥å®Œæˆ�u	     æ ‡é¢˜:r   u	     ç« èŠ‚:r   u   ç«  / é›†æ•°:c                 s   s   | ]}|d  V  qdS )r%   Nr   r
   r   r   r   rv   :  r   zmain.<locals>.<genexpr>u	     äººç‰©:r¦   rf   u   ä½� ->z, c                 s   s   | ]}|d  V  qdS )r*   Nr   r
   r   r   r   rv   ;  r   éP   u	     åœºæ™¯:rg   u   ä¸ª / é�“å…·:rh   u	     è¾“å‡º:u<     æ��ç¤º: æ‰“å¼€ç”»å¸ƒ â†’ ç‚¹ã€Œâ¬† å¯¼å…¥ã€�é€‰è¿™ä¸ª json)r~   r   ÚprintÚ__doc__ÚexitÚindexÚintr2   r3   r4   r8   rQ   r­   r6   Údumpr#   r    r:   r   Úabspath)Úargsr3   ÚoutÚtargetr¬   r   ÚresÚfr   r   r   Úmain"  s8    

@(B.r½   Ú__main__)r   )rB   )re   )r   T)r²   r6   r2   r!   r~   r3   Údirnamer·   Ú__file__ZBASE_DIRr   r5   Úcompiler   r   r&   rA   rY   rd   ru   r„   r©   r­   r½   Ú__name__r   r   r   r   Ú<module>   s*   ÿ


&1
