User:Uo4tie/bot/wikitext_parser.py
Python code to copy the informations in the sidebar of the Key:* and Tag:* description pages to the data item via MediaWiki Action API. See the Not copied ... categories in Category:Data item issues.
Copyright (C) 2026 uo4tie
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- User:Uo4tie/bot
- User:Uo4tie/bot/control.py
- User:Uo4tie/bot/wikibase.py
- User:Uo4tie/bot/wikitext_parser.py
- User:Uo4tie/bot/category.py
- User:Uo4tie/bot/login.py
#! /usr/bin/python3
"""
adapted from MediaWiki API Demos at https://www.mediawiki.org/wiki/API:Categorymembers under MIT License; assisted by AI
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
def extract_param(data, template_name, param_name):
text = data.get("parse", {}).get("wikitext", {}).get("*", "")
# --- 1. Die gesuchte Vorlage inkl. Verschachtelung isolieren ---
start = text.find("{{" + template_name)
if start == -1:
return None
depth, i = 1, start + 2
while i < len(text) and depth:
if text.startswith("{{", i):
depth += 1; i += 2
elif text.startswith("}}", i):
depth -= 1; i += 2
else:
i += 1
body = text[start + 2 : i - 2] # Inhalt zwischen {{ ... }}
# --- 2. Body an Top-Level-Pipes '|' trennen (ignoriert | in {{...}}) ---
parts, cur, depth, eq = [], "", 0, -1
j = 0
while j < len(body):
if body.startswith("{{", j):
depth += 1; cur += "{{"; j += 2
elif body.startswith("}}", j):
depth -= 1; cur += "}}"; j += 2
else:
ch = body[j]; j += 1
if depth == 0 and ch == "|":
parts.append((cur, eq)); cur, eq = "", -1
else:
if depth == 0 and ch == "=" and eq == -1:
eq = len(cur) # erstes '=' auf oberster Ebene merken
cur += ch
parts.append((cur, eq))
# --- 3. Gesuchten Parameter heraussuchen ---
for value, eq in parts:
if eq > -1 and value[:eq].strip().lower() == param_name.strip().lower():
return value[eq + 1:].strip()
return None
def get_param_for_page(page_title,template,param):
import requests
S = requests.Session()
URL = "https://test.wiki.openstreetmap.org/w/api.php"
PARAMS = {
"action": "parse",
"page": page_title,
"prop": "wikitext",
"format": "json"
}
R = S.get(url=URL, params=PARAMS)
DATA = R.json()
return extract_param(DATA, template, param)