
    i,                         d Z ddlmZmZ ddlmZ ddlm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mZmZ dd	lmZ dd
lmZmZmZmZ dddddddZg ZdZdZ	 dZ	 dZg dZdZ 	 dZ!	 d Z"d Z#d Z$d Z%defdZ&y)a  This engine uses the Qwant API (https://api.qwant.com/v3) to implement Qwant
-Web, -News, -Images and -Videos.  The API is undocumented but can be reverse
engineered by reading the network log of https://www.qwant.com/ queries.

For Qwant's *web-search* two alternatives are implemented:

- ``web``: uses the :py:obj:`api_url` which returns a JSON structure
- ``web-lite``: uses the :py:obj:`web_lite_url` which returns a HTML page


Configuration
=============

The engine has the following additional settings:

- :py:obj:`qwant_categ`

This implementation is used by different qwant engines in the :ref:`settings.yml
<settings engines>`:

.. code:: yaml

  - name: qwant
    qwant_categ: web-lite  # alternatively use 'web'
    ...
  - name: qwant news
    qwant_categ: news
    ...
  - name: qwant images
    qwant_categ: images
    ...
  - name: qwant videos
    qwant_categ: videos
    ...

Implementations
===============

    )datetime	timedelta)loads)	urlencodeN)gettext)EngineTraits) SearxEngineAccessDeniedExceptionSearxEngineAPIExceptionSearxEngineCaptchaException#SearxEngineTooManyRequestsException)raise_for_httperror)
eval_xpatheval_xpath_listextract_textget_embeded_stream_urlzhttps://www.qwant.com/	Q14657870TFJSON)websitewikidata_idofficial_api_documentationuse_official_apirequire_api_keyresults   )#ca_adca_esca_frco_frde_atde_chde_deen_auen_caen_gben_ieen_myen_nzen_uses_ades_ares_cles_coes_eses_mxes_peeu_eseu_frfc_cafr_adfr_befr_cafr_chfr_frit_chit_itnl_benl_nlpt_adpt_ptz https://api.qwant.com/v3/search/zhttps://lite.qwant.com/c                    | syt         j                  |d   d      }t        t         dz   }d| i}d|d<   t        d	k(  rIt        dz   }|j                         |d
<   |j                  d      d   |d<   |d   |d<   |d   |d<   d|d<   n_t        dk(  r)d|d<   ||d
<   |d   |d<   d|d<   |d   dz
  |d   z  |d<   n-d|d<   ||d
<   |d   |d<   d|d<   d|d<   |d   dz
  |d   z  |d<   |t        |      z   |d<   |S )zQwant search requestNsearxng_localeen_US)default?qFr   web-litelocale_r   l
safesearchspagenopTimages2   count   tgp   offset
   falsellmurl)traits
get_regionapi_urlqwant_categweb_lite_urllowersplitr   )queryparamsq_localerV   argss        $/root/searxng/searx/engines/qwant.pyrequestrc   n   s`      (8!97 KH
{m1%
%C<D$)F !j S !)XNN3'*S	<(S	8$S	(,$%		 W!X#L1\U *Q.$w-?X W!X#L1\UU *Q.$w-?X)D/)F5MM    c                 @    t         dk(  rt        |       S t        |       S )NrD   )rZ   parse_web_liteparse_web_api)resps    rb   responseri      s     j d##rd   c                 4   g }t         j                  j                  | j                        }t	        |d      D ]]  }t        |d      r|j                  t        t        |d            t        t        |d            t        t        |d            d       _ |S )zParse results from Qwant-Litez//section/articlez#./span[contains(@class, 'tooltip')]z'./span[contains(@class, 'url partner')]z./h2/az./p)rV   titlecontent)lxmlhtml
fromstringtextr   r   appendr   )rh   r   domitems       rb   rf   rf      s     G
))

tyy
)C%89 

dAB#Jt5^$_`%jx&@A'
4(?@	
	

 Nrd   c                 ~   g }	 t        | j                        }|j                  di       }|j                  d      dk7  r|j                  d      }|dk(  r
t	               |j                  di       j                  di       j                  d      
t               | j                  d	k(  r
t               d
j                  |j                  ddg            }t        | d| d      t        |        t        dk(  r3|j                  di       j                  di       j                  di       }n,|j                  di       j                  dg       }t        |dg}|sg S |D ]H  }|j                  dd      }|t        k7  r |dk(  r&|j                  dg       }	|	D ]  }
|
j                  dd      }|
j                  dd      }|dk(  r|
d   }|j                  |||d       H|dk(  rn|
d   }|t        j                  |      }|
j                  dg       }d}|r%|d   j                  di       j                  dd      }|j                  ||||d       |d k(  r>|
d!   }|
d   }|j                  ||d"|||
d#    d$|
d%    |
j                  d&      d'       |d(k(  s|
j                  d      |
j                  d)      |
j                  d*      }}}g }|r|j                  |       |r |j                  t        d+      d,|d-       |r |j                  t        d.      d,|d-       d/j                  |      }|
d0   }|t!        |1      }|
d   }|t        j                  |      }|
d!   }|j#                  d2d3d4      }|j                  |||t%        |      ||d5|d6        K |S # t        $ r i }Y w xY w)7zParse results from Qwant's APIdatastatussuccess
error_code   
error_data
captchaUrlNi  ,messageunknownz ()webresultitemsmainline)typer   r   adsrk   rV   desc)rk   rV   rl   newsdatemediar   pict)rk   rV   publishedDate	thumbnailrL   r   zimages.htmlwidthz x height
thumb_type)rk   rV   templatethumbnail_srcimg_src
resolution
img_formatvideossourcechannelSourcez:  Channelz // duration)millisecondszhttps://s2.qwant.comzhttps://s1.qwant.comrQ   zvideos.html)rk   rV   rl   
iframe_srcr   r   r   length)r   rp   
ValueErrorgetr   r   status_coder	   joinr
   r   rZ   rq   r   fromtimestampr   r   replacer   )rh   r   search_resultsru   rx   msgr   rowmainline_typemainline_itemsrs   rk   res_urlrl   pub_date
