a
    AdRq                     @   sj  U 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Z	d dl
mZmZmZmZmZmZmZmZ e ZG dd dZG dd dZeG d	d
 d
ZG dd dZG dd deZejadd Zedg dZg Zg Zedg dZ ddddZ!dd Z"dd Z#ddddZ$G d d! d!Z%da&e%e'd"< da(e%e'd#< da)ej*e'd$< dZ+e%e'd%< d&d' Z,e#Z-dS )(    N)
namedtuple)	dataclass)sharedpathsscript_callbacks
extensionsscript_loadingscripts_postprocessingerrorstimerc                   @   s   e Zd Zdd ZdS )PostprocessImageArgsc                 C   s
   || _ d S N)image)selfr    r   7/var/www/html/stable-diffusion-webui/modules/scripts.py__init__   s    zPostprocessImageArgs.__init__N__name__
__module____qualname__r   r   r   r   r   r      s   r   c                   @   s   e Zd Zdd ZdS )PostprocessBatchListArgsc                 C   s
   || _ d S r   )images)r   r   r   r   r   r      s    z!PostprocessBatchListArgs.__init__Nr   r   r   r   r   r      s   r   c                   @   s   e Zd ZU ejjed< dS )OnComponent	componentN)r   r   r   grblocksBlock__annotations__r   r   r   r   r      s   
r   c                   @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdZdZdZdd Zdd Zdd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZedddZ e!dddZ"dd  Z#d!d" Z$d#d$ Z%d%d& Z&d'd( Z'd)d* Z(d+d, Z)d-d. Z*dS )/ScriptNFTc                 C   s
   t  dS )zithis function should return the title of the script. This is what will be displayed in the dropdown menu.N)NotImplementedErrorr   r   r   r   titleJ   s    zScript.titlec                 C   s   dS )a  this function should create gradio UI elements. See https://gradio.app/docs/#components
        The return value should be an array of all components that are used in processing.
        Values of those returned components will be passed to run() and process() functions.
        Nr   r   
is_img2imgr   r   r   uiO   s    z	Script.uic                 C   s   dS )a  
        is_img2img is True if this function is called for the img2img interface, and Fasle otherwise

        This function should return:
         - False if the script should not be shown in UI at all
         - True if the script should be shown in UI if it's selected in the scripts dropdown
         - script.AlwaysVisible if the script should be shown in UI at all times
         Tr   r#   r   r   r   showW   s    
zScript.showc                 G   s   dS )a  
        This function is called if the script has been selected in the script dropdown.
        It must do all processing and return the Processed object with results, same as
        one returned by processing.process_images.

        Usually the processing is done by calling the processing.process_images function.

        args contains all values returned by components from ui()
        Nr   r   pargsr   r   r   runc   s    z
