Add redirect support, live candidate list, per-article save count, and error pages
- Detect redirect targets (e.g. "handling stolen goods" → "Possession of stolen goods") and use piped links [[target|title]] in edits; exclude articles already linking to the redirect target from candidates - Remove candidates from the list in real time as they are checked and found invalid, with live count update in the summary - Track and display per-article save count in the stats line - Rename "Find Link" to "Missing Link" throughout - Show redirect target in the article heading - Report save errors to the user via error page instead of crashing - Filter self-links using case-insensitive first-letter comparison Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0239b83555
commit
c9b4e2face
3 changed files with 64 additions and 17 deletions
47
web_view.py
47
web_view.py
|
|
@ -96,14 +96,20 @@ def search_count(q: str) -> int:
|
|||
return get_hit_count(article_title_to_search_query(q)) - 1
|
||||
|
||||
|
||||
def search_count_with_link(q: str) -> int:
|
||||
def search_count_with_link(q: str, redirect_to: str | None = None) -> int:
|
||||
"""Articles in Wikipedia that include this search term and a link."""
|
||||
return get_hit_count(article_title_to_search_query(q) + f' linksto:"{q}"')
|
||||
count = get_hit_count(article_title_to_search_query(q) + f' linksto:"{q}"')
|
||||
if redirect_to:
|
||||
count += get_hit_count(article_title_to_search_query(q) + f' linksto:"{redirect_to}"')
|
||||
return count
|
||||
|
||||
|
||||
def search_no_link(q: str) -> tuple[int, list[Hit]]:
|
||||
def search_no_link(q: str, redirect_to: str | None = None) -> tuple[int, list[Hit]]:
|
||||
"""Search for mentions of article title with no link included."""
|
||||
query = run_search(article_title_to_search_query(q) + f' -linksto:"{q}"', "max")
|
||||
exclude = f' -linksto:"{q}"'
|
||||
if redirect_to:
|
||||
exclude += f' -linksto:"{redirect_to}"'
|
||||
query = run_search(article_title_to_search_query(q) + exclude, "max")
|
||||
return (query["searchinfo"]["totalhits"], query["search"])
|
||||
|
||||
|
||||
|
|
@ -313,9 +319,15 @@ def handle_post(url_title: str) -> Response:
|
|||
do_save(from_title, hit_title)
|
||||
except mediawiki_oauth.LoginNeeded:
|
||||
return flask.redirect(flask.url_for("start_oauth"))
|
||||
except mediawiki_api.APIError as e:
|
||||
return flask.make_response(f"Save failed: {e}", 502)
|
||||
except (mediawiki_api.APIError, api.MediawikiError) as e:
|
||||
return flask.make_response(
|
||||
flask.render_template("error.html", message=f"Save failed: {e}"), 502
|
||||
)
|
||||
flask.session["saves"] = flask.session.get("saves", 0) + 1
|
||||
saves_by_title: dict[str, int] = flask.session.get("saves_by_title", {})
|
||||
saves_by_title[from_title] = saves_by_title.get(from_title, 0) + 1
|
||||
flask.session["saves_by_title"] = saves_by_title
|
||||
flask.session.modified = True
|
||||
_record_skip(from_title, hit_title)
|
||||
return flask.redirect(
|
||||
flask.url_for("article_page", url_title=url_title, after=hit_title)
|
||||
|
|
@ -330,10 +342,15 @@ def article_page(url_title: str) -> str | Response:
|
|||
|
||||
from_title = url_title.replace("_", " ").strip()
|
||||
|
||||
try:
|
||||
redirect_to = api.get_wiki_info(from_title)
|
||||
except (api.MissingPage, api.MultipleRedirects, api.MediawikiError):
|
||||
redirect_to = None
|
||||
|
||||
try:
|
||||
total = search_count(from_title)
|
||||
with_link = search_count_with_link(from_title)
|
||||
_no_link_count, hits = search_no_link(from_title)
|
||||
with_link = search_count_with_link(from_title, redirect_to)
|
||||
_no_link_count, hits = search_no_link(from_title, redirect_to)
|
||||
except api.MediawikiError as e:
|
||||
return flask.make_response(
|
||||
flask.render_template("error.html", message=str(e)), 502
|
||||
|
|
@ -362,13 +379,17 @@ def article_page(url_title: str) -> str | Response:
|
|||
if not hits:
|
||||
return flask.render_template("all_done.html")
|
||||
|
||||
saves_this_session = flask.session.get("saves_by_title", {}).get(from_title, 0)
|
||||
|
||||
return flask.render_template(
|
||||
"article.html",
|
||||
title=from_title,
|
||||
redirect_to=redirect_to,
|
||||
total=total,
|
||||
with_link=with_link,
|
||||
hits=hits,
|
||||
url_title=url_title,
|
||||
saves_this_session=saves_this_session,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -376,7 +397,12 @@ def do_save(title: str, hit_title: str) -> str:
|
|||
"""Update page on Wikipedia."""
|
||||
token = mediawiki_oauth.get_token()
|
||||
|
||||
found = get_match(title, hit_title, None)
|
||||
try:
|
||||
redirect_to = api.get_wiki_info(title)
|
||||
except (api.MissingPage, api.MultipleRedirects, api.MediawikiError):
|
||||
redirect_to = None
|
||||
|
||||
found = get_match(title, hit_title, redirect_to)
|
||||
|
||||
summary = (
|
||||
f"link [[{found['replacement']}]] using [[:en:User:Edward/Find link|Find link]]"
|
||||
|
|
@ -417,9 +443,10 @@ def api_valid_hit() -> werkzeug.wrappers.response.Response:
|
|||
"""Check if a candidate article has a valid unlinked mention."""
|
||||
link_to = flask.request.args["link_to"]
|
||||
link_from = flask.request.args["link_from"]
|
||||
redirect_to = flask.request.args.get("redirect_to") or None
|
||||
|
||||
try:
|
||||
found = get_diff(link_to, link_from, None)
|
||||
found = get_diff(link_to, link_from, redirect_to)
|
||||
except NoMatch:
|
||||
_record_skip(link_to, link_from)
|
||||
return flask.jsonify(valid=False)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue