
    +j!                    ^   S SK Jr  S SKrS SKrS SKJr  S SKJr  S SKJrJ	r	J
r
  S SKJr  S SKJrJrJrJrJrJrJrJrJr  S SKJr  \(       a  S S	KJr   " S
 S\
5      r " S S\
5      r " S S\
5      r " S S\
5      r " S S\
5      r\ " S S5      5       r  S       SS jjr!SS jr"g)    )annotationsN)	dataclass)datetime)TYPE_CHECKINGAny	TypedDict)Session)	bulk_insert_assets'bulk_insert_references_ignore_conflictsbulk_insert_tags_and_metadelete_assets_by_idsget_existing_asset_idsget_reference_ids_by_ids%get_references_by_paths_and_asset_ids#get_unreferenced_unhashed_asset_idsrestore_references_by_paths)get_utc_now)ExtractedMetadatac                  ~    \ rS rSr% SrS\S'   S\S'   S\S'   S\S'   S	\S
'   S\S'   S\S'   S\S'   S\S'   S\S'   Srg)SeedAssetSpec   z*Spec for seeding an asset from filesystem.strabs_pathint
size_bytesmtime_ns	info_namez	list[str]tagsfnamezExtractedMetadata | Nonemetadata
str | Nonehash	mime_typejob_id N__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r%       ?/home/wildlama/comfy/ComfyUI/app/assets/services/bulk_ingest.pyr   r      s;    4MOMN
OJ&&
r.   r   c                  L    \ rS rSr% SrS\S'   S\S'   S\S'   S\S	'   S
\S'   Srg)AssetRow+   z Row data for inserting an Asset.r   idr!   r"   r   r   r#   r   
created_atr%   Nr&   r%   r.   r/   r1   r1   +   s!    *G
Or.   r1   c                      \ rS rSr% SrS\S'   S\S'   S\S'   S\S'   S\S	'   S\S
'   S\S'   S\S'   S\S'   S\S'   S\S'   S\S'   Srg)ReferenceRow5   z)Row data for inserting an AssetReference.r   r3   asset_id	file_pathr   r   owner_idnamer!   
preview_iddict[str, Any] | Noneuser_metadatar$   r   r4   
updated_atlast_access_timer%   Nr&   r%   r.   r/   r6   r6   5   sG    3GMNMM
I((r.   r6   c                  B    \ rS rSr% SrS\S'   S\S'   S\S'   S\S'   S	rg
)TagRowF   zRow data for inserting a Tag.r   asset_reference_idtag_nameoriginr   added_atr%   Nr&   r%   r.   r/   rB   rB   F   s    'MKr.   rB   c                  `    \ rS rSr% SrS\S'   S\S'   S\S'   S\S	'   S
\S'   S\S'   S\S'   Srg)MetadataRowO   z&Row data for inserting asset metadata.r   rD   keyr   ordinalr!   val_strzfloat | Noneval_numzbool | Noneval_boolr=   val_jsonr%   Nr&   r%   r.   r/   rI   rI   O   s-    0	HL##r.   rI   c                  8    \ rS rSr% SrS\S'   S\S'   S\S'   Srg)	BulkInsertResult[   zResult of bulk asset insertion.r   inserted_refs	won_paths
lost_pathsr%   Nr&   r%   r.   r/   rR   rR   [   s    )NOr.   rR   c                   U(       d  [        SSSS9$ [        5       n/ n/ n0 n0 n/ nU GH0  n	[        R                  R	                  U	S   5      n
[        [        R                  " 5       5      n[        [        R                  " 5       5      nUR                  U
5        XU
'   U	R                  S5      nUR                  UU	R                  S5      U	S   UUS.5        U	R                  S5      nU(       a  UR                  5       nOU	S	   (       a  S
U	S	   0nOSnUR                  UUU
U	S   UU	S   SUU	R                  S5      UUUS.5        UU	S   U	S	   US.X{'   GM3     [        X5        [        X Vs/ s H  nUS   PM
     sn5      nU Vs/ s H  nUS   U;   d  M  UPM     nn[        X5        [        X5        [        X5      nU Vs1 s H  nUU   U;   d  M  UiM     nnUU-
  nU Vs/ s H  nUU   PM
     nnU(       a  [!        U U5        U(       d  [        SS[#        U5      S9$ U Vs/ s H  nXvU      S   PM     nn[%        U U5      n/ n/ nU(       a  U H  nUU   nX{   nUS   nUU;  a  M  US    H  nUR                  UUSUS.5        M     UR                  S5      nU(       a"  UR'                  UR)                  U5      5        Mu  US
   (       d  M  UR                  US
SUS
   SSSS.5        M     [+        U UUS9  [        [#        U5      [#        U5      [#        U5      S9$ s  snf s  snf s  snf s  snf s  snf )aO  Seed assets from filesystem specs in batch.

Each spec is a dict with keys:
  - abs_path: str
  - size_bytes: int
  - mtime_ns: int
  - info_name: str
  - tags: list[str]
  - fname: Optional[str]

This function orchestrates:
1. Insert seed Assets (hash=NULL)
2. Claim references with ON CONFLICT DO NOTHING on file_path
3. Query to find winners (paths where our asset_id was inserted)
4. Delete Assets for losers (path already claimed by another asset)
5. Insert tags and metadata for successfully inserted references

Returns:
    BulkInsertResult with inserted_refs, won_paths, lost_paths
r   )rT   rU   rV   r   r#   r"   r   )r3   r"   r   r#   r4   r    r   filenameNr   r   r$   )r3   r8   r9   r   r:   r;   r<   r>   r$   r4   r?   r@   r   )reference_idr   rX   extracted_metadatar8   rY   	automatic)rD   rE   rF   rG   rZ   )rD   rK   rL   rM   rN   rO   rP   )tag_rows	meta_rows)rR   r   ospathabspathr   uuiduuid4appendgetto_user_metadatar
   r   r   r   r   r   lenr   extendto_meta_rowsr   )sessionspecsr:   current_time
asset_rowsreference_rowspath_to_asset_idasset_id_to_ref_dataabsolute_path_listspecabsolute_pathr8   rY   r#   rZ   r>   rinserted_asset_idswinning_pathsr_   inserted_pathslosing_pathslost_asset_idswinning_ref_idsinserted_ref_idsr\   metadata_rowsref_dataref_idtags                                 r/   batch_insert_seed_assetsr   d   s   2 a1KK=L!#J)+N'),.$&Z(89tzz|$4::<(!!-0*2'HH[)	("<0&*	
 "XXj13E3V3V3XM']'g7M M"$* ,$[)"!.((8,**$0	
$ )LW"4	*
&Y f w+ 08A!J-8 "0WA1Z=DV3VaNW+GD<9'TM '&DD!%77 	&  
 "M1L9EF&t,NFWn5<(
 	
 "!D 	d34^D!   0IH')M!D'-H+5Hn-F--'.4$'"-$0	 ( "*.B!C!$$%7%D%DV%LM*%%$$.4)#$#+J#7#'$($(
1 "H gMR*+m$|$ W 9W Gs*   2L0
L5L5
L:L:,L?/Mc                .    [        U 5      n[        X5      $ )zHard-delete unhashed assets with no active references.

This is a destructive operation intended for explicit cleanup.
Only deletes assets where hash=None and all references are missing.

Returns:
    Number of assets deleted
)r   r   )ri   unreferenced_idss     r/   cleanup_unreferenced_assetsr     s     ;7C::r.   ) )ri   r	   rj   zlist[SeedAssetSpec]r:   r   returnrR   )ri   r	   r   r   )#
__future__r   r^   ra   dataclassesr   r   typingr   r   r   sqlalchemy.ormr	   app.assets.database.queriesr
   r   r   r   r   r   r   r   r   app.assets.helpersr   $app.assets.services.metadata_extractr   r   r1   r6   rB   rI   rR   r   r   r%   r.   r/   <module>r      s    " 	  !  0 0 "
 
 
 +FI y 9 "Y 	$) 	$    jjj j 	jZ
;r.   