news_mediar   r   drI   ccontent_partsr   s                          rb   rg   rg      s    Gtyy) fb)D (#y0XXl+
577fb)--lB?CCLQ]-//s"244hhtxx	I;78%R
|1&=>> e 88Hb)--gr:>>z2N
 88Hb)--gr: 84

 	 Z.K'E!"-" P	DHHWd+Ehhud+G%v,!&&#* &(<''55h?H!XXgr2
 	 *1 1 1&" = A A% NI!&&)1%.	 (* -	w-!&&$1)2#*)-gs4>:J&K&*hh|&<
 (* ((6*DHHX,>@Sa1 "!((+!((gh6G)KL!((gi6H!)LM ++m4j)%&F;F<''55h?H -	 &--.DF\^_`	!&&#*&<W&E)1%.$1"(	KP	Zx NE  s   N- -N<;N<engine_traitsc           	         ddl m} ddlm} ddlm}  |t        d   d      }|j                  st        d       ||j                  d	d
      }t        |      }|j                  d      }t               }|j                         D ]S  \  }	}
|
d   D ]F  }dj                  ||	      }t        dk(  r|j                         t         vr6|j#                  |       H U |D ]p  }	  |t$        j&                  j)                  |d            }| j.                  j                  |      }|r||k7  rt-        d|d|d|       b|| j.                  |<   r y # t$        j*                  $ r t-        d|z         Y w xY w)Nr   )
region_tag)r   )extrr   r   )timeoutzResponse from Qwant is not OK.zINITIAL_PROPS = z	</script>localeslangsz{lang}_{country})langcountryr   rF   )sepz8ERROR: can't determine babel locale of quant's locale %szCONFLICT: babel z --> z, )searx.localesr   searx.networkr   searx.utilsr   aboutokRuntimeErrorrp   r   setr   formatrZ   r\   qwant_news_localesaddbabelLocaleparseUnknownLocaleErrorprintregions)r   r   r   r   rh   json_stringq_initial_props	q_localeseng_tag_listr   vr   _localeeng_tagsxng_tagconflicts                   rb   fetch_traitsr   A  su    )! iD 77;<<tyy"4kBKK(O##I.I5Loo' &
gJ 	&D(//T7/KGf$@R)RW%	&&   2	!%,,"4"4W#"4"FGH
 !((,,X67"8WUV*1h'2 '' 	LwVW	s   !'E!E54E5)'__doc__r   r   jsonr   urllib.parser   r   rm   flask_babelr   searx.enginelib.traitsr   searx.exceptionsr	   r
   r   r   r   r   r   r   r   r   r   r   
categoriespagingmax_pagerZ   rH   r   rY   r[   rc   ri   rf   rg   r    rd   rb   <module>r      s   &P  "    /  .  ("&	 
	  J
  - ( &R*K\*2 *2rd   