From e76ab1a4b3a99b0ec2ef90c3aadc92ffbf6889b1 Mon Sep 17 00:00:00 2001 From: Bnyro Date: Tue, 20 Feb 2024 10:51:58 +0100 Subject: [PATCH] [refactor] images: add resolution, image format and filesize fields Co-authored-by: Markus Heiser --- docs/dev/engines/engine_overview.rst | 60 ++++++++++++++----- searx/engines/artic.py | 5 +- searx/engines/bing_images.py | 5 +- searx/engines/brave.py | 3 +- searx/engines/demo_online.py | 5 +- searx/engines/duckduckgo_extra.py | 2 +- searx/engines/flickr_noapi.py | 4 +- searx/engines/google_images.py | 2 +- searx/engines/qwant.py | 2 + searx/engines/seekr.py | 2 +- searx/engines/wallhaven.py | 7 ++- searx/engines/wikicommons.py | 2 +- .../static/themes/simple/src/less/detail.less | 6 +- .../simple/result_templates/images.html | 7 ++- searx/utils.py | 12 ++++ 15 files changed, 91 insertions(+), 33 deletions(-) diff --git a/docs/dev/engines/engine_overview.rst b/docs/dev/engines/engine_overview.rst index 9c1ea0427..091d217c0 100644 --- a/docs/dev/engines/engine_overview.rst +++ b/docs/dev/engines/engine_overview.rst @@ -271,22 +271,54 @@ type. ``images`` ---------- -.. table:: Parameter of the **images** media type: +.. list-table:: Parameter of the **images** media type + :header-rows: 2 :width: 100% - ========================= ===================================================== - result-parameter information - ------------------------- ----------------------------------------------------- - template is set to ``images.html`` - ========================= ===================================================== - url string, url to the result site - title string, title of the result *(partly implemented)* - content *(partly implemented)* - publishedDate :py:class:`datetime.datetime`, - time of publish *(partly implemented)* - img\_src string, url to the result image - thumbnail\_src string, url to a small-preview image - ========================= ===================================================== + * - result-parameter + - Python type + - information + + * - template + - :py:class:`str` + - is set to ``images.html`` + + * - url + - :py:class:`str` + - url to the result site + + * - title + - :py:class:`str` + - title of the result + + * - content + - :py:class:`str` + - description of the image + + * - publishedDate + - :py:class:`datetime ` + - time of publish + + * - img_src + - :py:class:`str` + - url to the result image + + * - thumbnail_src + - :py:class:`str` + - url to a small-preview image + + * - resolution + - :py:class:`str` + - the resolution of the image (e.g. ``1920 x 1080`` pixel) + + * - img_format + - :py:class:`str` + - the format of the image (e.g. ``png``) + + * - filesize + - :py:class:`str` + - size of bytes in :py:obj:`human readable ` notation + (e.g. ``MB`` for 1024 \* 1024 Bytes filesize). .. _template videos: diff --git a/searx/engines/artic.py b/searx/engines/artic.py index c0ae0a5e7..506a9cea6 100644 --- a/searx/engines/artic.py +++ b/searx/engines/artic.py @@ -57,11 +57,10 @@ def response(resp): results.append( { 'url': 'https://artic.edu/artworks/%(id)s' % result, - 'title': result['title'] + " (%(date_display)s) // %(artist_display)s" % result, - 'content': result['medium_display'], + 'title': result['title'] + " (%(date_display)s) // %(artist_display)s" % result, + 'content': "%(medium_display)s // %(dimensions)s" % result, 'author': ', '.join(result['artist_titles']), 'img_src': image_api + '/%(image_id)s/full/843,/0/default.jpg' % result, - 'img_format': result['dimensions'], 'template': 'images.html', } ) diff --git a/searx/engines/bing_images.py b/searx/engines/bing_images.py index faf0941c8..788c90278 100644 --- a/searx/engines/bing_images.py +++ b/searx/engines/bing_images.py @@ -92,7 +92,7 @@ def response(resp): metadata = json.loads(result.xpath('.//a[@class="iusc"]/@m')[0]) title = ' '.join(result.xpath('.//div[@class="infnmpt"]//a/text()')).strip() - img_format = ' '.join(result.xpath('.//div[@class="imgpt"]/div/span/text()')).strip() + img_format = ' '.join(result.xpath('.//div[@class="imgpt"]/div/span/text()')).strip().split(" ยท ") source = ' '.join(result.xpath('.//div[@class="imgpt"]//div[@class="lnkw"]//a/text()')).strip() results.append( { @@ -103,7 +103,8 @@ def response(resp): 'content': metadata['desc'], 'title': title, 'source': source, - 'img_format': img_format, + 'resolution': img_format[0], + 'img_format': img_format[1] if len(img_format) >= 2 else None, } ) return results diff --git a/searx/engines/brave.py b/searx/engines/brave.py index 397af6094..8588c2efd 100644 --- a/searx/engines/brave.py +++ b/searx/engines/brave.py @@ -367,9 +367,10 @@ def _parse_images(json_resp): 'title': result['title'], 'content': result['description'], 'template': 'images.html', - 'img_format': result['properties']['format'], + 'resolution': result['properties']['format'], 'source': result['source'], 'img_src': result['properties']['url'], + 'thumbnail_src': result['thumbnail']['src'], } result_list.append(item) diff --git a/searx/engines/demo_online.py b/searx/engines/demo_online.py index 08add5371..33cfde822 100644 --- a/searx/engines/demo_online.py +++ b/searx/engines/demo_online.py @@ -88,11 +88,10 @@ def response(resp): results.append( { 'url': 'https://artic.edu/artworks/%(id)s' % result, - 'title': result['title'] + " (%(date_display)s) // %(artist_display)s" % result, - 'content': result['medium_display'], + 'title': result['title'] + " (%(date_display)s) // %(artist_display)s" % result, + 'content': "%(medium_display)s // %(dimensions)s" % result, 'author': ', '.join(result['artist_titles']), 'img_src': image_api + '/%(image_id)s/full/843,/0/default.jpg' % result, - 'img_format': result['dimensions'], 'template': 'images.html', } ) diff --git a/searx/engines/duckduckgo_extra.py b/searx/engines/duckduckgo_extra.py index 25692add7..83ca38c26 100644 --- a/searx/engines/duckduckgo_extra.py +++ b/searx/engines/duckduckgo_extra.py @@ -96,7 +96,7 @@ def _image_result(result): 'content': '', 'thumbnail_src': result['thumbnail'], 'img_src': result['image'], - 'img_format': '%s x %s' % (result['width'], result['height']), + 'resolution': '%s x %s' % (result['width'], result['height']), 'source': result['source'], } diff --git a/searx/engines/flickr_noapi.py b/searx/engines/flickr_noapi.py index 5299c604f..ebd61570f 100644 --- a/searx/engines/flickr_noapi.py +++ b/searx/engines/flickr_noapi.py @@ -110,7 +110,7 @@ def response(resp): # pylint: disable=too-many-branches continue img_src = size_data['url'] - img_format = f"{size_data['width']} x {size_data['height']}" + resolution = f"{size_data['width']} x {size_data['height']}" # For a bigger thumbnail, keep only the url_z, not the url_n if 'n' in photo['sizes']['data']: @@ -131,7 +131,7 @@ def response(resp): # pylint: disable=too-many-branches 'img_src': img_src, 'thumbnail_src': thumbnail_src, 'source': source, - 'img_format': img_format, + 'resolution': resolution, 'template': 'images.html', } result['author'] = author.encode(errors='ignore').decode() diff --git a/searx/engines/google_images.py b/searx/engines/google_images.py index d2d33d408..31211b9b6 100644 --- a/searx/engines/google_images.py +++ b/searx/engines/google_images.py @@ -103,7 +103,7 @@ def response(resp): 'title': item["result"]["page_title"], 'content': item["text_in_grid"]["snippet"], 'source': item["result"]["site_title"], - 'img_format': f'{item["original_image"]["width"]} x {item["original_image"]["height"]}', + 'resolution': f'{item["original_image"]["width"]} x {item["original_image"]["height"]}', 'img_src': item["original_image"]["url"], 'thumbnail_src': item["thumbnail"]["url"], 'template': 'images.html', diff --git a/searx/engines/qwant.py b/searx/engines/qwant.py index 1f8556cf1..775a11292 100644 --- a/searx/engines/qwant.py +++ b/searx/engines/qwant.py @@ -265,6 +265,8 @@ def parse_web_api(resp): 'template': 'images.html', 'thumbnail_src': thumbnail, 'img_src': img_src, + 'resolution': f"{item['width']} x {item['height']}", + 'img_format': item.get('thumb_type'), } ) diff --git a/searx/engines/seekr.py b/searx/engines/seekr.py index 9250ac991..014b736dc 100644 --- a/searx/engines/seekr.py +++ b/searx/engines/seekr.py @@ -122,7 +122,7 @@ def _images_response(json): 'url': summary['refererurl'], 'title': result['title'], 'img_src': result['url'], - 'img_format': f"{summary['width']}x{summary['height']}", + 'resolution': f"{summary['width']}x{summary['height']}", 'thumbnail_src': 'https://media.seekr.com/engine/rp/' + summary['tg'] + '/?src= ' + result['thumbnail'], } ) diff --git a/searx/engines/wallhaven.py b/searx/engines/wallhaven.py index f80b5d86d..94be1a6a7 100644 --- a/searx/engines/wallhaven.py +++ b/searx/engines/wallhaven.py @@ -8,6 +8,8 @@ from datetime import datetime from urllib.parse import urlencode +from searx.utils import humanize_bytes + about = { 'website': 'https://wallhaven.cc/', 'official_api_documentation': 'https://wallhaven.cc/help/api', @@ -68,6 +70,7 @@ def response(resp): json = resp.json() for result in json['data']: + results.append( { 'template': 'images.html', @@ -76,8 +79,10 @@ def response(resp): 'url': result['url'], 'img_src': result['path'], 'thumbnail_src': result['thumbs']['small'], - 'img_format': result['resolution'], + 'resolution': result['resolution'].replace('x', ' x '), 'publishedDate': datetime.strptime(result['created_at'], '%Y-%m-%d %H:%M:%S'), + 'img_format': result['file_type'], + 'filesize': humanize_bytes(result['file_size']), } ) diff --git a/searx/engines/wikicommons.py b/searx/engines/wikicommons.py index a478f57d2..9b0849716 100644 --- a/searx/engines/wikicommons.py +++ b/searx/engines/wikicommons.py @@ -62,7 +62,7 @@ def response(resp): 'title': title, 'content': item["snippet"], 'img_src': imageinfo["url"], - 'img_format': f'{imageinfo["width"]} x {imageinfo["height"]}', + 'resolution': f'{imageinfo["width"]} x {imageinfo["height"]}', 'thumbnail_src': imageinfo["thumburl"], 'template': 'images.html', } diff --git a/searx/static/themes/simple/src/less/detail.less b/searx/static/themes/simple/src/less/detail.less index b7894797c..253ffd5b2 100644 --- a/searx/static/themes/simple/src/less/detail.less +++ b/searx/static/themes/simple/src/less/detail.less @@ -49,8 +49,7 @@ article.result-images .detail { .result-images-labels { color: var(--color-result-detail-font); - max-height: 16rem; - min-height: 16rem; + height: 19rem; hr { border-top: 1px solid var(--color-result-detail-hr); @@ -62,11 +61,13 @@ article.result-images .detail { overflow: hidden; text-overflow: ellipsis; font-size: 0.9rem; + margin-bottom: 0; } p { color: var(--color-result-detail-label-font); font-size: 0.9rem; + line-height: 0.9rem; span { display: inline-block; @@ -82,6 +83,7 @@ article.result-images .detail { p.result-content { height: 2rem; + line-height: unset; overflow: hidden; text-overflow: ellipsis; } diff --git a/searx/templates/simple/result_templates/images.html b/searx/templates/simple/result_templates/images.html index 8aadbd204..0462588be 100644 --- a/searx/templates/simple/result_templates/images.html +++ b/searx/templates/simple/result_templates/images.html @@ -2,7 +2,10 @@ {{- "" -}} {{ result.title|striptags }}{{- "" -}} {{ result.title|striptags }}{{- "" -}} - {{ result.parsed_url.netloc }}{{- "" -}} + + {{- result.parsed_url.netloc -}} + {%- if result.resolution %} - {{ result.resolution }}{%- endif -%} + {{- "" -}} {{- "" -}}
{{- "" -}} {{ icon('close') }}{{- "" -}} @@ -16,7 +19,9 @@