Script.runc                 G   s   dS )zFor AlwaysVisible scripts, this function is called when the processing object is set up, before any processing starts.
        args contains all values returned by components from ui().
        Nr   r'   r   r   r   setupp   s    zScript.setupc                 G   s   dS )z
        This function is called very early during processing begins for AlwaysVisible scripts.
        You can modify the processing object (p) here, inject hooks, etc.
        args contains all values returned by components from ui()
        Nr   r'   r   r   r   before_processw   s    zScript.before_processc                 G   s   dS )z
        This function is called before processing begins for AlwaysVisible scripts.
        You can modify the processing object (p) here, inject hooks, etc.
        args contains all values returned by components from ui()
        Nr   r'   r   r   r   process   s    zScript.processc                 O   s   dS )a   
        Called before extra networks are parsed from the prompt, so you can add
        new extra network keywords to the prompt with this callback.

        **kwargs will have those items:
          - batch_number - index of current batch, from 0 to number of batches-1
          - prompts - list of prompts for current batch; you can change contents of this list but changing the number of entries will likely break things
          - seeds - list of seeds for current batch
          - subseeds - list of subseeds for current batch
        Nr   r   r(   r)   kwargsr   r   r   before_process_batch   s    zScript.before_process_batchc                 O   s   dS )a  
        Called after extra networks activation, before conds calculation
        allow modification of the network after extra networks activation been applied
        won't be call if p.disable_extra_networks

        **kwargs will have those items:
          - batch_number - index of current batch, from 0 to number of batches-1
          - prompts - list of prompts for current batch; you can change contents of this list but changing the number of entries will likely break things
          - seeds - list of seeds for current batch
          - subseeds - list of subseeds for current batch
          - extra_network_data - list of ExtraNetworkParams for current stage
        Nr   r.   r   r   r   after_extra_networks_activate   s    z$Script.after_extra_networks_activatec                 O   s   dS )a  
        Same as process(), but called for every batch.

        **kwargs will have those items:
          - batch_number - index of current batch, from 0 to number of batches-1
          - prompts - list of prompts for current batch; you can change contents of this list but changing the number of entries will likely break things
          - seeds - list of seeds for current batch
          - subseeds - list of subseeds for current batch
        Nr   r.   r   r   r   process_batch   s    zScript.process_batchc                 O   s   dS )aT  
        Same as process_batch(), but called for every batch after it has been generated.

        **kwargs will have same items as process_batch, and also:
          - batch_number - index of current batch, from 0 to number of batches-1
          - images - torch tensor with all generated images, with values ranging from 0 to 1;
        Nr   r.   r   r   r   postprocess_batch   s    	zScript.postprocess_batchppc                 O   s   dS )a
  
        Same as postprocess_batch(), but receives batch images as a list of 3D tensors instead of a 4D tensor.
        This is useful when you want to update the entire batch instead of individual images.

        You can modify the postprocessing object (pp) to update the images in the batch, remove images, add images, etc.
        If the number of images is different from the batch size when returning,
        then the script has the responsibility to also update the following attributes in the processing object (p):
          - p.prompts
          - p.negative_prompts
          - p.seeds
          - p.subseeds

        **kwargs will have same items as process_batch, and also:
          - batch_number - index of current batch, from 0 to number of batches-1
        Nr   )r   r(   r5   r)   r/   r   r   r   postprocess_batch_list   s    zScript.postprocess_batch_listc                 G   s   dS )zE
        Called for every image after it has been generated.
        Nr   )r   r(   r5   r)   r   r   r   postprocess_image   s    zScript.postprocess_imagec                 G   s   dS )z
        This function is called after processing ends for AlwaysVisible scripts.
        args contains all values returned by components from ui()
        Nr   )r   r(   	processedr)   r   r   r   postprocess   s    zScript.postprocessc                 K   s   dS )ai  
        Called before a component is created.
        Use elem_id/label fields of kwargs to figure out which component it is.
        This can be useful to inject your own components somewhere in the middle of vanilla UI.
        You can return created components in the ui() function to add them to the list of arguments for your processing functions
        Nr   r   r   r/   r   r   r   before_component   s    zScript.before_componentc                 K   s   dS )zE
        Called after a component is created. Same as above.
        Nr   r:   r   r   r   after_component   s    zScript.after_componentc                C   s$   | j du rg | _ | j ||f dS )a  
        Calls callback before a component is created. The callback function is called with a single argument of type OnComponent.

        May be called in show() or ui() - but it may be too late in latter as some components may already be created.

        This function is an alternative to before_component in that it also cllows to run before a component is created, but
        it doesn't require to be called for every created component - just for the one you need.
        N)on_before_component_elem_idappendr   callbackelem_idr   r   r   on_before_component   s    	
zScript.on_before_componentc                C   s$   | j du rg | _ | j ||f dS )z
        Calls callback after a component is created. The callback function is called with a single argument of type OnComponent.
        N)on_after_component_elem_idr>   r?   r   r   r   on_after_component   s    
zScript.on_after_componentc                 C   s   dS )unused r   r!   r   r   r   describe  s    zScript.describec              
   C   sh   |  d|  dk}| jrdnd}|r0| dnd}tddtdd|   }d	| | d| S )
