o
    vaU                     @   s   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ZddlZddl	Z	ddl
mZ ddlmZ ddlmZ zddlmZmZmZmZmZmZmZmZ W n ey_   ed ed	 Y nw d
d ZG dd deZG dd deZdS )zWeb interface class.    N)open)b)Timer)logger)Bottlestatic_fileabortresponserequest
auth_basictemplateTEMPLATE_PATHzABottle module not found. Glances cannot start in web server mode.   c                    s    fdd}ddd |S )z@Compress result with deflate algorithm if the client ask for it.c               	      sl   | i |}t dtjtjdd tj D  dtjddv r/dt	jd<  |}|S dt	jd< |S )	z@Wrapper that take one function and return the compressed result.z%Receive {} {} request with header: {}c                 S   s    g | ]}d  |tj|qS )z{}: {})formatr
   headersget).0h r   @/usr/lib/python3/dist-packages/glances/outputs/glances_bottle.py
<listcomp>2   s     z-compress.<locals>.wrapper.<locals>.<listcomp>ZdeflatezAccept-Encoding zContent-Encodingidentity)
r   debugr   r
   methodZurlr   keysr   r	   )argskwargsretdeflate_compressfuncr   r   wrapper,   s   

zcompress.<locals>.wrapper   c                 S   s0   t |t jt jt jt j}|t| |  S )z/Compress given data using the DEFLATE algorithm)	zlibcompressobjDEFLATED	MAX_WBITSDEF_MEM_LEVELZ_DEFAULT_STRATEGYcompressr   flush)dataZcompress_levelZzobjr   r   r   r    ;   s   z"compress.<locals>.deflate_compressN)r#   r   )r!   r"   r   r   r   r*   *   s   
r*   c                   @   s6  e Zd ZdZdZ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dZdd Zedd Zedd Zedd Zedd Zed d! Zed"d# Zed>d%d&Zed'd( Zed)d* Zd?d,d-Zed.d/ Zed>d0d1Zed2d3 Zed4d5 Zed6d7 Zed8d9 Zed:d; Z dS )@GlancesBottlez)This class manages the Bottle Web server.3Nc              
   C   s   || _ || _d | _td| _| | d| jj| jj| _	t
 | _| jt  |jdkr7| jt| j |   tjtjtjtd| _tdtjtjtjtd d S )Nr   zhttp://{}:{}/r   zstatic/publiczstatic/templates)configr   statsr   timerload_configr   bind_addressportbind_urlr   _appinstall
EnableCorspasswordr   
check_auth_routeospathjoindirnamerealpath__file__STATIC_PATHr   insert)selfr/   r   r   r   r   __init__O   s   



 *zGlancesBottle.__init__c                 C   sH   |dur | dr"td |jdddd}td| dS dS dS )z3Load the outputs section of the configuration file.NZoutputsz0Read number of processes to display in the WebUIZmax_processes_display)defaultz/Number of processes to display in the WebUI: {})Zhas_sectionr   r   Z	get_valuer   )rD   r/   nr   r   r   r2   v   s
   
zGlancesBottle.load_configc                 C   s*   | j  r| j  t| jj| _ d S d S N)r1   Zfinishedr0   updater   r   Zcached_timerD   r   r   r   
__update__~   s   

zGlancesBottle.__update__c                 C   s   |   S rH   )r6   rJ   r   r   r   app   s   zGlancesBottle.appc                 C   s8   || j jkrddlm} | }|| j j||S dS )z2Check if a username/password combination is valid.r   )GlancesPasswordF)r   usernameZglances.passwordrM   Zcheck_passwordr9   Zsha256_hash)rD   rN   r9   rM   pwdr   r   r   r:      s
   zGlancesBottle.check_authc                 C   sd  | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd	| j d| j	d | j jd
| j d| j
d | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd | j jd| j d| jd d| j| j}t| | jjs'| j jdd| jd | j jddg| jd | j jdd| jd d| j}t| ntd t| dS )zDefine route.z/api/%s/configZGET)r   callbackz/api/%s/config/<item>z/api/%s/argsz/api/%s/args/<item>z/api/%s/helpz/api/%s/pluginslistz/api/%s/allz/api/%s/all/limitsz/api/%s/all/viewsz/api/%s/<plugin>z/api/%s/<plugin>/historyz!/api/%s/<plugin>/history/<nb:int>z/api/%s/<plugin>/limitsz/api/%s/<plugin>/viewsz/api/%s/<plugin>/<item>z/api/%s/<plugin>/<item>/historyz(/api/%s/<plugin>/<item>/history/<nb:int>z/api/%s/<plugin>/<item>/<value>z/Glances RESTful API Server started on {}api/{}//z/<refresh_time:int>z/<filepath:path>z(Glances Web User Interface started on {}z&The WebUI is disable (--disable-webui)N)r6   ZrouteAPI_VERSION_api_config_api_config_item	_api_args_api_args_item	_api_help_api_plugins_api_all_api_all_limits_api_all_views_api_api_history_api_limits
_api_views	_api_item_api_item_history
_api_valuer   r5   r   infor   Zdisable_webui_index	_resourceprint)rD   Zbindmsgr   r   r   r;      s   


