diff --git a/src/wikimore/app.py b/src/wikimore/app.py index afd1a37..65e14e2 100644 --- a/src/wikimore/app.py +++ b/src/wikimore/app.py @@ -51,8 +51,21 @@ def get_wikimedia_projects() -> ( - The language name. """ url = "https://meta.wikimedia.org/w/api.php?action=sitematrix&format=json" - with urllib.request.urlopen(url) as response: - data = json.loads(response.read().decode()) + with urllib.request.urlopen(url, timeout=30) as response: + 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 = {} languages = {} @@ -75,6 +88,30 @@ def get_wikimedia_projects() -> ( "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 @@ -213,6 +250,10 @@ def wiki_article( language_projects = app.languages.get(lang, {}).get("projects", {}) 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: return ( render_template( @@ -250,6 +291,8 @@ def wiki_article( ) else: 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 ( render_template( "article.html", @@ -381,6 +424,10 @@ def search_results( language_projects = app.languages.get(lang, {}).get("projects", {}) 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: return ( render_template( @@ -441,13 +488,16 @@ def index_php_redirect(project, lang) -> Response: try: url = f"{app.languages[lang]['projects'][project]}/w/api.php?action=query&format=json&meta=siteinfo&siprop=general" except KeyError: - return ( - render_template( - "article.html", - title="Project does not exist", - content=f"Sorry, the project {project} does not exist in the {lang} language.", - ), - ) + try: + url = f"{app.languages['special']['projects'][project]}/w/api.php?action=query&format=json&meta=siteinfo&siprop=general" + except KeyError: + return ( + 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: data = json.loads(response.read().decode()) main_page = data["query"]["general"]["mainpage"] diff --git a/src/wikimore/static/css/style.css b/src/wikimore/static/css/style.css index 5e1a3c5..7e58f71 100644 --- a/src/wikimore/static/css/style.css +++ b/src/wikimore/static/css/style.css @@ -938,7 +938,8 @@ Currently blocked by implementation of comments retrieval in the backend } .mw-reflink-text.decimal::before { - content: "[" counter(mw-Ref, decimal) "]";; + content: "[" counter(mw-Ref, decimal) "]"; + ; } .mw-reflink-text::before { @@ -953,6 +954,146 @@ Currently blocked by implementation of comments retrieval in the backend 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 (max-width: 768px) { #header {