o
    Ղi                     @   s   d Z ddlZddlmZ ddlZddlmZ ddlmZ ddl	m
Z
 e ZdZej dZd	ed
dfddZded
efddZdddZejde
dddd ZdS )uk   媒体批处理任务 — 切换到 media_processing 模式，批量 OCR/ASR，完成后切回 inference。    N)logger)
celery_app)get_settings)DatabaseTaskzhttp://localhost:8400/v1z/internal/switch_modemodereturnc              
   C   s   dd l }ttdd pd}tjtd| id|idd  td|  d	 z<dd l	}|j
d
dddd}tdD ]}|d}|| krMtd|    W d S |d q6td|d  W d S  ty{ } ztd|  W Y d }~d S d }~ww )Nr   internal_api_token r   zX-Internal-Token   )jsonheaderstimeoutu#   [ocr_tasks] 模式切换已触发: u   ，等待就绪...	localhosti  T)hostportdbdecode_responsesx   zllm:service:statusu    [ocr_tasks] 已切换到模式:    u5   [ocr_tasks] 等待模式切换超时，当前状态: u/   [ocr_tasks] 无法轮询 Redis，直接继续: )timegetattrsettingshttpxpostSWITCH_MODE_URLraise_for_statusr   inforedisRedisrangegetsleepwarning	Exception)r   r   token_redisr_currente r*   A/lsinfo/ai/hellotax_ai/data_center/backend/app/tasks/ocr_tasks.py_switch_mode   s0   
r,   
local_pathc                 C   s`   d}t jt dddddd|  idd	|d
gdgdddd}| d d d d  S )Nut   提取图片中所有文字内容，表格用Markdown格式输出，保持原始结构，不要添加任何解释。z/chat/completionszQwen3-VL-32B-Instructuser	image_urlurlzfile://)typer/   text)r1   r2   )rolecontenti   )modelmessages
max_tokensr   )r   r   choicesr   messager4   )r   r   VL_BASE_URLr   strip)r-   promptrespr*   r*   r+   
_ocr_image+   s   r>   c                    s   ddl m} | jsdS || jd}| jpg D ]#  dsq|jd fddd	}|r9||d
 d  dd q||t	|
dd| _dS )uV   将 inline_images[i].ocr_text 原位插入 content_html，重新生成 content_text。r   )BeautifulSoupNlxmlocr_textimgc                    s   | o d | v S )Nsrc_originalr*   )simg_infor*   r+   <lambda>E   s    z'_rebuild_content_text.<locals>.<lambda>)srcz<p class="ocr-text">z</p>zhtml.parser r	   )bs4r?   content_htmlinline_imagesr    findinsert_aftermarkdown_to_rag_texthtml_to_markdownstrreplacecontent_text)doccleanerr?   souptagr*   rE   r+   _rebuild_content_text<   s$   
rX   Tz#app.tasks.ocr_tasks.run_media_batch)bindbasenamec                 C   s@  ddl m} ddlm} ddlm} | j}|||j	
d }dd |D }|s6td d	dd
S tdt| d | }td d}z|D ]}	d}
|	j	D ]<}|ds`|dsaqTzt|d |d< d	}
W qT ty } ztd|	j d|d  d|  W Y d}~qTd}~ww |
rt|	| ||	d z?|  |d7 }ddlm} ||	j|	j	|	j |	jr|	jrddlm} ddl}|tj t!tddd}|"|#|	j|	j$ W qM ty } z|%  t&d|	j d|  W Y d}~qMd}~ww qMW td ntd w td| dt|  d	|t|dS )uS   批量处理所有待 OCR 文档（inline_images 有 path 但 ocr_text 为空）。r   )TaxDocument)DocumentCleaner)flag_modifiedNc                 S   s(   g | ]}t d d |jpg D r|qS )c                 s   s&    | ]}| d  o| dV  qdS )rA   pathN)r    ).0rB   r*   r*   r+   	<genexpr>Z   s   $ z-run_media_batch.<locals>.<listcomp>.<genexpr>)anyrL   )r`   dr*   r*   r+   
<listcomp>X   s    z#run_media_batch.<locals>.<listcomp>u'   [ocr_tasks] 无待处理文档，跳过T)success	processedu   [ocr_tasks] 待处理文档: u    条media_processingFrA   r_   z[ocr_tasks] doc_id=u    OCR 失败: u    — rL      )index_document_media)KnowledgeBaseClientbase_platform_api_key)base_urlapi_keyu    写库失败: 	inferenceu   [ocr_tasks] 完成: processed=/)re   rf   total)'app.models.tax_datar\   0app.services.tax_data_processor.document_cleanerr]   sqlalchemy.orm.attributesr^   r   queryfilterrL   isnotallr   r   lenr,   r    r>   r#   r"   idrX   commitapp.services.multimodal_indexerri   inline_videosis_importedknowledge_doc_id5app.services.tax_data_processor.knowledge_base_clientrj   asyncior   base_platform_urlr   runupdate_document_contentrS   rollbackerror)selfr\   r]   r^   r   docspendingrU   rf   rT   updatedrB   r)   ri   rj   _asyncio_clientr*   r*   r+   run_media_batchO   sh   


.

$r   )r   N)__doc__r   logurur   r   app.celery_appr   
app.configr   app.tasks.processor_tasksr   r   r:   r   r   rQ   r,   r>   rX   taskr   r*   r*   r*   r+   <module>   s    
