mirror of
https://github.com/searxng/searxng.git
synced 2026-09-22 22:26:05 +00:00
[mod] typification of SearXNG: add new result type Video (#6743)
- Python class: searx/result_types/video.py - Jinja template: searx/templates/simple/result_templates/videos.html - CSS (less) client/simple/src/less/result_types/video.less Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
committed by
Markus Heiser
parent
fdd8525b1a
commit
e40de2d992
25
client/simple/src/less/result_types/video.less
Normal file
25
client/simple/src/less/result_types/video.less
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
/*
|
||||
Layout of the Video result class
|
||||
*/
|
||||
|
||||
.result-videos {
|
||||
a.thumbnail_link {
|
||||
.ltr-float-left();
|
||||
.ltr-margin-right(1rem);
|
||||
.ltr-margin-left(0);
|
||||
width: 10rem !important;
|
||||
aspect-ratio: 16 / 9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.embedded-video iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
@@ -431,34 +431,6 @@ article[data-vim-selected].category-social {
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
|
||||
.result-videos {
|
||||
a.thumbnail_link {
|
||||
.ltr-float-left();
|
||||
.ltr-margin-right(1rem);
|
||||
.ltr-margin-left(0);
|
||||
width: 10rem !important;
|
||||
aspect-ratio: 16 / 9 !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.embedded-video iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
padding: 10px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@supports not (aspect-ratio: 1 / 1) {
|
||||
// support older browsers which do not have aspect-ratio
|
||||
// https://caniuse.com/?search=aspect-ratio
|
||||
.result-videos .embedded-video iframe {
|
||||
height: calc(@results-width * 9 / 16);
|
||||
}
|
||||
}
|
||||
|
||||
.engines {
|
||||
.ltr-float-right();
|
||||
clear: both;
|
||||
|
||||
7
docs/dev/result_types/main/video.rst
Normal file
7
docs/dev/result_types/main/video.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
.. _result_types.video:
|
||||
|
||||
=============
|
||||
Video Results
|
||||
=============
|
||||
|
||||
.. automodule:: searx.result_types.video
|
||||
@@ -19,13 +19,13 @@ following types have been implemented so far ..
|
||||
main/paper
|
||||
main/file
|
||||
main/image
|
||||
main/video
|
||||
|
||||
The :ref:`LegacyResult <LegacyResult>` is used internally for the results that
|
||||
have not yet been typed. The templates can be used as orientation until the
|
||||
final typing is complete.
|
||||
|
||||
- :ref:`template default` / :py:obj:`Result`
|
||||
- :ref:`template videos`
|
||||
- :ref:`template torrent`
|
||||
- :ref:`template map`
|
||||
- :ref:`template packages`
|
||||
|
||||
@@ -129,29 +129,6 @@ audio_src : uri,
|
||||
URL of an embedded ``<audio controls>``.
|
||||
|
||||
|
||||
.. _template videos:
|
||||
|
||||
``videos.html``
|
||||
---------------
|
||||
|
||||
Displays result fields from:
|
||||
|
||||
- :ref:`macro result_header` and
|
||||
- :ref:`macro result_sub_header`
|
||||
|
||||
Additional fields used in the :origin:`videos.html
|
||||
<searx/templates/simple/result_templates/videos.html>`:
|
||||
|
||||
iframe_src : :py:class:`str`
|
||||
URL of an embedded ``<iframe>`` / the frame is collapsible.
|
||||
|
||||
The videos are displayed as small thumbnails in the main results list, there
|
||||
is an additional button to collaps/open the embeded video.
|
||||
|
||||
content : :py:class:`str`
|
||||
Description of the code fragment.
|
||||
|
||||
|
||||
.. _template torrent:
|
||||
|
||||
``torrent.html``
|
||||
|
||||
@@ -28,6 +28,7 @@ __all__ = [
|
||||
"File",
|
||||
"Image",
|
||||
"ImageRef",
|
||||
"Video",
|
||||
]
|
||||
|
||||
import typing as t
|
||||
@@ -40,6 +41,7 @@ from .code import Code
|
||||
from .paper import Paper
|
||||
from .file import File
|
||||
from .image import Image, ImageRef
|
||||
from .video import Video
|
||||
|
||||
|
||||
class ResultList(list[Result | LegacyResult], abc.ABC):
|
||||
@@ -56,6 +58,7 @@ class ResultList(list[Result | LegacyResult], abc.ABC):
|
||||
Paper = Paper
|
||||
File = File
|
||||
Image = Image
|
||||
Video = Video
|
||||
MainResult = MainResult
|
||||
Result = Result
|
||||
Translations = Translations
|
||||
|
||||
@@ -31,7 +31,6 @@ from collections.abc import Callable
|
||||
import msgspec
|
||||
|
||||
from searx import logger
|
||||
from searx.utils import get_embedded_stream_url
|
||||
|
||||
log = logger.getChild("result_types")
|
||||
|
||||
@@ -386,7 +385,11 @@ class MainResult(Result): # pylint: disable=missing-class-docstring
|
||||
"""URL of a image that is displayed in the result item."""
|
||||
|
||||
iframe_src: str = ""
|
||||
"""URL of an embedded ``<iframe>`` / the frame is collapsible."""
|
||||
"""URL of an embedded ``<iframe>`` / the frame is collapsible.
|
||||
|
||||
To convert a standard video URL from a widely know video services into its
|
||||
embed format, have a look at :obj:`searx.utils.get_embedded_stream_url`.
|
||||
"""
|
||||
|
||||
audio_src: str = ""
|
||||
"""URL of an embedded ``<audio controls>``."""
|
||||
@@ -542,10 +545,6 @@ class LegacyResult(dict[str, t.Any]):
|
||||
DeprecationWarning,
|
||||
)
|
||||
|
||||
# TODO: move into typed video results class once it is implemented # pylint: disable=fixme
|
||||
if self.template == "videos.html" and self.url and not self.iframe_src:
|
||||
self.iframe_src = get_embedded_stream_url(self.url)
|
||||
|
||||
def __getattr__(self, name: str, default: t.Any = UNSET) -> t.Any:
|
||||
if default == UNSET and name not in self:
|
||||
raise AttributeError(f"LegacyResult object has no field named: {name}")
|
||||
|
||||
30
searx/result_types/video.py
Normal file
30
searx/result_types/video.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""Typification of the *video* results. Results of this type are rendered in
|
||||
the :origin:`videos.html <searx/templates/simple/result_templates/videos.html>`
|
||||
template.
|
||||
|
||||
.. autoclass:: Video
|
||||
:members:
|
||||
:show-inheritance:
|
||||
"""
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
__all__ = ["Video"]
|
||||
|
||||
import typing as t
|
||||
|
||||
from searx.utils import get_embedded_stream_url
|
||||
from ._base import MainResult
|
||||
|
||||
|
||||
@t.final
|
||||
class Video(MainResult, kw_only=True):
|
||||
"""Result type suitable for displaying videos."""
|
||||
|
||||
template: str = "videos.html"
|
||||
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
|
||||
if self.url and not self.iframe_src:
|
||||
self.iframe_src = get_embedded_stream_url(self.url)
|
||||
@@ -593,13 +593,24 @@ def eval_xpath_getindex(
|
||||
return default
|
||||
|
||||
|
||||
def get_embedded_stream_url(url: str):
|
||||
"""
|
||||
Converts a standard video URL into its embed format. Supported services include Youtube,
|
||||
Facebook, Instagram, TikTok, Dailymotion, and Bilibili.
|
||||
def get_embedded_stream_url(url: str) -> str:
|
||||
"""Converts a standard video URL into its embed format.
|
||||
|
||||
Supported services include:
|
||||
|
||||
- Youtube
|
||||
- Facebook
|
||||
- Instagram
|
||||
- TikTok
|
||||
- Dailymotion
|
||||
- Bilibili
|
||||
|
||||
The function is suitable for the field :obj:`MainResult.iframe_src
|
||||
<searx.result_types.MainResult.iframe_src>`. If ``url`` is not from one of
|
||||
the supported services, an empty string is returned.
|
||||
"""
|
||||
parsed_url = urlparse(url)
|
||||
iframe_src = None
|
||||
iframe_src = ""
|
||||
|
||||
# YouTube
|
||||
if parsed_url.netloc in ['www.youtube.com', 'youtube.com'] and parsed_url.path == '/watch' and parsed_url.query:
|
||||
|
||||
Reference in New Issue
Block a user