
    ^i#                         S r SSKrSSKrSSKJrJr  SSKJr  SSKJrJ	r	  SSK
Jr  SSKJrJr  SS	KJr  SS
KJr  SSKJrJr  SSKJr  SSKJr  SSKJr  \R8                  " \5      r " S S5      rg)zDDGS class implementation.    N)ThreadPoolExecutorwait)ceil)randomshuffle)TracebackType)AnyClassVar   )BaseSearchEngine)ENGINES)DDGSExceptionTimeoutException)ResultsAggregator)SimpleFilterRanker)_expand_proxy_tb_aliasc                   4   \ rS rSr% SrSr\\S-     \S'   Sr	\\
S-     \S'   S+SS.S\S-  S	\S-  S
\\-  SS4S jjjrS,S jr   S-S\\   S-  S\S-  S\S-  SS4S jjr\S\
4S j5       rS\S\S\\\      4S jr S.SSSSSSS.S\S\S\S-  S\S\S \S-  S!\S-  S"\S\S#\S\\\\4      4S$ jjjrS\S#\S\\\\4      4S% jrS\S#\S\\\\4      4S& jrS\S#\S\\\\4      4S' jrS\S#\S\\\\4      4S( jrS\S#\S\\\\4      4S) jrS*r g)/DDGS   a{  DDGS | Dux Distributed Global Search.

A metasearch library that aggregates results from diverse web search services.

Args:
    proxy: The proxy to use for the search. Defaults to None.
    timeout: The timeout for the search. Defaults to 5.
    verify: bool (True to verify, False to skip) or str path to a PEM file. Defaults to True.

Attributes:
    threads: The number of threads to use for the search. Defaults to None (automatic).
    _executor: The ThreadPoolExecutor instance.

Raises:
    DDGSException: If an error occurs during the search.

Example:
    >>> from ddgs import DDGS
    >>> results = DDGS().search("python")

