
    i8)                        U g d 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mZ ddlmZ ej                  rddlmZ ddlmZmZmZ ddlZ ej.                  d      Zej2                  ed	<   e G d
 d             Z ej8                  d      Z G d dej<                        Ze G d d             Z  G d d      Z!y))
PluginInfoPlugin	PluginCfgPluginStorage    N)	Generator)	dataclassfield)SXNG_Request)SearchWithPlugins)ResultEngineResultsLegacyResultzsearx.pluginslogc                       e Zd ZU dZeed<   	 eed<   	 eed<   	 dZej                  d   dz  ed<   	  e	e
	      Ze
e   ed
<   	  e	e
	      Ze
e   ed<   y)r   a  Object that holds information about a *plugin*, these infos are shown to
    the user in the Preferences menu.

    To be able to translate the information into other languages, the text must
    be written in English and translated with :py:obj:`flask_babel.gettext`.
    idnamedescriptiongeneral)r   uiprivacyqueryNpreference_section)default_factoryexampleskeywords)__name__
__module____qualname____doc__str__annotations__r   tLiteralr	   listr   r        $/root/searxng/searx/plugins/_core.pyr   r      so     	G.
I.PY		"EFMY
  5Hd3i5?5Hd3i5'r&   r   z[a-z][a-z0-9].*c                   (    e Zd ZU dZdZeed<   	 ej                  e	   ed<   	 g Z
ee   ed<   	 ej                  ed<   	 eed<   	 dZeed<   d fd
Zd	efdZdej&                  fdZddd	e	fdZdeddd	e	fdZdeddddd	e	fdZdeddd	dfdZ xZS )r   z#Abstract base class of all Plugins. r   activer   r   infofqnreturnc                 b   t         |           | j                  s(| j                  j                  d   j
                  | _        |j                  j                         D ]  \  }}t        | ||        dD ]   }t        | |d       t        d|  d|        t        j                  | j                        st        d| j                   d      t        | dd       sSt        j                   | j                        j"                  }t%        j&                  | d| j                         | _        y y )	Nr   r   plugin z is missing attribute z
plugin ID z1 contains invalid character (use lowercase ASCII)r   .)super__init__r,   	__class____mro__r   __dict__itemssetattrgetattrNotImplementedErrorID_REGXPmatchr   
ValueErrorinspect	getmodule__package__logging	getLoggerr   )selfplg_cfgnvattrpkg_namer4   s         r'   r3   zPlugin.__init__\   s   xx~~--a0;;DH $$**, 	 DAqD!Q	 
 	XD tT4(0)GD69OPTv*VWW		X ~~dgg&z$''2cdeetUD)((8DDH((H:Qtwwi)@ADH *r&   c                     t        |       S )a	  The hash value is used in :py:obj:`set`, for example, when an object
        is added to the set.  The hash value is also used in other contexts,
        e.g. when checking for equality to identify identical plugins from
        different sources (name collisions).r/   rC   s    r'   __hash__zPlugin.__hash__s   s     $xr&   otherc                 0    t        |       t        |      k(  S )zZpy:obj:`Plugin` objects are equal if the hash values of the two
        objects are equal.)hash)rC   rL   s     r'   __eq__zPlugin.__eq__{   s     DzT%[((r&   appflask.Flaskc                      y)ax  Initialization of the plugin, the return value decides whether this
        plugin is active or not.  Initialization only takes place once, at the
        time the WEB application is set up.  The base method always returns
        ``True``, the method can be overwritten in the inheritances,

        - ``True`` plugin is active
        - ``False`` plugin is inactive
        Tr%   )rC   rP   s     r'   initzPlugin.init   s     r&   requestsearchr   c                      y)zRuns BEFORE the search request and returns a boolean:

        - ``True`` to continue the search
        - ``False`` to stop the search
        Tr%   rC   rT   rU   s      r'   
pre_searchzPlugin.pre_search   s     r&   resultr   c                      y)a  Runs for each result of each engine and returns a boolean:

        - ``True`` to keep the result
        - ``False`` to remove the result from the result list

        The ``result`` can be modified to the needs.

        .. hint::

           If :py:obj:`Result.url <searx.result_types._base.Result.url>` is modified,
           :py:obj:`Result.parsed_url <searx.result_types._base.Result.parsed_url>` must
           be changed accordingly:

           .. code:: python

              result["parsed_url"] = urlparse(result["url"])
        Tr%   )rC   rT   rU   rY   s       r'   	on_resultzPlugin.on_result   s    $ r&   z2None | list[Result | LegacyResult] | EngineResultsc                      y)zRuns AFTER the search request.  Can return a list of
        :py:obj:`Result <searx.result_types._base.Result>` objects to be added to the
        final result list.Nr%   rW   s      r'   post_searchzPlugin.post_search   s     	r&   )rD   r   r-   N)r   r   r   r   r   r    r!   r"   ClassVarboolr   r$   rA   Loggerr   r,   r3   intrK   AnyrO   rS   r
   rX   r[   r]   __classcell__)r4   s   @r'   r   r   D   s    -BL+JJtMHd3i/
 
9 CCMB.# )AEE )	 	$ 	, 8K PT  7J T\ ae (#-@	=r&   r   c                        e Zd ZU dZdZeed<   y)r   ziSettings of a plugin.

    .. code:: yaml

       mypackage.mymodule.MyPlugin:
         active: true
    Fr*   N)r   r   r   r   r*   r_   r!   r%   r&   r'   r   r      s     FDTr&   r   c                       e Zd ZU dZee   ed<   	 d Zdee   fdZ	d Z
