
    +jp                     v	   U d dl Z d dl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 d dlZd dlmZ d dlmZmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZmZ d dlmZm Z  d dlm!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- d dl.m/Z/ d dl0m1Z1  ej2                    Z3da4ej5        dz  e6d<   da7d Z8dZ9dej:        de;e<e	f         fdZ=	 dEdej>        dej5        dz  ddfdZ?dFdZ@	 dEdeAde<de<de;dz  dejB        f
dZCde<dedejB        fd ZDd!e<dz  de<fd"ZEd#eFe<         d$e;e<e	f         dz  de<dz  fd%ZGd&ejH        ejI        z  dejJ        fd'ZKe3L                    d(          e8dej:        dejB        fd)                        ZMe3N                    d*          e8dej:        dejB        fd+                        ZOe3N                    d,e9 d-          e8dej:        dejB        fd.                        ZPe3N                    d,e9 d/          e8dej:        dejB        fd0                        ZQe3R                    d1          e8dej:        dejB        fd2                        ZSe3R                    d*          e8dej:        dejB        fd3                        ZTe3U                    d,e9 d-          e8dej:        dejB        fd4                        ZVe3W                    d,e9 d-          e8dej:        dejB        fd5                        ZXe3N                    d6          e8dej:        dejB        fd7                        ZYe3R                    d,e9 d8          e8dej:        dejB        fd9                        ZZe3W                    d,e9 d8          e8dej:        dejB        fd:                        Z[e3N                    d;          e8dej:        dejB        fd<                        Z\e3R                    d=          e8dej:        dejB        fd>                        Z]e3N                    d?          e8dej:        dejB        fd@                        Z^e3R                    dA          e8dej:        dejB        fdB                        Z_e3R                    dC          e8dej:        dejB        fdD                        Z`dS )G    N)Any)web)ValidationError)user_manager)
schemas_inschemas_out)schemas)AssetValidationErrorUploadError)validate_blake3_hash)delete_temp_file_if_existsparse_multipart_upload)ScanInProgressErrorasset_seeder)DependencyMissingErrorHashMismatchError
apply_tagsasset_existscreate_from_hashdelete_asset_referenceget_asset_detaillist_assets_page	list_tagsremove_tagsresolve_asset_for_downloadupdate_asset_metadataupload_from_temp_path)InvalidCursorError)list_tag_histogramUSER_MANAGERFc                 x     t          j                   dt          j        dt          j        f fd            }|S )Nrequestreturnc                 Z   K   t           st          ddd          S  |            d {V S )N  SERVICE_DISABLEDzUAssets system is disabled. Start the server with --enable-assets to use this feature.)_ASSETS_ENABLED_build_error_response)r"   handlers    5/home/wildlama/comfy/ComfyUI/app/assets/api/routes.pywrapperz0_require_assets_feature_enabled.<locals>.wrapper3   sN       	("g  
 WW%%%%%%%%%    )	functoolswrapsr   RequestResponse)r)   r+   s   ` r*   _require_assets_feature_enabledr1   2   sO    _W&s{ &s| & & & & & & Nr,   zK[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}r"   r#   c                 R      fd j                                         D             }|S )zGets a dictionary of query parameters from the request.

    request.query is a MultiMapping[str], needs to be converted to a dict
    to be validated by Pydantic.
    c                     i | ]b}|t          j                            |                    d k    rj                            |          nj                            |          cS )   )lenquerygetallget).0keyr"   s     r*   
<dictcomp>z"get_query_dict.<locals>.<dictcomp>J   sy         	w}##C(())A-- ]!!#&&&]s##  r,   )r6   keys)r"   
query_dicts   ` r*   get_query_dictr>   D   sC        =%%''	  J r,   appuser_manager_instancec                 F    ||a da|                     t                     d S )NT)r    r'   
add_routesROUTES)r?   r@   s     r*   register_assets_routesrD   X   s,    
 (,NN6r,   c                  
    da dS )z=Disable asset routes at runtime (e.g. after DB init failure).FN)r'    r,   r*   disable_assets_routesrG   c   s     OOOr,   statuscodemessagedetailsc                 >    t          j        d|||pi di|           S )Nerror)rI   rJ   rK   rH   )r   json_response)rH   rI   rJ   rK   s       r*   r(   r(   i   s7     	4G2NNO   r,   vec                 v    t          j        |                                           }t          d| dd|i          S )N  zValidation failed.errors)jsonloadsr(   )rI   rP   rS   s      r*    _build_validation_error_responserV   r   s3    Z		""F d,@8VBTUUUr,   	requestedc                 B    | sdS |                                  }|dv r|S dS )N
