o
    i("                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZ d dlmZmZmZmZmZmZmZmZmZ d dlmZ erNd d	lmZ G d
d de
ZG dd de
ZG dd de
ZG dd de
ZG dd de
ZeG dd dZ 	d#d$ddZ!d%d!d"Z"dS )&    )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                   @  sb   e Zd ZU dZded< ded< ded< ded< ded	< ded
< ded< ded< ded< ded< dS )SeedAssetSpecz*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_idN__name__
__module____qualname____doc____annotations__ r(   r(   =/mnt/c/Users/fbmor/ComfyUI/app/assets/services/bulk_ingest.pyr      s   
 r   c                   @  s:   e Zd ZU dZded< ded< ded< ded< d	ed
< dS )AssetRowz Row data for inserting an Asset.r   idr   r   r   r   r    r   
created_atNr"   r(   r(   r(   r)   r*   +   s   
 r*   c                   @  sr   e Zd ZU dZded< ded< ded< ded< ded< ded	< d
ed< ded< d
ed< ded< ded< ded< dS )ReferenceRowz)Row data for inserting an AssetReference.r   r+   asset_id	file_pathr   r   owner_idnamer   
preview_iddict[str, Any] | Noneuser_metadatar!   r   r,   
updated_atlast_access_timeNr"   r(   r(   r(   r)   r-   5   s   
 r-   c                   @  s2   e Zd ZU dZded< ded< ded< ded< dS )	TagRowzRow data for inserting a Tag.r   asset_reference_idtag_nameoriginr   added_atNr"   r(   r(   r(   r)   r7   F   s   
 r7   c                   @  sJ   e Zd ZU dZded< ded< ded< ded< d	ed
< ded< ded< dS )MetadataRowz&Row data for inserting asset metadata.r   r8   keyr   ordinalr   val_strzfloat | Noneval_numzbool | Noneval_boolr3   val_jsonNr"   r(   r(   r(   r)   r<   O   s   
 r<   c                   @  s*   e Zd ZU dZded< ded< ded< dS )BulkInsertResultzResult of bulk asset insertion.r   inserted_refs	won_paths
lost_pathsNr"   r(   r(   r(   r)   rC   [   s
   
 rC    sessionr   specslist[SeedAssetSpec]r0   r   returnc                   s  |s	t ddddS t }g }g }i i  g }|D ]s}tj|d }tt }	tt }
|| |	|< |	d}||	|	d|d ||d |	d}|rX|
 }n|d	 rcd
|d	 i}nd}||
|	||d ||d d||	d|||d |
|d |d	 |d |	< qt| | t| dd |D fdd|D }t| | t| | t| }fdd|D }|| }fdd|D }|rt| | |st ddt|dS  fdd|D }t| |}g }g }|r@|D ]K}| }	 |	 }|d }||vrq|d D ]}|||d|d q|	d}|r+||| q|d
 r?||d
d|d
 dddd qt| ||d t t|t|t|dS )a  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   )rD   rE   rF   r   r    r   r   )r+   r   r   r    r,   r   r   filenameNr   r   r!   )r+   r.   r/   r   r0   r1   r2   r4   r!   r,   r5   r6   r   )reference_idr   rL   extracted_metadatac                 S  s   g | ]}|d  qS r.   r(   .0rr(   r(   r)   
<listcomp>       z,batch_insert_seed_assets.<locals>.<listcomp>c                   s   g | ]
}|d   v r|qS rO   r(   rP   )inserted_asset_idsr(   r)   rS      s    c                   s   h | ]
}|  v r|qS r(   r(   rQ   path)rU   path_to_asset_idr(   r)   	<setcomp>   s
    z+batch_insert_seed_assets.<locals>.<setcomp>c                   s   g | ]} | qS r(   r(   rV   )rX   r(   r)   rS      rT   c                   s   g | ]
} |  d  qS )rM   r(   rV   )asset_id_to_ref_datarX   r(   r)   rS      s    rM   	automatic)r8   r9   r:   r;   rN   )r8   r=   r>   r?   r@   rA   rB   )tag_rows	meta_rows)rC   r   osrW   abspathr   uuiduuid4appendgetto_user_metadatar	   r   r
   r   r   r   lenr   extendto_meta_rowsr   )rH   rI   r0   current_time
asset_rowsreference_rowsabsolute_path_listspecabsolute_pathr.   rM   r    rN   r4   winning_pathsinserted_pathslosing_pathslost_asset_idswinning_ref_idsinserted_ref_idsr\   metadata_rowsrW   ref_dataref_idtagr(   )rZ   rU   rX   r)   batch_insert_seed_assetsd   s   













rx   r   c                 C  s   t | }t| |S )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   )rH   unreferenced_idsr(   r(   r)   cleanup_unreferenced_assets  s   	
rz   )rG   )rH   r   rI   rJ   r0   r   rK   rC   )rH   r   rK   r   )#
__future__r   r^   r`   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   r*   r-   r7   r<   rC   rx   rz   r(   r(   r(   r)   <module>   s,    ,
	 .