sec06: 28 карточек (11✅/2🔶/15❌) + rulabel.py (ru labels как канал канонической кириллицы)
- Кросс-рефы: 01→sec01#05, 02→sec02#06, 03→sec01#32, 05→sec03#09, 06→sec01#15, 11→sec03#20
- Новые ✅: Eliade HRI («История веры и религиозных идей» Акад.проект 2008-09),
Otto «Священное» СПбГУ 2008, Kerényi «Дионис» ВРС 2007, MacCulloch Э/Эксмо 2018,
Schimmel «Мир исламского мистицизма» Садра 2012, Scholem 4 изд., von Franz CW6
(«Видения Николая из Флюэ…» Акад.проект 2025, rescue через rutitles diff)
- tools/rulabel.py: Wikidata ru label + aliases = каноническая кириллица
(VIAF/ISNI/GND/BnF с этой машины недоступны: 403/mёртвые API). Ловушки:
Циммер не Зиммер, Корбен не Корбин, Шолем не Шулем.
- AGENTS.md: источник 12 дополнен (rulabel.py + статус authority-APIs)
This commit is contained in:
parent
e758885774
commit
7b24100450
50 changed files with 786 additions and 17 deletions
63
tools/rulabel.py
Executable file
63
tools/rulabel.py
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python3
|
||||
"""tools/rulabel.py — каноническое кириллическое имя автора по Wikidata (ru label + ru aliases).
|
||||
|
||||
Идея (2026-09-24, предложил пользователь): authority-записи (VIAF/ISNI/GND) хранят имя во
|
||||
всех транскрипциях — но с этой машины VIAF (403 + JS-app), ISNI (403), GND (API mёртв,
|
||||
services.dnb.de → 404), BnF SRU (403) НЕДОСТУПНЫ. Wikidata-ru label/aliases доступны свободно
|
||||
и для известных людей = тот же канонический вариант (обычно взят из русскоязычных sources).
|
||||
|
||||
Использование:
|
||||
rulabel.py Q44847 # один QID
|
||||
rulabel.py Q1|Q2|Q3 # батч
|
||||
rulabel.py --find "Scholem, Gershom" # поиск (ОСТОРОЖНО: top-5, омонимы!)
|
||||
|
||||
Выход: <QID>\t<EN label>\t<ru label>\t<ru aliases (| разделены)>
|
||||
"""
|
||||
import json, sys, urllib.parse, urllib.request, time
|
||||
|
||||
UA = "jung-research/1.0 (research script; contact dmitry@kokorin.org)"
|
||||
|
||||
def api(params):
|
||||
url = "https://www.wikidata.org/w/api.php?" + urllib.parse.urlencode(params)
|
||||
req = urllib.request.Request(url, headers={"User-Agent": UA})
|
||||
for attempt in range(4):
|
||||
try:
|
||||
return json.load(urllib.request.urlopen(req, timeout=45))
|
||||
except Exception as e:
|
||||
if attempt == 3:
|
||||
raise
|
||||
time.sleep(15 * (attempt + 1))
|
||||
|
||||
def show(qid, e):
|
||||
lab_en = e.get("labels", {}).get("en", {}).get("value", "")
|
||||
lab_ru = e.get("labels", {}).get("ru", {}).get("value")
|
||||
al_ru = [a["value"] for a in e.get("aliases", {}).get("ru", [])]
|
||||
print(f"{qid}\t{lab_en}\t{lab_ru or '—'}\t{' | '.join(al_ru) or '—'}")
|
||||
|
||||
def main():
|
||||
args = sys.argv[1:]
|
||||
if not args:
|
||||
sys.exit(__doc__)
|
||||
if args[0] == "--find":
|
||||
query = args[1]
|
||||
d = api({"action": "wbsearchentities", "search": query, "language": "en",
|
||||
"type": "item", "limit": 5, "format": "json"})
|
||||
for r in d.get("search", []):
|
||||
print(f" {r['id']}\t{r.get('label','?')}\t{r.get('description','')[:70]}")
|
||||
qids = [r["id"] for r in d.get("search", [])]
|
||||
else:
|
||||
qids = args[0].split("|")
|
||||
if not qids:
|
||||
return
|
||||
d = api({"action": "wbgetentities", "ids": "|".join(qids),
|
||||
"props": "labels|aliases", "languages": "en|ru", "format": "json"})
|
||||
for qid in qids:
|
||||
e = d.get("entities", {}).get(qid)
|
||||
if e:
|
||||
show(qid, e)
|
||||
else:
|
||||
print(f"{qid}\tMISSING\t\t")
|
||||
time.sleep(2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue