
    +j*              	       8   d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ  e              eddh          ZdZe G d	 d
                      Zefdededeee	f         dz  fdZdeee	f         deddfdZ	 	 ddedej        dz  dedz  defdZdS )zMetadata extraction for asset scanning.

Tier 1: Filesystem metadata (zero parsing)
Tier 2: Safetensors header metadata (fast JSON read only)
    N)	dataclass)Any)init_mime_typesz.safetensorsz.sfti   c                      e Zd ZU dZdZeed<   dZeed<   dZe	ed<   dZ
edz  ed<   dZeed	<   dZedz  ed
<   dZee         dz  ed<   dZedz  ed<   dZeed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   deeef         fdZdedee         fdZdS )ExtractedMetadataz/Metadata extracted from a file during scanning. filename	file_pathr   content_lengthNcontent_typeformat
base_modeltrained_wordsairFhas_preview_images
source_url
source_arnrepo_urlpreview_urlsource_hashrepo_idrevisionfilepathresolve_urlreturnc                 $   | j         | j        | j        d}| j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        rd|d<   | j	        r
| j	        |d	<   | j
        r
| j
        |d
<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   | j        r
| j        |d<   |S )zJConvert to user_metadata dict for AssetReference.user_metadata JSON field.)r	   r   r   r
   r   r   r   r   Tr   r   r   r   r   r   r   r   r   r   )r	   r   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )selfdatas     D/home/wildlama/comfy/ComfyUI/app/assets/services/metadata_extract.pyto_user_metadataz"ExtractedMetadata.to_user_metadata9   s    "1k 
  

 > 	/ $D 	5#'#4D  ? 	1!%D 	7$($6D!8 	#(DK" 	.)-D%& ? 	1!%D? 	1!%D= 	-#}D 	3"&"2D 	3"&"2D < 	+"lDO= 	-#}D= 	-#}D 	3"&"2D    reference_idc           	      n   g ddt           dt           dz  dt          ddffd}dt           dt          t          z  dz  ddffd}dt           dt          dz  ddffd	} |d
| j                    |d| j                    |d| j                    |d| j                    |d| j                    |d| j	                   | j
        r| j
        nd} |d|           | j        r0t          | j        dd                   D ]\  }} |d||            |d| j                    |d| j                    |d| j                    |d| j                    |d| j                    |d| j                    |d| j                    |d| j                    |d| j                   S )z@Convert to asset_reference_meta rows for typed/indexed querying.r   keyvalNordinalr   c           
          |r<                     | |t          |          dk    r
|d d         n|d d d d           d S d S )Ni   asset_reference_idr$   r&   val_strval_numval_boolval_json)appendlen)r$   r%   r&   r"   rowss      r   add_strz/ExtractedMetadata.to_meta_rows.<locals>.add_strk   sn     	*6&-0XX__s5D5zz## $ $      	 	r!   c           
      J    |                     | dd |d d d           d S d S Nr   r(   r.   r$   r%   r"   r0   s     r   add_numz/ExtractedMetadata.to_meta_rows.<locals>.add_numw   sN    *6 #" $ $       r!   c           
      J    |                     | dd d |d d           d S d S r3   r4   r5   s     r   add_boolz0ExtractedMetadata.to_meta_rows.<locals>.add_bool   sN    *6 ## # $       r!   r	   r   r   r   r   r   r   d   r   )r&   r   r   r   r   r   r   r   r   r   )r   )strintfloatboolr	   r   r   r   r   r   r   r   	enumerater   r   r   r   r   r   r   r   r   )	r   r"   r1   r6   r8   has_previewsiwordr0   s	    `      @r   to_meta_rowszExtractedMetadata.to_meta_rowsg   s   
	 
	 
	3: 
	 
	D 
	 
	 
	 
	 
	 
	 
	
	 
	3;#5 
	$ 
	 
	 
	 
	 
	 
	 
	
	# 
	D4K 
	D 
	 
	 
	 
	 
	 
	 
	 	
DM*** $"5666 1222$+&&& 	do...tx   262ISt..t%|444  	:$T%7%=>> : :4q99999 	do...do...
DM***t/000t/000 		4<(((
DM***
DM***t/000r!   )__name__
__module____qualname____doc__r	   r:   __annotations__r
   r   r;   r   r   r   r   listr   r   r=   r   r   r   r   r   r   r   r   r   dictr   r    rB    r!   r   r   r      s        99 HcIsNC#L#*###FC "Jd
!!!&*M49t#***Ct$$$$ "Jd
!!!!Jd
!!!HcDj"Kt""""Kt""" GS4ZHcDjHcDj"Kt""",$sCx. , , , ,\F Fd F F F F F Fr!   r   pathmax_sizer   c                 8   	 t          | d          5 }|                    d          }t          |          dk     r	 ddd           dS t          j        d|          d         }||k    r	 ddd           dS |                    |          }t          |          |k     r	 ddd           dS t          j        |                    d                    cddd           S # 1 swxY w Y   dS # t          t
          j	        t          t          j        f$ r Y dS w xY w)aW  Read only the JSON header from a safetensors file.

    This is very fast - reads 8 bytes for header length, then the JSON header.
    No tensor data is loaded.

    Args:
        path: Absolute path to safetensors file
        max_size: Maximum header size to read (default 8MB)

    Returns:
        Parsed header dict or None if failed
    rb   Nz<Qr   zutf-8)openreadr/   structunpackjsonloadsdecodeOSErrorJSONDecodeErrorUnicodeDecodeErrorerror)rK   rL   fheader_byteslength_of_headerheader_datas         r   _read_safetensors_headerr_      s   $ 
	;66!99L<  1$$
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	;  &}T<@@C(**
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; &&!122K;"222
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; :k0099::
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; 
	; T)+=v|L   ttsW   C. *C!C. 	"C!+C. 8)C!!C. .&C!C. !C%%C. (C%)C. .'DDheadermetac                    |                      di           }t          |t                    sdS |                     d          p)|                     d          p|                     d          |_        |                     d          }|rt          |t                    r	 t          j        |          }t                      }|                                D ]>}t          |t                    r'|	                    |
                                           ?|rt          |          dd         |_        n# t
          j        $ r Y nw xY w|j        s|                     d          }t          |t                    r	 t          j        |          }t          |t                    rd	 |D             |_        n$d
 |                    d          D             |_        n_# t
          j        $ r' d |                    d          D             |_        Y n*w xY wt          |t                    rd |D             |_        |                     d          p|                     d          |_        |                     d          }	|	rd|_        |                     d          |_        |                     d          |_        |                     d          |_        |                     d          |_        |                     d          p|                     d          |_        |                     d          p|                     d          |_        |                     d          p|                     d          |_        |                     d          p|                     d          |_        |                     d          p|                     d          |_        dS ) z`Extract metadata from safetensors header __metadata__ section.

    Modifies meta in-place.
    __metadata__Nss_base_model_versionzmodelspec.base_modelr   ss_tag_frequencyr9   r   c                 ,    g | ]}t          |          S rJ   r:   .0xs     r   