edee   fd       Zdeeeeej$                  f   f   fd	Zd
efdZddZdedddefdZdedddddefdZdeddddfdZy)r   z0A storage for managing the *plugins* of SearXNG.plugin_listc                 "    t               | _        y N)setrf   rJ   s    r'   r3   zPluginStorage.__init__   s    5r&   r-   c              #   8   K   | j                   E d {    y 7 wrh   )rf   rJ   s    r'   __iter__zPluginStorage.__iter__   s     ####s   c                 ,    t        | j                        S rh   )lenrf   rJ   s    r'   __len__zPluginStorage.__len__   s    4##$$r&   c                 T    | j                   D cg c]  }|j                   c}S c c}w rh   )rf   r+   )rC   ps     r'   r+   zPluginStorage.info   s"     !% 0 011111s   %cfgc                 h   |j                         D ]t  \  }}d}|j                  dd      \  }}	 t        j                  |      }t	        ||d      }|d| d}	t        |	       |t        di |      }
| j                  |
       v y# t
        $ r}t        j                  |       Y d}~[d}~ww xY w)zNLoad plugins configured in SearXNG's settings :ref:`settings
        plugins`.Nr1      r0   z is not implementedr%   )r7   rsplit	importlibimport_moduler9   	Exceptionr   	exceptionr=   r   register)rC   rq   r,   plg_settingsclsmod_namecls_namemodexcmsgplgs              r'   load_settingszPluginStorage.load_settings   s     "% 	CC!$C!3Hh#--h7c8T2 {u$78 o%i/,/0CMM#	  #c""#s   "B			B1B,,B1pluginc                 2   || j                   D cg c]  }|j                   c}v r6d|j                   d}|j                  j                  |       t	        |      | j                   j                  |       |j                  j                  d       yc c}w )zRegister a :py:obj:`Plugin`.  In case of name collision (if two
        plugins have same ID) a :py:obj:`KeyError` exception is raised.
        zname collision ''zplugin has been loadedN)rf   r   r   criticalKeyErroradddebug)rC   r   rp   r   s       r'   ry   zPluginStorage.register   s{    
 D$4$45qadd55$VYYKq1CJJ$3-V$

12 6s   BNc                     | j                   j                         D ]/  }|j                  |      r| j                   j                  |       1 y)zCalls the method :py:obj:`Plugin.init` of each plugin in this
        storage.  Depending on its return value, the plugin is removed from
        *this* storage or not.N)rf   copyrS   remove)rC   rP   r   s      r'   rS   zPluginStorage.init   sA    
 ##((* 	-C88C=  '',	-r&   rT   rU   r   c                    d}| j                   D cg c]  }|j                  |j                  v s| c}D ]$  }	 t        |j	                  ||            }|r# |S  |S c c}w # t
        $ r |j                  j                  d       Y Tw xY w)NTrT   rU   z"Exception while calling pre_search)rf   r   user_pluginsr_   rX   rw   r   rx   )rC   rT   rU   retrp   r   s         r'   rX   zPluginStorage.pre_search   s    "&"2"2RQaddf>Q>Q6QqR 	F6,,WV,LM 
	 
 S  

$$%IJs   AAA$$$B
BrY   r   c                    d}| j                   D cg c]  }|j                  |j                  v s| c}D ]%  }	 t        |j	                  |||            }|r$ |S  |S c c}w # t
        $ r |j                  j                  d       Y Uw xY w)NT)rT   rU   rY   z!Exception while calling on_result)rf   r   r   r_   r[   rw   r   rx   )rC   rT   rU   rY   r   rp   r   s          r'   r[   zPluginStorage.on_result  s    "&"2"2RQaddf>Q>Q6QqR 	F6++GFSY+Z[ 
	 
 S  

$$%HIs   A A A%%$BBc                    d}|j                   j                  j                         D ]  }|s n | j                  D cg c]  }|j                  |j
                  v s| c}D ]`  }|j                  r|r||j                  vr 	 |j                  ||      xs g }|j                  j                  d|j                   |       b yc c}w # t        $ r |j                  j                  d       Y w xY w)zExtend :py:obj:`search.result_container
        <searx.results.ResultContainer`> with result items from plugins listed
        in :py:obj:`search.user_plugins <SearchWithPlugins.user_plugins>`.
        Nr   z#Exception while calling post_searchzplugin: )search_queryr   splitrf   r   r   r   r]   rw   r   rx   result_containerextend)rC   rT   rU   keywordrp   r   resultss          r'   r]   zPluginStorage.post_search  s     **00668 	G	 #'"2"2RQaddf>Q>Q6QqR 	LFwfoo= ,,WV,LRPR ##**Xfii[+A7K	LR  

$$%JKs   CCC$C32C3)rP   rQ   r-   N)r   r   r   r   ri   r   r!   r3   r   rk   rn   propertyr$   r   r+   dictr    r"   rb   r   ry   rS   r
   r_   rX   r[   r]   r%   r&   r'   r   r      s    :V8!$)F+ $% 2d:& 2 2c4QUU
+;&;!< &3v 3-, 8K PT  7J T\ ae L< L9L LQU Lr&   r   )"__all__abcru   r>   rA   retypingr"   collections.abcr   dataclassesr   r	   searx.extended_typesr
   TYPE_CHECKINGsearx.searchr   searx.result_typesr   r   r   flaskrB   r   r`   r!   r   compiler;   ABCr   r   r   r%   r&   r'   <module>r      s    A
@ 
    	  % ( -??.FF'g''8W^^ 8 "( "( "(J 2::'(kSWW k\ 
U 
U 
UrL rLr&   