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

Functions

 init (_)
 
list[str] server_list ()
 
 request (query, params)
 
 response (resp)
 
 fetch_traits (EngineTraits engine_traits)
 

Variables

 logger = logging.getLogger()
 
dict about
 
bool paging = True
 
list categories = ['music', 'radio']
 
int number_of_results = 10
 
list station_filters = []
 

Detailed Description

Search radio stations from RadioBrowser by `Advanced station search API`_.

.. _Advanced station search API:
   https://de1.api.radio-browser.info/#Advanced_station_search

Function Documentation

◆ fetch_traits()

searx.engines.radio_browser.fetch_traits ( EngineTraits engine_traits)
Fetch languages and countrycodes from RadioBrowser

- ``traits.languages``: `list of languages API`_
- ``traits.custom['countrycodes']``: `list of countries API`_

.. _list of countries API: https://de1.api.radio-browser.info/#List_of_countries
.. _list of languages API: https://de1.api.radio-browser.info/#List_of_languages

Definition at line 175 of file radio_browser.py.

175def fetch_traits(engine_traits: EngineTraits):
176 """Fetch languages and countrycodes from RadioBrowser
177
178 - ``traits.languages``: `list of languages API`_
179 - ``traits.custom['countrycodes']``: `list of countries API`_
180
181 .. _list of countries API: https://de1.api.radio-browser.info/#List_of_countries
182 .. _list of languages API: https://de1.api.radio-browser.info/#List_of_languages
183 """
184 # pylint: disable=import-outside-toplevel
185
186 init(None)
187 from babel.core import get_global
188
189 babel_reg_list = get_global("territory_languages").keys()
190
191 server = server_list()[0]
192 language_list = get(f'{server}/json/languages').json() # type: ignore
193 country_list = get(f'{server}/json/countries').json() # type: ignore
194
195 for lang in language_list:
196
197 babel_lang = lang.get('iso_639')
198 if not babel_lang:
199 # the language doesn't have any iso code, and hence can't be parsed
200 # print(f"ERROR: lang - no iso code in {lang}")
201 continue
202 try:
203 sxng_tag = language_tag(babel.Locale.parse(babel_lang, sep="-"))
204 except babel.UnknownLocaleError:
205 # print(f"ERROR: language tag {babel_lang} is unknown by babel")
206 continue
207
208 eng_tag = lang['name']
209 conflict = engine_traits.languages.get(sxng_tag)
210 if conflict:
211 if conflict != eng_tag:
212 print("CONFLICT: babel %s --> %s, %s" % (sxng_tag, conflict, eng_tag))
213 continue
214 engine_traits.languages[sxng_tag] = eng_tag
215
216 countrycodes = set()
217 for region in country_list:
218 # country_list contains duplicates that differ only in upper/lower case
219 _reg = region['iso_3166_1'].upper()
220 if _reg not in babel_reg_list:
221 print(f"ERROR: region tag {region['iso_3166_1']} is unknown by babel")
222 continue
223 countrycodes.add(_reg)
224
225 countrycodes = list(countrycodes)
226 countrycodes.sort()
227 engine_traits.custom['countrycodes'] = countrycodes

References init(), and server_list().

+ Here is the call graph for this function:

◆ init()

searx.engines.radio_browser.init ( _)

Definition at line 68 of file radio_browser.py.

68def init(_):
69 global CACHE # pylint: disable=global-statement
70 CACHE = EngineCache("radio_browser")
71 server_list()
72
73

References server_list().

Referenced by fetch_traits().

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

◆ request()

searx.engines.radio_browser.request ( query,
params )

Definition at line 95 of file radio_browser.py.