{%- if result.content %}{{ result.content|striptags }}{% else %} {% endif -%}

{{- "" -}}
{{- "" -}}

{%- if result.author %}{{ _('Author') }}:{{ result.author|striptags }}{% else %} {% endif -%}

{{- "" -}} +

{%- if result.resolution %}{{ _('Resolution') }}:{{ result.resolution }}{% else %} {% endif -%}

{{- "" -}}

{%- if result.img_format %}{{ _('Format') }}:{{ result.img_format }}{% else %} {% endif -%}

{{- "" -}} +

{%- if result.filesize %}{{ _('Filesize') }}:{{ result.filesize}}{% else %} {% endif -%}

{{- "" -}}

{%- if result.source %}{{ _('Source') }}:{{ result.source }}{% else %} {% endif -%}

{{- "" -}}

{{ _('Engine') }}:{{ result.engine }}

{{- "" -}}{{- "" -}}

{{ _('View source') }}:{{ result.url }}

{{- "" -}} diff --git a/searx/utils.py b/searx/utils.py index c009c3144..b0794c244 100644 --- a/searx/utils.py +++ b/searx/utils.py @@ -353,6 +353,18 @@ def get_torrent_size(filesize: str, filesize_multiplier: str) -> Optional[int]: return None +def humanize_bytes(size, precision=2): + """Determine the *human readable* value of bytes on 1024 base (1KB=1024B).""" + s = ['B ', 'KB', 'MB', 'GB', 'TB'] + + x = len(s) + p = 0 + while size > 1024 and p < x: + p += 1 + size = size / 1024.0 + return "%.*f %s" % (precision, size, s[p]) + + def convert_str_to_int(number_str: str) -> int: """Convert number_str to int or 0 if number_str is not a number.""" if number_str.isdigit():