import pywikibot
import re
from pywikibot import pagegenerators
import itertools

site = pywikibot.Site('de')

anchorRegLeft  = '(?P<left>((((region|REGION|Region)(-ISO| ISO|ISO|-iso| iso|)|ISO-CODE|ISO-Code)\s*=)|\{\{Einbindung von Wikidata-Koordinate\s*\|[a-z12\s]+\|)\s*([A-Z]+(\-[A-Z0-9]+)?\/)*)'
anchorRegRight = '(?P<right>[^A-Z0-9\-])' # do mot match only part of code
# match parameter names
# match ' = '
# match multi regions like AT-7/DE-BY
# alternatively match {{Einbindung von Wikidata-Koordinate|landmark|PL-LD}}
anchorRefLeft  = '\g<left>' # refer to match of anchorReg
anchorRefRight = '\g<right>'

# sample replacement
# out = re.sub(r"(((region|REGION|Region)(-ISO| ISO|-iso| iso|)|ISO-CODE|ISO-Code)\s*=\s*([A-Z]+(\-[A-Z0-9]+)?\/)*)CN-33","\g<1>CN-ZJ",out)

# global pages like global lists not matched by country category
# add new lists on demand
globalPageNames = [
                u'Global Stratotype Section and Point',
                u'Weltraumbahnhof',
                u'DP World',
                u'Eisenbahnteststrecke',
                u'Eisenbahnfährverbindung',
                u'Sprachvergleich_anhand_des_Vaterunsers',
                u'Liste von Regattastrecken',
                u'Links- und Rechtsverkehr',
                u'Liste der größten Bogenbrücken',
                u'Liste von Leuchttürmen in Asien',
                u'Liste_von_Leuchttürmen_in_Europa',
                u'Liste in der europäischen Expansion entdeckter Inseln',
                u'Liste der höchsten Leuchttürme der Welt',
                u'Liste der höchsten Inseln der Erde',
                u'Liste von Karstquellen',
                u'Liste europäischer Freilichtmuseen',
                u'Liste bedeutender Kletterrouten',
                u'Liste von Schaubergwerken',
                u'Liste der deutschen Feuerschiffspositionen',
                u'Liste der Einschlagkrater der Erde',
                u'Liste der höchsten Statuen',
                u'Liste von Bauernhofmuseen',
                u'Liste_von_Bauwerken_des_Brutalismus',
                u'Liste_von_Biathlonstrecken',
                u'Liste_von_hohen_Kreuzen',
                u'Liste_von_Radrennbahnen_in_Europa',
                u'Liste geographischer Mittelpunkte',
                u'Liste_von_Seehäfen',
              ]
globalPagesGenerator = []
for n in globalPageNames:
    globalPagesGenerator.append(pywikibot.Page(site, n))

namespaces = [0] # namespaces to operate on

# use the iso3166changer for irregular, externally triggered updates
# use the iso3166fixer for regular code fixes for only a small number of occurrences
class iso3166changer:
    """Describe the change needed for a set of ISO 3166 changes"""
    countryCode = '' # defined in derived class
    editcomment = '' # defined in derived class, without pre and post, or defaulted
    editcommentPre = 'ISO 3166 Bot: '
    #editcommentPost = '; weitere / offene Fehler unter https://quarry.wmflabs.org/query/11685'
    editcommentPost = ''
    isoRefDate = '' # reference date of publication of new set of iso codes, in German, effective date of change
    
    category = '' # root category, without namespace

    replacements = [] # an array of pairs, defined in derived class
    extraPagesNames = [] # list of special page names that are not matched by category, defined in derived class
    
    def execute(self, wikitext): # may be overwritten in derived class
        out = wikitext
        for i in range(len(self.replacements)):
            out = re.sub(anchorRegLeft+self.replacements[i][0]+anchorRegRight,
                         anchorRefLeft+self.replacements[i][1]+anchorRefRight,
                         out)
        return out
    def getEditcomment(self):
        if (self.editcomment == ''):
            return self.editcommentPre + 'ISO-Code Änderungen gemäß [[ISO 3166-2:' + self.countryCode + \
                ']] (https://www.iso.org/obp/ui/#iso:code:3166:' + self.countryCode + '), gültig seit ' + \
                self.isoRefDate + \
                self.editcommentPost
        else:
            return self.editcommentPre + self.editcomment + self.editcommentPost
    
    def extraPagesGenerator(self):
        "returns a page generator for the extra pages"
        extraPages = []
        for n in self.extraPagesNames:
            extraPages.append(pywikibot.Page(site, n))
        return extraPages
    
    def searchFilterGenerator(self):
        return None


class iso3166fixer(iso3166changer):
    # fix a set of mistakes found quite often
    def getEditcomment(self):
        if (self.editcomment == ''):
            return self.editcommentPre + 'ISO-Code Änderungen gemäß [[ISO 3166-2:' + self.countryCode + \
                ']], falschen Code korrigiert' + \
                self.editcommentPost
        else:
            return self.editcommentPre + self.editcomment + self.editcommentPost

    def searchFilterGenerator(self):
        if len(self.replacements) == 0:
            return None
        else:
            searchFilter = []
            for i in range(len(self.replacements)):
                search = 'insource:"' + self.replacements[i][0] + '" insource:/' + self.replacements[i][0] + '[^A-Z0-9\-]/'
                searchFilter.append(pagegenerators.SearchPageGenerator(search, namespaces=namespaces, site=site))
                print ('search filter:', search, 'added')
            if len(self.replacements) == 1:
                return searchFilter[0]
            else:
                return pagegenerators.CombinedPageGenerator(searchFilter) # OR the filters