zxhelper function to generate id for a HTML element, constructs final id out of script name, tab and user-supplied item_idTFimg2imgtxt2img_rF   z
[^a-z_0-9]z\sZscript_)r&   r$   resubr"   lower)r   item_idneed_tabnameZtabkindtabnamer"   r   r   r   rA     s
     zScript.elem_idc                 G   s   dS )zA
        This function is called before hires fix start.
        Nr   r'   r   r   r   	before_hr  s    zScript.before_hr)+r   r   r   namesectionfilename	args_fromargs_toalwayson
is_txt2imgr$   rP   groupcreate_groupinfotext_fieldspaste_field_namesapi_infor=   rC   setup_for_ui_onlyr"   r%   r&   r*   r+   r,   r-   r0   r1   r2   r3   r   r6   r   r7   r9   r;   r<   rB   rD   rG   rA   rQ   r   r   r   r   r      sL   		
	
r   c                   @   s   e Zd ZdZdd ZdS )ScriptBuiltinUITc                 C   s:   |  d|  dk}|r*| jr"dndd nd}| | S )zkhelper function to generate id for a HTML element, constructs final id out of tab and user-supplied item_idTFrH   rI   rJ   rF   )r&   r$   )r   rN   rO   rP   r   r   r   rA      s    zScriptBuiltinUI.elem_idN)r   r   r   r^   rA   r   r   r   r   r_     s   r_   c                   C   s   t S )a+  returns the base directory for the current script. For scripts in the main scripts directory,
    this is the main directory (where webui.py resides), and for scripts in extensions directory
    (ie extensions/aesthetic/script/aesthetic.py), this is extension's directory (extensions/aesthetic)
    )current_basedirr   r   r   r   basedir,  s    ra   
ScriptFile)ra   rT   pathScriptClassData)script_classrc   ra   moduleTinclude_extensionsc             
      s   g }t jtj| }t j|rRtt |D ]"}|t	tj|t j|| q.|rtt
 D ]}|||  7 }q^ fdd|D }|S )Nc                    s8   g | ]0}t j|jd    krt j|jr|qS )   )osrc   splitextrM   isfile).0x	extensionr   r   
<listcomp>G      z list_scripts.<locals>.<listcomp>)rj   rc   joinr   script_pathexistssortedlistdirr>   rb   r   active
list_files)Zscriptdirnamerp   rh   scripts_listra   rT   extr   ro   r   list_scripts;  s     r|   c                 C   s^   g }t jgdd t D  }|D ]6}tj|s4q"tj|| }tj|r"|	| q"|S )Nc                 S   s   g | ]
}|j qS r   )rc   )rm   r{   r   r   r   rq   O  rr   z(list_files_with_name.<locals>.<listcomp>)
r   rt   r   rx   rj   rc   isdirrs   rl   r>   )rT   resdirsdirpathrc   r   r   r   list_files_with_nameL  s    r   c               
      s  t   t  t  tddtdddd } tj}fdd}dd	  t|  fd
ddD ]zz:j	t
jkrj	gtj t_j	atj}|| W n( ty   tjdj dd Y n0 W |t_t
jatjj q^|t_t
jatjj 0 q^t at at ad S )Nscriptsz.pyzmodules/processing_scriptsFrg   c                    sh   | j  D ]X}t|sq
t|tr>tt| j	 j
|  q
t|tjr
tt| j	 j
|  q
d S r   )__dict__valuesinspectisclass
issubclassr   scripts_datar>   rd   rc   ra   r	   ZScriptPostprocessingpostprocessing_scripts_data)rf   re   )
scriptfiler   r   register_scripts_from_modulef  s    

z2load_scripts.<locals>.register_scripts_from_modulec                 S   s>   t jtjddtjdi}|D ]}| |r||   S qdS )Nzextensions-builtinri   r   i'  )rj   rc   rs   r   rt   
startswith)ra   prioritykeyr   r   r   orderbyp  s
    
