o
    tf!)                     @  s   d Z ddlmZ ddl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 ddlmZ dd	lmZmZ dd
lmZ ddlmZ dZdZeddu reedd G dd deZG dd deZ dS )z3Manager and Tornado handlers for license reporting.    )annotationsN)ThreadPoolExecutor)Path)TYPE_CHECKINGAny)
APIHandler)web)ListUnicode)LoggingConfigurable   )get_federated_extensionszthird-party-licenses.jsonUNKNOWNtext/markdownz.mdc                   @  s   e Zd ZdZeddZee ede gddZ	e
d,d	d
Z	d-d.ddZd.ddZd/ddZd/ddZd0d1ddZd2d$d%Zd3d'd(Zd4d5d)d*Zd+S )6LicensesManagerzA manager for listing the licenses for all frontend end code distributed
    by an application and any federated extensions
    r   )max_workerszstatic/z=the license report data in built app and federated extensions)default_valuehelpreturndict[str, Any]c                 C  sF   t rddlm} t| j|sJ | jj| jjg}dd |D }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.
        r   LabServerAppc                 S  s   g | ]	}|D ]}|qqS  r   ).0
extensions	extensionr   r   k/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/jupyterlab_server/licenses_handler.py
<listcomp>A       z8LicensesManager.federated_extensions.<locals>.<listcomp>)r   appr   
isinstanceparentlabextensions_pathZextra_labextensions_pathr   )selfr   Z	per_pathsr"   r   r   r   federated_extensions1   s   z$LicensesManager.federated_extensionsmarkdown.*Freport_formatstrbundles_pattern	full_textbooltuple[str, str]c                   s$   t | jj| j|||dI dH S )zrAsynchronous wrapper around the potentially slow job of locating
        and encoding all of the licenses
        r'   r)   r*   N)asynciowrap_futureexecutorsubmitreport)r#   r'   r)   r*   r   r   r   report_asyncD   s   
zLicensesManager.report_asyncc                 C  sf   | j |d}|dkr| |dfS |dkr| |dfS |dkr)| j||ddfS d	| d
}t|)z*create a human- or machine-readable report)r)   jsonzapplication/jsoncsvztext/csvr%   )r*   r   zUnsupported report format .)bundlesreport_json
report_csvreport_markdown
ValueError)r#   r'   r)   r*   r7   msgr   r   r   r2   S   s   zLicensesManager.reportr7   c                 C  s   t jd|idddS )z0create a JSON report
        TODO: SPDX
        r7      T)indent	sort_keys)r4   dumps)r#   r7   r   r   r   r8   c   s   zLicensesManager.report_jsonc                   st   t  }g d}tj|dg|d}|  | D ]\}}|d D ] |d|i fdd|D  q"q| S )zcreate a CSV report)nameversionInfo	licenseIdextractedTextbundle)
fieldnamespackagesc                   s   i | ]	}|  |d qS ) )get)r   fieldpackager   r   
<dictcomp>t   r   z.LicensesManager.report_csv.<locals>.<dictcomp>)ioStringIOr5   
DictWriterwriteheaderitemswriterowgetvalue)r#   r7   outfilerF   writerbundle_namerE   r   rK   r   r9   i   s   zLicensesManager.report_csvTc              
   C  s  g }dd |  D }|rt|nd}|  D ]o\}}|d| dg7 }|dg }|s3|ddg7 }q|D ]P}	|	dt }
|	d	t }|	d
t }|	dd}|ddd|
 d|d| dd|g g7 }|r|s{|g d7 }q5|ddd|ddg7 }q5qd|S )zcreate a markdown reportc                 S  s2   g | ]\}}| d g D ]
}t| dtqqS )rG   rA   )rI   lenUNKNOWN_PACKAGE_NAME)r   rW   rE   rL   r   r   r   r   |   s    
z3LicensesManager.report_markdown.<locals>.<listcomp>r   z# rH   rG   z> No licenses foundrA   rB   rC   rD   z## 	z**`   )rH   z> No license text availablerH   z<pre/>z</pre>
)rR   maxrI   rY   stripjoinljust)r#   r7   r*   linesZlibrary_namesZlongest_namerW   rE   rG   rL   rA   version_infoZ
license_idZextracted_textr   r   r   r:   y   sB   
zLicensesManager.report_markdownpathr   rE   
str | Nonec           	      C  s   dg i}g }| j D ]d}|| }| jd| | s ||g7 }q	zt|jdd}W n tyF } z| jd||| W Y d}~q	d}~ww z|d 	|d  W q	 tym } z| jd||| W Y d}~q	d}~ww |d sz| jd|| |S )	z2Return the content of a packages's license bundlesrG   zLoading licenses from %sutf-8encodingz1Failed to open third-party licenses for %s: %s
%sNz%Failed to find packages for %s: %s
%sz)Third-party licenses not found for %s: %s)
third_party_licenses_fileslogdebugexistsr4   loads	read_text	Exceptionwarningextend)	r#   rd   rE   Zbundle_jsonZchecked_pathsZlicense_fileZlicenses_pathZ	file_jsonerrr   r   r   license_bundle   sF   

		zLicensesManager.license_bundletuple[Path | None, str | None]c                 C  sv   t rddlm} t| j|sJ t| jj}|d }| s,|jd }| r*|}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`.
        r   r   zpackage.json)NNrf   rg   rA   )r   r   r   r    r!   r   Z
static_dirrl   r4   rm   rn   )r#   r   rd   Zpackage_jsonZparent_package_jsonrA   r   r   r   app_static_info   s   
zLicensesManager.app_static_infoc                   sj    fddj  D } \}}|dur+|dusJ t |r+||||< |s3jd |S )z6Read all of the licenses
        TODO: schema
        c                   s2   i | ]\}}t  |r|t|d  |qS )Zext_path)rematchrs   r   )r   rA   extr)   r#   r   r   rM      s    
z+LicensesManager.bundles.<locals>.<dictcomp>NzNo license bundles found at all)r$   rR   ru   rv   rw   rs   rj   rp   )r#   r)   r7   Zapp_pathapp_namer   ry   r   r7      s   zLicensesManager.bundlesN)r   r   )r%   r&   F)r'   r(   r)   r(   r*   r+   r   r,   )r7   r   r   r(   )T)r7   r   r*   r+   r   r(   )rd   r   rE   re   r   r   )r   rt   )r&   )r)   r(   r   r   )__name__
__module____qualname____doc__r   r0   r	   r
    DEFAULT_THIRD_PARTY_LICENSE_FILEri   propertyr$   r3   r2   r8   r9   r:   rs   ru   r7   r   r   r   r   r   !   s*    
	



-
'r   c                      s@   e Zd ZdZd fddZejdd
dZd fddZ  Z	S )LicensesHandlerz6A handler for serving licenses used by the applicationmanagerr   r   Nonec                   s   t    || _dS )zInitialize the handler.N)super
initializer   )r#   r   	__class__r   r   r      s   

zLicensesHandler.initialize_argsr   c           
        s   t t| dd}| dd}| dd}t t| dd}| jj|||d	I d
H \}}trBddlm} t	| jj
|sBJ |rWd| jj
j t|}	| |	 | | | j|dI d
H  d
S )z Return all the frontend licensesr*   trueformatr4   r7   r&   download0r-   Nr   r   z{}-licenses{})
_mime_type)r+   r4   rm   Zget_argumentr   r3   r   r   r   r    r!   r   rz   lower	mimetypesguess_extensionZset_attachment_headerwritefinish)
r#   r   r*   r'   r)   r   r2   mimer   filenamer   r   r   rI      s(   

zLicensesHandler.getr   r(   argskwargsc                   s2   |    | d| tt| j|i |I dH S )z>Overload the regular finish, which (sensibly) always sets JSONzContent-TypeN)Zupdate_api_activityZ
set_headerr   r   r   )r#   r   r   r   r   r   r   r     s   zLicensesHandler.finish)r   r   r   r   )r   r   r   r   )r   r(   r   r   r   r   r   r   )
r{   r|   r}   r~   r   r   authenticatedrI   r   __classcell__r   r   r   r   r      s    r   )!r~   
__future__r   r.   r5   rN   r4   r   rv   concurrent.futuresr   pathlibr   typingr   r   Zjupyter_server.base.handlersr   tornador   Z	traitletsr	   r
   Ztraitlets.configr   configr   r   rY   r   add_typer   r   r   r   r   r   <module>   s.     X