<listcomp>z1_extract_safetensors_metadata.<locals>.<listcomp>   s    )A)A)AQ#a&&)A)A)Ar!   c                 ^    g | ]*}|                                 |                                 +S rJ   stripri   ws     r   rk   z1_extract_safetensors_metadata.<locals>.<listcomp>   s-    )X)X)Xaggii)X!'')))X)X)Xr!   ,c                 ^    g | ]*}|                                 |                                 +S rJ   rm   ro   s     r   rk   z1_extract_safetensors_metadata.<locals>.<listcomp>   s-    %T%T%TA!''))%Taggii%T%T%Tr!   c                 ,    g | ]}t          |          S rJ   rg   rh   s     r   rk   z1_extract_safetensors_metadata.<locals>.<listcomp>   s    !5!5!5Q#a&&!5!5!5r!   r   zmodelspec.airssmd_cover_imagesTr   r   r   r   r   sshs_model_hashr   
hf_repo_idr   hf_revisionr   hf_filepathr   hf_url)get
isinstancerI   r   r:   rT   rU   setvaluesupdatekeyssortedr   rX   rH   splitr   r   r   r   r   r   r   r   r   r   r   )
r`   ra   st_metar   tag_freqall_tagsdataset_tagstwparsedcover_imagess
             r   _extract_safetensors_metadatar      s    jj,,Ggt$$  	+,, 	%;;-..	%;;|$$ 	O KK 233M M377 
	z-00H!$H ( 1 1 9 9lD11 9OOL$5$5$7$7888 <%+H%5%5dsd%;"# 	 	 	D	  6[[))b# 
	6UBfd++ Y)A)A&)A)A)AD&&)X)XRXXc]])X)X)XD&' U U U%T%T#%T%T%T"""UD!! 	6!5!5"!5!5!5D {{5!!AW[[%A%ADH ;;233L '"& kk,//DOkk,//DOKK
++DM{{=11D{{=11SW[[AR5S5SD ;;y))FW[[-F-FDLKK
++Iw{{=/I/IDMKK
++Iw{{=/I/IDM{{=11JW[[5J5JDs&   BD3 3EE:AG 3HHabs_pathstat_resultrelative_filenamec                    t                      }|pt          j                            |           |_        | |_        t          j                            |           \  }}|r'|                    d                                          nd|_	        t          j        |           \  }}||_        |(	 t          j        | d          }n# t          $ r Y nw xY w|r|j        |_        |                                t"          v rPt%          |           }|r?	 t'          ||           n-# t(          $ r }t+          j        d| |           Y d}~nd}~ww xY w|S )a  Extract metadata from a file using tier 1 and tier 2 methods.

    Tier 1: Filesystem metadata from path and stat
    Tier 2: Safetensors header parsing if applicable

    Args:
        abs_path: Absolute path to the file
        stat_result: Optional pre-fetched stat result (saves a syscall)
        relative_filename: Optional relative filename to use instead of basename
            (e.g., "flux/123/model.safetensors" for model paths)

    Returns:
        ExtractedMetadata with all available fields populated
    .r   NT)follow_symlinksz&Safetensors meta extract failed %s: %s)r   osrK   basenamer	   r
   splitextlstriplowerr   	mimetypes
guess_typer   statrW   st_sizer   SAFETENSORS_EXTENSIONSr_   r   	Exceptionloggingdebug)	r   r   r   ra   _ext	mime_typer`   es	            r   extract_file_metadatar     s|   & D &C)9)9()C)CDMDNWh''FAs-08#**S//'')))bDK'11LIq!D 	'(DAAAKK 	 	 	D	  2)1 yy{{,,,)(33 	UU-fd;;;; U U UFRSTTTTTTTTU Ks*   /C 
CCD" "
E,EE)NN)rF   rT   r   r   r   rR   dataclassesr   typingr   utils.mime_typesr   	frozensetr   MAX_SAFETENSORS_HEADER_SIZEr   r:   r;   rI   r_   r   r   r   rJ   r!   r   <module>r      s          				  ! ! ! ! ! !       , , , , , ,     #NF#;<<  .  Q Q Q Q Q Q Q Qj  ; 
	#s(^d   >CKcNCK"3CK	CK CK CK CKP *.$(1 11$&1 Tz1 	1 1 1 1 1 1r!   