zload_scripts.<locals>.orderbyc                    s    | j | gS r   )ra   rn   )r   r   r   <lambda>x  rr   zload_scripts.<locals>.<lambda>)r   zError loading script: Texc_info)r   clearr   r   Zclear_callbacksr|   sysrc   rv   ra   r   rt   r`   r   load_module	Exceptionr
   reportrT   r   startup_timerrecordScriptRunnerscripts_txt2imgscripts_img2imgr	   ScriptPostprocessingRunnerscripts_postproc)rz   Zsyspathr   script_moduler   )r   r   r   load_scripts\  s2    
r   defaultc                O   sB   z| |i |W S  t y<   tjd| d| dd Y n0 |S )NzError calling: /Tr   )r   r
   r   )funcrT   funcnamer   r)   r/   r   r   r   	wrap_call  s
     r   c                   @   s   e Zd Zdd Zdd Zdd Zdd Zd3d
dZdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zed d!d"Zed d#d$Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0d1d2Zd	S )4r   c                 C   sB   g | _ g | _g | _g | _i | _g | _g | _d g| _i | _i | _	d S r   )
r   selectable_scriptsalwayson_scriptstitles	title_mapr[   r\   inputsr=   rC   r!   r   r   r   r     s    zScriptRunner.__init__c                 C   s   ddl m} | j  | j  | j  | }|t D ]}| }|j	|_
| |_||_|rddnd|_||j}|tkr| j| | j| d|_q:|r:| j| | j| q:|   d S )Nr   )scripts_auto_postprocessingrH   rI   T)modulesr   r   r   r   r   Z%create_auto_preprocessing_script_datar   re   rc   rT   rX   r$   rP   r&   AlwaysVisibler>   rW   #apply_on_before_component_callbacks)r   r$   r   Zauto_processing_scriptsZscript_datascript
visibilityr   r   r   initialize_scripts  s(    


zScriptRunner.initialize_scriptsc                 C   s   | j D ]}|jpg }|jpg }|D ]0\}}|| jvr>g | j|< | j| ||f q"|D ]0\}}|| jvrtg | j|< | j| ||f qX|  |  qd S r   )r   r=   rC   r>   r   )r   r   Z	on_beforeZon_afterrA   r@   r   r   r   r     s    






z0ScriptRunner.apply_on_before_component_callbacksc           	      C   s8  dd l m  m} t| j|_t| j|_t|j|j	d|j
}|d u rJd S t|j|j	d|j	d |_g }|D ]Z}tj|j	|_|j|jpdd}dD ]$}t||d }|d urt||| q|| qn|j|j|j
|j|d|_|jd ur|  j|j7  _|jd ur|  j|j7  _|  j|7  _t| j|_d S )	Nr   r%   r"   r   rF   )label)valueminimummaximumstepchoices)rR   r$   Zis_alwaysonr)   )Zmodules.api.modelsapimodelslenr   rU   rV   r   r%   rT   r$   r"   rM   rR   rj   rc   basenameZcustom_script_sourceZ	ScriptArgr   getattrsetattrr>   Z
ScriptInforW   r]   r[   r\   )	r   r   Z
api_modelscontrolsZapi_argscontrolZarg_infofieldvr   r   r   create_script_ui  s8    
zScriptRunner.create_script_uiNc              	   C   s~   |d u r| j }|D ]f}|jr(|j|kr(q|jrntj|jd}| | W d    n1 s\0    Y  ||_q| | qd S )Nvisible)r   rW   rS   rZ   r   Groupr   rY   )r   rS   Z
scriptlistr   rY   r   r   r   setup_ui_for_section  s    (z!ScriptRunner.setup_ui_for_sectionc                 C   s   d g| _ d S r   )r   r!   r   r   r   
prepare_ui  s    zScriptRunner.prepare_uic                    s  dd j D }dd t|j D _dd jD _d  tjdddgj dd	d
}|jd< d j fdd}fdd}||_	|j
||gdd jD d d_fdd j|dd f j fddjD    jS )Nc                 S   s"   g | ]}t |j|jd p|jqS )r"   r   r"   rT   rm   r   r   r   r   rq     rr   z)ScriptRunner.setup_ui.<locals>.<listcomp>c                 S   s   i | ]\}}|  |qS r   )rM   )rm   r"   r   r   r   r   
<dictcomp>  rr   z)ScriptRunner.setup_ui.<locals>.<dictcomp>c                 S   s(   g | ] }t |j|jd p"|j dqS )r"   z [error]r   r   r   r   r   rq     rr   r   Zscript_listNoneindex)r   rA   r   r   typer   c                    s.   | dkrj | d  nd   fddj D S )Nr   ri   c                    s   g | ]}t j |kd qS )r   )r   update)rm   sZselected_scriptr   r   rq   '  rr   z@ScriptRunner.setup_ui.<locals>.select_script.<locals>.<listcomp>)r   )script_indexr!   r   r   select_script$  s    z,ScriptRunner.setup_ui.<locals>.select_scriptc                    s*   | dkrdS  j | }d j| j_dS )zVcalled when an initial value is set from ui-config.json to show script's UI componentsr   NT)r   r   r   rY   r   )r"   r   r!   r   r   
init_field)  s    z)ScriptRunner.setup_ui.<locals>.init_fieldc                 S   s   g | ]
}|j qS r   rY   r   r   r   r   rq   7  rr   )fnr   outputsc                    sX   |  dd }|rH j|}| jk} jd t j  _tj|dS tjddS d S )Nr   ri   r   F)getr   r   script_load_ctrr   r   r   )paramsr"   Ztitle_indexr   r!   r   r   onload_script_visibility<  s    
z7ScriptRunner.setup_ui.<locals>.onload_script_visibilityc                 S   s   t j| dddS )Nr   r   )r   )r   r   r   r   r   r   r   r   F  rr   z'ScriptRunner.setup_ui.<locals>.<lambda>c                    s   g | ]}|j  fqS r   r   r   )r   r   r   rq   G  rr   )r   zipr   r   r   r   r   Dropdownr   r   changer   r[   r>   extendr   )r   Z
all_titlesdropdownr   r   r   )r   r   r   setup_ui  s*    

	
zScriptRunner.setup_uic                 G   s^   |d }|dkrd S | j |d  }|d u r.d S ||j|j }|j|g|R  }tj  |S )Nr   ri   )r   rU   rV   r*   r   
total_tqdmr   )r   r(   r)   r   r   script_argsr8   r   r   r   r*   M  s    
zScriptRunner.runc              	   C   sb   | j D ]V}z(|j|j|j }|j|g|R   W q tyZ   tjd|j dd Y q0 qd S )NzError running before_process: Tr   )	r   r   rU   rV   r,   r   r
   r   rT   r   r(   r   r   r   r   r   r,   _  s    
zScriptRunner.before_processc              	   C   sb   | j D ]V}z(|j|j|j }|j|g|R   W q tyZ   tjd|j dd Y q0 qd S )NzError running process: Tr   )	r   r   rU   rV   r-   r   r
   r   rT   r   r   r   r   r-   g  s    
zScriptRunner.processc              	   K   sh   | j D ]\}z.|j|j|j }|j|g|R i | W q ty`   tjd|j dd Y q0 qd S )Nz$Error running before_process_batch: Tr   )	r   r   rU   rV   r0   r   r
   r   rT   r   r(   r/   r   r   r   r   r   r0   o  s    
z!ScriptRunner.before_process_batchc              	   K   sh   | j D ]\}z.|j|j|j }|j|g|R i | W q ty`   tjd|j dd Y q0 qd S )Nz-Error running after_extra_networks_activate: Tr   )	r   r   rU   rV   r1   r   r
   r   rT   r   r   r   r   r1   w  s    
z*ScriptRunner.after_extra_networks_activatec              	   K   sh   | j D ]\}z.|j|j|j }|j|g|R i | W q ty`   tjd|j dd Y q0 qd S )NzError running process_batch: Tr   )	r   r   rU   rV   r2   r   r
   r   rT   r   r   r   r   r2     s    
