feat: Add badge support to wiki articles
Fetches and displays badges for articles using the MediaWiki API. Updates templates to show badges as icons linking to detailed info. Adds CSS styling for badge presentation in the article view. Enhances user experience by providing additional context through quick-access badge information. Fixes #21.
This commit is contained in:
parent
5bd90742b0
commit
2167528f19
3 changed files with 75 additions and 3 deletions
|
@ -169,6 +169,7 @@ else:
|
||||||
"ar",
|
"ar",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def langsort(input: list[dict], key: str = "lang") -> list[dict]:
|
def langsort(input: list[dict], key: str = "lang") -> list[dict]:
|
||||||
"""Sorting of language data.
|
"""Sorting of language data.
|
||||||
|
|
||||||
|
@ -199,12 +200,17 @@ def langsort(input: list[dict], key: str = "lang") -> list[dict]:
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
logger.debug("Initialized language sort order")
|
logger.debug("Initialized language sort order")
|
||||||
|
|
||||||
app_languages = [{"lang": lang, "name": data["name"]} for lang, data in app.languages.items()]
|
app_languages = [
|
||||||
|
{"lang": lang, "name": data["name"]} for lang, data in app.languages.items()
|
||||||
|
]
|
||||||
app_languages = langsort(app_languages)
|
app_languages = langsort(app_languages)
|
||||||
|
|
||||||
app.languages = {lang: app.languages[lang] for lang in [lang["lang"] for lang in app_languages]}
|
app.languages = {
|
||||||
|
lang: app.languages[lang] for lang in [lang["lang"] for lang in app_languages]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def render_template(*args, **kwargs) -> Text:
|
def render_template(*args, **kwargs) -> Text:
|
||||||
|
@ -393,6 +399,56 @@ def wiki_article(
|
||||||
|
|
||||||
logger.debug(f"Request URL: {api_request.full_url}")
|
logger.debug(f"Request URL: {api_request.full_url}")
|
||||||
|
|
||||||
|
# Use the MediaWiki API to fetch any badges for the article
|
||||||
|
api_request_badges = urllib.request.Request(
|
||||||
|
f"{base_url}/w/api.php?action=query&format=json&titles={escape(quote(title.replace(' ', '_')), True)}&prop=pageprops",
|
||||||
|
headers=HEADERS,
|
||||||
|
)
|
||||||
|
|
||||||
|
badges = []
|
||||||
|
|
||||||
|
with urllib.request.urlopen(api_request_badges) as response:
|
||||||
|
logger.debug(f"Tried to fetch badges from {api_request_badges.full_url}")
|
||||||
|
data = json.loads(response.read().decode())
|
||||||
|
page = data["query"]["pages"].popitem()[1]
|
||||||
|
props = page.get("pageprops", {})
|
||||||
|
|
||||||
|
for prop in props:
|
||||||
|
if prop.startswith("wikibase-badge-"):
|
||||||
|
try:
|
||||||
|
badge_id = prop.replace("wikibase-badge-", "")
|
||||||
|
|
||||||
|
badge_request = urllib.request.Request(
|
||||||
|
f"https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids={badge_id}&languages={lang}",
|
||||||
|
headers=HEADERS,
|
||||||
|
)
|
||||||
|
|
||||||
|
with urllib.request.urlopen(badge_request) as badge_response:
|
||||||
|
logger.debug(
|
||||||
|
f"Tried to fetch badge {badge_id} from {badge_request.full_url}"
|
||||||
|
)
|
||||||
|
|
||||||
|
badge_data = json.loads(badge_response.read().decode())
|
||||||
|
|
||||||
|
badge = badge_data["entities"][badge_id]["labels"][lang][
|
||||||
|
"value"
|
||||||
|
]
|
||||||
|
badge_image = badge_data["entities"][badge_id]["claims"]["P18"][
|
||||||
|
0
|
||||||
|
]["mainsnak"]["datavalue"]["value"]
|
||||||
|
badges.append(
|
||||||
|
{
|
||||||
|
"title": badge,
|
||||||
|
"url": f"https://www.wikidata.org/wiki/{badge_id}",
|
||||||
|
"image": get_proxy_url(
|
||||||
|
f"https://commons.wikimedia.org/wiki/Special:Redirect/file/{badge_image}"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error fetching badge {prop}: {e}")
|
||||||
|
|
||||||
# Use the MediaWiki API to fetch interwiki links
|
# Use the MediaWiki API to fetch interwiki links
|
||||||
api_request_interwiki = urllib.request.Request(
|
api_request_interwiki = urllib.request.Request(
|
||||||
f"{base_url}/w/api.php?action=query&format=json&titles={escape(quote(title.replace(' ', '_')), True)}&prop=langlinks&lllimit=500",
|
f"{base_url}/w/api.php?action=query&format=json&titles={escape(quote(title.replace(' ', '_')), True)}&prop=langlinks&lllimit=500",
|
||||||
|
@ -622,6 +678,7 @@ def wiki_article(
|
||||||
rtl=rtl,
|
rtl=rtl,
|
||||||
license=license,
|
license=license,
|
||||||
interwiki=interwiki,
|
interwiki=interwiki,
|
||||||
|
badges=badges,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1316,3 +1316,7 @@ Currently blocked by implementation of comments retrieval in the backend
|
||||||
.language-selector-link:focus {
|
.language-selector-link:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
max-height: 1em;
|
||||||
|
}
|
|
@ -1,7 +1,18 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="title{% if rtl %} title-rtl{% endif %}">{{ title }}</h1>
|
<h1 class="title{% if rtl %} title-rtl{% endif %}">
|
||||||
|
{{ title }}
|
||||||
|
{% if badges %}
|
||||||
|
<span class="badges">
|
||||||
|
{% for badge in badges %}
|
||||||
|
<a href="{{ badge.url }}" class="badge" title="{{ badge.title }}">
|
||||||
|
<img src="{{ badge.image }}" alt="{{ badge.title }}">
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</h1>
|
||||||
{% if interwiki %}
|
{% if interwiki %}
|
||||||
<div class="language-selector">
|
<div class="language-selector">
|
||||||
<input type="checkbox" id="language-selector-toggle" class="language-selector-toggle">
|
<input type="checkbox" id="language-selector-toggle" class="language-selector-toggle">
|
||||||
|
|
Loading…
Reference in a new issue