mirror of
https://github.com/searxng/searxng.git
synced 2026-05-27 21:30:11 +02:00
[mod] typification of SearXNG: add new result type File
This PR adds a new result type: File
Python class: searx/result_types/file.py
Jinja template: searx/templates/simple/result_templates/file.html
CSS (less) client/simple/src/less/result_types/file.less
Class 'File' (singular) replaces template 'files.html' (plural). The renaming
was carried out because there is only one file (singular) in a result. Not to be
confused with the category 'files' where in multiple results can exist.
As mentioned in issue [1], the class '.category-files' was removed from the CSS
and the stylesheet was adopted in result_types/file.less (there based on the
templates and no longer based on the category).
[1] https://github.com/searxng/searxng/issues/5198
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
committed by
Markus Heiser
parent
ee6d4f322f
commit
9371658531
@@ -23,6 +23,7 @@ __all__ = [
|
||||
"WeatherAnswer",
|
||||
"Code",
|
||||
"Paper",
|
||||
"File",
|
||||
]
|
||||
|
||||
import typing as t
|
||||
@@ -33,6 +34,7 @@ from .answer import AnswerSet, Answer, Translations, WeatherAnswer
|
||||
from .keyvalue import KeyValue
|
||||
from .code import Code
|
||||
from .paper import Paper
|
||||
from .file import File
|
||||
|
||||
|
||||
class ResultList(list[Result | LegacyResult], abc.ABC):
|
||||
@@ -47,6 +49,7 @@ class ResultList(list[Result | LegacyResult], abc.ABC):
|
||||
KeyValue = KeyValue
|
||||
Code = Code
|
||||
Paper = Paper
|
||||
File = File
|
||||
MainResult = MainResult
|
||||
Result = Result
|
||||
Translations = Translations
|
||||
|
||||
@@ -27,7 +27,6 @@ import typing as t
|
||||
import re
|
||||
import urllib.parse
|
||||
import warnings
|
||||
import time
|
||||
import datetime
|
||||
|
||||
from collections.abc import Callable
|
||||
@@ -236,13 +235,6 @@ class Result(msgspec.Struct, kw_only=True):
|
||||
url: str | None = None
|
||||
"""A link related to this *result*"""
|
||||
|
||||
template: str = "default.html"
|
||||
"""Name of the template used to render the result.
|
||||
|
||||
By default :origin:`result_templates/default.html
|
||||
<searx/templates/simple/result_templates/default.html>` is used.
|
||||
"""
|
||||
|
||||
engine: str | None = ""
|
||||
"""Name of the engine *this* result comes from. In case of *plugins* a
|
||||
prefix ``plugin:`` is set, in case of *answerer* prefix ``answerer:`` is
|
||||
@@ -350,6 +342,13 @@ class Result(msgspec.Struct, kw_only=True):
|
||||
class MainResult(Result): # pylint: disable=missing-class-docstring
|
||||
"""Base class of all result types displayed in :ref:`area main results`."""
|
||||
|
||||
template: str = "default.html"
|
||||
"""Name of the template used to render the result.
|
||||
|
||||
By default :origin:`result_templates/default.html
|
||||
<searx/templates/simple/result_templates/default.html>` is used.
|
||||
"""
|
||||
|
||||
title: str = ""
|
||||
"""Link title of the result item."""
|
||||
|
||||
@@ -359,6 +358,12 @@ class MainResult(Result): # pylint: disable=missing-class-docstring
|
||||
img_src: str = ""
|
||||
"""URL of a image that is displayed in the result item."""
|
||||
|
||||
iframe_src: str = ""
|
||||
"""URL of an embedded ``<iframe>`` / the frame is collapsible."""
|
||||
|
||||
audio_src: str = ""
|
||||
"""URL of an embedded ``<audio controls>``."""
|
||||
|
||||
thumbnail: str = ""
|
||||
"""URL of a thumbnail that is displayed in the result item."""
|
||||
|
||||
@@ -372,7 +377,7 @@ class MainResult(Result): # pylint: disable=missing-class-docstring
|
||||
completely eliminated.
|
||||
"""
|
||||
|
||||
length: time.struct_time | None = None
|
||||
length: datetime.timedelta | None = None
|
||||
"""Playing duration in seconds."""
|
||||
|
||||
views: str = ""
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""
|
||||
Typification of the *file* results. Results of this type are rendered in
|
||||
the :origin:`file.html <searx/templates/simple/result_templates/file.html>`
|
||||
template.
|
||||
|
||||
----
|
||||
|
||||
.. autoclass:: File
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
|
||||
__all__ = ["File"]
|
||||
|
||||
import typing as t
|
||||
import mimetypes
|
||||
|
||||
from ._base import MainResult
|
||||
|
||||
|
||||
@t.final
|
||||
class File(MainResult, kw_only=True):
|
||||
"""Class for results of type *file*"""
|
||||
|
||||
template: str = "file.html"
|
||||
|
||||
filename: str = ""
|
||||
"""Name of the file."""
|
||||
|
||||
size: str = ""
|
||||
"""Size of bytes in human readable notation (``MB`` for 1024 * 1024 Bytes
|
||||
file size.)"""
|
||||
|
||||
time: str = ""
|
||||
"""Indication of a time, such as the date of the last modification or the
|
||||
date of creation. This is a simple string, the *date* of which can be freely
|
||||
chosen according to the context."""
|
||||
|
||||
mimetype: str = ""
|
||||
"""Mimetype/Subtype of the file. For ``audio`` and ``video``, a URL can be
|
||||
passed in the :py:obj:`File.embedded` field to embed the referenced media in
|
||||
the result. If no value is specified, the MIME type is determined from
|
||||
``self.filename`` or, alternatively, from ``self.embedded`` (if either of
|
||||
the two values is set)."""
|
||||
|
||||
abstract: str = ""
|
||||
"""Abstract of the file."""
|
||||
|
||||
author: str = ""
|
||||
"""Author of the file."""
|
||||
|
||||
embedded: str = ""
|
||||
"""URL of an embedded media type (audio or video) / is collapsible."""
|
||||
|
||||
mtype: str = ""
|
||||
"""Used for displaying :py:obj:`File.embedded`. Its value is automatically
|
||||
populated from the base type of :py:obj:`File.mimetype`, and can be
|
||||
explicitly set to enforce e.g. ``audio`` or ``video`` when mimetype is
|
||||
something like "application/ogg" but its know the content is for example a
|
||||
video."""
|
||||
|
||||
subtype: str = ""
|
||||
"""Used for displaying :py:obj:`File.embedded`. Its value is automatically
|
||||
populated from the subtype type of :py:obj:`File.mimetype`, and can be
|
||||
explicitly set to enforce a subtype for the :py:obj:`File.embedded`
|
||||
element."""
|
||||
|
||||
def __post_init__(self):
|
||||
super().__post_init__()
|
||||
|
||||
if not self.mtype or not self.subtype:
|
||||
|
||||
fn = self.filename or self.embedded
|
||||
if not self.mimetype and fn:
|
||||
self.mimetype = mimetypes.guess_type(fn, strict=False)[0] or ""
|
||||
|
||||
mtype, subtype = (self.mimetype.split("/", 1) + [""])[:2]
|
||||
|
||||
if not self.mtype:
|
||||
# I don't know why, but the ogg video stream is not displayed,
|
||||
# may https://github.com/videojs/video.js can help?
|
||||
if self.embedded.endswith(".ogv"):
|
||||
self.mtype = "video"
|
||||
elif self.embedded.endswith(".oga"):
|
||||
self.mtype = "audio"
|
||||
else:
|
||||
self.mtype = mtype
|
||||
|
||||
if not self.subtype:
|
||||
self.subtype = subtype
|
||||
Reference in New Issue
Block a user