o
    ²µj’3  ã                	   @   s0  d 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m	Z	m
Z
 dedefdd„Zdedefd	d
„Zdedefdd„Zdedefdd„Zdedefdd„Zdedefdd„Zdedefdd„Zdededefdd„Zd"dedededefdd„Zd"dededefdd„Zdd „ Zed!kr–e eƒ ¡ dS dS )#zv
gunicornc - Gunicorn control interface CLI

Interactive and single-command modes for controlling Gunicorn instances.
é    N)Ú_get_default_control_socket)ÚControlClientÚControlClientErrorÚparse_commandÚdataÚreturnc           	   
   C   sô   |   dg ¡}|s
dS g }| dd›ddd›ddd	›dd
› ¡ | d¡ |D ]:}|  dd¡}|  dd¡}|  d¡r;dnd}|  d¡}|durK|› dnd}| |d›d|d›d|d	›d|› ¡ q&| d¡ | d|   dt|ƒ¡› d¡ d |¡S )z"Format workers output for display.ÚworkerszNo workers runningÚPIDú<10ú ÚAGEú<6ÚBOOTEDú<8Ú	LAST_BEATz(----------------------------------------Úpidú?ÚageÚbootedÚyesÚnoÚlast_heartbeatNús agoún/aÚ úTotal: Úcountz workersÚ
©ÚgetÚappendÚlenÚjoin)	r   r   ÚlinesÚwr   r   r   ÚhbÚhb_str© r'   úE/var/www/ai-app/venv/lib/python3.10/site-packages/gunicorn/ctl/cli.pyÚformat_workers   s    &

(

r)   c              
   C   sº  |   d¡sdS g }| d|   d¡› ¡ | d¡ |   dg ¡}|r„| d¡ | dd	›d
dd›d
dd›d
d› ¡ | d¡ |D ]>}|  dd¡}|  dd¡}d |  dg ¡¡dd… }|  d¡}|duri|› dnd}| |d	›d
|d›d
|d›d
|› ¡ q@| d¡ |   dg ¡}|rØ| d¡ | dd›d
dd	›d
d› ¡ | d¡ |D ]0}	|	  dd¡dd… }
|	  d d!¡}|	  d"¡}|durÆt|ƒnd#}| |
d›d
|d	›d
|› ¡ q§d$ |¡S )%z(Format dirty workers output for display.ÚenabledzDirty arbiter not runningzDirty arbiter PID: r   r   r   zDIRTY WORKERS:r	   r
   r   r   r   ÚAPPSz<30r   z<------------------------------------------------------------r   r   ú, ÚappsNé   r   r   r   zDIRTY APPS:ÚAPPÚWORKERSÚLIMITú2--------------------------------------------------Úimport_pathÚcurrent_workersr   Úworker_countÚnoner   )r   r    r"   Ústr)r   r#   r   r$   r   r   r-   r%   r&   ÚappÚpathÚcurrentÚlimitÚ	limit_strr'   r'   r(   Úformat_dirty-   s<   


&

(



 
r=   c                 C   sD  g }|   d¡}|r<t|d ƒ}t|d d ƒ}t|d ƒ}|r+|› d|› d|› d}n|r6|› d|› d}n|› d}nd}| d|› ¡ | d	|   d
d¡› ¡ | d|   dd¡› ¡ | d|   dd¡› ¡ | d|   dd¡› ¡ | d|   dd¡› ¡ | d|   dd¡› ¡ |   d¡}|r| d|› ¡ d |¡S )z Format stats output for display.Úuptimei  é<   zh zm ÚsÚunknownzUptime:           zPID:              r   zWorkers current:  Úworkers_currentr   zWorkers target:   Úworkers_targetzWorkers spawned:  Úworkers_spawnedzWorkers killed:   Úworkers_killedzReloads:          ÚreloadsÚdirty_arbiter_pidzDirty arbiter:    r   )r   Úintr    r"   )r   r#   r>   ÚhoursÚminutesÚsecondsÚ
uptime_strÚ	dirty_pidr'   r'   r(   Úformat_statsW   s.   


rN   c                 C   s¾   |   dg ¡}|s
dS g }| dd›ddd›dd› ¡ | d	¡ |D ]#}|  d
d¡}|  dd¡}|  dd¡}| |d›d|d›d|› ¡ q"| d¡ | d|   dt|ƒ¡› d¡ d |¡S )z$Format listeners output for display.Ú	listenerszNo listeners boundÚADDRESSz<40r   ÚTYPEr   ÚFDz7-------------------------------------------------------Úaddressr   ÚtypeÚfdr   r   r   z
 listenersr   r   )r   rO   r#   ÚlnrÚaddrÚltyperU   r'   r'   r(   Úformat_listenersx   s   
 