zScriptRunner.process_batchc              	   C   sd   | j D ]X}z*|j|j|j }|j||g|R   W q ty\   tjd|j dd Y q0 qd S )NzError running postprocess: Tr   )	r   r   rU   rV   r9   r   r
   r   rT   )r   r(   r8   r   r   r   r   r   r9     s    
zScriptRunner.postprocessc              	   K   sl   | j D ]`}z2|j|j|j }|j|g|R d|i| W q tyd   tjd|j dd Y q0 qd S )Nr   z!Error running postprocess_batch: Tr   )	r   r   rU   rV   r3   r   r
   r   rT   )r   r(   r   r/   r   r   r   r   r   r3     s    
 zScriptRunner.postprocess_batchr4   c              	   K   sj   | j D ]^}z0|j|j|j }|j||g|R i | W q tyb   tjd|j dd Y q0 qd S )Nz&Error running postprocess_batch_list: Tr   )	r   r   rU   rV   r6   r   r
   r   rT   )r   r(   r5   r/   r   r   r   r   r   r6     s    
z#ScriptRunner.postprocess_batch_listc              	   C   sd   | j D ]X}z*|j|j|j }|j||g|R   W q ty\   tjd|j dd Y q0 qd S )Nz!Error running postprocess_image: Tr   )	r   r   rU   rV   r7   r   r
   r   rT   )r   r(   r5   r   r   r   r   r   r7     s    
zScriptRunner.postprocess_imagec              	   K   s   | j |dg D ]D\}}z|t|d W q tyV   tjd|j dd Y q0 q| jD ]D}z|j|fi | W q` ty   tjd|j dd Y q`0 q`d S )NrA   r   z#Error running on_before_component: Tr   z Error running before_component: )	r=   r   r   r   r
   r   rT   r   r;   r   r   r/   r@   r   r   r   r   r;     s    
