U
    TGˆh.  ã                   @   sú   d Z dZdZddlZddlZddlm  mZ ddl	m
Z
 ddlmZ ddlmZmZmZmZ ddlmZmZmZmZmZmZmZmZmZmZ dd	lmZ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) e
ddddgƒZ*G dd„ deƒZ+dS )zCopyright 2021, 3LizzGPL version 3zinfo@3liz.orgé    N)Ú
namedtuple)ÚPath)Ú	GeneratorÚListÚTupleÚUnion)
ÚQgisÚQgsDistanceAreaÚQgsEditFormConfigÚQgsExpressionÚQgsExpressionContextÚQgsExpressionContextUtilsÚ
QgsFeatureÚQgsFeatureRequestÚ
QgsProjectÚQgsRelationManager)ÚQgsServerFilterÚQgsServerProjectUtils)Úfind_vector_layerÚserver_feature_id_expression)ÚLoggerÚexception_handler)Úto_bool)ÚTooltipÚResultÚlayerÚ
feature_idÚ
expressionc                   @   s€   e Zd Zeeeeeef ddf dœdd„ƒZeeeeee	f eedœdd„ƒZ
eeeeeeee dœd	d
„ƒZedd„ ƒZdS )ÚGetFeatureInfoFilterN)ÚstringÚreturnc                 c   sD   t  |¡}|D ]0}|D ]&}|j d¡r|jd |jd fV  qqdS )zB Generator for layer and feature found in the XML GetFeatureInfo. ÚidÚnameN)ÚETÚ
fromstringÚattribÚget)Úclsr   Úrootr   Úfeature© r*   ú@/var/www/lizmap/lizmap/plugins/lizmap_server/get_feature_info.pyÚ	parse_xml)   s
    
zGetFeatureInfoFilter.parse_xml)r   Ú
layer_namer   Úmaptipr    c                 C   sÎ   t  |¡}|D ]ˆ}|j ¡ dkr"q|jd |kr2q|D ]^}|jd t|ƒkrNq6| d¡}|dk	rl||jd< q6t  d¡}d|jd< ||jd< | |¡ q6qt j	|d	d
d 
d¡ d¡}	d |	dd… ¡}
|
 ¡ S )zR Edit the XML GetFeatureInfo by adding a maptip for a given layer and feature ID. ÚLAYERr"   r!   zAttribute[@name='maptip']NÚvalueÚ	Attributer.   Úutf8Úxml)ÚencodingÚmethodúutf-8Ú
é   )r#   r$   ÚtagÚupperr%   ÚstrÚfindZElementÚappendZtostringÚdecodeÚsplitÚjoinÚstrip)r'   r   r-   r   r.   r(   r   r)   ÚitemZ	xml_linesZ
xml_stringr*   r*   r+   Úappend_maptip2   s&    




z"GetFeatureInfoFilter.append_maptip)ÚcfgÚprojectÚrelation_managerr3   Úbootstrap_5r    c              
   C   sR  g }t  |¡D ]<\}}t||ƒ}	|	s:t d|› d¡ q||	 ¡ kr\t d ||	 ¡ ¡¡ | d¡}
|
s‚t d| 	¡ › d¡ q|
 |	 ¡ ¡}|s°t d |	 ¡ | 	¡ ¡¡ qt
