Here naverokê

Bikarhêner:Wikihez/skrîpt/py/dengbot.py

Ji Wîkîferhengê, ferhenga kurdî
#!/usr/bin/env python3
"""

Bikaranîn

The following parameters are supported:

-always           The bot won't ask for confirmation when putting a page.

-showdiff         The bot will show the differences in the console.

-async            Edits will be performed asynchronously.

Use global -simulate option for test purposes. No changes to live wiki
will be done.
"""
#
#
import pywikibot
from pywikibot import pagegenerators
from pywikibot.bot import SingleSiteBot, ConfigParserBot, AutomaticTWSummaryBot
import mwparserfromhell
import re
import json
import mytools
from typing import Set


class DengBot(
    SingleSiteBot,
    ConfigParserBot,
    AutomaticTWSummaryBot,
):
    use_redirects = False
    update_options = {
        'async': False,
        'showdiff': False,
    }

    REPORT_PAGE_TITLE = "User:Balyozbot/kontrol/dengbot"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.bot_name = "Bikarhêner:Wikihez/skrîpt/py/dengbot.py"
        json_title = "Bikarhêner:Wikihez/skrîpt/json/botoptions.json"
        json_page = pywikibot.Page(self.site, json_title)
        self.json_content = json_page.text

        try:
            self.botoptions = json.loads(self.json_content).get('dengbot')
            self.country_replacements = self.botoptions.get('country_replacements', {})
            self.deng_redirects = self.botoptions.get('redirects', {})
            self.dever_countries = self.botoptions.get('dever_countries', {})

        except json.JSONDecodeError as e:
            pywikibot.error(f"Error decoding JSON content: {e}")
            self.botoptions = {}

        # --- report-page bookkeeping (param 3 anomalies) ---
        self.report_page = pywikibot.Page(self.site, self.REPORT_PAGE_TITLE)
        self.reported_values: Set[str] = set()
        if self.report_page.exists():
            for line in self.report_page.text.splitlines():
                m = re.match(r"^\*\s*\[\[.*?\]\]:\s*(.+)$", line.strip())
                if m:
                    self.reported_values.add(m.group(1).strip())
        self.new_reports = []

    def report_third_param(self, page_title: str, value: str) -> None:
        """Queue an unrecognized param-3 value for the control page, skipping duplicates."""
        if value in self.reported_values:
            return
        self.reported_values.add(value)
        self.new_reports.append(f"* [[{page_title}]]: {value}")

    def treat_page(self) -> None:
        page = self.current_page
        if not page.exists():
            pywikibot.error(f"Skipping {page.title()} since it does not exist")
            return

        if page.namespace() != 0 and page.title() != 'Bikarhêner:Wikihez/ceribandin':
            pywikibot.output(f"Skipping page '{page.title()}' because it is not in namespace 0")
            return

        text = page.text
        wikicode = mwparserfromhell.parse(text)
        deng_list = ["deng", "Deng", "audio", "Audio"]
        for template in wikicode.filter_templates():
            if not template.name.strip().replace('\u200e', '') in self.deng_redirects:
                continue  # Skip non-"deng" templates

            if template.has("dever"):

                dever_value = template.get("dever").value.strip()
                match = re.search(r"^(.+?) \((.+?)\)$", dever_value)
                new_value = None
                match2 = dever_value.split(",")
                if dever_value in self.country_replacements:
                    new_value = self.country_replacements[dever_value]

                elif match:

                    if (dever_value == "Almanya (Berlîn)" or dever_value == "Berlîn, Almanya") and "(zza)-Mirzali-" in template.get(2).value:
                        new_value = "Pilemor"
                    else:
                        country, city = match.groups()

                        # Apply country replacements
                        country = self.country_replacements.get(country, country)
                        city = self.country_replacements.get(city, city)

                        new_value = f"{city}, {country}"
                elif len(match2) == 2:
                    city = match2[0].strip()
                    country = match2[1].strip()
                    # Apply country replacements
                    country = self.country_replacements.get(country, country)
                    city = self.country_replacements.get(city, city)
                    if country and city:
                        # Preserve the original comma spacing instead of
                        # always forcing "city, country" (e.g. keep
                        # "London,QY" as-is if there was no space after
                        # the comma in the source).
                        comma_idx = dever_value.find(",")
                        if comma_idx != -1 and comma_idx + 1 < len(dever_value) and dever_value[comma_idx + 1] == " ":
                            separator = ", "
                        else:
                            separator = ","
                        new_value = f"{city}{separator}{country}"

                if new_value:
                    template.add("dever", new_value)
            elif template.has("spr"):
                lang = template.get(1).value.strip()
                spr_val = template.get("spr").value.strip()
                third_param = None
                if template.has(3):
                    third_param = template.get(3).value.strip()
                if lang == "de" and spr_val == "at":
                    if third_param and third_param in deng_list:
                        template.remove(3)
                        template.remove("spr")
                        template.add("dever", "Awistirya")
                    if third_param and third_param == self.current_page.title():
                        template.remove(3)
                        template.remove("spr")
                        template.add("dever", "Awistirya")
                    if not third_param:
                        template.remove("spr")
                        template.add("dever", "Awistirya")
            elif template.has(4):
                # Move param 4 into "dever".
                dever_value = template.get(4).value.strip()
                template.remove(4)
                if dever_value:
                    template.add("dever", dever_value)

                # Handle param 3: drop it if it's just a generic
                # deng/audio label, otherwise flag the value for manual
                # review
                if template.has(3):
                    third_param = template.get(3).value.strip()
                    if third_param in deng_list:
                        template.remove(3)
                    else:
                        self.report_third_param(page.title(), third_param)
            elif template.has(3):
                third_param = template.get(3).value.strip()
                new_value = None
                deng = None
                if third_param in self.country_replacements:
                    new_value = self.country_replacements[third_param]
                else:
                    match = re.search(r"^(.+?) \((.+?)\)$", third_param)

                    if match:
                        deng, dever = match.groups()
                        country = self.country_replacements.get(dever, None)  # Replace or keep the same
                        if country:
                            new_value = country
                        elif dever in self.dever_countries:
                            new_value = dever
                if new_value:
                    if deng and deng.strip() in deng_list:
                        template.remove(3)
                    elif deng:
                        template.add(3, deng.strip())
                    template.add("dever", new_value)
                elif third_param.strip() in deng_list:
                    template.remove(3)

        new_text = str(wikicode)

        if text != new_text:
            summary = f'[[{self.bot_name}|Bot]]: Formata parametreya "dever" hat guhartin'
            self.put_current(
                new_text,
                summary=summary,
                asynchronous=self.opt['async'],
                show_diff=self.opt['showdiff']
            )

    def teardown(self):
        if self.new_reports:
            old_text = self.report_page.text if self.report_page.exists() else ""
            addition = "\n".join(self.new_reports)
            if old_text.strip():
                new_text = old_text.rstrip("\n") + "\n" + addition + "\n"
            else:
                new_text = addition + "\n"
            self.report_page.text = new_text
            self.report_page.save(
                summary=f"[[{self.bot_name}|Bot]]: Zêdekirina nirxên nenas ên parametreya 3",
                asynchronous=self.opt['async'],
            )
        super().teardown()


def main(*args: str) -> None:
    local_args = pywikibot.handle_args(args)
    gen_factory = pagegenerators.GeneratorFactory()
    local_args = gen_factory.handle_args(local_args)

    options = {}
    for arg in local_args:
        option, _, value = arg.partition(':')
        if option in ('-always', '-async', '-showdiff'):
            options[option[1:]] = True

    # The preloading option is responsible for downloading multiple
    # pages from the wiki simultaneously.
    gen = gen_factory.getCombinedGenerator(preload=True)

    if gen:
        bot = DengBot(generator=gen, **options)
        bot.run()
    else:
        page_list = []

        template_page = pywikibot.Page(pywikibot.Site(), f"Template:deng")
        pages = mytools.referring_page_generator(template_page,
                                                 only_template_inclusion=True)
        page_list.extend(pages)

        if not pywikibot.bot.suggest_help(missing_generator=not page_list):
            bot = DengBot(generator=page_list, **options)
            bot.run()


if __name__ == '__main__':
    main()