# do not write back, for test only!
class TestChanger(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Verkehr (Berlin)'

    replacements = [
                ['DE-B', 'DE-BE'],
                ['DE-(BB|BE)',    'DE-XXX'], # does not match both in a line ??
                #['DE-BB',    'DE-XXX'],
                #['DE-BE',    'DE-XXX'],
            ]
class AL(iso3166changer):
    countryCode = 'AL' # Albanien
    category = 'Albanien'
    isoRefDate = '2015-11-27'

    replacements = [
                ['AL-(BR|KC|SK)',    'AL-01'],
                ['AL-(DR|KR)',       'AL-02'],
                ['AL-(EL|GR|LB|PQ)', 'AL-03'],
                ['AL-(FR|LU|MK)',    'AL-04'],
                ['AL-(GJ|PR|TE)',    'AL-05'],
                ['AL-(DV|ER|KO|PG)', 'AL-06'],
                ['AL-(HA|KU|TP)',    'AL-07'],
                ['AL-(KB|LE|MR)',    'AL-08'],
                ['AL-(BU|DI|MT)',    'AL-09'],
                ['AL-(MM|PU|SH)',    'AL-10'],
                ['AL-(KA|TR)',       'AL-11'],
                ['AL-(DL|SR|VL)',    'AL-12'],
            ]
class DE_BE(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Berlin'

    replacements = [
                ['DE-B', 'DE-BE'],
            ]
class DE_NI(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Niedersachsen'

    replacements = [
                ['DE-NS', 'DE-NI'],
            ]
class DE_NW(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Nordrhein-Westfalen'

    replacements = [
                ['DE-NRW', 'DE-NW'],
            ]
class DE_SL(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Saarland'

    replacements = [
                ['DE-SA', 'DE-SL'],
            ]
class DE_SN(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Sachsen'

    replacements = [
                ['DE-SA', 'DE-SN'],
            ]
class DE_ST(iso3166fixer):
    countryCode = 'DE' # Deutschland
    category = 'Sachsen-Anhalt'

    replacements = [
                ['DE-SA', 'DE-ST'],
            ]
class CN(iso3166fixer):
    countryCode = 'CN' # China
    category = 'China'
    isoRefDate = '2017-11-23'

    replacements = [
                ['CN-11', 'CN-BJ'],
                ['CN-12', 'CN-TJ'],
                ['CN-13', 'CN-HE'],
                ['CN-14', 'CN-SX'],
                ['CN-15', 'CN-NM'],
                ['CN-21', 'CN-LN'],
                ['CN-22', 'CN-JL'],
                ['CN-23', 'CN-HL'],
                ['CN-31', 'CN-SH'],
                ['CN-32', 'CN-JS'],
                ['CN-33', 'CN-ZJ'],
                ['CN-34', 'CN-AH'],
                ['CN-35', 'CN-FJ'],
                ['CN-36', 'CN-JX'],
                ['CN-37', 'CN-SD'],
                ['CN-41', 'CN-HA'],
                ['CN-42', 'CN-HB'],
                ['CN-43', 'CN-HN'],
                ['CN-44', 'CN-GD'],
                ['CN-45', 'CN-GX'],
                ['CN-46', 'CN-HI'],
                ['CN-50', 'CN-CQ'],
                ['CN-51', 'CN-SC'],
                ['CN-52', 'CN-GZ'],
                ['CN-53', 'CN-YN'],
                ['CN-54', 'CN-XZ'],
                ['CN-61', 'CN-SN'],
                ['CN-62', 'CN-GS'],
                ['CN-63', 'CN-QH'],
                ['CN-64', 'CN-NX'],
                ['CN-65', 'CN-XJ'],
                ['CN-71', 'CN-TW'],
                ['CN-91', 'CN-HK'],
                ['CN-92', 'CN-MO'],
            ]
    extraPagesNames = [
        u'Spratly-Inseln',
            ] 
class CZ(iso3166changer):
    countryCode = 'CZ' # Tschechien
    category = 'Prag'
    isoRefDate = '2018-11-26'

    replacements = [
                ['CZ-10[1-9]|CZ-11[0-9]|CZ-12[0-2]', 'CZ-10'], # subcodes of Prague
            ]
class DK_81(iso3166fixer):
    countryCode = 'DK' # Dänemark
    category = 'Region Nordjylland'

    replacements = [
                ['DK-070', 'DK-81'], # tw.
                ['DK-076', 'DK-81'], # tw.
                ['DK-080', 'DK-81'],
            ]
class DK_82(iso3166fixer):
    countryCode = 'DK' # Dänemark
    category = 'Region Midtjylland'

    replacements = [
                ['DK-065', 'DK-82'],
                ['DK-070', 'DK-82'], # tw.
                ['DK-076', 'DK-82'], # tw.
            ]
class DK_83(iso3166fixer):
    countryCode = 'DK' # Dänemark
    category = 'Region Syddanmark'

    replacements = [
                ['DK-042', 'DK-83'],
                ['DK-050', 'DK-83'],
                ['DK-055', 'DK-83'],
                ['DK-060', 'DK-83'],
            ]
class DK_84(iso3166fixer):
    countryCode = 'DK' # Dänemark
    category = 'Region Hovedstaden'

    replacements = [
                ['DK-015', 'DK-84'],
                ['DK-020', 'DK-84'],
                ['DK-040', 'DK-84'],
                ['DK-101', 'DK-84'],
                ['DK-147', 'DK-84'],
            ]
class DK_85(iso3166fixer):
    countryCode = 'DK' # Dänemark
    category = 'Region Sjælland'

    replacements = [
                ['DK-025', 'DK-85'],
                ['DK-030', 'DK-85'],
                ['DK-035', 'DK-85'],
            ]
class GL_QT(iso3166fixer):
    countryCode = 'GL' # Grönland
    category = 'Kommune Qeqertalik'
    isoRefDate = '2018-11-26'

    replacements = [
                ['GL-QA', 'GL-QT'], #aufgespalten
            ]

class GL_AV(iso3166fixer):
    countryCode = 'GL' # Grönland
    category = 'Avannaata Kommunia'
    isoRefDate = '2018-11-26'

    replacements = [
                ['GL-QA', 'GL-AV'], #aufgespalten
            ]
class GR(iso3166fixer):
    countryCode = 'GR' # Griechenland
    category = 'Griechenland'
    isoRefDate = '2016-11-15'

    replacements = [
                ['GR-A1', 'GR-I'],
                ['GR-01', 'GR-G'],
                ['GR-03', 'GR-H'],
                ['GR-04', 'GR-H'],
                ['GR-05', 'GR-H'],
                ['GR-06', 'GR-H'],
                ['GR-07', 'GR-H'],
                ['GR-11', 'GR-J'],
                ['GR-12', 'GR-J'],
                ['GR-13', 'GR-G'],
                ['GR-14', 'GR-G'],
                ['GR-15', 'GR-J'],
                ['GR-16', 'GR-J'],
                ['GR-17', 'GR-J'],
                ['GR-21', 'GR-F'],
                ['GR-22', 'GR-F'],
                ['GR-23', 'GR-F'],
                ['GR-24', 'GR-F'],
                ['GR-31', 'GR-D'],
                ['GR-32', 'GR-D'],
                ['GR-33', 'GR-D'],
                ['GR-34', 'GR-D'],
                ['GR-41', 'GR-E'],
                ['GR-42', 'GR-E'],
                ['GR-43', 'GR-E'],
                ['GR-44', 'GR-E'],
                ['GR-51', 'GR-C'],
                ['GR-52', 'GR-A'],
                ['GR-53', 'GR-B'],
                ['GR-54', 'GR-B'],
                ['GR-55', 'GR-A'],
                ['GR-56', 'GR-C'],
                ['GR-57', 'GR-B'],
                ['GR-58', 'GR-C'],
                ['GR-59', 'GR-B'],
                ['GR-61', 'GR-B'],
                ['GR-62', 'GR-B'],
                ['GR-63', 'GR-C'],
                ['GR-64', 'GR-B'],
                ['GR-71', 'GR-A'],
                ['GR-72', 'GR-A'],
                ['GR-73', 'GR-A'],
                ['GR-81', 'GR-L'],
                ['GR-82', 'GR-L'],
                ['GR-83', 'GR-K'],
                ['GR-84', 'GR-K'],
                ['GR-85', 'GR-K'],
                ['GR-91', 'GR-M'],
                ['GR-92', 'GR-M'],
                ['GR-93', 'GR-M'],
                ['GR-94', 'GR-M'],
            ]
class NO(iso3166changer):
    countryCode = 'NO' # Norwegen
    category = 'Norwegen'
    isoRefDate = '2018-11-26'

    replacements = [
                ['NO-(16|17)', 'NO-23'], # zusammengelegt
            ]
# list of local changers
NP = []
# mapping of districts to code
NP_map= [
    {
    'districts' : ['Bhojpur','Dhankuta','Ilam','Jhapa','Khotang','Morang','Okhaldhunga','Panchthar',
                   'Sankhuwasabha','Solukhumbu','Sunsari','Taplejung','Terhathum','Udayapur'],
    'code' : 'P1'
    },
    {
    'districts' : ['Bara','Dhanusha','Mahottari','Parsa','Rautahat','Saptari','Sarlahi','Siraha'],
    'code' : 'P2'
    },
    {
    'districts' : ['Bhaktapur','Chitwan','Dhading','Dolakha','Kathmandu','Kabhrepalanchok','Lalitpur',
                   'Makwanpur','Nuwakot','Ramechhap','Rasuwa','Sindhuli','Sindhupalchok'],
    'code' : 'P3'
    },
    {
    'districts' : ['Baglung','Gorkha','Kaski','Lamjung','Manang','Mustang','Myagdi','Parbat','Syangja','Tanahu'],
    'code' : 'P4'
    },
    {
    'districts' : ['Arghakhanchi','Banke','Bardiya','Dang Deukhuri','Gulmi','Kapilbastu','Palpa','Pyuthan','Rolpa','Rupandehi'],
    'code' : 'P5'
    },
    {
    'districts' : ['Dailekh','Dolpa','Humla','Jajarkot','Jumla','Kalikot','Mugu','Salyan','Surkhet'],
    'code' : 'P6'
    },
    {
    'districts' : ['Achham','Baitadi','Bajhang','Bajura','Dadeldhura','Darchula','Doti','Kailali','Kanchanpur'],
    'code' : 'P7'
    },
]

# list of local changers
NP = []
# mapping of districts to code
# 'NP-(BH|JA|NA|RA|SA)'
NP_map= [
    {
    'districts' : ['Khotang','Okhaldhunga','Solukhumbu','Udayapur'],
    'srccode' : 'NP-SA',
    'targcode' : 'NP-P1'
    },
    {
    'districts' : ['Bara','Dhanusha','Mahottari','Parsa','Rautahat','Saptari','Sarlahi','Siraha'],
    'srccode' : 'NP-(JA|NA|SA)',
    'targcode' : 'NP-P2'
    },
    {
    'districts' : ['Chitwan','Dolakha','Makwanpur','Ramechhap','Sindhuli'],
    'srccode' : 'NP-(JA|NA)',
    'targcode' : 'NP-P3'
    },
    {
    'districts' : ['Arghakhanchi','Gulmi','Kapilbastu','Palpa','Rupandehi'],
    'srccode' : 'NP-LU',
    'targcode' : 'NP-P5'
    },
    {
    'districts' : ['Banke','Bardiya','Dang Deukhuri','Pyuthan','Rolpa'],
    'srccode' : 'NP-(BH|RA)',
    'targcode' : 'NP-P5'
    },
    {
    'districts' : ['Dailekh','Jajarkot','Salyan','Surkhet'],
    'srccode' : 'NP-(BH|RA)',
    'targcode' : 'NP-P6'
    },
]

class NPall(iso3166changer):
    countryCode = 'NP' # Nepal
    category = 'Nepal'
    isoRefDate = '2018-11-26'

    replacements = [
                ['NP-(KO|ME)', 'NP-P1'],
                ['NP-BA',      'NP-P3'],
                ['NP-(DH|GA)', 'NP-P4'],
                ['NP-KA',      'NP-P6'],
                ['NP-(MA|SE)', 'NP-P7'],
            ]
NP = [NPall()]

for k in NP_map:
    for d in k['districts']:
        
        changer = type('NP'+d, (iso3166changer,), {
            'countryCode' : 'NP', # Nepal
            'category' : 'Distrikt '+d,
            'isoRefDate' : '2018-11-26',

            'replacements' : [
                        [k['srccode'], k['targcode']],
                    ],
            })
        i = changer()
        #print ("district cat=%s, code=%s\n" % (i.category, k['targcode']))
                        
        NP.append (i)
class PL(iso3166changer):
    countryCode = 'PL' # Polen
    category = 'Polen'
    isoRefDate = '2018-11-26'
    extraPagesNames = [
        u'Liste der Grenz- und Zufluchtskirchen Schlesiens',
        u'Liste der norddeutschen Megalithanlagen nach Sprockhoff-Nummer',
        u'Liste der Schrotholzkirchen in Österreichisch-Schlesien',
        u'Thingplatz (Thingbewegung)',
        ]
    
    replacements = [
                ['PL-DS', 'PL-02'],
                ['PL-KP', 'PL-04'],
                ['PL-LB', 'PL-08'],
                ['PL-LD', 'PL-10'],
                ['PL-LU', 'PL-06'],
                ['PL-MA', 'PL-12'],
                ['PL-MZ', 'PL-14'],
                ['PL-OP', 'PL-16'],
                ['PL-PD', 'PL-20'],
                ['PL-PK', 'PL-18'],
                ['PL-PM', 'PL-22'],
                ['PL-SK', 'PL-26'],
                ['PL-SL', 'PL-24'],
                ['PL-WN', 'PL-28'],
                ['PL-WP', 'PL-30'],
                ['PL-ZP', 'PL-32'],
            ]
class TW(iso3166changer):
    countryCode = 'TW' # Taiwan
    category = 'Taiwan'
    isoRefDate = '2016-11-15'

    replacements = [
                ['TW-TPQ', 'TW-TPE'],
                ['TW-KHQ', 'TW-KHH'],
            ]
class isoCodeChanger:
    def __init__(self, changer, test=False, stopAfter=0):
        self.changer = changer # type iso3166changer
        self.count   = 0
        self.successCount   = 0
        self.errCount  = 0
        self.test = test
        self.stopAfter = stopAfter
        self.editComment = self.changer.getEditcomment()
        self.extraPagesGenerator = self.changer.extraPagesGenerator()
    
    def execute(self):
        cat = pywikibot.Category(site,'Category:'+self.changer.category)
        searchFilter = self.changer.searchFilterGenerator()
        pages = itertools.chain (
                        self.changer.extraPagesGenerator(),
                        globalPagesGenerator,
                        pywikibot.tools.filter_unique (pagegenerators.CategorizedPageGenerator(cat,6))
                       )
        if searchFilter != None:
            pages = pagegenerators.intersect_generators ([searchFilter, pages])

        for page in pages:
            if page.isRedirectPage():
                print (page, 'is redirect')
            oldpage = page.get(get_redirect=True) # changing the redirect instead of the page it redirects to
            newpage= self.changer.execute(oldpage)
            if (oldpage != newpage):
                print (page, 'changed(%d)'% int(self.successCount+1))
                pywikibot.showDiff(oldpage, newpage)
                self.count = self.count + 1
                if (not self.test):
                    try: # might fail if no write access (as bot is not admin)
                        page.put(newpage, self.editComment, minor=True, botflag=True)
                        self.successCount = self.successCount + 1
                    except:                        
                        self.errCount = self.errCount + 1
                    pass
                
                if (self.count == self.stopAfter):
                    break
        if self.errCount > 0:
            print ('finished:', self.successCount, 'pages changed,', self.errCount, 'pages unchanged due to error.')
        else:
            print ('finished:', self.successCount, 'pages changed,')
### for tests only !!!
cc = isoCodeChanger (TestChanger(), test=True, stopAfter=0)
print (cc.editComment)
#print (cc.extraPagesGenerator)
cc.execute()
### irregular updates from outside (change of ISO codes on https://www.iso.org/obp/ui/#iso:code:)
#for c in [PL()]:
for c in NP:
    cc = isoCodeChanger (c, test=False, stopAfter=0)
    print (cc.editComment)
    #print (cc.extraPagesGenerator)
    cc.execute()
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Shringi]] is redirect
[[de:Moditse]] changed(1)
@@ -12 +12 @@ ***
- | REGION-ISO       = NP-DH/NP-P4 ***
+ | REGION-ISO       = NP-P4/NP-P4 ***

WARNING: API error badtoken: Invalid CSRF token.
Sleeping for 9.8 seconds, 2018-12-14 01:15:08
Page [[de:Moditse]] saved
[[de:Chhiv Himal]] changed(2)
@@ -11 +11 @@ ***
- | REGION-ISO       = NP-DH/NP-P4 ***
+ | REGION-ISO       = NP-P4/NP-P4 ***

Page [[de:Chhiv Himal]] saved
[[de:Khumjungar Himal]] changed(3)
@@ -11 +11 @@ ***
- | REGION-ISO       = NP-DH/NP-P4 ***
+ | REGION-ISO       = NP-P4/NP-P4 ***

Sleeping for 8.1 seconds, 2018-12-14 01:15:29
Page [[de:Khumjungar Himal]] saved
[[de:Purkung]] changed(4)
@@ -11 +11 @@ ***
- | REGION-ISO       = NP-GA/NP-P4 ***
+ | REGION-ISO       = NP-P4/NP-P4 ***

Sleeping for 8.1 seconds, 2018-12-14 01:15:39
Page [[de:Purkung]] saved
@@ -11 +11 @@ ***
- | REGION-ISO       = NP-GA/NP-P4 ***
+ | REGION-ISO       = NP-P4/NP-P4 ***

[[de:Putrun Himal]] changed(5)
Sleeping for 8.9 seconds, 2018-12-14 01:15:49
Page [[de:Putrun Himal]] saved
[[de:Thorong La]] changed(6)
@@ -4 +4 @@ ***
- | REGION-ISO        = NP-DH/NP-P4 ***
+ | REGION-ISO        = NP-P4/NP-P4 ***

Sleeping for 8.5 seconds, 2018-12-14 01:15:59
Page [[de:Thorong La]] saved
[[de:Tilicho Peak]] changed(7)
@@ -10 +10 @@ ***
- | REGION-ISO       = NP-GA/NP-P4 ***
+ | REGION-ISO       = NP-P4/NP-P4 ***

Sleeping for 8.3 seconds, 2018-12-14 01:16:09
Page [[de:Tilicho Peak]] saved
[[de:Lhotse Shar]] is redirect
[[de:Lobuche (Ostgipfel)]] is redirect
[[de:Langchung Kang]] is redirect
[[de:Chulu (Ostgipfel)]] is redirect
[[de:Chulu (Westgipfel)]] is redirect
[[de:Nuptse Nup II]] is redirect
[[de:Gurans Himal]] changed(8)
@@ -16 +16 @@ ***
- |REGION-ISO=NP-SE/NP-P7 ***
+ |REGION-ISO=NP-P7/NP-P7 ***

Page [[de:Gurans Himal]] saved
[[de:Nepalesen in Portugal]] is redirect
[[de:Bahnstrecke Jaynagar–Bijalpura]] is redirect
finished: 8 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Flughafen Lukla]] changed(1)
@@ -16 +16 @@ ***
- |Koordinate_Region=NP-SA ***
+ |Koordinate_Region=NP-P1 ***

Page [[de:Flughafen Lukla]] saved
[[de:Hillary Step]] changed(2)
@@ -34 +34 @@ ***
- {{Coordinate|NS=27.987468|EW=86.924828|type=landmark|region=NP-SA}} ***
+ {{Coordinate|NS=27.987468|EW=86.924828|type=landmark|region=NP-P1}} ***

Sleeping for 8.4 seconds, 2018-12-14 01:18:38
Page [[de:Hillary Step]] saved
[[de:Khumbi Yul Lha]] changed(3)
@@ -9 +9 @@ ***
- |REGION-ISO=NP-SA ***
+ |REGION-ISO=NP-P1 ***

Sleeping for 7.9 seconds, 2018-12-14 01:18:49
Page [[de:Khumbi Yul Lha]] saved
[[de:Lhotse Shar]] is redirect
[[de:Lobuche (Ostgipfel)]] is redirect
[[de:Tal des Schweigens]] changed(4)
@@ -24,3 +24,3 @@ ***
- * Eisbruch-Ende: {{Coordinate|NS=27/59/28/N|EW=86/52/20/E|text=DMS|name=Ende Eisbruch|region=NP-SA|type=landmark}} auf 6000 m ***
+ * Eisbruch-Ende: {{Coordinate|NS=27/59/28/N|EW=86/52/20/E|text=DMS|name=Ende Eisbruch|region=NP-P1|type=landmark}} auf 6000 m ***
- * Mitte des Tals: {{Coordinate|NS=27/58/51/N|EW=86/53/53/E|text=DMS|name=Mitte Tal des Schweigens|region=NP-SA|type=landmark}} auf 6400 m ***
+ * Mitte des Tals: {{Coordinate|NS=27/58/51/N|EW=86/53/53/E|text=DMS|name=Mitte Tal des Schweigens|region=NP-P1|type=landmark}} auf 6400 m ***
- * Ende des Tals:  {{Coordinate|NS=27/58/7/N|EW=86/54/41/E|text=DMS|name=Ende Tal des Schweigens|region=NP-SA|type=landmark}} auf 6780 m ***
+ * Ende des Tals:  {{Coordinate|NS=27/58/7/N|EW=86/54/41/E|text=DMS|name=Ende Tal des Schweigens|region=NP-P1|type=landmark}} auf 6780 m ***

@@ -29 +29 @@ ***
- {{Coordinate|NS=27/58/51/N|EW=86/53/53/E|type=landmark|elevation=6400|region=NP-SA}} ***
+ {{Coordinate|NS=27/58/51/N|EW=86/53/53/E|type=landmark|elevation=6400|region=NP-P1}} ***

Sleeping for 5.0 seconds, 2018-12-14 01:19:02
Page [[de:Tal des Schweigens]] saved
finished: 4 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Drolambaogletscher]] changed(1)
@@ -29 +29 @@ ***
- | REGION-ISO         = NP-JA ***
+ | REGION-ISO         = NP-P3 ***

