.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
tagesschau.py
Go to the documentation of this file.
1# SPDX-License-Identifier: AGPL-3.0-or-later
2"""ARD: `Tagesschau API`_
3
4The Tagesschau is a news program of the ARD. Via the `Tagesschau API`_, current
5news and media reports are available in JSON format. The `Bundesstelle für Open
6Data`_ offers a `OpenAPI`_ portal at bundDEV_ where APIs are documented an can
7be tested.
8
9This SearXNG engine uses the `/api2u/search`_ API.
10
11.. _/api2u/search: http://tagesschau.api.bund.dev/
12.. _bundDEV: https://bund.dev/apis
13.. _Bundesstelle für Open Data: https://github.com/bundesAPI
14.. _Tagesschau API: https://github.com/AndreasFischer1985/tagesschau-api/blob/main/README_en.md
15.. _OpenAPI: https://swagger.io/specification/
16
17"""
18from typing import TYPE_CHECKING
19
20from datetime import datetime
21from urllib.parse import urlencode
22import re
23
24if TYPE_CHECKING:
25 import logging
26
27 logger: logging.Logger
28
29about = {
30 'website': "https://tagesschau.de",
31 'wikidata_id': "Q703907",
32 'official_api_documentation': None,
33 'use_official_api': True,
34 'require_api_key': False,
35 'results': 'JSON',
36 'language': 'de',
37}
38categories = ['general', 'news']
39paging = True
40
41results_per_page = 10
42base_url = "https://www.tagesschau.de"
43
44use_source_url = True
45"""When set to false, display URLs from Tagesschau, and not the actual source
46(e.g. NDR, WDR, SWR, HR, ...)
47
48.. note::
49
50 The actual source may contain additional content, such as commentary, that is
51 not displayed in the Tagesschau.
52
53"""
54
55
56def request(query, params):
57 args = {
58 'searchText': query,
59 'pageSize': results_per_page,
60 'resultPage': params['pageno'] - 1,
61 }
62
63 params['url'] = f"{base_url}/api2u/search?{urlencode(args)}"
64
65 return params
66
67
68def response(resp):
69 results = []
70
71 json = resp.json()
72
73 for item in json['searchResults']:
74 item_type = item.get('type')
75 if item_type in ('story', 'webview'):
76 results.append(_story(item))
77 elif item_type == 'video':
78 results.append(_video(item))
79 else:
80 logger.error("unknow result type: %s", item_type)
81
82 return results
83
84
85def _story(item):
86 return {
87 'title': item['title'],
88 'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'),
89 'publishedDate': datetime.strptime(item['date'][:19], '%Y-%m-%dT%H:%M:%S'),
90 'content': item['firstSentence'],
91 'url': item['shareURL'] if use_source_url else item['detailsweb'],
92 }
93
94
95def _video(item):
96 streams = item['streams']
97 video_url = streams.get('h264s') or streams.get('h264m') or streams.get('h264l') or streams.get('h264xl')
98 title = item['title']
99
100 if "_vapp.mxf" in title:
101 title = title.replace("_vapp.mxf", "")
102 title = re.sub(r"APP\d+ (FC-)?", "", title, count=1)
103
104 return {
105 'template': 'videos.html',
106 'title': title,
107 'thumbnail': item.get('teaserImage', {}).get('imageVariants', {}).get('16x9-256'),
108 'publishedDate': datetime.strptime(item['date'][:19], '%Y-%m-%dT%H:%M:%S'),
109 'content': item.get('firstSentence', ''),
110 'iframe_src': video_url,
111 'url': video_url,
112 }
request(query, params)
Definition tagesschau.py:56