| d¡ƒsÀq| d	¡d
krÐq|	 ¡ }| ¡ tjjkrôt d¡ q| ¡ }t |	|dg d||¡}t |¡}|t ¡ 7 }| t|	||ƒ¡ t d ||¡¡ q|S )zJ Parse the XML and check for each layer according to the Lizmap CFG file. zSkipping the layer 'z!' because it's not a vector layerz3Request on layer shortname '{}' and layer name '{}'Úlayersz$No 'layers' section in the CFG file ú.cfgz:No layer configuration for layer {} in the CFG file {}.cfgZpopupZpopupSourceZformzPThe CFG is requesting a form popup, but the layer is not a form drag&drop layoutr   Ú z=The popup has been replaced for feature ID '{}' in layer '{}')r   r,   r   r   Úinfor"   Úformatr&   ÚcriticalÚfileNamer   ÚeditFormConfigÚlayoutr
   ÚEditorLayoutÚ	TabLayoutÚwarningÚinvisibleRootContainerr   Z create_popup_node_item_from_formZcreate_popupZcssr=   r   )r'   rD   rE   rF   r3   rG   Úfeaturesr-   r   r   rH   Zlayer_configÚconfigr(   Zhtml_contentr*   r*   r+   Úfeature_list_to_replaceR   sl    

 ÿ
 ÿÿÿ      ÿ
 ÿÿz,GetFeatureInfoFilter.feature_list_to_replacec              
   C   s`  t ƒ }|  ¡  ¡ }| ¡ }| dd¡ ¡ dkr2dS | dd¡ ¡ dkrJdS | dd¡ ¡ dkr~| d	 | dd¡ ¡ ¡¡ dS t|  ¡  	¡ ƒ}| 
¡ s²| d
 |  ¡  	¡ ¡¡ dS t|  ¡  	¡ d ƒ}| 
¡ sê| d |  ¡  	¡ ¡¡ dS tt|ƒddd}t | ¡ ¡}W 5 Q R X t ¡ }| ¡ }	| ¡  ¡  d¡}
| dd¡ ¡ dk}z|  |||	|
|¡}W n` tk
rÂ } z@tt d¡ƒr’| |¡ ‚ | d |¡¡ | |¡ W Y ¢dS d}~X Y nX |sÞ| d|› ¡ dS | d t|ƒd dd„ |D ƒ¡¡¡ tƒ }|  t! "¡ ¡ |  t! #|¡¡ t$ %|¡}zÌ|D ]v}t&ƒ }| '|j( )¡ | *¡ ¡ | +| ,¡ ¡ |  t! -|j(¡¡ t.|j/|j( 0¡ ƒ}|rÌt1t2|ƒƒ}|s²| 3t1j4¡ t5ƒ }|j( 6|¡ 7|¡ n|j( 8t9|j/ƒ¡}| :¡ s| ;d |j/|j( <¡ ¡¡ q:| =|¡ | >| ?¡ ¡ t2 @|jA||¡}|sR| ;d |j/|j( <¡ ¡¡ q:tB C¡ dk rl|j( D¡ }n|j( E¡  D¡ }|sŠ|j( F¡ }| d |j/|¡¡ |  G|
||j/|¡}
q:|
sÊ| d¡ W dS | H¡  | Idd¡ | JtK|
dƒ¡ | d |› ¡ W nZ tk
rZ } z:tt d¡ƒr0| |¡ ‚ | d!¡ | |¡ W Y ¢dS d}~X Y nX dS )"zA Intercept the GetFeatureInfo and add the form maptip if needed. ÚSERVICErJ   ZWMSNÚREQUESTZGETFEATUREINFOZINFO_FORMATzTEXT/XMLz9Lizmap is only processing INFO_FORMAT=TEXT/XML, not '{}'.zmThe QGIS project {} does not exist as a file, not possible to process with Lizmap this request GetFeatureInforI   zlThe QGIS project {} is not a Lizmap project, not possible to process with Lizmap this request GetFeatureInfoÚrr6   )r4   ZCSS_FRAMEWORKZ
BOOTSTRAP5ÚCIz^Error while reading the XML response GetFeatureInfo for project {}, returning default responsez:No features found in the XML from QGIS Server for project zTReplacing the maptip from QGIS by the drag and drop expression for {} features on {}ú,c                 S   s   g | ]}|j  ¡ ‘qS r*   )r   r"   )Ú.0Úresultr*   r*   r+   Ú
<listcomp>Ô   s     z9GetFeatureInfoFilter.responseComplete.<locals>.<listcomp>znThe feature {} for layer {} is not valid, skip replacing this XML GetFeatureInfo, continue to the next featurez‰The GetFeatureInfo result for feature {} in layer {} is not valid, skip replacing this XML GetFeatureInfo, , continue to the next featurei„  zQReplacing feature '{}' in layer '{}' for the GetFeatureInfo by the drag&drop formzRThe new XML for the GetFeatureInfo is empty. Let's return the default previous XMLzContent-Typeztext/xmlz$GetFeatureInfo replaced for project zQError while rewriting the XML response GetFeatureInfo, returning default response)Lr   ZserverInterfaceÚrequestHandlerÚparameterMapr&   r:   rK   rL   r   ÚconfigFilePathÚexistsÚopenr;   ÚjsonÚloadsÚreadr   ÚinstanceÚrelationManagerÚbodyÚdatar>   rW   Ú	Exceptionr   ÚosÚgetenvÚlog_exceptionrM   Úlenr@   r   ÚappendScoper   ÚglobalScopeÚprojectScoper   ZwmsFeatureInfoAddWktGeometryr	   ÚsetSourceCrsr   ÚcrsÚtransformContextÚsetEllipsoidÚ	ellipsoidÚ
layerScoper   r   ÚdataProviderr   r   ÚsetFlagsÚ
NoGeometryr   ÚgetFeaturesÚnextFeatureÚ
getFeatureÚintÚisValidrS   r!   Ú
setFeatureÚ	setFieldsÚfieldsÚreplaceExpressionTextr   r   Ú
versionIntÚ	shortNameÚserverPropertiesr"   rC   ÚclearZsetResponseHeaderZ
appendBodyÚbytes)ÚselfÚloggerÚrequestÚparamsZproject_pathÚconfig_pathÚcfg_filerD   rE   rF   r3   rG   rU   ÚeÚexp_contextZgeometry_resultr^   Zdistance_arear   Zexpression_requestr)   r0   r-   r*   r*   r+   ÚresponseComplete   sþ    ÿÿ
ÿÿ
ÿÿ
ÿÿ
ÿ ÿÿ


 þÿ
 þÿ
 ÿÿÿ
ÿ
z%GetFeatureInfoFilter.responseComplete)Ú__name__Ú
__module__Ú__qualname__Úclassmethodr;   r   r   r,   r   r€   rC   Údictr   r   Úboolr   r   rW   r   r“   r*   r*   r*   r+   r   '   s   $ ù<r   ),Ú__copyright__Ú__license__Ú	__email__re   rm   Zxml.etree.ElementTreeZetreeZElementTreer#   Úcollectionsr   Úpathlibr   Útypingr   r   r   r   Ú	qgis.corer   r	   r
   r   r   r   r   r   r   r   Úqgis.serverr   r   Úlizmap_server.corer   r   Úlizmap_server.loggerr   r   Úlizmap_server.toolsr   Zlizmap_server.tooltipr   r   r   r*   r*   r*   r+   Ú<module>   s    0