Page [[de:Drolambaogletscher]] saved
finished: 1 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Arghakhanchi]] changed(1)
@@ -20 +20 @@ ***
- |ISO-CODE                = NP-LU ***
+ |ISO-CODE                = NP-P5 ***

Sleeping for 3.8 seconds, 2018-12-14 01:19:27
Page [[de:Arghakhanchi]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Sandhikharka]] changed(2)
Sleeping for 8.8 seconds, 2018-12-14 01:19:32
Page [[de:Sandhikharka]] saved
finished: 2 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Gulmi]] changed(1)
@@ -17 +17 @@ ***
- | ISO-CODE               = NP-LU ***
+ | ISO-CODE               = NP-P5 ***

Sleeping for 8.2 seconds, 2018-12-14 01:19:42
Page [[de:Gulmi]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Resunga]] changed(2)
Sleeping for 8.9 seconds, 2018-12-14 01:19:51
Page [[de:Resunga]] saved
finished: 2 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Kapilbastu]] changed(1)
@@ -19 +19 @@ ***
- |ISO-CODE= NP-LU ***
+ |ISO-CODE= NP-P5 ***

Sleeping for 8.0 seconds, 2018-12-14 01:20:02
Page [[de:Kapilbastu]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Banganga]] changed(2)
Sleeping for 9.0 seconds, 2018-12-14 01:20:11
Page [[de:Banganga]] saved
@@ -14 +14 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Bhrikuti (Kapilbastu)]] changed(3)
Sleeping for 8.6 seconds, 2018-12-14 01:20:22
Page [[de:Bhrikuti (Kapilbastu)]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Buddhabatika]] changed(4)
Sleeping for 8.6 seconds, 2018-12-14 01:20:32
Page [[de:Buddhabatika]] saved
@@ -17 +17 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Kapilavastu]] changed(5)
Sleeping for 8.6 seconds, 2018-12-14 01:20:42
Page [[de:Kapilavastu]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Krishnanagar (Nepal)]] changed(6)
Sleeping for 8.6 seconds, 2018-12-14 01:20:52
Page [[de:Krishnanagar (Nepal)]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Shivaraj]] changed(7)
Sleeping for 8.6 seconds, 2018-12-14 01:21:02
Page [[de:Shivaraj]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Tilaurakot]] changed(8)
Sleeping for 8.6 seconds, 2018-12-14 01:21:12
Page [[de:Tilaurakot]] saved
finished: 8 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Palpa (Distrikt)]] changed(1)
@@ -17 +17 @@ ***
- | ISO-CODE               = NP-LU ***
+ | ISO-CODE               = NP-P5 ***