zScriptRunner.before_componentc              	   K   s   | j |jg D ]D\}}z|t|d W q tyR   tjd|j dd Y q0 q| jD ]D}z|j	|fi | W q\ ty   tjd|j dd Y q\0 q\d S )Nr   z"Error running on_after_component: Tr   zError running after_component: )
rC   r   rA   r   r   r
   r   rT   r   r<   r   r   r   r   r<     s    
zScriptRunner.after_componentc                 C   s   | j | S r   )r   r   rM   )r   r"   r   r   r   r     s    zScriptRunner.scriptc           	      C   s   t t| jD ]\}}|j}|j}|j}||d }|d u rPt|j}|||< |j	
 D ]J}t|tkrZt|trZ| | j|< || j| _|| j| _|| j| _qZqd S r   )list	enumerater   rU   rV   rT   r   r   r   r   r   r   r   r   )	r   cachesir   rU   rV   rT   rf   re   r   r   r   reload_sources  s    zScriptRunner.reload_sourcesc              	   C   sb   | j D ]V}z(|j|j|j }|j|g|R   W q tyZ   tjd|j dd Y q0 qd S )NzError running before_hr: Tr   )	r   r   rU   rV   rQ   r   r
   r   rT   r   r   r   r   rQ     s    
zScriptRunner.before_hrT)is_uic             	   C   sn   | j D ]b}|s|jrqz(|j|j|j }|j|g|R   W q tyf   tjd|j	 dd Y q0 qd S )NzError running setup: Tr   )
r   r^   r   rU   rV   r+   r   r
   r   rT   )r   r(   r   r   r   r   r   r   setup_scrips  s    

zScriptRunner.setup_scrips)N)r   r   r   r   r   r   r   r   r   r   r*   r,   r-   r0   r1   r2   r9   r3   r   r6   r   r7   r;   r<   r   r   rQ   r   r   r   r   r   r     s.   *
5r   r   r   r   scripts_currentc                  C   s   i } t |  t|  d S r   )r   r   r   )r   r   r   r   reload_script_body_only  s    
r   ).rj   rK   r   r   collectionsr   dataclassesr   gradior   r   r   r   r   r   r   r	   r
   r   objectr   r   r   r   r   r_   rt   r`   ra   rb   r   r   rd   r|   r   r   r   r   r   r   r   r   r   r   r   Zreload_scriptsr   r   r   r   <module>   sF   
(  4	  S