Wikipedia:Dugnadskontor/Opprydding interwiki/Interwiki/script
Dette er et script skrevet i python og baserer seg på å benytte deler av Pywikibot-rammeverket (xmlreader). Det plasseres under scripts/-katalogen som check_for_interwiki.py og kalles opp slik:
$ python pwb.py check_for_interwiki.py nowiki-xml-fil.xml 2> output.txt
Scriptet skriver til STDERR og dette må altså omdirigeres til den fila du ønsker å skrive til (i eksempelet til "output.txt").
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
check_for_interwiki.py - a quick script checking for interwiki-links in wikitext from XML-dump on nowiki
"""
#
# Copyright (C) 2016 Stig Meireles Johansen (stigmjATgmail.com)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import re
import pywikibot
from pywikibot import xmlreader
checklist = [
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(a[abfkmnrsvyz]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ace\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(als\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ang\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(arc\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(arz\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ast\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(azb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(b[aeghimnors]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bar\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bat-smg\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bcl\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(be-tarask\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bjn\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bpy\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bug\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(bxr\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(c[aehorsuvy]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(cbk-zam\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(cdo\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ceb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(cho\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(chr\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(chy\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ckb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(crh\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(csb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(d[aevz]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(diq\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(dsb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(e[elnostu]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(eml\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ext\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(f[afijory]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(fiu-vro\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(frp\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(frr\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(fur\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(g[adlnuv]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(gag\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(gan\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(glk\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(gom\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(got\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(h[aeiortuyz]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(hak\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(haw\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(hif\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(hsb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(i[adegikostu]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ilo\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(j[av]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(jbo\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(k[agijklmnorsuvwy]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(kaa\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(kab\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(kbd\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(koi\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(krc\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ksh\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(l[abginotv]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(lad\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(lbe\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(lez\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(lij\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(lmo\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(lrc\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(ltg\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mai\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(map-bms\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mdf\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(m[ghiklnorsty]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mhr\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(min\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mrj\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mus\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mwl\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(myv\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(mzn\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(n[aeglnovy]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nah\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nap\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nds\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nds-nl\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(new\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nov\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nrm\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(nso\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(o[cmrs]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(p[ailst]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pag\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pam\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pap\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pcd\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pdc\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pfl\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pih\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pms\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pnb\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(pnt\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(qu\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(r[mnouw]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(rmy\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(roa-rup\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(roa-tara\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(rue\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(s[acdeghisklmnoqrstuvw]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(sah\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(scn\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(sco\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(simple\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(srn\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(stq\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(szl\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(t[aeghiklnorstwy]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(tet\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(tpi\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(tum\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(tyv\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(udm\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(u[gkrz]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(v[eio]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(vec\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(vep\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(vls\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(w[ao]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(war\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(wuu\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(xal\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(xh\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(xmf\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(y[io]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(z[ahu]\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(zea\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(zh-classical\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(zh-min-nan\:[^\]\#]+)]]'),
re.compile(r'\n\s*(?:<!--.*-->)*(?:<!--){0}\s*\[\[\s*(zh-yue\:[^\]\#]+)]]'),
]
specialcases = re.compile(r'^(?:category|kategori|file|fil|media|medium)\:', re.I)
for page in xmlreader.XmlDump(sys.argv[1]).parse():
if specialcases.match(page.title):
new_title = ":%s" % page.title
else:
new_title = page.title
output = "* [[%s]] (" % (new_title)
found = 0
for checkR in checklist:
m = checkR.finditer(page.text)
if m:
for match in m:
prefix = ''
if found:
prefix = ', '
output = "%s%s[[:%s]]" % (output, prefix, match.group(1))
found = 1
if found:
pywikibot.output( "%s)" % (output))