Sleeping for 8.4 seconds, 2018-12-14 01:21:22
Page [[de:Palpa (Distrikt)]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Rampur (Nepal)]] changed(2)
Sleeping for 8.9 seconds, 2018-12-14 01:21:31
Page [[de:Rampur (Nepal)]] saved
@@ -16 +16 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Tansen (Nepal)]] changed(3)
Sleeping for 8.5 seconds, 2018-12-14 01:21:42
Page [[de:Tansen (Nepal)]] saved
finished: 3 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
[[de:Rupandehi]] changed(1)
@@ -19 +19 @@ ***
- |ISO-CODE=NP-LU ***
+ |ISO-CODE=NP-P5 ***

Sleeping for 8.2 seconds, 2018-12-14 01:21:52
Page [[de:Rupandehi]] saved
@@ -7 +7 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Butwal]] changed(2)
Sleeping for 8.9 seconds, 2018-12-14 01:22:02
Page [[de:Butwal]] saved
@@ -7 +7 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Devdaha]] changed(3)
Sleeping for 8.6 seconds, 2018-12-14 01:22:12
Page [[de:Devdaha]] saved
@@ -7 +7 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Lumbini Sanskritik]] changed(4)
Sleeping for 8.4 seconds, 2018-12-14 01:22:22
Page [[de:Lumbini Sanskritik]] saved
@@ -7 +7 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Sainamaina]] changed(5)
Sleeping for 8.6 seconds, 2018-12-14 01:22:32
Page [[de:Sainamaina]] saved
@@ -7 +7 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Siddharthanagar]] changed(6)
Sleeping for 8.5 seconds, 2018-12-14 01:22:42
Page [[de:Siddharthanagar]] saved
@@ -7 +7 @@ ***
- |ISO-CODE      = NP-LU ***
+ |ISO-CODE      = NP-P5 ***