created_at>   namesizerY   
updated_atlast_access_time)lower)rW   vs     r*   _validate_sort_fieldr`   w   s4     |ALLL<r,   tagsuser_metadatac                 B   |sdS |                     d          }|sdS d| v rd}n	d| v rd}ndS d}d|v r|                    dd          \  }}t          j                            |d          }d	| d
| }|r'|dt          j                            |d           z  }|S )zIBuild a /api/view preview URL from asset tags and user_metadata filename.Nfilenameinputoutput /r4   )safez/api/view?type=z
&filename=z&subfolder=)r8   rspliturllibparsequote)ra   rb   rd   	view_type	subfolderencoded_filenameurls          r*   _build_preview_url_from_viewrr      s     t  ,,H t$			T				tI
h&ooc155	8|))()<<
CI
C
C1A
C
CC FEV\//	/CCEEEJr,   resultc                    | j         j        r>t          | j         j                  }|r t          |j        |j         j                  }n"d}nt          | j        | j         j                  }| j        r| j        j        nd}t          j	        di d| j         j
        d| j         j        d|d|d| j        rt          | j        j                  ndd| j        r| j        j        ndd| j        d	|d
| j         j        d| j         j        pi d| j         j        d| j         j        d| j         j        d| j         j        d| j         j        d| j         j        S )z.Build an Asset response from a service result.NidrZ   hash
asset_hashr[   	mime_typera   preview_url
preview_idrb   metadatajob_id	prompt_idrY   r\   r]   rF   )refrz   r   rr   ra   rb   assetrv   r   Assetru   rZ   int
size_bytesrx   system_metadatar|   rY   r\   r]   )rs   preview_detailry   asset_content_hashs       r*   _build_asset_responser      s   z Z)&**?@@ 	6~7JNL^LlmmKKKK26;
@XYY.4lD**   :==Z__   &%	
 .4\CS()))t -3LB&,((d [[  K :(( j.4" ++ z   *## :(( :((   44! r,   z/api/assets/hash/{hash}c                 8  K   | j                             dd                                                                          }	 t	          |          }n!# t
          $ r t          ddd          cY S w xY wt          |          }t          j	        |rdnd          S )	Nrv   rg   rR   INVALID_HASHz hash must be like 'blake3:<hex>'     rN   )

match_infor8   stripr^   r   
ValueErrorr(   r   r   r0   )r"   hash_strexistss      r*   head_asset_by_hashr      s       !%%fb117799??AAH
'11 
 
 
$!C
 
 	
 	
 	

 (##F<f5ss#6666s   A A10A1z/api/assetsc                 R  K   t          |           }	 t          j                            |          }n'# t          $ r}t          d|          cY d}~S d}~ww xY wt          |j                  }|j        pd	                                }|dv r|nd}	 t          t                              |           |j        |j        |j        |j        |j        |j        |||j        
  
        }n5# t(          $ r(}t+          ddt-          |                    cY d}~S d}~ww xY wd |j        D             }	|j        
|j        du}
n |j        t3          |	          z   |j        k     }
t7          j        |	|j        |
|j        	          }t;          j        |                    d
d                    S )z%
    GET request to list assets.
    INVALID_QUERYNdesc>   ascr   )
owner_idinclude_tagsexclude_tagsname_containsmetadata_filterlimitoffsetsortorderafterrR   INVALID_CURSORc                 ,    g | ]}t          |          S rF   )r   )r9   items     r*   
<listcomp>z%list_assets_route.<locals>.<listcomp>   s!    FFF&t,,FFFr,   )assetstotalhas_morenext_cursorrT   Tmodeexclude_none) r>   r   ListAssetsQuerymodel_validater   rV   r`   r   r   r^   r   r    get_request_user_idr   r   r   r   r   r   r   r   r(   stritemsr   r5   r   r   
AssetsListr   rO   
model_dump)r"   r=   qrP   r   order_candidater   rs   e	summariesr   payloads               r*   list_assets_router      s       ((JE&55jAA E E E/DDDDDDDDE  ''Dw(&//11O./AAOOvED!!55g>>/-'8'
 
 
  D D D$S*:CFFCCCCCCCCD GFFFFI
 	w%T1Hs9~~-=$l&	  G W//V$/OOPPPs9   3 
