Bikarhêner:Balyozxane/skrîpt/py/replacesitil.py

Ji Wîkîpediya, ensîklopediya azad.
#!/usr/bin/env python3
"""
python pwb.py updatewin -f:"replacesitil.py" -s:"fix"

Eger ne şitil be, şablonê radike.
Şûnda Şablona Şitil şabloneke şitilan a din li gorî kategoriyên rûpelê zêde dike.

Bikaranîn:

python pwb.py replacesitil -ns:0 -cat:"Kategorî:Şitil"  -always

python pwb.py replacesitil -ns:0 -cat:"Kategorî:Şitil" -showdiff

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.

"""
#
# (C) Balyozxane
#
# Distributed under the terms of the MIT license.
#

import json
import pywikibot
from pywikibot import pagegenerators
from pywikibot.bot import (
    ConfigParserBot,
    ExistingPageBot,
    SingleSiteBot,
)
import mwparserfromhell
from kucosmetics import CANCEL, CosmeticChangesToolkit, PageTagger
import mytools

VERBOSE = True

# This is required for the text that is shown when you run this script
# with the parameter -help.
docuReplacements = {'&params;': pagegenerators.parameterHelp}  # noqa: N816


class StubBot(
    SingleSiteBot,  # A bot only working on one site
    ConfigParserBot,  # A bot which reads options from scripts.ini setting file
    ExistingPageBot,  # CurrentPageBot which only treats existing pages
):
    use_redirects = False  # treats non-redirects only

    update_options = {
        'async': False,
        'showdiff': False,
        'ignore': CANCEL.MATCH,
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.bot_name = "User:Balyozxane/skrîpt/py/replacesitil.py"
        self.json_categories, self.kategoriyan_sitilan = self.get_json_cats()

    @staticmethod
    def get_json_cats():
        with open('kategoriyen_sitilan.json', 'r', encoding='utf-8') as f:
            kategoriyen_sitilan = json.load(f)

        # Get the list of keys (categories to compare)
        json_categories = set(kategoriyen_sitilan.keys())
        return json_categories, kategoriyen_sitilan

    def do_kozmetik(self, old_text):
        kozmetik_cebu = ""
        cc_toolkit = CosmeticChangesToolkit(self.current_page,
                                            ignore=self.opt.ignore)
        new_text, summaries = cc_toolkit.change(old_text)
        applied_summaries = ', '.join(summaries.values())
        if new_text is not False and new_text != old_text:
            kozmetik_cebu = "; paqijiyên kozmetîk"
            if applied_summaries:
                kozmetik_cebu += f' ({applied_summaries}.)'

        return new_text, kozmetik_cebu

    def get_common_cats(self):
        """
        Checks if the current page should be treated based on its categories.

        Returns:
        set: A set of common categories.
        """
        # Get unhidden categories from the current page
        categories = mytools.get_unhidden_categories("ku", self.current_page.title())

        # Find common categories
        common_categories = self.json_categories.intersection(categories)

        return common_categories

    def add_templates(self, wikicode, common_categories):
        """
        Adds the corresponding templates from kategoriyan_sitilan.
        """
        added_templates = []
        for category in common_categories:
            template_value = self.kategoriyan_sitilan[category]
            new_template = str(mwparserfromhell.nodes.Template(template_value))
            wikicode.append("\n" + new_template)
            added_template = "{{[[Şablon:" + template_value + "|" + template_value + "]]}}"
            added_templates.append(added_template)

        added_templates_str = ', '.join(added_templates)
        return str(wikicode), added_templates_str

    def treat_page(self) -> None:
        if self.current_page.namespace() != 0:
            if VERBOSE:
                print("Skipping Namespace not 0.")
            return

        if not mytools.is_category_in_page(self.current_page, "Şitil"):
            return

        is_sitil = PageTagger.isSitil(self.current_page)
        print("is_sitil: ", is_sitil)
        common_categories = self.get_common_cats()

        text = self.current_page.text
        if not is_sitil:
            text = mytools.remove_template_redirects(self.site, "Şitil", text)
            append_sum = "hat rakirin"
        elif common_categories:
            text = mytools.remove_template_redirects(self.site, "Şitil", text)

            wikicode = mwparserfromhell.parse(text)
            text, added_templates = self.add_templates(wikicode, common_categories)
            append_sum = f"bi {added_templates} hat guhartin"
        else:
            return

        text, kozmetik_cebu = self.do_kozmetik(text)
        summary = f'[[{self.bot_name}|Bot]]: Şablona {{{{[[Şablon:şitil|Şitil]]}}}}'
        summary += f' {append_sum}{kozmetik_cebu}'

        self.put_current(
            text,
            summary=summary,
            asynchronous=self.opt['async'],
            show_diff=self.opt['showdiff']
        )


def main(*args: str) -> None:
    """
    Process command line arguments and invoke bot.

    If args is an empty list, sys.argv is used.

    :param args: command line arguments
    """
    options = {}
    # Process global arguments to determine desired site
    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    gen_factory = pagegenerators.GeneratorFactory()

    # Process pagegenerators arguments
    local_args = gen_factory.handle_args(local_args)

    # Parse your own command line arguments
    for arg in local_args:
        arg, _, value = arg.partition(':')
        option = arg[1:]
        if option in ('-always', '-async', '-showdiff'):
            options[option[1:]] = True
        elif option == '-ignore':
            value = value.upper()
            try:
                options['ignore'] = getattr(CANCEL, value)
            except AttributeError:
                raise ValueError(f'Unknown ignore mode {value!r}!')
        # take the remaining options as booleans.
        # You will get a hint if they aren't pre-defined in your bot class
        else:
            options[option] = True
    # The preloading option is responsible for downloading multiple
    # pages from the wiki simultaneously.
    gen = gen_factory.getCombinedGenerator(preload=True)

    # check if further help is needed
    if not pywikibot.bot.suggest_help(missing_generator=not gen):
        # pass generator and private options to the bot
        bot = StubBot(generator=gen, **options)
        bot.run()  # guess what it does


if __name__ == '__main__':
    main()