[[de:Tilottama]] changed(7)
Sleeping for 8.1 seconds, 2018-12-14 01:22:52
Page [[de:Tilottama]] saved
finished: 7 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:NP]] (https://www.iso.org/obp/ui/#iso:code:3166:NP), gültig seit 2018-11-26
finished: 0 pages changed,
### irregular updates from outside (change of ISO codes on https://www.iso.org/obp/ui/#iso:code:)
### run in background, kills the current kernel, use ps -A to find bg job
import time
from datetime import date
from datetime import datetime
import codecs
import os
import sys
from pywikibot import daemonize

timestamp = datetime.now()
log = 'data/' + "iso fix" + timestamp.strftime(" %Y%m%d") + '.log'

pywikibot.daemonize.daemonize(close_fd=False, chdir=True, redirect_std=None)
for c in [PL()]:
    cc = isoCodeChanger (c, test=False, stopAfter=0)
    print (cc.editComment)
    #print (cc.extraPagesGenerator)
    cc.execute()
### regular error fixes
#for c in [DK_81(),DK_82(),DK_83(),DK_84(),DK_85(),GR(),DE_BE(),DE_NI(),DE_SL(),DE_SN(),DE_ST(),DE_NW(),PL()]:
for c in [DE_BE(),DE_NI(),DE_SL(),DE_SN(),DE_ST(),DE_NW()]:
#for c in [DK_81(),DK_82(),DK_83(),DK_84(),DK_85()]:
#for c in [DE_BE()]:
#for c in [DE_NI()]:
    cc = isoCodeChanger (c, test=False, stopAfter=0)
    print (cc.editComment)
    #print (cc.extraPagesGenerator)
    cc.execute()
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:DE]], falschen Code korrigiert
search filter: insource:"DE-B" insource:/DE-B[^A-Z0-9\-]/ added
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:DE]], falschen Code korrigiert
search filter: insource:"DE-NS" insource:/DE-NS[^A-Z0-9\-]/ added
[[de:Festung Apen]] changed(1)
@@ -54 +54 @@ ***
- {{Coordinate|NS=53.2188|EW=7.7977|type=landmark|region=DE-NS}} ***
+ {{Coordinate|NS=53.2188|EW=7.7977|type=landmark|region=DE-NI}} ***

