.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
piped.py
Go to the documentation of this file.
1
# SPDX-License-Identifier: AGPL-3.0-or-later
2
"""An alternative privacy-friendly YouTube frontend which is efficient by
3
design. `Piped’s architecture`_ consists of 3 components:
4
5
- :py:obj:`backend <backend_url>`
6
- :py:obj:`frontend <frontend_url>`
7
- proxy
8
9
.. _Piped’s architecture: https://docs.piped.video/docs/architecture/
10
11
Configuration
12
=============
13
14
The :py:obj:`backend_url` and :py:obj:`frontend_url` has to be set in the engine
15
named `piped` and are used by all piped engines
16
17
.. code:: yaml
18
19
- name: piped
20
engine: piped
21
piped_filter: videos
22
...
23
frontend_url: https://..
24
backend_url:
25
- https://..
26
- https://..
27
28
- name: piped.music
29
engine: piped
30
network: piped
31
shortcut: ppdm
32
piped_filter: music_songs
33
...
34
35
Known Quirks
36
============
37
38
The implementation to support :py:obj:`paging <searx.enginelib.Engine.paging>`
39
is based on the *nextpage* method of Piped's REST API / the :py:obj:`frontend
40
API <frontend_url>`. This feature is *next page driven* and plays well with the
41
:ref:`infinite_scroll <settings ui>` setting in SearXNG but it does not really
42
fit into SearXNG's UI to select a page by number.
43
44
Implementations
45
===============
46
"""
47
48
from
__future__
import
annotations
49
50
import
time
51
import
random
52
from
urllib.parse
import
urlencode
53
import
datetime
54
from
dateutil
import
parser
55
56
# about
57
about = {
58
"website"
:
'https://github.com/TeamPiped/Piped/'
,
59
"wikidata_id"
:
'Q107565255'
,
60
"official_api_documentation"
:
'https://docs.piped.video/docs/api-documentation/'
,
61
"use_official_api"
:
True
,
62
"require_api_key"
:
False
,
63
"results"
:
'JSON'
,
64
}
65
66
# engine dependent config
67
categories = []
68
paging =
True
69
70
# search-url
71
backend_url: list | str =
"https://pipedapi.kavin.rocks"
72
"""Piped-Backend_: The core component behind Piped. The value is an URL or a
73
list of URLs. In the latter case instance will be selected randomly. For a
74
complete list of official instances see Piped-Instances (`JSON
75
<https://piped-instances.kavin.rocks/>`__)
76
77
.. _Piped-Instances: https://github.com/TeamPiped/Piped/wiki/Instances
78
.. _Piped-Backend: https://github.com/TeamPiped/Piped-Backend
79
80
"""
81
82
frontend_url: str =
"https://piped.video"
83
"""Piped-Frontend_: URL to use as link and for embeds.
84
85
.. _Piped-Frontend: https://github.com/TeamPiped/Piped
86
"""
87
88
piped_filter =
'all'
89
"""Content filter ``music_songs`` or ``videos``"""
90
91
92
def
_backend_url
() -> str:
93
from
searx.engines
import
engines
# pylint: disable=import-outside-toplevel
94
95
url = engines[
'piped'
].backend_url
# type: ignore
96
if
isinstance(url, list):
97
url = random.choice(url)
98
return
url
99
100
101
def
_frontend_url
() -> str:
102
from
searx.engines
import
engines
# pylint: disable=import-outside-toplevel
103
104
return
engines[
'piped'
].frontend_url
# type: ignore
105
106
107
def
request
(query, params):
108
109
args = {
110
'q'
: query,
111
'filter'
: piped_filter,
112
}
113
114
path =
"/search"
115
if
params[
'pageno'
] > 1:
116
# don't use nextpage when user selected to jump back to page 1
117
nextpage = params[
'engine_data'
].get(
'nextpage'
)
118
if
nextpage:
119
path =
"/nextpage/search"
120
args[
'nextpage'
] = nextpage
121
122
params[
"url"
] =
_backend_url
() + f
"{path}?"
+ urlencode(args)
123
return
params
124
125
126
def
response
(resp):
127
results = []
128
129
json = resp.json()
130
131
for
result
in
json[
"items"
]:
132
# note: piped returns -1 for all upload times when filtering for music
133
uploaded = result.get(
"uploaded"
, -1)
134
135
item = {
136
# the api url differs from the frontend, hence use piped.video as default
137
"url"
:
_frontend_url
() + result.get(
"url"
,
""
),
138
"title"
: result.get(
"title"
,
""
),
139
"publishedDate"
: parser.parse(time.ctime(uploaded / 1000))
if
uploaded != -1
else
None
,
140
"iframe_src"
:
_frontend_url
() +
'/embed'
+ result.get(
"url"
,
""
),
141
}
142
length = result.get(
"duration"
)
143
if
length:
144
item[
"length"
] = datetime.timedelta(seconds=length)
145
146
if
piped_filter ==
'videos'
:
147
item[
"template"
] =
"videos.html"
148
# if the value of shortDescription set, but is None, return empty string
149
item[
"content"
] = result.get(
"shortDescription"
,
""
)
or
""
150
item[
"thumbnail"
] = result.get(
"thumbnail"
,
""
)
151
152
elif
piped_filter ==
'music_songs'
:
153
item[
"template"
] =
"default.html"
154
item[
"img_src"
] = result.get(
"thumbnail"
,
""
)
155
item[
"content"
] = result.get(
"uploaderName"
,
""
)
or
""
156
157
results.append(item)
158
159
results.append(
160
{
161
"engine_data"
: json[
"nextpage"
],
162
"key"
:
"nextpage"
,
163
}
164
)
165
return
results
searx.engines.piped.request
request(query, params)
Definition
piped.py:107
searx.engines.piped._frontend_url
str _frontend_url()
Definition
piped.py:101
searx.engines.piped.response
response(resp)
Definition
piped.py:126
searx.engines.piped._backend_url
str _backend_url()
Definition
piped.py:92
searx.engines
::1337x
Definition
1337x.py:1
searxng
searx
engines
piped.py
Generated on Wed May 15 2024 21:10:12 for .oO SearXNG Developer Documentation Oo. by
1.10.0