.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.engines.mullvad_leta Namespace Reference

Functions

bool is_vpn_connected (html.HtmlElement dom)
 
dict assign_headers (dict headers)
 
 request (str query, dict params)
 
 extract_result (list[html.HtmlElement] dom_result)
 
 extract_results (html.HtmlElement search_results)
 
 response (Response resp)
 
 fetch_traits (EngineTraits engine_traits)
 

Variables

 logger = logging.getLogger()
 
bool use_cache = True
 
str leta_engine = 'google'
 
str search_url = "https://leta.mullvad.net"
 
dict about
 
list categories = ['general', 'web']
 
bool paging = True
 
int max_page = 50
 
bool time_range_support = True
 
dict time_range_dict
 
list available_leta_engines
 

Detailed Description

This is the implementation of the Mullvad-Leta meta-search engine.

This engine **REQUIRES** that searxng operate within a Mullvad VPN

If using docker, consider using gluetun for easily connecting to the Mullvad

- https://github.com/qdm12/gluetun

Otherwise, follow instructions provided by Mullvad for enabling the VPN on Linux

- https://mullvad.net/en/help/install-mullvad-app-linux

.. hint::

   The :py:obj:`EngineTraits` is empty by default.  Maintainers have to run
   ``make data.traits`` (in the Mullvad VPN / :py:obj:`fetch_traits`) and rebase
   the modified JSON file ``searx/data/engine_traits.json`` on every single
   update of SearXNG!

Function Documentation

◆ assign_headers()

dict searx.engines.mullvad_leta.assign_headers ( dict headers)
Assigns the headers to make a request to Mullvad Leta

Definition at line 80 of file mullvad_leta.py.

80def assign_headers(headers: dict) -> dict:
81 """Assigns the headers to make a request to Mullvad Leta"""
82 headers['Accept'] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
83 headers['Content-Type'] = "application/x-www-form-urlencoded"
84 headers['Host'] = "leta.mullvad.net"
85 headers['Origin'] = "https://leta.mullvad.net"
86 return headers
87
88

Referenced by searx.engines.mullvad_leta.fetch_traits(), and searx.engines.mullvad_leta.request().

+ Here is the caller graph for this function:

◆ extract_result()

searx.engines.mullvad_leta.extract_result ( list[html.HtmlElement] dom_result)

Definition at line 130 of file mullvad_leta.py.

130def extract_result(dom_result: list[html.HtmlElement]):
131 # Infoboxes sometimes appear in the beginning and will have a length of 0
132 if len(dom_result) == 3:
133 [a_elem, h3_elem, p_elem] = dom_result
134 elif len(dom_result) == 4:
135 [_, a_elem, h3_elem, p_elem] = dom_result
136 else:
137 return None
138
139 return {
140 'url': extract_text(a_elem.text),
141 'title': extract_text(h3_elem),
142 'content': extract_text(p_elem),
143 }
144
145

Referenced by searx.engines.mullvad_leta.extract_results().

+ Here is the caller graph for this function:

◆ extract_results()

searx.engines.mullvad_leta.extract_results ( html.HtmlElement search_results)

Definition at line 146 of file mullvad_leta.py.

146def extract_results(search_results: html.HtmlElement):
147 for search_result in search_results:
148 dom_result = eval_xpath_list(search_result, 'div/div/*')
149 result = extract_result(dom_result)
150 if result is not None:
151 yield result
152
153

References searx.engines.mullvad_leta.extract_result().

Referenced by searx.engines.mullvad_leta.response().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fetch_traits()

searx.engines.mullvad_leta.fetch_traits ( EngineTraits engine_traits)
Fetch languages and regions from Mullvad-Leta

.. warning::

    Fetching the engine traits also requires a Mullvad VPN connection. If
    not connected, then an error message will print and no traits will be
    updated.

Definition at line 165 of file mullvad_leta.py.

165def fetch_traits(engine_traits: EngineTraits):
166 """Fetch languages and regions from Mullvad-Leta
167
168 .. warning::
169
170 Fetching the engine traits also requires a Mullvad VPN connection. If
171 not connected, then an error message will print and no traits will be
172 updated.
173 """
174 # pylint: disable=import-outside-toplevel
175 # see https://github.com/searxng/searxng/issues/762
176 from searx.network import post as http_post
177
178 # pylint: enable=import-outside-toplevel
179 resp = http_post(search_url, headers=assign_headers({}))
180 if not isinstance(resp, Response):
181 print("ERROR: failed to get response from mullvad-leta. Are you connected to the VPN?")
182 return
183 if not resp.ok:
184 print("ERROR: response from mullvad-leta is not OK. Are you connected to the VPN?")
185 return
186 dom = html.fromstring(resp.text)
187 if not is_vpn_connected(dom):
188 print('ERROR: Not connected to Mullvad VPN')
189 return
190 # supported region codes
191 options = eval_xpath_list(dom.body, '//main/div/form/div[2]/div/select[1]/option')
192 if options is None or len(options) <= 0:
193 print('ERROR: could not find any results. Are you connected to the VPN?')
194 for x in options:
195 eng_country = x.get("value")
196
197 sxng_locales = get_official_locales(eng_country, engine_traits.languages.keys(), regional=True)
198
199 if not sxng_locales:
200 print(
201 "ERROR: can't map from Mullvad-Leta country %s (%s) to a babel region."
202 % (x.get('data-name'), eng_country)
203 )
204 continue
205
206 for sxng_locale in sxng_locales:
207 engine_traits.regions[region_tag(sxng_locale)] = eng_country

