o
    i3                     @   s   d Z ddlZddlZddlmZ eg ddd eddD  d	d eddD  Zed
Z	edZ
dZdddddddddZddddddededee dee dee dedefddZdedefddZd edefd!d"Zded#edefd$d%ZdS )&u  文件名安全工具

按分类规则生成文件名，确保跨平台安全（Unicode 标准化、非法字符替换、字节截断）。

命名规则（与方案文档一致）：
  - 法律（1）          : {title}
  - 行政法规（2）      : {title}_{compose_date}
  - 国务院文件（3）    : {title}_{doc_number}_{compose_date}
  - 税务部门规章（4）  : {title}_{sub_title}
  - 财税文件（5）      : {title}_{doc_number}_{compose_date}
  - 税务规范性文件（6）: {title}_{doc_number}_{compose_date}
  - 其他文件（7）      : {title}_{doc_number}_{compose_date}
  - 工作通知（8）      : {title}_{doc_number}_{compose_date}
    N)Optional)CONPRNAUXNULc                 C      g | ]}d | qS )COM .0ir	   r	   \/lsinfo/ai/hellotax_ai/data_center/backend/app/services/tax_data_processor/filename_utils.py
<listcomp>       r      
   c                 C   r   )LPTr	   r
   r	   r	   r   r      r   z[<>:"/\\|?*\x00-\x1f\x7f]z5[\u200b-\u200f\u202a-\u202e\u2060-\u2064\ufeff\u00ad]   
title_only
title_datetitle_docno_datetitle_subtitle)r                        z.md)
doc_numbercompose_date	sub_title	extensiontitlecategory_idr   r    r!   r"   returnc                C   s   t |d}t| }|rt|nd}|rt|nd}	|r t|nd}
|dkr*|g}n&|dkr8dd ||	fD }n|dkrFdd ||
fD }n
d	d |||	fD }|rWd
|nd}| tv rdd
| }t|tt	|
  }|| S )u  
    生成安全的文件名（含扩展名）。

    Args:
        title:        文档主标题
        category_id:  分类 ID（1-8）
        doc_number:   发文字号，如 "财税[2023]10号"
        compose_date: 成文日期，格式 YYYY-MM-DD 或 YYYYMMDD
        sub_title:    副标题（仅税务部门规章使用）
        extension:    文件扩展名，默认 ".md"

    Returns:
        安全的文件名字符串，如 "中华人民共和国增值税法_财税[2023]10号_20231015.md"
    r    r   r   c                 S      g | ]}|r|qS r	   r	   r   pr	   r	   r   r   W       z!safe_filename.<locals>.<listcomp>r   c                 S   r'   r	   r	   r(   r	   r	   r   r   Y   r*   c                 S   r'   r	   r	   r(   r	   r	   r   r   [   r*   _untitled)_CATEGORY_RULESget	_sanitize_normalize_datejoinupper_RESERVED_NAMES_truncate_to_bytes
_MAX_BYTESlenencode)r#   r$   r   r    r!   r"   ruleclean_titleclean_docno
clean_dateclean_subtitlepartsstemr	   r	   r   safe_filename4   s"   
r?   textc                 C   sH   | sdS t d| } td| } td| } tdd| } | d S )u_   清理字段：NFC 标准化 → 去零宽/控制字符 → 替换非法字符 → 折叠空白r&   NFCr+   z[\s_]+)unicodedata	normalize_ZERO_WIDTH_REsub_ILLEGAL_CHARS_RErestrip)r@   r	   r	   r   r/   i   s   r/   date_strc                 C   s:   t dd| }t|dkr|S t|dkr|dd S | S )u   
    将日期字符串统一转换为 YYYYMMDD 格式。
    接受：YYYY-MM-DD、YYYY/MM/DD、YYYYMMDD、YYYY年MM月DD日 等。
    z\Dr&   r   r   N)rG   rE   r6   )rI   digitsr	   r	   r   r0   x   s   r0   	max_bytesc                 C   s4   |  d}t||kr| S |d| }|jdddS )uC   按 UTF-8 字节数截断字符串，确保不破坏多字节字符zutf-8Nignore)errors)r7   r6   decode)r@   rK   encoded	truncatedr	   r	   r   r4      s
   
r4   )__doc__rG   rB   typingr   	frozensetranger3   compilerF   rD   r5   r-   strintr?   r/   r0   r4   r	   r	   r	   r   <module>   s^    

5