Page [[de:Festung Apen]] saved
[[de:Löhnhorst]] changed(2)
@@ -41 +41 @@ ***
- Löhnhorst hatte bereits 1782 eine eigene Schule in einem angemieteten Raum. Zwischen 1830 und 1835 wurde ein gemeindeeigenes Schulhaus gebaut, das jedoch schnell baufällig wurde. Der 1885 errichtete Neubau wurde bis zur Schließung der Schule genutzt.<ref>[https://www.schwanewede.de/unsere-gemeinde/ortschaften/loehnhorst/ Löhnhorst auf der Website der Gemeinde Schwanewede], zuletzt abgerufen am 28.12.2018.</ref> Das Gebäude wird nun von der freiwilligen Feuerwehr und als Dorfgemeinschaftshaus genutzt {{Coordinate|NS=53/12/19.5/N|EW=8/38/01.5/E|type=building|dim=15|region=DE-NS|text=(Position)|name=Dorfschule Löhnhorst}}. 1996 schlossen sich die von der Schließung bedrohten Grundschulen der Ortsteile [[Beckedorf (Schwanewede)|Beckedorf]] und Löhnhorst zusammen und gründeten die Wiesenschule in Beckedorf. Zum Schulbezirk V der Gemeinde Schwanewede gehört neben Löhnhorst und Beckedorf (außer die [[Ortslage]]n Wölpsche und Schwankenfurth) auch der Ortsteil [[Leuchtenburg (Schwanewede)|Leuchtenburg]].<ref>§ 2 Ziffer 5 der Satzung über die Festlegung von Schulbezirken in der Gemeinde Schwanewede vom 16.12.1997. [https://www.schwanewede.de/portal/dokumenteplus-907000109-21070.html?naviID=907000026&brotID=907000026&ordner=1&containerSort=0&schwelle_zuklappen=-2# PDF], 0,1 MB, zuletzt abgerufen am 28.12.2018.</ref> ***
+ Löhnhorst hatte bereits 1782 eine eigene Schule in einem angemieteten Raum. Zwischen 1830 und 1835 wurde ein gemeindeeigenes Schulhaus gebaut, das jedoch schnell baufällig wurde. Der 1885 errichtete Neubau wurde bis zur Schließung der Schule genutzt.<ref>[https://www.schwanewede.de/unsere-gemeinde/ortschaften/loehnhorst/ Löhnhorst auf der Website der Gemeinde Schwanewede], zuletzt abgerufen am 28.12.2018.</ref> Das Gebäude wird nun von der freiwilligen Feuerwehr und als Dorfgemeinschaftshaus genutzt {{Coordinate|NS=53/12/19.5/N|EW=8/38/01.5/E|type=building|dim=15|region=DE-NI|text=(Position)|name=Dorfschule Löhnhorst}}. 1996 schlossen sich die von der Schließung bedrohten Grundschulen der Ortsteile [[Beckedorf (Schwanewede)|Beckedorf]] und Löhnhorst zusammen und gründeten die Wiesenschule in Beckedorf. Zum Schulbezirk V der Gemeinde Schwanewede gehört neben Löhnhorst und Beckedorf (außer die [[Ortslage]]n Wölpsche und Schwankenfurth) auch der Ortsteil [[Leuchtenburg (Schwanewede)|Leuchtenburg]].<ref>§ 2 Ziffer 5 der Satzung über die Festlegung von Schulbezirken in der Gemeinde Schwanewede vom 16.12.1997. [https://www.schwanewede.de/portal/dokumenteplus-907000109-21070.html?naviID=907000026&brotID=907000026&ordner=1&containerSort=0&schwelle_zuklappen=-2# PDF], 0,1 MB, zuletzt abgerufen am 28.12.2018.</ref> ***

Page [[de:Löhnhorst]] saved
[[de:Feldbahn Rühlermoor]] changed(3)
@@ -128 +128 @@ ***
- {{Coordinate|NS=52.6654|EW=7.1955 |type=landmark|region=DE-NS}} ***
+ {{Coordinate|NS=52.6654|EW=7.1955 |type=landmark|region=DE-NI}} ***

Page [[de:Feldbahn Rühlermoor]] saved
finished: 3 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:DE]], falschen Code korrigiert
search filter: insource:"DE-SA" insource:/DE-SA[^A-Z0-9\-]/ added
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:DE]], falschen Code korrigiert
search filter: insource:"DE-SA" insource:/DE-SA[^A-Z0-9\-]/ added
finished: 0 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:DE]], falschen Code korrigiert
search filter: insource:"DE-SA" insource:/DE-SA[^A-Z0-9\-]/ added
[[de:Jagdschloss Hasselburg]] changed(1)
@@ -15 +15 @@ ***
- {{Koordinate|NS=52.3253|EW=11.2664|type=landmark|region=DE-SA}} ***
+ {{Koordinate|NS=52.3253|EW=11.2664|type=landmark|region=DE-ST}} ***