zGlancesBottle._routec              
   C   s   || _ | j  | _| jjrtj| jddd z| jj	| jj
| jj| jj d W dS  tjyE } ztd| W Y d}~dS d}~ww )zStart the bottle.r      )newZ	autoraise)Zhostr4   quietz*Error: Can not ran Glances Web server ({})N)r0   ZgetPluginsListplugins_listr   Zopen_web_browser
webbrowserr   r5   r6   runr3   r4   r   socketerrorr   criticalr   )rD   r0   er   r   r   start   s    zGlancesBottle.startc                 C   s   dS )zEnd the bottle.Nr   rJ   r   r   r   end   s   zGlancesBottle.endc                 C   s0   |du s|dk rt | jj}|   td|dS )z(Bottle callback for index.html (/) file.Nrg   z
index.html)refresh_time)intr   timerK   r   )rD   rs   r   r   r   rd      s   zGlancesBottle._indexc                 C   s   t || jdS )z$Bottle callback for resources files.)root)r   rB   )rD   filepathr   r   r   re      s   zGlancesBottle._resourcec              
   C   sd   dt _| jd }z
tj|dd}W |S  ty1 } ztddt	|  W Y d}~|S d}~ww )zXGlances API RESTful implementation.

        Return the help data or 404 error.
        application/json; charset=utf-8helpT)Z	sort_keys  zCannot get help view data (%s)N)
r	   content_typer0   
get_pluginZget_view_datajsondumps	Exceptionr   str)rD   Z	view_dataplistrp   r   r   r   rW      s   zGlancesBottle._api_helpc              
   C   sZ   dt _|   z	t| j}W |S  ty, } ztddt|  W Y d}~|S d}~ww )aO  Glances API RESTFul implementation.

        @api {get} /api/%s/pluginslist Get plugins list
        @apiVersion 2.0
        @apiName pluginslist
        @apiGroup plugin

        @apiSuccess {String[]} Plugins list.

        @apiSuccessExample Success-Response:
            HTTP/1.1 200 OK
            [
               "load",
               "help",
               "ip",
               "memswap",
               "processlist",
               ...
            ]

         @apiError Cannot get plugin list.

         @apiErrorExample Error-Response:
            HTTP/1.1 404 Not Found
        rx   rz   zCannot get plugin list (%s)N)	r	   r{   rK   r}   r~   rj   r   r   r   )rD   r   rp   r   r   r   rX     s   zGlancesBottle._api_pluginsc              
   C   s   dt _| jjr<tjt d}zt	|}|
 W  d   W S 1 s%w   Y  W n ty;   td|  Y nw |   zt| j }W |S  tyg } ztddt|  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of all the plugins
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx   zglances-debug.jsonNzDebug file (%s) not foundrz   zCannot get stats (%s))r	   r{   r   r   r<   r=   r>   tempfileZ
gettempdirr   readIOErrorr   rK   r}   r~   r0   ZgetAllAsDictr   r   r   )rD   fnamefstatvalrp   r   r   r   rY   +  s&   	
&zGlancesBottle._api_allc              
   C   V   dt _zt| j }W |S  ty* } ztddt|  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of all the plugins limits
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx   rz   zCannot get limits (%s)N)	r	   r{   r}   r~   r0   ZgetAllLimitsAsDictr   r   r   rD   limitsrp   r   r   r   rZ   I     	zGlancesBottle._api_all_limitsc              
   C   r   )zGlances API RESTful implementation.

        Return the JSON representation of all the plugins views
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx   rz   zCannot get views (%s)N)	r	   r{   r}   r~   r0   ZgetAllViewsAsDictr   r   r   r   r   r   r   r[   [  r   zGlancesBottle._api_all_viewsc              
   C   s   dt _|| jvrtdd|| jf  |   z| j| }W |S  ty? } ztdd|t	|f  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of a given plugin
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx     )Unknown plugin %s (available plugins: %s)rz   zCannot get plugin %s (%s)N)
r	   r{   rj   r   rK   r0   r|   Z	get_statsr   r   )rD   pluginr   rp   r   r   r   r\   m  s   	
 zGlancesBottle._apir   c              
   C   s   dt _|| jvrtdd|| jf  |   z| j|jt|d}W |S  t	yC } ztdd|t
|f  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of a given plugin history
        Limit to the last nb items (all if nb=0)
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx   r   r   nbrz   z!Cannot get plugin history %s (%s)N)r	   r{   rj   r   rK   r0   r|   get_stats_historyrt   r   r   )rD   r   r   r   rp   r   r   r   r]     s   

 zGlancesBottle._api_historyc              
   C   sv   dt _|| jvrtdd|| jf  z
