From fa48e7d7507e17f7bc19922be6a3cb4d27289fd7 Mon Sep 17 00:00:00 2001 From: Adam Parr Date: Thu, 16 Jan 2025 20:29:02 +0000 Subject: [PATCH 1/2] Make Bing search async with separate search_page --- .gitignore | 3 ++ lute/bing/routes.py | 46 ++++++++++++++++---- lute/static/js/dict-tabs.js | 2 +- lute/templates/imagesearch/index.html | 60 ++++++++++++++++++++------- 4 files changed, 88 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 86c057218..d5843b61e 100644 --- a/.gitignore +++ b/.gitignore @@ -117,6 +117,9 @@ ENV/ env.bak/ venv.bak/ +# VS Code config +.vscode/ + # Spyder project settings .spyderproject .spyproject diff --git a/lute/bing/routes.py b/lute/bing/routes.py index 1750c4823..98e4ad827 100644 --- a/lute/bing/routes.py +++ b/lute/bing/routes.py @@ -5,12 +5,43 @@ import os import re import urllib.request -from flask import Blueprint, request, Response, render_template, jsonify, current_app +from flask import ( + Blueprint, + request, + Response, + render_template, + jsonify, + current_app, + url_for, +) bp = Blueprint("bing", __name__, url_prefix="/bing") +@bp.route( + "/search_page///", methods=["GET"] +) +def bing_search_page(langid, text, searchstring): + """ + Load initial empty search page, passing real URL for subsequent ajax call to get images. + + Sometimes Bing image searches block or fail, so providing the initial empty search page + lets the user know work is in progress. The user can therefore interact with the page + immediately. The template for this route then makes an ajax call to the "bing_search()" + method below which actually does the search. + """ + + # Create URL for bing_search and pass into template. + search_url = url_for( + "bing.bing_search", langid=langid, text=text, searchstring=searchstring + ) + + return render_template( + "imagesearch/index.html", langid=langid, text=text, search_url=search_url + ) + + @bp.route("/search///", methods=["GET"]) def bing_search(langid, text, searchstring): "Do an image search." @@ -60,12 +91,13 @@ def build_struct(image): # Also bing seems to throttle images if the count is higher (??). images = images[:25] - return render_template( - "imagesearch/index.html", - langid=langid, - text=text, - images=images, - error_message=error_msg, + return jsonify( + { + "langid": langid, + "text": text, + "images": images, + "error_message": error_msg, + } ) diff --git a/lute/static/js/dict-tabs.js b/lute/static/js/dict-tabs.js index 6c0624f0d..80ceabbcc 100644 --- a/lute/static/js/dict-tabs.js +++ b/lute/static/js/dict-tabs.js @@ -132,7 +132,7 @@ class ImageLookupButton extends GeneralLookupButton { const raw_bing_url = 'https://www.bing.com/images/search?q=[LUTE]&form=HDRSC2&first=1&tsc=ImageHoverTitle'; const binghash = raw_bing_url.replace('https://www.bing.com/images/search?', ''); - const url = `/bing/search/${LookupButton.LANG_ID}/${encodeURIComponent(use_text)}/${encodeURIComponent(binghash)}`; + const url = `/bing/search_page/${LookupButton.LANG_ID}/${encodeURIComponent(use_text)}/${encodeURIComponent(binghash)}`; iframe.setAttribute("src", url); }; // end handler diff --git a/lute/templates/imagesearch/index.html b/lute/templates/imagesearch/index.html index 66772c0b8..27f47ac1f 100644 --- a/lute/templates/imagesearch/index.html +++ b/lute/templates/imagesearch/index.html @@ -26,25 +26,10 @@ then paste from your clipboard.

- {% for image in images %} - - {{ image['html'] | safe }} - - {% endfor %} - - {% if error_message != "" %} -

Error contacting image server: {{ error_message }}

- {% endif %} From 4780be0ffa514d72d8f4d28df5d0d589c2f6b6db Mon Sep 17 00:00:00 2001 From: Jeff Zohrab Date: Fri, 31 Jan 2025 17:02:02 -0600 Subject: [PATCH 2/2] Add note re searching, report failures to UI. --- lute/bing/routes.py | 20 +++++++++++--------- lute/templates/imagesearch/index.html | 14 +++++++++++++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lute/bing/routes.py b/lute/bing/routes.py index 9f57d38ba..fa60d2677 100644 --- a/lute/bing/routes.py +++ b/lute/bing/routes.py @@ -67,7 +67,10 @@ def bing_search(langid, text, searchstring): content = s.read().decode("utf-8") except urllib.error.URLError as e: content = "" - error_msg = e.reason + error_msg = str(e.reason) + except Exception as e: # pylint: disable=broad-exception-caught + content = "" + error_msg = str(e) # Sample data returned by bing image search: # @@ -93,14 +96,13 @@ def build_struct(image): # Also bing seems to throttle images if the count is higher (??). images = images[:25] - return jsonify( - { - "langid": langid, - "text": text, - "images": images, - "error_message": error_msg, - } - ) + ret = { + "langid": langid, + "text": text, + "images": images, + "error_message": error_msg, + } + return jsonify(ret) def _get_dir_and_filename(langid, text): diff --git a/lute/templates/imagesearch/index.html b/lute/templates/imagesearch/index.html index 6f1eb07bf..82890ba8f 100644 --- a/lute/templates/imagesearch/index.html +++ b/lute/templates/imagesearch/index.html @@ -26,6 +26,8 @@ then paste from your clipboard.

+

Searching ...

+ @@ -135,6 +137,14 @@ type: 'GET', dataType: 'json', success: function(data) { + if (data.error_message !== "") { + const msg = `Error: ${data.error_message}`; + console.error(msg); + $("#image_search_feedback").text(msg); + return; + } + + $("#image_search_feedback").hide(); if (data.images.length === 0) { const p = document.createElement('p'); p.textContent = 'No images found.'; @@ -150,7 +160,9 @@ }); }, error: function(xhr, status, error) { - console.error(`Error ${error}; ${status}; ${xhr.responseText}`); + const msg = `Error ${error}; ${status}; ${xhr.responseText}`; + console.error(msg); + $("#image_search_feedback").val(msg); } }); });