rY   c                 C   sZ   g }t |  ¡ ƒD ]}| | }t|tƒrd dd„ |D ƒ¡}| |› d|› ¡ qd |¡S )z!Format config output for display.r,   c                 s   ó    | ]}t |ƒV  qd S ©N)r7   )Ú.0Úvr'   r'   r(   Ú	<genexpr>–   ó   € z format_config.<locals>.<genexpr>z: r   )ÚsortedÚkeysÚ
isinstanceÚlistr"   r    )r   r#   ÚkeyÚvaluer'   r'   r(   Úformat_configŽ   s   

rf   c                 C   s„   |   di ¡}g }| d¡ | d¡ |rtdd„ | ¡ D ƒƒnd}t| ¡ ƒD ]\}}| d|d|d	 › ›d
|› ¡ q'd |¡S )zFormat help output for display.ÚcommandszAvailable commands:r   c                 s   rZ   r[   )r!   )r\   Úcmdr'   r'   r(   r^   ¤   r_   zformat_help.<locals>.<genexpr>r   ú  ú<é   r   r   )r   r    Úmaxra   r`   Úitemsr"   )r   rg   r#   Úmax_lenrh   Údescr'   r'   r(   Úformat_helpœ   s   

$
rp   c                 C   sº  g }|   di ¡}| d¡ | d|  dd¡› ¡ | d¡ |   dg ¡}| d|   d	d
¡› d¡ |rŽ| ddd›ddd›ddd›dd› ¡ | dd› ¡ |D ];}|  dd¡}|  dd¡}|  d¡rfdnd}|  d¡}|durv|› dnd}	| d|d›d|d›d|d›d|	› ¡ qQn| d¡ | d¡ |   d¡}
|
rN| d ¡ | d|
  dd¡› ¡ | d¡ |   d!g ¡}| d"|   d#d