95def request(query, params):
96
97 servers = server_list()
98 if not servers:
99 logger.error("Fetched server list is empty!")
100 params["url"] = None
101 return
102
103 server = random.choice(servers)
104
105 args = {
106 'name': query,
107 'order': 'votes',
108 'offset': (params['pageno'] - 1) * number_of_results,
109 'limit': number_of_results,
110 'hidebroken': 'true',
111 'reverse': 'true',
112 }
113
114 if 'language' in station_filters:
115 lang = traits.get_language(params['searxng_locale']) # type: ignore
116 if lang:
117 args['language'] = lang
118
119 if 'countrycode' in station_filters:
120 if len(params['searxng_locale'].split('-')) > 1:
121 countrycode = params['searxng_locale'].split('-')[-1].upper()
122 if countrycode in traits.custom['countrycodes']: # type: ignore
123 args['countrycode'] = countrycode
124
125 params['url'] = f"{server}/json/stations/search?{urlencode(args)}"
126
127

References server_list().

+ Here is the call graph for this function:

◆ response()

searx.engines.radio_browser.response ( resp)

Definition at line 128 of file radio_browser.py.

128def response(resp):
129 results = []
130
131 json_resp = resp.json()
132
133 for result in json_resp:
134 url = result['homepage']
135 if not url:
136 url = result['url_resolved']
137
138 content = []
139 tags = ', '.join(result.get('tags', '').split(','))
140 if tags:
141 content.append(tags)
142 for x in ['state', 'country']:
143 v = result.get(x)
144 if v:
145 v = str(v).strip()
146 content.append(v)
147
148 metadata = []
149 codec = result.get('codec')
150 if codec and codec.lower() != 'unknown':
151 metadata.append(f'{codec} ' + gettext('radio'))
152 for x, y in [
153 (gettext('bitrate'), 'bitrate'),
154 (gettext('votes'), 'votes'),
155 (gettext('clicks'), 'clickcount'),
156 ]:
157 v = result.get(y)
158 if v:
159 v = str(v).strip()
160 metadata.append(f"{x} {v}")
161 results.append(
162 {
163 'url': url,
164 'title': result['name'],
165 'thumbnail': result.get('favicon', '').replace("http://", "https://"),
166 'content': ' | '.join(content),
167 'metadata': ' | '.join(metadata),
168 'iframe_src': result['url_resolved'].replace("http://", "https://"),
169 }
170 )
171
172 return results
173
174

◆ server_list()

list[str] searx.engines.radio_browser.server_list ( )

Definition at line 74 of file radio_browser.py.

74def server_list() -> list[str]:
75
76 servers = CACHE.get("servers", [])
77 if servers:
78 return servers
79
80 # hint: can take up to 40sec!
81 ips = socket.getaddrinfo("all.api.radio-browser.info", 80, 0, 0, socket.IPPROTO_TCP)
82 for ip_tuple in ips:
83 _ip: str = ip_tuple[4][0] # type: ignore
84 url = socket.gethostbyaddr(_ip)[0]
85 srv = "https://" + url
86 if srv not in servers:
87 servers.append(srv)
88
89 # update server list once in 24h
90 CACHE.set(key="servers", value=servers, expire=60 * 60 * 24)
91
92 return servers
93
94

Referenced by fetch_traits(), init(), and request().

+ Here is the caller graph for this function:

Variable Documentation

◆ about

dict searx.engines.radio_browser.about
Initial value:
1= {
2 "website": 'https://www.radio-browser.info/',
3 "wikidata_id": 'Q111664849',
4 "official_api_documentation": 'https://de1.api.radio-browser.info/',
5 "use_official_api": True,
6 "require_api_key": False,
7 "results": 'JSON',
8}

Definition at line 29 of file radio_browser.py.

◆ categories

list searx.engines.radio_browser.categories = ['music', 'radio']

Definition at line 38 of file radio_browser.py.

◆ logger

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

Definition at line 25 of file radio_browser.py.

◆ number_of_results

int searx.engines.radio_browser.number_of_results = 10

Definition at line 40 of file radio_browser.py.

◆ paging

bool searx.engines.radio_browser.paging = True

Definition at line 37 of file radio_browser.py.

◆ station_filters

list searx.engines.radio_browser.station_filters = []

Definition at line 42 of file radio_browser.py.