U
    ô‰VbT*  ã                   @   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 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& 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)ÚQgsDistanceAreaÚQgsEditFormConfigÚQgsExpressionÚQgsExpressionContextÚQgsExpressionContextUtilsÚ
QgsFeatureÚQgsFeatureRequestÚ
QgsProject)ÚQgsServerFilter)Úfind_vector_layerÚserver_feature_id_expression)ÚLoggerÚexception_handler)Úto_bool)ÚTooltipÚResultÚlayerÚ
feature_idÚ
expressionc                   @   sv   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 dœd	d
„ƒZedd„ ƒZdS )ÚGetFeatureInfoFilterN)ÚstringÚreturnc                 c   s8   t  |¡}|D ]$}|D ]}|jd |jd fV  qqdS )zB Generator for layer and feature found in the XML GetFeatureInfo. ÚnameÚidN)ÚETÚ
fromstringÚattrib)Úclsr   Úrootr   Úfeature© r&   ú:/var/qgis-server/plugins/lizmap/server/get_feature_info.pyÚ	parse_xml'   s    
zGetFeatureInfoFilter.parse_xml)r   Ú
layer_namer   Úmaptipr   c                 C   s¾   t  |¡}|D ]x}|jd |kr"q|D ]^}|jd t|ƒkr>q&| d¡}|dk	r\||jd< q&t  d¡}d|jd< ||jd< | |¡ q&q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. r   r   zAttribute[@name='maptip']NÚvalueÚ	Attributer*   Úutf8Úxml)ÚencodingÚmethodúutf-8Ú
é   )r    r!   r"   ÚstrÚfindÚElementÚappendZtostringÚdecodeÚsplitÚjoinÚstrip)r#   r   r)   r   r*   r$   r   r%   ÚitemZ	xml_linesZ
xml_stringr&   r&   r'   Úappend_maptip/   s"    




z"GetFeatureInfoFilter.append_maptip)r   c              	   C   sJ  g }t  |¡D ]4\}}t||ƒ}|s8t d |¡¡ q|| ¡ krZt d || ¡ ¡¡ | d¡}	|	s~t 	d | 
¡ ¡¡ q|	 | ¡ ¡}
|
s¬t 	d | ¡ | 
¡ ¡¡ qt|
 d¡ƒs¼q|
 d¡dkrÌq| ¡ }| ¡ t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 '{}'z3Request 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   ÚwarningÚformatr   ÚinfoÚgetÚcriticalÚfileNamer   ÚeditFormConfigÚlayoutr	   Ú	TabLayoutÚinvisibleRootContainerr   Z create_popup_node_item_from_formZcreate_popupZcssr7   r   )r#   ÚcfgÚprojectÚrelation_managerr.   Úfeaturesr)   r   r   r>   Zlayer_configÚconfigr$   Zhtml_contentr&   r&   r'   Úfeature_list_to_replaceJ   s\    
 ÿ
 ÿÿÿ
 ÿÿ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¡}
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! #|¡¡ z¢|D ]L}t$ƒ }| %|j& '¡ | (¡ ¡ | )| *¡ ¡ |  t! +|j&¡¡ t,|j-|j& .¡ |j& /¡ ƒ}|r®t0t1|ƒƒ}| 2t0j3¡ t4ƒ }|j& 5|¡ 6|¡ n|j& 7t8|j-ƒ¡}| 9¡ sè| :d |j-|j& ;¡ ¡¡ q| <|¡ | =| /¡ ¡ t1 >|j?||¡}|s4| :d |j-|j& ;¡ ¡¡ q| d |j-|j& @¡ ¡¡ |  A|
|j& @¡ |j-|¡}
q|
s€| d¡ W dS | B¡  | Cdd¡ | DtE|
dƒ¡ | d |¡¡ W nZ tk
r } z:tt d¡ƒræ| |¡ ‚ | d¡ | |¡ W Y ¢dS d}~X Y nX dS )zA Intercept the GetFeatureInfo and add the form maptip if needed. ÚSERVICEr?   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 GetFeatureInfoz.cfgzlThe QGIS project {} is not a Lizmap project, not possible to process with Lizmap this request GetFeatureInfoÚrr1   )r/   Ú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 featurezMReplacing 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)Fr   ÚserverInterfaceÚrequestHandlerÚparameterMaprC   ÚupperrB   rA   r   ÚconfigFilePathÚexistsÚopenr4   ÚjsonÚloadsÚreadr   ÚinstanceÚrelationManagerÚbodyÚdatar8   rO   Ú	Exceptionr   ÚosÚgetenvÚlog_exceptionrD   Úlenr:   r   ÚappendScoper   ÚglobalScopeÚprojectScoper   ÚsetSourceCrsr   ÚcrsÚtransformContextÚsetEllipsoidÚ	ellipsoidÚ
layerScoper   r   ÚprimaryKeyAttributesÚfieldsr   r
   ÚsetFlagsÚ
NoGeometryr   ÚgetFeaturesÚnextFeatureÚ
getFeatureÚintÚisValidr@   r   Ú
setFeatureÚ	setFieldsÚreplaceExpressionTextr   r   r=   ÚclearÚsetResponseHeaderÚ
appendBodyÚbytes)ÚselfÚloggerÚrequestÚparamsZproject_pathÚconfig_pathÚcfg_filerJ   rK   rL   r.   rM   ÚeÚexp_contextrV   Zdistance_arear   Zexpression_requestr%   r+   r&   r&   r'   ÚresponseComplete   sö    ÿÿ
ÿÿ
ÿÿ
ÿÿ
ÿ ÿÿ
  ÿ
 þÿ
 þÿ ÿÿÿ
ÿ
z%GetFeatureInfoFilter.responseComplete)Ú__name__Ú
__module__Ú__qualname__Úclassmethodr4   r   r   r(   r   r{   r=   r   r   rO   r   rŒ   r&   r&   r&   r'   r   %   s   $ 4r   ))Ú__copyright__Ú__license__Ú	__email__r_   rg   Zxml.etree.ElementTreeÚetreeZElementTreer    Úcollectionsr   Úpathlibr   Útypingr   r   r   r   Ú	qgis.corer   r	   r
   r   r   r   r   r   Úqgis.serverr   Úlizmap.server.corer   r   Úlizmap.server.loggerr   r   Úlizmap.server.toolsr   Zlizmap.tooltipr   r   r   r&   r&   r&   r'   Ú<module>   s    (