¡› d¡ |rH| ddd›ddd›dd$› ¡ | dd%› ¡ |D ]`}|  dd¡}|  dd¡}|  d&g ¡}|r8|d
  d'¡d( }| d|d›d|d›d|› ¡ |d)d… D ]}| d'¡d( }| ddd›ddd›d|› ¡ qqæ| d|d›d|d›d*¡ qæn| d¡ n
| d ¡ | d+¡ d, |¡S )-z#Format show all output for display.ÚarbiterzARBITER (master)z  PID: r   r   r   Úweb_workerszWEB WORKERS (Úweb_worker_countr   ú)ri   r	   r
   r   r   r   r   r   r   z&--------------------------------------r   r   r   r   r   Nr   r   z  (none)Údirty_arbiterzDIRTY ARBITERÚdirty_workerszDIRTY WORKERS (Údirty_worker_countr+   r2   r-   ú:éÿÿÿÿé   z
 (no apps)z  (not running)r   )r   r    Úsplitr"   )r   r#   rq   rr   r$   r   r   r   r%   r&   ru   rv   r-   Ú	first_appr8   Úapp_namer'   r'   r(   Ú
format_all¬   s^   

(
*ú




  $þô


r~   Úcommandc                 C   s’   |   ¡  ¡ }|dkrt|ƒS |dkrt|ƒS |dkrt|ƒS |dkr&t|ƒS |dkr.t|ƒS |dkr6t|ƒS |dkr>t|ƒS |rGt	j
|dd	S d
S )z¾
    Format response data based on command.

    Args:
        command: Original command string
        data: Response data dictionary

    Returns:
        Formatted string for display
    zshow allzshow workersz
show dirtyz
show statszshow listenerszshow configÚhelprk   ©ÚindentÚOK)ÚlowerÚstripr~   r)   r=   rN   rY   rf   rp   ÚjsonÚdumps)r   r   Ú	cmd_lowerr'   r'   r(   Úformat_responseê   s$   r‰   FÚsocket_pathÚjson_outputc           
   
   C   sâ   zJt | ƒ;}t|ƒ\}}|r|› dd |¡›  ¡ n|}| |¡}|r-ttj|ddƒ n	t||ƒ}t|ƒ 	 W d  ƒ W dS 1 sCw   Y  W dS  t	yg }	 ztd|	› t
jd W Y d}	~	dS d}	~	w typ   Y d	S w )
zð
    Execute single command and exit.

    Args:
        socket_path: Path to control socket
        command: Command to execute
        json_output: If True, output raw JSON

    Returns:
        Exit code (0 for success, 1 for error)
    r   rk   r   Nr   úError: ©Úfilerz   é‚   )r   r   r"   r…   Úsend_commandÚprintr†   r‡   r‰   r   ÚsysÚstderrÚKeyboardInterrupt)
rŠ   r   r‹   Úclientrh   ÚargsÚfull_commandÚresultÚoutputÚer'   r'   r(   Úrun_command  s$   
 

(õ€ÿr›   c                 C   s~  zddl }d}W n ty   d}Y nw z
t| ƒ}| ¡  W n ty; } ztd|› tjd W Y d}~dS d}~ww td| › ƒ td	ƒ tƒ  tj	 
d
¡}|rcz| |¡ W n	 tyb   Y nw d}z¿z‘	 ztdƒ ¡ }W n ty|   tƒ  Y nzw |s€qg| ¡ dv r‡noz2t|ƒ\}	}
|
rœ|	› dd |
¡›  ¡ n|	}| |¡}|r¯ttj|ddƒ n	t|	|ƒ}t|ƒ W n8 tyñ } z,td|› ƒ z
| ¡  | ¡  W n tyæ   tdƒ d}Y W Y d}~nw W Y d}~nd}~ww tƒ  qhW n ty   tƒ  d}Y nw W | ¡  |r#z| |¡ W |S  ty"   Y |S w |S | ¡  |r>z| |¡ W w  ty=   Y w w w )z¹
    Run interactive CLI with readline support.

    Args:
        socket_path: Path to control socket
        json_output: If True, output raw JSON

    Returns:
        Exit code
    r   NTFrŒ   r   rz   zConnected to z3Type 'help' for available commands, 'quit' to exit.z~/.gunicornc_historyz
gunicorn> )ÚquitÚexitÚqr   rk   r   zConnection lost. Exiting.r   )ÚreadlineÚImportErrorr   Úconnectr   r‘   r’   r“   Úosr9   Ú
expanduserÚread_history_fileÚFileNotFoundErrorÚinputr…   ÚEOFErrorr„   r   r"   r   r†   r‡   r‰   Úcloser”   Úwrite_history_fileÚ	Exception)rŠ   r‹   rŸ   Úhas_readliner•   rš   Úhistory_fileÚ	exit_codeÚlinerh   r–   r—   r˜   r™   r'   r'   r(   Úrun_interactive.  sª   ÿ€þÿþ 

€ýÿ€ûÝ€%þ€ýýùÿýr¯   c                  C   sÎ   t jdt jdd} | jddtƒ dd | jdd	d
d | jddddd | jddddd |  ¡ }|jrDddlm} t	d|› dƒ dS |j
}tj |¡sVtj t ¡ |¡}|jrat||j|jƒS t||jƒS )z#Main entry point for gunicornc CLI.zGunicorn control interfacea?  
Examples:
  gunicornc                      # Interactive mode (default socket)
  gunicornc -s /tmp/myapp.ctl    # Interactive mode with custom socket
  gunicornc -c "show workers"    # Single command mode
  gunicornc -c "worker add 2"    # Add 2 workers
  gunicornc -c "show stats" -j   # Output stats as JSON
        )ÚdescriptionÚformatter_classÚepilogz-sz--socketzUControl socket path (default: auto-detected based on XDG_RUNTIME_DIR or ~/.gunicorn/))Údefaultr€   z-cz	--commandzExecute single command and exit)r€   z-jz--jsonÚ
store_truezOutput raw JSON (for scripting))Úactionr€   z-vz	--versionzShow version and exitr   )Ú__version__zgunicornc (gunicorn rt   )ÚargparseÚArgumentParserÚRawDescriptionHelpFormatterÚadd_argumentr   Ú
parse_argsÚversionÚgunicornr¶   r‘   Úsocketr¢   r9   Úisabsr"   Úgetcwdr   r›   r†   r¯   )Úparserr–   r¶   rŠ   r'   r'   r(   Úmainˆ  sF   ýýþýýrÂ   Ú__main__)F)Ú__doc__r·   r†   r¢   r’   Úgunicorn.configr   Úgunicorn.ctl.clientr   r   r   Údictr7   r)   r=   rN   rY   rf   rp   r~   r‰   ÚboolrH   r›   r¯   rÂ   Ú__name__r   r'   r'   r'   r(   Ú<module>   s*   *!>#!Z9ÿ