Page [[de:Jagdschloss Hasselburg]] saved
[[de:Oberbergamt Halle]] changed(2)
@@ -41 +41 @@ ***
- {{Coordinate |NS=51.489306|EW=11.969707|type=landmark |region=DE-SA}} ***
+ {{Coordinate |NS=51.489306|EW=11.969707|type=landmark |region=DE-ST}} ***

Page [[de:Oberbergamt Halle]] saved
[[de:Verteidigungsbezirkskommando 81]] changed(3)
@@ -54 +54 @@ ***
- {{Coordinate|article=/|NS=51.5134|EW=11.9184|type=landmark|region=DE-SA}} ***
+ {{Coordinate|article=/|NS=51.5134|EW=11.9184|type=landmark|region=DE-ST}} ***

Sleeping for 4.8 seconds, 2019-02-03 20:02:04
Page [[de:Verteidigungsbezirkskommando 81]] saved
[[de:Verteidigungsbezirkskommando 82]] changed(4)
@@ -54 +54 @@ ***
- {{Coordinate|article=/|NS=52.127136|EW=11.573319|type=landmark|region=DE-SA}} ***
+ {{Coordinate|article=/|NS=52.127136|EW=11.573319|type=landmark|region=DE-ST}} ***

Page [[de:Verteidigungsbezirkskommando 82]] saved
finished: 4 pages changed,
ISO 3166 Bot: ISO-Code Änderungen gemäß [[ISO 3166-2:DE]], falschen Code korrigiert
search filter: insource:"DE-NRW" insource:/DE-NRW[^A-Z0-9\-]/ added
[[de:Panarbora-Park]] changed(1)
@@ -1 +1 @@ ***
- {{Coordinate|NS=50.8581|EW=7.6072|type=landmark|region=DE-NRW}} ***
+ {{Coordinate|NS=50.8581|EW=7.6072|type=landmark|region=DE-NW}} ***

Page [[de:Panarbora-Park]] saved
Sleeping for 5.0 seconds, 2019-02-03 23:55:48
finished: 1 pages changed,
# test
cat = pywikibot.Category(site,'Category:'+'Sachsen')
pages = pagegenerators.intersect_generators ([
                pagegenerators.SearchPageGenerator('insource:"DE-SA" insource:/DE-SA[^A-Z0-9\-]/', total=None, namespaces=[0], site=site),
                pagegenerators.DuplicateFilterPageGenerator (pagegenerators.CategorizedPageGenerator(cat,7)),
               ])

for page in pages:
    print (page)
print ('finished')
finished
# test
cat = pywikibot.Category(site,'Category:'+'Sachsen')
pages = pagegenerators.SearchPageGenerator('insource:"DE-SA" insource:/DE-SA[^A-Z0-9\-]/', total=None, namespaces=[0], site=site)
                

for page in pages:
    print (page)
print ('finished')
[[de:Goethe-Denkmal (Rom)]]
[[de:ISO 3166-2:DE]]
[[de:Stadtarchiv Saarbrücken]]
finished