| j|j}W |S  ty: } ztdd|t|f  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON limits of a given plugin
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx   r   r   rz   z$Cannot get limits for plugin %s (%s)N)	r	   r{   rj   r   r0   r|   r   r   r   rD   r   r   rp   r   r   r   r^     s   	
 zGlancesBottle._api_limitsc              
   C   sx   dt _|| jvrtdd|| jf  z| j| }W |S  ty; } ztdd|t|f  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON views of a given plugin
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        rx   r   r   rz   z#Cannot get views for plugin %s (%s)N)	r	   r{   rj   r   r0   r|   Z	get_viewsr   r   r   r   r   r   r_     s   	
 zGlancesBottle._api_viewsFc                 C   s   dt _|| jvrtdd|| jf  |   |du rG|r*| j|j|t|d}n	| j|	|}|du rEtdd||r?dnd	|f  |S |rLd}n
| j|
||}|du ritdd
|radnd	|||f  |S )z+Father method for _api_item and _api_value.rx   r   r   Nr   rz   z!Cannot get item %s%s in plugin %szhistory r   z&Cannot get item %s(%s=%s) in plugin %s)r	   r{   rj   r   rK   r0   r|   r   rt   Zget_stats_itemZget_stats_value)rD   r   itemvaluehistoryr   r   r   r   r   _api_itemvalue  s"   
zGlancesBottle._api_itemvaluec                 C   s   |  ||S )zGlances API RESTful implementation.

        Return the JSON representation of the couple plugin/item
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error

        r   )rD   r   r   r   r   r   r`     s   
zGlancesBottle._api_itemc                 C   s   | j ||dt|dS )zGlances API RESTful implementation.

        Return the JSON representation of the couple plugin/history of item
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error

        T)r   r   )r   rt   )rD   r   r   r   r   r   r   ra     s   
zGlancesBottle._api_item_historyc                 C   s   |  |||S )zGlances API RESTful implementation.

        Return the process stats (dict) for the given item=value
        HTTP/200 if OK
        HTTP/400 if plugin is not found
        HTTP/404 if others error
        r   )rD   r   r   r   r   r   r   rb     s   	zGlancesBottle._api_valuec              
   C   r   )zGlances API RESTful implementation.

        Return the JSON representation of the Glances configuration file
        HTTP/200 if OK
        HTTP/404 if others error
        rx   rz   zCannot get config (%s)N)	r	   r{   r}   r~   r/   as_dictr   r   r   rD   	args_jsonrp   r   r   r   rS     s   zGlancesBottle._api_configc              
   C   st   dt _| j }||vrtdd|  z
t|| }W |S  ty9 } ztddt|  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of the Glances configuration item
        HTTP/200 if OK
        HTTP/400 if item is not found
        HTTP/404 if others error
        rx   r   zUnknown configuration item %srz   zCannot get config item (%s)N)	r	   r{   r/   r   r   r}   r~   r   r   )rD   r   Zconfig_dictr   rp   r   r   r   rT   #  s   	
zGlancesBottle._api_config_itemc              
   C   sV   dt _ztt| j}W |S  ty* } ztddt|  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of the Glances command line arguments
        HTTP/200 if OK
        HTTP/404 if others error
        rx   rz   zCannot get args (%s)N)	r	   r{   r}   r~   varsr   r   r   r   r   r   r   r   rU   9  s   zGlancesBottle._api_argsc              
   C   sr   dt _|| jvrtdd|  ztt| j| }W |S  ty8 } ztddt|  W Y d}~|S d}~ww )zGlances API RESTful implementation.

        Return the JSON representation of the Glances command line arguments item
        HTTP/200 if OK
        HTTP/400 if item is not found
        HTTP/404 if others error
        rx   r   zUnknown argument item %srz   zCannot get args item (%s)N)	r	   r{   r   r   r}   r~   r   r   r   )rD   r   r   rp   r   r   r   rV   L  s   	
zGlancesBottle._api_args_item)NNrH   )r   )NFr   )!__name__
__module____qualname____doc__rR   rE   r2   rK   rL   r:   r;   rq   rr   rd   re   r*   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r   r`   ra   rb   rS   rT   rU   rV   r   r   r   r   r-   J   s\    
'	7


%












r-   c                   @   s   e Zd ZdZdZdd ZdS )r8   Zenable_corsr   c                    s    fdd}|S )Nc                     s:   dt jd< dt jd< dt jd< tjdkr | i |S d S )N*zAccess-Control-Allow-OriginzGET, POST, PUT, OPTIONSzAccess-Control-Allow-Methodsz<Origin, Accept, Content-Type, X-Requested-With, X-CSRF-TokenzAccess-Control-Allow-HeadersZOPTIONS)r	   r   r
   r   )r   r   fnr   r   _enable_corsi  s   



z&EnableCors.apply.<locals>._enable_corsr   )rD   r   contextr   r   r   r   applyh  s   
zEnableCors.applyN)r   r   r   nameZapir   r   r   r   r   r8   d  s    r8   ) r   r}   r<   sysr   ior   rk   r$   rm   Zglances.compatr   Zglances.timerr   Zglances.loggerr   Zbottler   r   r   r	   r
   r   r   r   ImportErrorro   exitr*   objectr-   r8   r   r   r   r   <module>   s2   ,
     