AAAAAC' '
D1DDDz/api/assets/{id:}c                 `  K   t          t          j        | j        d                             }	 t	          |t
                              |                     }|st          ddd| dd|i          S t          |          }n# t          $ r+}t          ddt          |          d|i          cY d}~S d}~wt          $ rB t          j        d|t
                              |                      t          d	d
d          cY S w xY wt          j        |                    dd          d          S )z5
    GET request to get an asset's info as JSON.
    ru   reference_idr   r   ASSET_NOT_FOUNDAssetReference z
 not foundNz1get_asset failed for reference_id=%s, owner_id=%s  INTERNALUnexpected server error.rT   Tr   r   rN   )r   uuidUUIDr   r   r    r   r(   r   r   	Exceptionlogging	exceptionr   rO   r   )r"   r   rs   r   r   s        r*   get_asset_router      s      ty!3D!9::;;LR!%!55g>>
 
 
  	(!:,:::|$	   (// 
 
 
$"CFFT<,@
 
 	
 	
 	
 	
 	
 	
  R R R?,,W55	
 	
 	

 %S*6PQQQQQR W//V$/OOX[\\\\s+   AB 3B 
D B3-D3ADDz	}/contentc                   K   | j                             dd                                                                          }|dvrd}	 t	          t          t          j        | j        d                             t          
                    |                     }|j        |j        }|j        }n# t          $ r(}t          ddt          |                    cY d }~S d }~wt           $ r(}t          dd	t          |                    cY d }~S d }~wt"          $ r t          dd
d          cY S w xY wh d}||v rd}|pd                    dd                              dd          }t&          j                            |          }	| d|	 }
t,          j                                      }|dz  }t3          j        d||||           fd}t7          j         |            ||
t          |          dd          S )Ndisposition
attachment>   inliner   ru   r   r   r   i  BACKEND_UNSUPPORTEDFILE_NOT_FOUNDz"Underlying file not found on disk.>   text/css	text/htmltext/javascripttext/html-sandboxedapplication/xhtml+xmlzapplication/octet-streamrg   
z; filename*=UTF-8''i   zJdownload_asset_content: path=%s, size=%d bytes (%.2f MB), type=%s, name=%sc                    K   d} t          d          5 }	 |                    |           }|sn|W V  	 d d d            d S # 1 swxY w Y   d S )Ni   rb)openread)
chunk_sizefchunkabs_paths      r*   stream_file_chunksz2download_asset_content.<locals>.stream_file_chunksK  s      
(D!! 	Qz** 	 		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s    AAAnosniff)zContent-DispositionzContent-LengthzX-Content-Type-Options)bodycontent_typeheaders)r6   r8   r^   r   r   r   r   r   r   r    r   r   r   download_namer   r(   NotImplementedErrorFileNotFoundErrorreplacerk   rl   rm   ospathgetsizer   infor   r0   )r"   r   rs   r   rd   rP   nie_DANGEROUS_MIME_TYPES	safe_nameencodedcd	file_sizesize_mbr   r   s                 @r*   download_asset_contentr     s      -##M<@@FFHHNNPPK222"
+TYw'9$'?@@AA!55g>>
 
 
 ?*' F F F$S*;SWWEEEEEEEE K K K$S*?SJJJJJJJJ 
 
 
$!#G
 
 	
 	
 	


   ,,,1R((r22::4DDIl  ++G	5	5G	5	5B))I;'GLT       <!!!#%!)nn&/
 
   s7   
A(B3 3
D1=C D1 D1-D
D1D10D1z/api/assets/from-hashc           	        K   	 |                                   d {V }t          j                            |          }nC# t          $ r}t          d|          cY d }~S d }~wt          $ r t          ddd          cY S w xY w|j        }|1d|j	        v r!|j	        
                    dd          d         n|j	        }t          |j	        ||j        |j        t                              |           |j        |j                  }|t          dd	d
|j	         d          S t%          |          }t'          j        di |                                d|j        i}t/          j        |                    dd          d          S )NINVALID_BODYrR   INVALID_JSON Request body must be valid JSON.:r4   r   rZ   ra   rb   r   rx   rz   r   r   Asset content  does not existcreated_newrT   Tr      rN   rF   )rT   r   CreateFromHashBodyr   r   rV   r   r(   rZ   rv   splitr   ra   rb   r    r   rx   rz   r   r   AssetCreatedr   r   r   rO   )r"   r   r   rP   rZ   rs   r   payload_outs           r*   create_asset_from_hash_router   _  s     
&&&&&&,;;GDD D D D/CCCCCCCC 
 
 
$!C
 
 	
 	
 	

 9D|-0DI-=-=tysA&&q))49Y(11'::.?  F ~$"$OTY$O$O$O
 
 	
 "&))E*  




 &  K [33d3SS\_````s!   9> 
A>AA>A>=A>c                 .	  K   	 t          | t                     d{V }n7# t          $ r*}t          |j        |j        |j                  cY d}~S d}~ww xY wt                              |           }	 t          j
                            |j        |j        |j        |j        |j        |j        d          }nQ# t$          $ rD}t'          |j                   t          ddd|                                           cY d}~S d}~ww xY w|j        r|j        d         dk    rt/          |j                  d	k     s|j        d
         t0          j        vrPt'          |j                   t/          |j                  d	k    r|j        d
         nd}t          ddd| d          S 	 |j        r|j        du rt9          |j        |j        p |j                            dd
          d
         |j        |j        pi ||j         |j!                  }|.t'          |j                   t          ddd|j         d          S t'          |j                   n~|j        r$tD          j#        $                    |j                  st          ddd          S tK          |j        |j        |j        |j        pi |j&        ||j        |j         |j!        	  	        }nW# tN          $ rA}t'          |j                   t          d|j        tQ          |                    cY d}~S d}~wtR          $ r<}t'          |j                   t          ddtQ          |                    cY d}~S d}~wtT          $ r<}t'          |j                   t          ddtQ          |                    cY d}~S d}~wtV          $ r4}t'          |j                   t          dd|j                  cY d}~S d}~wtX          $ r= t'          |j                   t[          j.        d|           t          ddd          cY S w xY wt_          |          }ta          j1        d&i |2                                d |j3        i}	|j3        rd!nd"}
ti          j5        |	2                    d#d$          |
%          S )'z/Multipart/form-data endpoint for Asset uploads.)check_hash_existsN)ra   rZ   rb   rv   rx   rz   rR   r   zValidation failed: r   models   r4   rg   zunknown models category ''Tr   r   r   r   r   r   MISSING_INPUTz-Provided hash not found and no file uploaded.)		temp_pathrZ   ra   rb   client_filenamer   expected_hashrx   rz   BAD_REQUESTHASH_MISMATCHr%   DEPENDENCY_MISSINGz#upload_asset failed for owner_id=%sr   r   r   r   r   r   rT   r   rN   rF   )6r   r   r   r(   rH   rI   rJ   r    r   r   UploadAssetSpecr   tags_rawprovided_nameuser_metadata_rawprovided_hashprovided_mime_typeprovided_preview_idr   r   tmp_pathrT   ra   r5   folder_pathsfolder_names_and_pathsrv   provided_hash_existsr   rZ   r   rb   rx   rz   r   r   r   r   file_client_namer
   r   r   r   r   r   r   r   r   r   r   r   r   r   rO   )r"   parsedr   r   specrP   categoryrs   r   r   rH   s              r*   upload_assetr    s]     B-gVVVVVVVVV B B B$QXqvqyAAAAAAAAB //88H
)88,!'!9,#6$8 	
 	
  
 
 
"6?333$!Brwwyy!B!B
 
 	
 	
 	
 	
 	
 	

 y 	TYq\X--	NNQy|<#FFF&v777'*49~~':':ty||H(^%L%L%L%L  5R9 #	4<<%Y>49??3#:#:1#=Y"06B!.?  F ~*6?;;;,*,WTY,W,W,W   'v7777 ? "'..*I*I ,#C   + /YY"06B & 7!"i.?
 
 
F   : : :"6?333$S!&#a&&99999999 A A A"6?333$S-Q@@@@@@@@ C C C"6?333$S/3q66BBBBBBBB! K K K"6?333$S*>	JJJJJJJJ R R R"6?333?JJJ$S*6PQQQQQR
 "&))E*  




 &  K &/SSCF[33d3SS\bccccs   ! 
AA
AA3AB8 8
D9D;DD#BK :AK AK 
P#6LP#P#"1MP#P#&1NP#P#*)OP#AP#"P#c                   K   t          t          j        | j        d                             }	 t          j                            |                                  d {V           }nC# t          $ r}t          d|          cY d }~S d }~wt          $ r t          ddd          cY S w xY w	 t          ||j        |j        t                              |           |j                  }t%          |          }n# t&          $ r+}t          ddt          |          d|i          cY d }~S d }~wt(          $ r+}t          d	d
t          |          d|i          cY d }~S d }~wt          $ rB t+          j        d|t                              |                      t          ddd          cY S w xY wt/          j        |                    dd          d          S )Nru   r   rR   r   r   )r   rZ   rb   r   rz     	FORBIDDENr   r   z4update_asset failed for reference_id=%s, owner_id=%sr   r   r   rT   Tr   r   rN   )r   r   r   r   r   UpdateAssetBodyr   rT   r   rV   r   r(   r   rZ   rb   r    r   rz   r   PermissionErrorr   r   r   r   rO   r   )r"   r   r   rP   rs   r   pes          r*   update_asset_router!    sU      ty!3D!9::;;L
)88w||~~9M9M9M9M9M9MNN D D D/CCCCCCCC 
 
 
$!C
 
 	
 	
 	


R&%,!55g>>
 
 
 (// V V V$S+s2ww|@TUUUUUUUU 
 
 
$"CGGdL-A
 
 	
 	
 	
 	
 	
 	
  R R RB,,W55	
 	
 	

 %S*6PQQQQQR W//V$/OOX[\\\\s[   7A( (
B(2BB(B('B(,A
C7 7
F) D'!F)'F)4 EF)AF)(F)c                   K   t          t          j        | j        d                             }	 t	          |t
                              |           d          }nO# t          $ rB t          j	        d|t
                              |                      t          ddd          cY S w xY w|st          dd	d
| d          S t          j        d          S )Nru   F)r   r   delete_content_if_orphanz>delete_asset_reference failed for reference_id=%s, owner_id=%sr   r   r   r   r   r   z not found.   rN   )r   r   r   r   r   r    r   r   r   r   r(   r   r0   )r"   r   deleteds      r*   delete_asset_router&    s	      ty!3D!9::;;LR )%!55g>>%*
 
 

  R R RL,,W55	
 	
 	

 %S*6PQQQQQR  
$"$Ol$O$O$O
 
 	
 <s####s   *A A	B'&B'z	/api/tagsc                 t  K   t          | j        j                  }	 t          j                            |          }nO# t          $ rB}t          ddddt          j	        |                                          i          cY d}~S d}~ww xY wt          |j        |j        |j        |j        |j        t                               |                     \  }}d |D             }t%          j        |||j        t)          |          z   |k               }t+          j        |                    d	d
                    S )zA
    GET request to list all tags based on query parameters.
    rR   r   zInvalid query parametersrS   N)prefixr   r   r   include_zeror   c                 @    g | ]\  }}t          j        ||           S ))rZ   count)r   TagUsage)r9   rZ   r+  s      r*   r   zget_tags.<locals>.<listcomp>K  s<       T5 	$e444  r,   )ra   r   r   rT   Tr   )dictrel_urlr6   r   TagsListQueryr   r   r(   rT   rU   r   r(  r   r   r   r)  r    r   r   TagsListr5   r   rO   r   )r"   	query_mapr6   r   rowsr   ra   r   s           r*   get_tagsr3  0  s_      W_*++I
(77	BB 
 
 
$&tz!&&((++,	
 
 	
 	
 	
 	
 	
 	

 |k|k'11'::  KD% !  D "%,T*Be)K  G W//V$/OOPPPs   = 
B	7B>B	B	z}/tagsc           	        K   t          t          j        | j        d                             }	 |                                  d {V }t
          j                            |          }nY# t          $ r0}t          dddd|
                                i          cY d }~S d }~wt          $ r t          ddd          cY S w xY w	 t          ||j        dt                              |           	          }t!          j        |j        |j        |j        
          }n# t(          $ r+}t          ddt          |          d|i          cY d }~S d }~wt*          $ r+}t          ddt          |          d|i          cY d }~S d }~wt          $ rB t-          j        d|t                              |                      t          ddd          cY S w xY wt1          j        |                    dd          d          S )Nru   rR   r   zInvalid JSON body for tags add.rS   r   r   manual)r   ra   originr   )addedalready_present
total_tagsr  r  r   r   z9add_tags_to_asset failed for reference_id=%s, owner_id=%sr   r   r   rT   Tr   r   rN   )r   r   r   r   rT   r   TagsAddr   r   r(   rS   r   r   ra   r    r   r   r7  r8  r9  r  r   r   r   r   rO   r   r"   r   json_payloaddatarP   rs   r   r   s           r*   add_asset_tagsr>  U  s      ty!3D!9::;;L
$\\^^++++++!00>> 
 
 
$-ryy{{#	
 
 	
 	
 	
 	
 	
 	
  
 
 
$!C
 
 	
 	
 	


R%!55g>>	
 
 
 %,"2(
 
 

  V V V$S+s2ww|@TUUUUUUUU 
 
 
$"CGGdL-A
 
 	
 	
 	
 	
 	
 	
  R R RG,,W55	
 	
 	

 %S*6PQQQQQR W//V$/OOX[\\\\s[   9A* *
C 4%BC C ?C AD 
G% EGG E>8G>AGGc           	        K   t          t          j        | j        d                             }	 |                                  d {V }t
          j                            |          }nY# t          $ r0}t          dddd|
                                i          cY d }~S d }~wt          $ r t          ddd          cY S w xY w	 t          ||j        t                              |                     }t!          j        |j        |j        |j        	          }n# t(          $ r+}t          d
dt          |          d|i          cY d }~S d }~wt*          $ r+}t          ddt          |          d|i          cY d }~S d }~wt          $ rB t-          j        d|t                              |                      t          ddd          cY S w xY wt1          j        |                    dd          d          S )Nru   rR   r   z"Invalid JSON body for tags remove.rS   r   r   )r   ra   r   )removednot_presentr9  r  r  r   r   z>remove_tags_from_asset failed for reference_id=%s, owner_id=%sr   r   r   rT   Tr   r   rN   )r   r   r   r   rT   r   
TagsRemover   r   r(   rS   r   r   ra   r    r   r   r@  rA  r9  r  r   r   r   r   rO   r   r;  s           r*   delete_asset_tagsrC    s      ty!3D!9::;;L
$\\^^++++++$33LAA 
 
 
$0ryy{{#	
 
 	
 	
 	
 	
 	
 	
  
 
 
$!C
 
 	
 	
 	


R%!55g>>
 
 

 (N*(
 
 

  V V V$S+s2ww|@TUUUUUUUU 
 
 
$"CGGdL-A
 
 	
 	
 	
 	
 	
 	
  R R RL,,W55	
 	
 	

 %S*6PQQQQQR W//V$/OOX[\\\\s[   9A* *
C 4%BC C ?C AD 
G$ E
G
G E=7G=AGGz/api/assets/tags/refinec                   K   t          |           }	 t          j                            |          }n'# t          $ r}t          d|          cY d}~S d}~ww xY wt          t                              |           |j	        |j
        |j        |j        |j                  }t          j        |          }t!          j        |                    dd          d	          S )
z5GET request to get tag histogram for filtered assets.r   N)r   r   r   r   r   r   )
tag_countsrT   Tr   r   rN   )r>   r   TagsRefineQueryr   r   rV   r   r    r   r   r   r   r   r   r   TagHistogramr   rO   r   )r"   r=   r   rP   rE  r   s         r*   get_tags_refinerH    s        ((JE&55jAA E E E/DDDDDDDDE $11'::^^o)g  J &*===GW//V$/OOX[\\\\s   3 
AAAAz/api/assets/seedc                 0  K   	 |                                   d{V }|                    dg d          }n# t          $ r g d}Y nw xY wt          d |D                       }|st	          ddd          S | j                            dd	                                          }|d
v }t          j        |          }|st          j
        ddid          S |rt          j        t          j                   d{V  t          j                    }t          j
        d|j        r|j        j        nd|j        r|j        j        nd|j        r|j        j        nd|j        r|j        j        ndd|j        dd          S t          j
        ddid          S )a<  Trigger asset seeding for specified roots (models, input, output).

    Query params:
        wait: If "true", block until scan completes (synchronous behavior for tests)

    Returns:
        202 Accepted if scan started
        409 Conflict if scan already running
        200 OK with final stats if wait=true
    Nrootsr  re   rf   c              3   "   K   | ]
}|d v |V  dS )rK  NrF   )r9   rs     r*   	<genexpr>zseed_assets.<locals>.<genexpr>  s-      OOaA1N,N,N,N,N,N,NOOr,   rR   r   zNo valid roots specifiedwaitrg   )true1yes)rJ  rH   already_running  rN   	completedr   scannedr   createdskipped)rH   progressrS   r   started   )rT   r8   r   tupler(   r6   r^   r   startr   rO   asyncio	to_threadrO  
get_statusrZ  rW  r   rX  rY  rS   )r"   r   rJ  valid_roots
wait_paramshould_waitr[  rH   s           r*   seed_assetsre    s     .&&&&&&G%B%B%BCC . . .---. OO5OOOOOK V$S.:TUUU""62..4466J 44K {333G L (,=!>sKKKK 
 1222222222(** %:@/Pv66q6<oLV_221:@/Pv66q:@/Pv66q	  !-	 	 
 
 
 	
 h	23????s   27 AAz/api/assets/seed/statusc                    K   t          j                    }t          j        |j        j        |j        r/|j        j        |j        j        |j        j	        |j        j
        dnd|j        dd          S )z%Get current scan status and progress.rV  N)staterZ  rS   r   rN   )r   ra  r   rO   rg  valuerZ  rW  r   rX  rY  rS   )r"   rH   s     r*   get_seed_statusri    s       $&&F\' !?2.!?2!?2	   m	
 	
    r,   z/api/assets/seed/cancelc                    K   t          j                    }|rt          j        ddid          S t          j        ddid          S )z)Request cancellation of in-progress scan.rH   
cancellingr   rN   idle)r   cancelr   rO   )r"   	cancelleds     r*   cancel_seedro    sU       #%%I G (L!9#FFFFh/<<<<r,   z/api/assets/prunec                    K   	 t          j                    }n)# t          $ r t          j        dddd          cY S w xY wt          j        d|dd          S )as  Mark assets as missing when outside all known root prefixes.

    This is a non-destructive soft-delete operation. Assets and metadata
    are preserved, but references are flagged as missing. They can be
    restored if the file reappears in a future scan.

    Returns:
        200 OK with count of marked assets
        409 Conflict if a scan is currently running
    scan_runningr   )rH   markedrT  rN   rU  r   )r   mark_missing_outside_prefixesr   r   rO   )r"   rr  s     r*   mark_missing_assetsrt    s      
;== 
 
 
 %33
 
 
 	
 	
 	


 vFFsSSSSs    #>>)N)r#   N)ar_  r-   rT   r   r   urllib.parserk   r   typingr   aiohttpr   pydanticr   r  r?   r   app.assets.apir   r   app.assets.servicesr	   app.assets.api.schemas_inr
   r   app.assets.helpersr   app.assets.api.uploadr   r   app.assets.seederr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   app.assets.services.cursorr   app.assets.services.taggingr   RouteTableDefrC   r    UserManager__annotations__r'   r1   UUID_REr/   r-  r   r>   ApplicationrD   rG   r   r0   r(   rV   r`   listrr   AssetDetailResultUploadResultr   r   headr   r8   r   r   r   postr   r  putr!  deleter&  r3  r>  rC  rH  re  ri  ro  rt  rF   r,   r*   <module>r     s2	          				                  $ $ $ $ $ $           2 2 2 2 2 2 2 2 ' ' ' ' ' '        4 3 3 3 3 3        @ ? ? ? ? ? ? ?                              : 9 9 9 9 9 : : : : : :				04l&- 4 4 4   YCK DcN    , >B 	'3d: 
       BF %(37$;\   V3 VO V V V V V
C$J 3    tCy c3hRVAV [^ae[e    4'";g>R"R WbWh    > &'' 	7ck 	7cl 	7 	7 	7 !  ('	7 M .QS[ .QS\ .Q .Q .Q !  .Qb ++++,, ]3; ]3< ] ] ] !  -,]B 333344 =#+ =#, = = = !  54=@ $%% #a #a #a #a #a !  &%#aL ] bd bd bd bd bd !  bdJ ++++,, !]ck !]cl !] !] !] !  -,!]H .7...// $ck $cl $ $ $ !  0/$4 K  QCK  QCL  Q  Q  Q !   QF 111122 +]#+ +]#, +] +] +] !  32+]\ 3733344 *]S[ *]S\ *] *] *] !  54*]Z %&& ]3; ]3< ] ] ] !  '&](    -@s{ -@s| -@ -@ -@ !  ! -@` %&& 3; 3<    !  '&( &'' =s{ =s| = = = !  ('=  !! Ts{ Ts| T T T !  "!T T Tr,   