References searx.engines.mullvad_leta.assign_headers(), and searx.engines.mullvad_leta.is_vpn_connected().

+ Here is the call graph for this function:

◆ is_vpn_connected()

bool searx.engines.mullvad_leta.is_vpn_connected ( html.HtmlElement dom)
Returns true if the VPN is connected, False otherwise

Definition at line 74 of file mullvad_leta.py.

74def is_vpn_connected(dom: html.HtmlElement) -> bool:
75 """Returns true if the VPN is connected, False otherwise"""
76 connected_text = extract_text(eval_xpath(dom, '//main/div/p[1]'))
77 return connected_text != 'You are not connected to Mullvad VPN.'
78
79

Referenced by searx.engines.mullvad_leta.fetch_traits(), and searx.engines.mullvad_leta.response().

+ Here is the caller graph for this function:

◆ request()

searx.engines.mullvad_leta.request ( str query,
dict params )

Definition at line 89 of file mullvad_leta.py.

89def request(query: str, params: dict):
90 country = traits.get_region(params.get('searxng_locale', 'all'), traits.all_locale) # type: ignore
91
92 result_engine = leta_engine
93 if leta_engine not in available_leta_engines:
94 result_engine = available_leta_engines[0]
95 logger.warning(
96 'Configured engine "%s" not one of the available engines %s, defaulting to "%s"',
97 leta_engine,
98 available_leta_engines,
99 result_engine,
100 )
101
102 params['url'] = search_url
103 params['method'] = 'POST'
104 params['data'] = {
105 "q": query,
106 "gl": country if country is str else '',
107 'engine': result_engine,
108 }
109 # pylint: disable=undefined-variable
110 if use_cache:
111 params['data']['oc'] = "on"
112 # pylint: enable=undefined-variable
113
114 if params['time_range'] in time_range_dict:
115 params['dateRestrict'] = time_range_dict[params['time_range']]
116 else:
117 params['dateRestrict'] = ''
118
119 if params['pageno'] > 1:
120 # Page 1 is n/a, Page 2 is 11, page 3 is 21, ...
121 params['data']['start'] = ''.join([str(params['pageno'] - 1), "1"])
122
123 if params['headers'] is None:
124 params['headers'] = {}
125
126 assign_headers(params['headers'])
127 return params
128
129

References searx.engines.mullvad_leta.assign_headers().

+ Here is the call graph for this function:

◆ response()

searx.engines.mullvad_leta.response ( Response resp)
Checks if connected to Mullvad VPN, then extracts the search results from
the DOM resp: requests response object

Definition at line 154 of file mullvad_leta.py.

154def response(resp: Response):
155 """Checks if connected to Mullvad VPN, then extracts the search results from
156 the DOM resp: requests response object"""
157
158 dom = html.fromstring(resp.text)
159 if not is_vpn_connected(dom):
160 raise SearxEngineResponseException('Not connected to Mullvad VPN')
161 search_results = eval_xpath(dom.body, '//main/div[2]/div')
162 return list(extract_results(search_results))
163
164

References searx.engines.mullvad_leta.extract_results(), and searx.engines.mullvad_leta.is_vpn_connected().

+ Here is the call graph for this function:

Variable Documentation

◆ about

dict searx.engines.mullvad_leta.about
Initial value:
1= {
2 "website": search_url,
3 "wikidata_id": 'Q47008412', # the Mullvad id - not leta, but related
4 "official_api_documentation": 'https://leta.mullvad.net/faq',
5 "use_official_api": False,
6 "require_api_key": False,
7 "results": 'HTML',
8}

Definition at line 47 of file mullvad_leta.py.

◆ available_leta_engines

list searx.engines.mullvad_leta.available_leta_engines
Initial value:
1= [
2 'google', # first will be default if provided engine is invalid
3 'brave',
4]

Definition at line 68 of file mullvad_leta.py.

◆ categories

list searx.engines.mullvad_leta.categories = ['general', 'web']

Definition at line 57 of file mullvad_leta.py.

◆ leta_engine

str searx.engines.mullvad_leta.leta_engine = 'google'

Definition at line 42 of file mullvad_leta.py.

◆ logger

searx.engines.mullvad_leta.logger = logging.getLogger()

Definition at line 36 of file mullvad_leta.py.

◆ max_page

int searx.engines.mullvad_leta.max_page = 50

Definition at line 59 of file mullvad_leta.py.

◆ paging

bool searx.engines.mullvad_leta.paging = True

Definition at line 58 of file mullvad_leta.py.

◆ search_url

str searx.engines.mullvad_leta.search_url = "https://leta.mullvad.net"

Definition at line 44 of file mullvad_leta.py.

◆ time_range_dict

dict searx.engines.mullvad_leta.time_range_dict
Initial value:
1= {
2 "day": "d1",
3 "week": "w1",
4 "month": "m1",
5 "year": "y1",
6}

Definition at line 61 of file mullvad_leta.py.

◆ time_range_support

bool searx.engines.mullvad_leta.time_range_support = True

Definition at line 60 of file mullvad_leta.py.

◆ use_cache

bool searx.engines.mullvad_leta.use_cache = True

Definition at line 40 of file mullvad_leta.py.