Nthreads	_executorT)verifyproxytimeoutr   returnc                    [        U5      =(       d    [        R                  R                  S5      U l        X l        X0l        0 U l        g )N
DDGS_PROXY)r   osenvironget_proxy_timeout_verify_engines_cache)selfr   r   r   s       C/home/james-whalen/.local/lib/python3.13/site-packages/ddgs/ddgs.py__init__DDGS.__init__/   s7    ,U3Srzz~~l7S  	    c                     U $ )z7Enter the context manager and return the DDGS instance. )r%   s    r&   	__enter__DDGS.__enter__7   s    r)   exc_typeexc_valexc_tbc                     g)zExit the context manager.Nr+   )r%   r.   r/   r0   s       r&   __exit__DDGS.__exit__;   s    r)   c                 f    U R                   c  [        U R                  SS9U l         U R                   $ )z/Get a ThreadPoolExecutor instance and cache it.r   )max_workersthread_name_prefix)r   r   r   )clss    r&   get_executorDDGS.get_executorC   s+     == .3;;[abCM}}r)   categorybackendc           
         [        U[        5      (       a  SR                  U5      nUR                  S5       Vs/ s H  o3R	                  5       PM     nn[        [
        U   R                  5       5      n[        U5        SU;   d  SU;   a'  UnUS:X  a  S/U Vs/ s H  owS:w  d  M
  UPM     sn-   nOUn U Vs/ s H  n[
        U   U   PM     nn/ n	U Hw  n
XR                  ;   a   U	R                  U R                  U
   5        M2  U
" U R                  U R                  U R                  S9nXR                  U
'   U	R                  U5        My     U	R                  S SS	9  U	$ s  snf s  snf s  snf ! [         aK  n[        R!                  S
USR                  [#        U5      5      5        U R%                  US5      s SnA$ SnAff = f)a~  Retrieve a list of search engine instances for a given category and backend.

Args:
    category: The category of search engines (e.g., 'text', 'images', etc.).
    backend: A single or comma-delimited backends. Defaults to "auto".

Returns:
    A list of initialized search engine instances corresponding to the specified
    category and backend. Instances are cached for reuse.

,autoalltext	wikipedia)r   r   r   c                 &    U R                   [        4$ N)priorityr   )es    r&   <lambda>#DDGS._get_engines.<locals>.<lambda>v   s    !**f)=r)   T)keyreversezB%r - backend is not exist or disabled. Available: %s. Using 'auto'z, N)
isinstancelistjoinsplitstripr   keysr   r$   appendr!   r"   r#   sortKeyErrorloggerwarningsorted_get_engines)r%   r:   r;   xbackend_listengine_keysrO   rH   engine_classes	instancesengine_classengine_instanceexs                r&   rV   DDGS._get_enginesJ   s     gt$$hhw'G+2==+=>+=a	+=>78,1134\!Ul%:D6!#}t'Rtk?Qt'RRD	@DEgh/4NEI .#6#66$$T%8%8%FG '3dmmdhdpdp&qO8G''5$$_5 !/ NN=tNL G ? (S
 F  	7NNT		&-.
 $$Xv66	7sC   E$	E)'E)6E3 :E.BE3 .E3 3
G=A G=GGzus-enmoderate
   r   r>   )region
safesearch	timelimitmax_resultspager;   querykeywordsrb   rc   rd   re   rf   kwargsc          	         U=(       d    UnU(       d  Sn[        U5      eU R                  X5      n[        U Vs1 s H  oR                  iM     sn5      n[	        5       n[        1 Sk5      nU(       a  [        U[        US-  5      S-   5      OUnU R                  5       n0 Snn[        USS9 GH  u  nnUR                  U;   a  M  UR                  " UR                  U4UUUUS.U
D6nUUU'   [        U5      U:  d  UU:  a  [        UU R                  SS	9u  nnUR                  5        HT  u  nnUU;   d  M   UR                  5       =n(       a.  UR!                  U5        UR#                  UR                  5        MT  MV     U Vs0 s H	  nUUU   _M     nnU(       d  M  [        U5      U:  d  GM    O   UR-                  5       n[/        5       nUR1                  UU5      nU(       a  U(       a  USU $ U$ SU ;   a  [3        U5      e[        U=(       d    S5      es  snf ! [$         a/  nUn[&        R)                  S
UR*                  U5         SnAGM-  SnAff = fs  snf )a  Perform a search across engines in the given category.

Args:
    category: The category of search engines (e.g., 'text', 'images', etc.).
    query: The search query.
    keywords: Deprecated alias for `query`.
    region: The region to use for the search (e.g., us-en, uk-en, ru-ru, etc.).
    safesearch: The safesearch setting (e.g., on, moderate, off).
    timelimit: The timelimit for the search (e.g., d, w, m, y) or custom date range.
    max_results: The maximum number of results to return. Defaults to 10.
    page: The page of results to return. Defaults to 1.
    backend: A single or comma-delimited backends. Defaults to "auto".
    **kwargs: Additional keyword arguments to pass to the search engines.

Returns:
    A list of dictionaries containing the search results.

zquery is mandatory.>   urlhrefimage	embed_urlra   r   N)start)rb   rc   rd   rf   FIRST_EXCEPTION)r   return_whenzError in engine %s: %rz	timed outzNo results found.)r   rV   lenprovidersetr   minr   r8   	enumeratesubmitsearchr   r"   itemsresultextendadd	ExceptionrS   infonameextract_dictsr   rankr   )r%   r:   rg   rh   rb   rc   rd   re   rf   r;   ri   msgenginesenginelen_unique_providersseen_providersresults_aggregatorr5   executorfutureserrifuturedonenot_doneff_enginerr^   resultsrankers                                  r&   _searchDDGS._search   sU   @ !E'C$$##H6"'#J'OO'#JK#&5 ;LLq:rOZc.[25E0F0JK`t$$&4"7!4IAv.0__ %# F %GFO7|{*a;.>!%gt}}Rc!dh#*==?KAxDyS$%HHJq 2 9 9! < . 2 283D3D E  / $3 3;;(Q1gaj=(;{s#56+E9 5< %224#%++gu-,77<K(DWDSE""3''C6#677a $K<  ) S"$C"KK(@&++rRRS <s$   H!<AH&	I"&
I0#IIc                 *    U R                   " SU40 UD6$ )zPerform a text search.r@   r   r%   rg   ri   s      r&   r@   	DDGS.text       ||FE4V44r)   c                 *    U R                   " SU40 UD6$ )zPerform an image search.imagesr   r   s      r&   r   DDGS.images       ||He6v66r)   c                 *    U R                   " SU40 UD6$ )zPerform a news search.newsr   r   s      r&   r   	DDGS.news   r   r)   c                 *    U R                   " SU40 UD6$ )zPerform a video search.videosr   r   s      r&   r   DDGS.videos   r   r)   c                 *    U R                   " SU40 UD6$ )zPerform a book search.booksr   r   s      r&   r   
DDGS.books   s    ||GU5f55r)   )r$   r!   r"   r#   )N   )r   r   )NNNrC   )!__name__
__module____qualname____firstlineno____doc__r   r
   int__annotations__r   r   strboolr'   r,   typeBaseExceptionr   r2   classmethodr8   rK   r   r	   rV   dictr   r@   r   r   r   r   __static_attributes__r+   r)   r&   r   r      s{   , %)GXcDj!(59Ix*T129bf cDj #* UY\_U_ ko  04(,'+	(}%,( %( $	(
 
( /  55 5 
s#	$	5v  $	V8 $ $"$V8V8 V8 *	V8 V8 V8 :V8 4ZV8 V8 V8 V8 
d38n	V8p5# 5 5d38n1E 57C 73 74S#X3G 75# 5 5d38n1E 57C 73 74S#X3G 763 6# 6$tCH~2F 6r)   r   ) r   loggingr   concurrent.futuresr   r   mathr   r   r   typesr   typingr	   r
   baser   r   r   
exceptionsr   r   r   r   
similarityr   utilsr   	getLoggerr   rS   r   r+   r)   r&   <module>r      sK       	 7  "    "  7 & * )			8	$V6 V6r)   