diff --git a/dab_mechanic/wikipedia.py b/dab_mechanic/wikipedia.py index 8ee58d1..96eb110 100644 --- a/dab_mechanic/wikipedia.py +++ b/dab_mechanic/wikipedia.py @@ -186,6 +186,9 @@ class Article: a.set("href", "https://en.wikipedia.org" + href) a.set("target", "_blank") + def dab_link_to(self): + return [dab["link_to"] for dab in self.dab_list] + def process_links(self) -> None: """Process links in parsed wikitext.""" for dab_num, (a, link_to, title) in enumerate(self.iter_links()): diff --git a/templates/article.html b/templates/article.html index 3f8ec6a..87680b0 100644 --- a/templates/article.html +++ b/templates/article.html @@ -54,7 +54,7 @@ a.new { color: red; }

{{ article.enwiki }}

- +
@@ -62,8 +62,9 @@ a.new { color: red; }
There are {{ article.dab_list | count }} links in the article that need disambiguating.
{% for dab in article.dab_list %}
-

{{ dab.title }}

- {% if dab.title != dab.link_to %}
redirect from {{ dab.link_to }}
{% endif %} +
+

{{ dab.title }}

+ {% if dab.title != dab.link_to %}
redirect from {{ dab.link_to }}
{% endif %}
highlight link @@ -73,6 +74,7 @@ a.new { color: red; }
{{ dab.html | safe }}
+
{% endfor %}
@@ -85,8 +87,8 @@ a.new { color: red; } var edit_set = new Set(); var edits = {}; - var dab_lookup = {{ article.dab_lookup | tojson }}; var dab_order = {{ article.dab_order | tojson }}; + var dab_link_to = {{ article.dab_link_to() | tojson }}; var dab_links = document.getElementsByClassName("disambig"); for(var i=0; i edits[t]).map(t => [t, edits[t]]); + var saves = dab_link_to.map((link_to, num) => ( + {"num": num, "link_to": link_to, "title": edits[num]})); var save_edits = document.getElementById("save-edits"); save_edits.value = JSON.stringify(saves); } @@ -166,7 +169,7 @@ a.new { color: red; } document.getElementById("cancel-" + dab_num).classList.remove("d-none"); var title = element.getAttribute("title"); - edits[dab_lookup[dab_num]] = title; + edits[dab_num] = title; edit_set.add(dab_num); update_edits(); @@ -188,7 +191,7 @@ a.new { color: red; } } function cancel_selection(dab_num) { - delete edits[dab_lookup[dab_num]]; + delete edits[dab_num]; document.getElementById("cancel-" + dab_num).classList.add("d-none"); clear_dab_highlight(dab_num); edit_set.delete(dab_num); diff --git a/templates/preview.html b/templates/preview.html index 7bd28a5..68fa693 100644 --- a/templates/preview.html +++ b/templates/preview.html @@ -4,15 +4,33 @@ {{ title }} – dab mechanic +
-

Save edits: {{ title }}

-

Edit summary: {{ edit_summary }}

-
-
-
{{ text }}
+

Preview of changes: {{ title }}

+
+
+
Edit summary
+

{{ edit_summary }}

+
+ {#
{{ text }}
#} + + + + + + + + + + {{ diff | safe }} + +
+ + + diff --git a/web_view.py b/web_view.py index 2730f23..cfdff71 100755 --- a/web_view.py +++ b/web_view.py @@ -3,7 +3,8 @@ import inspect import json import re -from typing import Optional +from typing import Optional, TypedDict +import mwparserfromhell import flask import lxml.html @@ -73,19 +74,22 @@ def index(): return flask.render_template("index.html", articles=articles) -def make_disamb_link(edit: tuple[str, str]) -> str: - """Given an edit return the appropriate link.""" - return f"[[{edit[1]}|{edit[0]}]]" +class Edit(TypedDict): + """Edit to an article.""" + + num: int + link_to: str + title: str -def apply_edits(article_text: str, edits: list[tuple[str, str]]) -> str: +def apply_edits(article_text: str, edits: list[Edit]) -> str: """Apply edits to article text.""" def escape(s: str) -> str: return re.escape(s).replace("_", "[ _]").replace(r"\ ", "[ _]") - for link_from, link_to in edits: - print(rf"\[\[{escape(link_from)}\]\]") + for edit in edits: + # print(rf"\[\[{escape(link_from)}\]\]") article_text = re.sub( rf"\[\[{escape(link_from)}\]\]", f"[[{link_to}|{link_from}]]", @@ -95,31 +99,61 @@ def apply_edits(article_text: str, edits: list[tuple[str, str]]) -> str: return article_text -@app.route("/save/", methods=["POST"]) -def save(enwiki: str) -> Response | str: - """Save edits to article.""" - edits = [ - (link_to, link_from) - for link_to, link_from in json.loads(flask.request.form["edits"]) - ] +def make_disamb_link(edit: Edit) -> str: + """Given an edit return the appropriate link.""" + return f"[[{edit['title']}|{edit['link_to']}]]" - enwiki = enwiki.replace("_", " ") + +def build_edit_summary(edits: list[Edit]) -> str: + """Given a list of edits return an edit summary.""" titles = ", ".join(make_disamb_link(edit) for edit in edits[:-1]) if len(titles) > 1: titles += " and " titles += make_disamb_link(edits[-1]) - edit_summary = f"Disambiguate {titles} using [[User:Edward/Dab mechanic]]" + return f"Disambiguate {titles} using [[User:Edward/Dab mechanic]]" - article_text = apply_edits(mediawiki_api.get_content(enwiki), edits) +def get_links(wikicode, edits): + dab_titles = {dab["link_to"] for dab in edits} + return [ + link for link in wikicode.filter_wikilinks() if str(link.title) in dab_titles + ] + + +@app.route("/preview/", methods=["POST"]) +def preview(enwiki: str) -> Response | str: + """Save edits to article.""" + enwiki = enwiki.replace("_", " ") + + dab_links = json.loads(flask.request.form["edits"]) + edits = [edit for edit in dab_links if edit.get("title")] + + edit_summary = build_edit_summary(edits) + # return flask.jsonify(edits=dab_links, edit_summary=edit_summary) + + text = mediawiki_api.get_content(enwiki) + wikicode = mwparserfromhell.parse(text) + links = get_links(wikicode, dab_links) + assert len(links) == len(dab_links) + + for wikilink, edit in zip(links, dab_links): + print(edit, wikilink) + if not edit.get("title"): + continue + if not wikilink.text: + wikilink.text = wikilink.title + wikilink.title = edit["title"] + + diff = mediawiki_api.compare(enwiki, str(wikicode)) return flask.render_template( - "save.html", + "peview.html", edit_summary=edit_summary, title=enwiki, - edits=edits, - text=article_text, + edits=dab_links, + # text=str(wikicode), + diff=diff, )