feat: improve error handling and add special projects

Enhanced error handling for fetching Wikimedia projects with specific log messages for various exceptions including JSON decode, HTTP error, and URL error. Introduced support for "special" Wikimedia projects and updated functions to handle missing base URLs by checking special projects. Added detailed debug logging in `wiki_article` function for debugging failed article fetches.

style: add CSS rules for Wikidata content

Implemented new CSS styles for improved display and readability of Wikidata content elements such as entity views, statements, and references. These styles enhance the user interface, making it cleaner and more user-friendly.

Fixes #27.
This commit is contained in:
Kumi 2024-08-28 07:52:09 +02:00
parent 4d47441fdb
commit 286a73cbc6
Signed by: kumi
GPG key ID: ECBCC9082395383F
2 changed files with 201 additions and 10 deletions

View file

@ -51,8 +51,21 @@ def get_wikimedia_projects() -> (
- The language name. - The language name.
""" """
url = "https://meta.wikimedia.org/w/api.php?action=sitematrix&format=json" url = "https://meta.wikimedia.org/w/api.php?action=sitematrix&format=json"
with urllib.request.urlopen(url) as response: with urllib.request.urlopen(url, timeout=30) as response:
data = json.loads(response.read().decode()) try:
data = json.loads(response.read().decode())
except json.JSONDecodeError as e:
logger.fatal("Error decoding JSON response")
raise
except urllib.error.HTTPError as e:
logger.fatal(f"HTTP error fetching Wikimedia projects and languages: {e}")
raise
except urllib.error.URLError as e:
logger.fatal(f"URL error fetching Wikimedia projects and languages: {e}")
raise
except Exception as e:
logger.fatal("Error fetching Wikimedia projects and languages")
raise
projects = {} projects = {}
languages = {} languages = {}
@ -75,6 +88,30 @@ def get_wikimedia_projects() -> (
"name": language, "name": language,
} }
languages["special"] = {
"projects": {},
"name": "Special",
}
for special in data["sitematrix"]["specials"]:
sitename = special["sitename"]
code = special["code"]
language_code = special["lang"]
if sitename == "Wikipedia":
logger.warning(
f"Wikipedia special project {code} in {language_code} has site name {sitename}"
)
sitename = code
if language_code not in languages:
language_code = "special"
if code not in projects:
projects[code] = sitename
languages[language_code]["projects"][code] = special["url"]
return projects, languages return projects, languages
@ -213,6 +250,10 @@ def wiki_article(
language_projects = app.languages.get(lang, {}).get("projects", {}) language_projects = app.languages.get(lang, {}).get("projects", {})
base_url = language_projects.get(project) base_url = language_projects.get(project)
if not base_url:
special_projects = app.languages.get("special", {}).get("projects", {})
base_url = special_projects.get(project)
if not base_url: if not base_url:
return ( return (
render_template( render_template(
@ -250,6 +291,8 @@ def wiki_article(
) )
else: else:
logger.error(f"Error fetching article {title} from {lang}.{project}: {e}") logger.error(f"Error fetching article {title} from {lang}.{project}: {e}")
logger.debug(f"Attempted URL: {api_request.full_url}")
logger.debug(f"Response: {e.read()}")
return ( return (
render_template( render_template(
"article.html", "article.html",
@ -381,6 +424,10 @@ def search_results(
language_projects = app.languages.get(lang, {}).get("projects", {}) language_projects = app.languages.get(lang, {}).get("projects", {})
base_url = language_projects.get(project) base_url = language_projects.get(project)
if not base_url:
special_projects = app.languages.get("special", {}).get("projects", {})
base_url = special_projects.get(project)
if not base_url: if not base_url:
return ( return (
render_template( render_template(
@ -441,13 +488,16 @@ def index_php_redirect(project, lang) -> Response:
try: try:
url = f"{app.languages[lang]['projects'][project]}/w/api.php?action=query&format=json&meta=siteinfo&siprop=general" url = f"{app.languages[lang]['projects'][project]}/w/api.php?action=query&format=json&meta=siteinfo&siprop=general"
except KeyError: except KeyError:
return ( try:
render_template( url = f"{app.languages['special']['projects'][project]}/w/api.php?action=query&format=json&meta=siteinfo&siprop=general"
"article.html", except KeyError:
title="Project does not exist", return (
content=f"Sorry, the project {project} does not exist in the {lang} language.", render_template(
), "article.html",
) title="Project does not exist",
content=f"Sorry, the project {project} does not exist in the {lang} language.",
),
)
with urllib.request.urlopen(url) as response: with urllib.request.urlopen(url) as response:
data = json.loads(response.read().decode()) data = json.loads(response.read().decode())
main_page = data["query"]["general"]["mainpage"] main_page = data["query"]["general"]["mainpage"]

View file

@ -938,7 +938,8 @@ Currently blocked by implementation of comments retrieval in the backend
} }
.mw-reflink-text.decimal::before { .mw-reflink-text.decimal::before {
content: "[" counter(mw-Ref, decimal) "]";; content: "[" counter(mw-Ref, decimal) "]";
;
} }
.mw-reflink-text::before { .mw-reflink-text::before {
@ -953,6 +954,146 @@ Currently blocked by implementation of comments retrieval in the backend
font-size: 0; font-size: 0;
} }
/* Wikidata content styling */
.wikibase-entityview-main {
display: flex;
flex-direction: column;
}
.wikibase-entitytermsview-heading {
margin-bottom: 20px;
}
.wikibase-entitytermsview-heading-description {
font-size: 1.1em;
color: #333;
}
.wikibase-entitytermsview-heading-aliases {
font-size: 0.9em;
color: #555;
}
.wikibase-entitytermsview-aliases-alias {
display: inline-block;
margin-right: 10px;
}
.wikibase-toolbar-container {
margin-top: 10px;
}
.wikibase-toolbar-button-edit {
color: #1e90ff;
text-decoration: none;
}
.wikibase-statementgrouplistview {
margin-top: 20px;
}
.wikibase-statementgroupview {
margin-bottom: 20px;
}
.wikibase-statementgroupview-property-label {
font-weight: bold;
color: #333;
}
.wikibase-statementlistview {
margin-top: 10px;
}
.wikibase-statementview {
border-top: 1px solid #ddd;
padding: 10px 0;
}
.wikibase-statementview-mainsnak {
display: flex;
align-items: center;
}
.wikibase-snakview-property-container {
margin-right: 10px;
}
.wikibase-snakview-value-container {
flex: 1;
}
.wikibase-snakview-value a {
color: #1e90ff;
text-decoration: none;
}
.wikibase-snakview-value a:hover {
text-decoration: underline;
}
.wikibase-statementview-references-container {
margin-top: 10px;
padding: 10px;
background-color: #f9f9f9;
border: 1px solid #ddd;
}
.wikibase-statementview-references-heading {
font-weight: bold;
margin-bottom: 5px;
}
.wikibase-statementview-references {
font-size: 0.9em;
}
.wikibase-statementview-references a {
color: #1e90ff;
}
.wikibase-sitelinkgrouplistview {
margin-top: 20px;
}
.wikibase-sitelinkgroupview-heading-container {
display: flex;
align-items: center;
justify-content: space-between;
}
.wikibase-sitelinkgroupview-heading {
font-size: 1.2em;
font-weight: bold;
}
.wikibase-sitelinkview {
margin: 5px 0;
}
.wikibase-sitelinkview-siteid {
font-weight: bold;
margin-right: 10px;
}
.wikibase-sitelinkview-link a {
color: #1e90ff;
text-decoration: none;
}
.wikibase-sitelinkview-link a:hover {
text-decoration: underline;
}
.wikibase-sitelinkgroupview-counter {
margin-left: 1em;
}
.wikibase-toolbar-container,
.wikibase-entitytermsview-entitytermsforlanguagelistview {
display: none;
}
/* Media query for devices with a max width of 768px */ /* Media query for devices with a max width of 768px */
@media (max-width: 768px) { @media (max-width: 768px) {
#header { #header {