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

#!/usr/bin/env python3
"""
python pwb.py updatewin -file:"addtarix.py" -summary:"fix"


Bikaranîn

python pwb.py addtarix -ns:0 -recentchanges:20,80  -always

python pwb.py addtarix -ns:0 -recentchanges:20,80 -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) w:ku:User:Balyozxane :)
#
# Distributed under the terms of the MIT license.
#
import pywikibot
from pywikibot.bot import SingleSiteBot, ConfigParserBot, AutomaticTWSummaryBot
from pywikibot import pagegenerators
import requests
import datetime
import mwparserfromhell
from kucosmetics import CANCEL, CosmeticChangesToolkit
import re
import mytools

VERBOSE = False
TESTING = False


class AddTarixBot(
    SingleSiteBot,
    ConfigParserBot,
    AutomaticTWSummaryBot,
):
    use_redirects = False

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

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        global VERBOSE
        VERBOSE = self.opt.get('showdiff', False)
        self.bot_name = "Bikarhêner:Balyozxane/skrîpt/py/addtarix.py"
        self.cat_title = 'Kategorî:Şablonên hişyarde bi parametreya tarîx'
        self.ku_months = {
                1: 'kanûna paşîn',
                2: 'sibat',
                3: 'adar',
                4: 'nîsan',
                5: 'gulan',
                6: 'hezîran',
                7: 'tîrmeh',
                8: 'tebax',
                9: 'îlon',
                10: 'çiriya pêşîn',
                11: 'çiriya paşîn',
                12: 'kanûna pêşîn'
            }
        self.ku_en_months = {
            'January': 'kanûna paşîn',
            'February': 'sibat',
            'March': 'adar',
            'April': 'nîsan',
            'May': 'gulan',
            'June': 'hezîran',
            'July': 'tîrmeh',
            'August': 'tebax',
            'September': 'îlon',
            'October': 'çiriya pêşîn',
            'November': 'çiriya paşîn',
            'December': 'kanûna pêşîn'
        }
        # Flags and arrays for summary generation
        self.added_tarix_flag = False
        self.fixed_month_flag = False
        self.edited_templates = []
        if not TESTING:
            self.hisyardeTemplates = {}
            self.create_template_redirects()
        else:
            self.hisyardeTemplates = {
                'Beşa bêçavkanî': ['Unreferenced section', 'Beşbêçavk', 'Bêçavkanî/b', 'Bêçavkanî/beş'],
                'Beşa vala': ['...', '…'], 'Beşê berfireh bike': ['Berfirehkirina beşê', 'Bbb'],
                'Bêalî': ['POV', 'Gotara alîgir'],
                'Bêkategorî': ['Uncategorized', 'Bêkat', 'Uncategorized stub'],
                'Bêçavkanî': ['Gotara bêçavkanî', 'Bê çavkanî', 'Gotara bê çavkanî', 'Be Balkêşî', 'Unreferenced', 'Çavkaniyên piştrast'],
                'Etîketa ref tine': ['No footnotes', 'Ref tine', 'Nf', 'Nofn', 'ILC'],
                'Gotara reklam': ['Reklam', 'Advert'], 'Kêm': [],
                'Navdarî': ['Qîmeta tomarkirinê'], 'Ne kurdî': ['Nekurdi', 'Nekurdî'],
                'Ne kurdî-biçûk': ['Kurdî?', 'Bi kurdî?'],
                'Paqij bike': ['Çav lê gerandin', 'Serast', 'Çavlêgerandin', 'Paqijkirin', 'Formata xirab', 'Şêwexirab', 'Gotarên ne standard', 'Paqijbike'],
                'Rêzimana xelet': ['Ne rind kurdî', 'Nerind kurdî', 'Copy edit'],
                'Sêwî': ['Orphan'],
                'Wergera xirab': ['Google translate', 'Rough translation', 'Google werger', 'Google Werger', 'Tercimeya xirab', 'Wergerandina xirab'],
                'Zelalkirin hewce ye': ['Çi?'],
                'Zêdetir çavkanî hewce ye': ['More citations needed', '+r', '+R', 'Add references', 'Additional citations', 'Citations missing', 'Citations needed', 'Cite sources', 'Cleanup-cite', 'Cleanup-verify', 'Few references', 'More references needed', 'More references', 'More cn', 'More citations', 'Missing citations', 'Improve sources', 'Improve references', 'Improve-refs', 'Few sources', 'Few refs', 'More refs', 'More sources', 'More sources needed', 'Needs additional citations', 'Needs more citations', 'Needs more references', 'Needs more sources', 'Not verified', 'Verify', 'Verification', 'Sources needed', 'Sources', 'Refimprove', 'Referenced', 'Reference improve', 'Ref improve', 'Ref-improve', 'Kêmçavkanî', 'Zçh'],
                'Çavkanî hewce ye': ['Fact', 'Çavk', 'Çp', 'Cn', 'Çavkanî pêwîst e', 'Citation needed', 'Çavkanî?']
            }

    @staticmethod
    def get_category_members(category_title):
        base_url = f'https://ku.wikipedia.org/w/api.php'
        params = {
            "action": "query",
            "format": "json",
            "list": "categorymembers",
            "cmtitle": category_title,
            "cmlimit": "max"  # Retrieve all members of the category
        }
        response = requests.get(base_url, params=params)
        data = response.json()
        if 'error' in data:
            if VERBOSE:
                print(f"Error: {data['error']['info']}")
            return None
        else:
            return [member['title'] for member in data['query']['categorymembers']]

    def get_template_redirects(self, template_title):
        template_page = pywikibot.Page(self.site, template_title)
        redirects = template_page.backlinks(filter_redirects=True, namespaces=[10])
        redirect_titles = [redirect.title(with_ns=False) for redirect in redirects]
        if VERBOSE:
            print(f"template_redirects:\n{redirect_titles}")
        return redirect_titles

    def create_template_redirects(self):
        self.hisyardeTemplates = {}

        category_members = self.get_category_members(self.cat_title)

        for member in category_members:

            template = member.replace("Şablon:", "")
            redirects = self.get_template_redirects(member)
            self.hisyardeTemplates[template] = redirects
        if VERBOSE:
            print(self.hisyardeTemplates)

    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)
        applies_summaries = ', '.join(summaries.values())
        if new_text is not False and new_text != old_text:
            kozmetik_cebu = "; paqijiyên kozmetîk"
            if applies_summaries:
                kozmetik_cebu += f' ({applies_summaries}.)'

        return new_text, kozmetik_cebu

    def add_tarix(self, wikicode):
        current_month_number = datetime.datetime.now().month
        current_year = datetime.datetime.now().year
        for template in wikicode.filter_templates():
            template_name = mytools.ucfirst(template.name)
            # Check if the template matches any template in the dictionary or their redirects
            for known_template, redirects in self.hisyardeTemplates.items():
                if template_name == known_template or template_name in redirects:
                    # Check if the template has date, tarîx, or dîrok parameter
                    if not template.has('date') and not template.has('tarîx') and not template.has('dîrok'):
                        month_name = self.ku_months[current_month_number]
                        template.add('tarîx', f"{month_name} {current_year}")
                        self.added_tarix_flag = True
                        self.add_to_edited_templates(template_name)

                        if VERBOSE:
                            print(f"Added tarîx parameter to template {template_name}")
                    else:
                        if VERBOSE:
                            print(str(template))
                        self.replace_param(template)

    def replace_param(self, template):
        date_param = ''
        old_template = str(template)
        template_name = mytools.ucfirst(template.name)
        for param_name in ['date', 'tarîx', 'dîrok']:
            if template.has(param_name):
                param_value = template.get(param_name)
                if param_value:
                    date_param = param_value.value.strip()
                    break

        if VERBOSE:
            print("Date parameter:", date_param)

        match = re.match(r"^(.*?) (\d+)$", date_param)
        if match:
            month_name = match.group(1)
            year = match.group(2)

            if VERBOSE:
                print("Month name:", month_name)
                print("Year:", year)

            if month_name in self.ku_en_months.keys():
                if VERBOSE:
                    print("Month name found in English or Kurdish months dictionary.")

                month_name = self.ku_en_months[month_name]
                date_param = f"{month_name} {year}"
                if param_name == "date":
                    template.remove("date")
                    template.add("tarîx", date_param)  # Replacing "date" with "tarîx"
                else:
                    template.add(param_name, date_param)
                if VERBOSE:
                    print("old_template: ", old_template)
                    print("template: ", str(template))

                if old_template != str(template):
                    self.fixed_month_flag = True
                    self.add_to_edited_templates(template_name)

            elif month_name.lower() in self.ku_en_months.values():
                month_name = month_name.lower()
                date_param = f"{month_name} {year}"
                if param_name == "date":
                    template.remove("date")
                    template.add("tarîx", date_param)
                else:
                    template.add(param_name, date_param)

                if old_template != str(template):
                    self.fixed_month_flag = True
                    self.add_to_edited_templates(template_name)
            else:
                if VERBOSE:
                    print(f"{date_param} is not valid")
                self.log_page(template.name.strip(), date_param)

    def log_page(self, template_title, param_value):
        page = pywikibot.Page(self.site, "Bikarhêner:Balyozbot/kontrol/addtarix")
        new_text = f"\n# [[{self.current_page.title()}]] şablona {template_title} bi tarîxeke xelet ({param_value}) bi kar tîne."
        page.text = page.text + new_text
        page.save(summary=f"[[{self.bot_name}|Bot]]: Problemek hat qeydkirin.")

    def add_to_edited_templates(self, template_name):
        if template_name not in self.edited_templates:
            self.edited_templates.append(template_name)

    def treat_page(self) -> None:
        current_page = self.current_page
        old_text = current_page.text
        self.added_tarix_flag = False
        self.fixed_month_flag = False
        self.edited_templates = []

        wikicode = mwparserfromhell.parse(old_text)

        self.add_tarix(wikicode)
        new_text = str(wikicode)

        kozmetik_cebu = ""
        if old_text != new_text:
            if TESTING:
                new_text = new_text
            else:
                cleaned_new_text, kozmetik_cebu = self.do_kozmetik(new_text, kozmetik_cebu)
                new_text = cleaned_new_text

            # Flags for summary generation
            summary_flags = []
            if self.added_tarix_flag:
                summary_flags.append("Parametreya tarîx lê hat zêdekirin")
            if self.fixed_month_flag:
                summary_flags.append("Tarîx hat sererastkirin")

            # Generate summary
            summary = f'[[{self.bot_name}|Bot]]:'
            if summary_flags:
                summary += f' {"; ".join(summary_flags)}'

            # Add edited template names to summary
            if self.edited_templates:
                template_list = " ".join(
                    f"{{{{[[Şablon:{template}|{template}]]}}}}" for template in self.edited_templates)
                summary += f': {template_list}'

            summary += f'{kozmetik_cebu}'

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


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
        elif option == '-ignore':
            value = value.upper()
            try:
                options['ignore'] = getattr(CANCEL, value)
            except AttributeError:
                raise ValueError(f'Unknown ignore mode {value!r}!')

    gen = gen_factory.getCombinedGenerator(preload=True)

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


if __name__ == '__main__':
    main()