a
    bP$                     @   s   d 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mZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ dZdZeddu redd G dd deZG dd deZdS )z3Manager and Tornado handlers for license reporting.    N)Path)ThreadPoolExecutor)webgen)UnicodeList)LoggingConfigurable   )
APIHandler)get_federated_extensionszthird-party-licenses.jsonZUNKNOWNtext/markdownz.mdc                   @   s   e Zd ZdZeddZee egddZ	e
dd ZejdddZdd Zdd Zdd ZdddZdd Zdd ZdddZdS ) LicensesManagerzA manager for listing the licenses for all frontend end code distributed
    by an application and any federated extensions
    r	   )max_workersz=the license report data in built app and federated extensions)Zdefault_valuehelpc                 C   s   t | jj| jjgg }t|S )zLazily load the currrently-available federated extensions.

        This is expensive, but probably the only way to be sure to get
        up-to-date license information for extensions installed interactively.
        )sumparentlabextensions_pathZextra_labextensions_pathr   )selfr    r   Alib/python3.9/site-packages/jupyterlab_server/licenses_handler.pyfederated_extensions-   s    z$LicensesManager.federated_extensionsmarkdown.*Fc                 c   s   | j j| j|||dV }|S )zrAsynchronous wrapper around the potentially slow job of locating
        and encoding all of the licenses
        report_formatbundles_pattern	full_text)executorZsubmitreport)r   r   r   r   r   r   r   r   report_async=   s    zLicensesManager.report_asyncc                 C   sV   | j |d}|dkr"| |dfS |dkr8| |dfS |dkrR| j||ddfS d	S )
z*create a human- or machine-readable report)r   jsonzapplication/jsoncsvztext/csvr   )r   r   N)bundlesreport_json
report_csvreport_markdown)r   r   r   r   r"   r   r   r   r   L   s    zLicensesManager.reportc                 C   s   t jd|idddS )z0create a JSON report
        TODO: SPDX
        r"      T)indentZ	sort_keys)r    dumps)r   r"   r   r   r   r#   Y   s    zLicensesManager.report_jsonc                    st   t  }g d}tj|dg| d}|  | D ]6\}}|d D ]$ |d|i fdd|D  qDq4| S )zcreate a CSV report)nameversionInfo	licenseIdextractedTextbundle)
fieldnamespackagesc                    s   i | ]}|  |d qS ) )get).0Zfieldpackager   r   
<dictcomp>j       z.LicensesManager.report_csv.<locals>.<dictcomp>)ioStringIOr!   Z
DictWriterZwriteheaderitemsZwriterowgetvalue)r   r"   Zoutfiler.   writerbundle_namer-   r   r3   r   r$   _   s    zLicensesManager.report_csvTc              
   C   s  g }dd |  D }|r"t|nd}|  D ]\}}|d| dg7 }|dg }|sf|ddg7 }q.|D ]}	|	dt }
|	d	t }|	d
t }|	dd}|ddd|
 d|d| dd|g g7 }|rj|s|g d7 }qj|ddd|ddg7 }qjq.d|S )zcreate a markdown reportc                 S   s2   g | ]*\}}| d g D ]}t| dtqqS )r/   r)   )r1   lenUNKNOWN_PACKAGE_NAME)r2   r<   r-   r4   r   r   r   
<listcomp>r   s   z3LicensesManager.report_markdown.<locals>.<listcomp>r	   z# r0   r/   z> No licenses foundr)   r*   r+   r,   z## 	z**`   )r0   z> No license text availabler0   z<pre/>z</pre>
)r9   maxr1   r>   stripjoinljust)r   r"   r   linesZlibrary_namesZlongest_namer<   r-   r/   r4   r)   version_infoZ
license_idZextracted_textr   r   r   r%   o   s>    zLicensesManager.report_markdownc                 C   s   dg i}| j D ]}|| }| jd| | sB| jd|| qzt|jdd}W nB ty } z*| jd||| W Y d}~qW Y d}~n
d}~0 0 z|d 	|d  W q ty } z*| jd||| W Y d}~qW Y d}~qd}~0 0 q|S )	z2Return the content of a packages's license bundlesr/   zLoading licenses from %sz)Third-party licenses not found for %s: %sutf-8encodingz1Failed to open third-party licenses for %s: %s
%sNz%Failed to find packages for %s: %s
%s)
third_party_licenses_fileslogdebugexistsZwarningr    loads	read_text	Exceptionextend)r   pathr-   Zbundle_jsonZlicense_fileZlicenses_pathZ	file_jsonerrr   r   r   license_bundle   s<    
"$zLicensesManager.license_bundlec                 C   sV   t | jj}|d }| s8|jd }| r4|}ndS t|jddd }||fS )zget the static directory for this app

        This will usually be in `static_dir`, but may also appear in the
        parent of `static_dir`.
        zpackage.json)NNrJ   rK   r)   )r   r   Z
static_dirrP   r    rQ   rR   )r   rU   Zpackage_jsonZparent_package_jsonr)   r   r   r   app_static_info   s    
zLicensesManager.app_static_infoc                    s^    fddj  D } \}}|durJt |rJ||||< |sZjd |S )z6Read all of the licenses
        TODO: schema
        c                    s2   i | ]*\}}t  |r|t|d  |qS )Zext_path)rematchrW   r   )r2   r)   extr   r   r   r   r5      s   z+LicensesManager.bundles.<locals>.<dictcomp>NzNo license bundles found at all)r   r9   rX   rY   rZ   rW   rN   warn)r   r   r"   Zapp_pathapp_namer   r\   r   r"      s    zLicensesManager.bundlesN)r   r   F)T)r   )__name__
__module____qualname____doc__r   r   r   r    DEFAULT_THIRD_PARTY_LICENSE_FILErM   propertyr   r   	coroutiner   r   r#   r$   r%   rW   rX   r"   r   r   r   r   r       s&   

 
-%r   c                       s@   e Zd ZdZed fddZejdd Z fddZ	  Z
S )	LicensesHandlerz6A handler for serving licenses used by the application)managerc                    s   t t|   || _d S )N)superrf   
initializerg   )r   rg   	__class__r   r   ri      s    zLicensesHandler.initializec           	         s   t t| dd}| dd}| dd}t t| dd}| jj|||d	I d
H \}}|rd| jjj	 t
|}| | | | | j|dI d
H  d
S )z Return all the frontend licensesr   trueformatr    r"   r   download0r   Nz{}-licenses{})
_mime_type)boolr    rQ   Zget_argumentrg   r   rm   r   r^   lower	mimetypesguess_extensionZset_attachment_headerwritefinish)	r   _argsr   r   r   rn   r   Zmimefilenamer   r   r   r1      s     

zLicensesHandler.getc                    s*   |    | d| tt| j|i |S )z>Overload the regular finish, which (sensibly) always sets JSONzContent-Type)Zupdate_api_activityZ
set_headerrh   r
   rv   )r   rp   argskwargsrj   r   r   rv     s    zLicensesHandler.finish)r_   r`   ra   rb   r   ri   r   Zauthenticatedr1   rv   __classcell__r   r   rj   r   rf      s
   
rf   )rb   rs   r    rY   r!   r7   pathlibr   concurrent.futuresr   Ztornador   r   Z	traitletsr   r   Ztraitlets.configr   Zserverr
   Zconfigr   rc   r>   rt   Zadd_typer   rf   r   r   r   r   <module>   s&    G