o
    S`                     @   s  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	m
Z
 d dl	mZ d dlmZ d dlmZ d	d
lmZ d dlmZ d dlmZ G dd dZd-ddZd.ddZG dd dZdd Zdd Zdd ZG dd dedd Zd!d" Zd#d$ Zd%d& Z d'd( Z!d)d* Z"d+d, Z#dS )/    N)
namedtuple)cycle)
attrgetter)Empty)Queue)Thread)APIError   )colors)ShutdownException)split_bufferc                   @   s   e Zd ZdddZdd ZdS )LogPresenterTc                 C   s   || _ || _|| _d S N)prefix_width
color_funckeep_prefix)selfr   r   r    r   9/usr/lib/python3/dist-packages/compose/cli/log_printer.py__init__   s   
zLogPresenter.__init__c                 C   s>   dj |d}| jr|j| j}dj | |d d| }|S )Nz{line}linez	{prefix} z |)prefix)formatr   name_without_projectljustr   r   )r   	containerr   to_logr   r   r   r   present   s
   zLogPresenter.presentNT)__name__
__module____qualname__r   r   r   r   r   r   r      s    
r   Tc                 c   s@    t | }dd }t|r|gnt D ]	}t|||V  qdS )znReturn an iterable of functions.

    Each function can be used to format the logs output of a container.
    c                 S   s   | S r   r   )textr   r   r   no_color)   s   z&build_log_presenters.<locals>.no_colorN)max_name_widthr   r
   rainbowr   )service_names
monochromer   r   r$   r   r   r   r   build_log_presenters"   s   r)      c                 C   s   t dd | D | S )zCalculate the maximum width of container names so we can make the log
    prefixes line up like so:

    db_1  | Listening
    web_1 | Listening
    c                 s   s    | ]}t |V  qd S r   )len).0namer   r   r   	<genexpr>7   s    z!max_name_width.<locals>.<genexpr>)max)r'   max_index_widthr   r   r   r%   0   s   r%   c                   @   s2   e Zd ZdZejddfddZdd Zdd	 ZdS )

LogPrinterz:Print logs from many containers to a single output stream.FNc                 C   s,   || _ || _|| _|| _|| _|pi | _d S r   )
containers
presentersevent_streamoutputcascade_stoplog_args)r   r2   r3   r4   r5   r6   r7   r   r   r   r   =   s   zLogPrinter.__init__c                    s   | j sd S t }|| jf}t| j | j|}t|| j| j|f t|| jD ]( t	| | jr@ fdd| j D } |v r@   S  sH|sG d S q%| 
  q%d S )Nc                    s   g | ]
}|j  kr|j qS r   )r-   )r,   contr   r   r   
<listcomp>\   s    z"LogPrinter.run.<locals>.<listcomp>)r2   r   r7   build_thread_mapr3   start_producer_threadr4   consume_queuer6   remove_stopped_threadswrite)r   queuethread_args
thread_mapmatching_containerr   r   r   runK   s.   
zLogPrinter.runc              	   C   sJ   z| j | W n ty   | j |dd  Y nw | j   d S )Nasciireplace)r5   r>   UnicodeEncodeErrorencodedecodeflush)r   r   r   r   r   r>   l   s   zLogPrinter.write)	r    r!   r"   __doc__sysstdoutr   rC   r>   r   r   r   r   r1   :   s    
!r1   c                 C   s.   t |  D ]\}}| s| |d  qd S r   )listitemsis_alivepop)rA   container_idtailer_threadr   r   r   r=   x   s
   r=   c                 C   s&   t t| |||fd}d|_|  |S N)targetargsT)r   tail_container_logsdaemonstart)r   	presenterr?   r7   tailerr   r   r   build_thread~   s   
r[   c                    s     fddt | tddD S )Nc                    s&   i | ]}|j t|t gR  qS r   )idr[   next)r,   r   r3   r@   r   r   
<dictcomp>   s    z$build_thread_map.<locals>.<dictcomp>r-   )key)sortedr   )initial_containersr3   r@   r   r^   r   r:      s   r:   c                   @   s2   e Zd Zedd Zedd ZedddZdS )		QueueItemc                 C   s   | |d d S r   r   clsitemr   r   r   new      zQueueItem.newc                 C   s   | d d |S r   r   )re   excr   r   r   	exception   rh   zQueueItem.exceptionNc                 C   s   | |dd S )NTr   rd   r   r   r   stop   rh   zQueueItem.stopr   )r    r!   r"   classmethodrg   rj   rk   r   r   r   r   rc      s    

rc   
_QueueItemzitem is_stop excc              
   C   s   zt | |D ]}|t|| | qW n ty1 } z|t| W Y d }~d S d }~ww |drD|t|t	|  |t
| j d S )Nfollow)build_log_generatorputrc   rg   r   	Exceptionrj   getr   wait_on_exitrk   r-   )r   rY   r?   r7   rf   er   r   r   rV      s   
rV   c                 C   s8   | j d u r| jddddd|}t|S | j }t|S )NT)rL   stderrstreamr   )
log_streamlogsr   )r   r7   rv   r   r   r   ro      s
   
ro   c              
   C   sZ   z|   }d| j|W S  ty, } zd| j|jj|jjp dW  Y d }~S d }~ww )Nz{} exited with code {}
z=Unexpected API error for {} (HTTP code {})
Response body:
{}
z[empty])waitr   r-   r   responsestatus_coder#   )r   	exit_codert   r   r   r   rs      s   

rs   c                 C   s   t t| d}d|_|  d S rS   )r   watch_eventsrW   rX   )r@   producerr   r   r   r;      s   r;   c              	   C   s   t  }|D ]x}|d dkr| |d d  |d dkr*| |d d  ||d  |d dkr1q|d | v rH| |d   r@q| |d d  |d |v rl|d }|jsez|  W n	 tyd   Y nw ||d  t|d t	|g|R  | |d < qd S )Nactionrk   r\   dierX   r   )
setrP   addrO   is_restartingattach_log_streamr   remover[   r]   )rA   r4   r3   r@   crashed_containerseventr   r   r   r   r}      s:   r}   c                 c   sd    	 z| j dd}W n ty   dV  Y q tjy    t w |jr'|j|jr-|s-q|jV  q)z?Consume the queue by reading lines off of it and yielding them.Tg?)timeoutN)rr   r   threaderrorr   ri   is_stoprf   )r?   r6   rf   r   r   r   r<      s    
r<   r   )r*   )$_threadr   rK   collectionsr   	itertoolsr   operatorr   r?   r   r   	threadingr   docker.errorsr    r
   compose.cli.signalsr   compose.utilsr   r   r)   r%   r1   r=   r[   r:   rc   rV   ro   rs   r;   r}   r<   r   r   r   r   <module>   s4    


>	
%