#!/usr/bin/env python3
"""
Skrîpta ji bo subst:kirina şablonan. Nimûne:
https://ku.wikipedia.org/w/index.php?title=Bikarh%C3%AAner:Balyozxane/ceribandin&diff=prev&oldid=1572867
Bikaranîn
python pwb.py templsubst -ns:0 -transcludes:"Modul:CS1 translator" -always
python pwb.py templsubst -ns:0 -transcludes:"Modul:CS1 translator" -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.
-summary: Set the action summary message for the edit.
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 import pagegenerators
from pywikibot.bot import (
AutomaticTWSummaryBot,
ConfigParserBot,
ExistingPageBot,
SingleSiteBot,
)
from kucosmetics import CANCEL, CosmeticChangesToolkit
import mwparserfromhell
# This is required for the text that is shown when you run this script
# with the parameter -help.
docuReplacements = {'¶ms;': pagegenerators.parameterHelp} # noqa: N816
TESTING = False
VERBOSE = False
class TemplSubstBot(
# Refer pywikobot.bot for generic bot classes
SingleSiteBot, # A bot only working on one site
ConfigParserBot, # A bot which reads options from scripts.ini setting file
# CurrentPageBot, # Sets 'current_page'. Process it in treat_page method.
# # Not needed here because we have subclasses
ExistingPageBot, # CurrentPageBot which only treats existing pages
AutomaticTWSummaryBot, # Automatically defines summary; needs summary_key
):
use_redirects = False # treats non-redirects only
summary_key = 'basic-changing'
def __init__(self, **kwargs):
self.templates = kwargs.pop('templates', [])
self.bot_name = "Bikarhêner:Balyozxane/skrîpt/py/templsubst.py"
self.cat_title = "Kategorî:Şablonên ku otomatîk were substkirin"
super().__init__(**kwargs)
update_options = {
'async': False,
'showdiff': False,
'ignore': CANCEL.MATCH,
}
@staticmethod
def log_to_page(page_title, ref_content):
site = pywikibot.Site("ku", "wikipedia")
log_page = pywikibot.Page(site, "User:Balyozbot/kontrol/tempsubst")
log_text = f"\n\nPage title: {page_title}\nRef content causing ValueError: {ref_content}"
# Append the log text to the existing content of the log page
log_page.text += log_text
# Save the changes to the log page
log_page.save(summary="Logging ValueError")
def subst_ref_tags(self, parsed_wikitext):
for index, tag in enumerate(parsed_wikitext.filter_tags()):
if tag.tag == "ref":
ref_content = tag.contents.strip()
sablon_heye = self.check_template(ref_content)
if sablon_heye:
if tag.has("name"):
name = tag.get("name").value.strip()
replaced_content = f'{{{{safesubst:#tag:ref|{ref_content}|name="{name}"}}}}'
else:
replaced_content = f'{{{{safesubst:#tag:ref|{ref_content}}}}}'
try:
# Attempt to replace the tag content
parsed_wikitext.replace(tag, replaced_content)
except ValueError as e:
# If ValueError occurs, log the error and skip replacement
pywikibot.error(f"Error replacing tag: {e}. Skipping replacement.")
ref_log = f"{{{{subst:codenowiki |1={str(tag)}}}}}"
self.log_to_page(self.current_page.title(), ref_log)
return
def check_template(self, ref_content):
parsed_content = mwparserfromhell.parse(ref_content)
templates = parsed_content.filter_templates()
for template in templates:
template_name = template.name.strip()
if template_name.lower() in map(str.lower, self.templates):
return True
return False
def subst_templates(self, parsed_wikitext):
for template in parsed_wikitext.filter_templates():
template_name = template.name.strip()
if template_name.lower() in map(str.lower, self.templates):
template.name = "subst:" + template_name
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 treat_page(self) -> None:
"""Load the given page, do some changes, and save it."""
if self.current_page.namespace() != 0 and self.current_page.title() != 'Bikarhêner:Balyozxane/ceribandin':
pywikibot.output(f"Skipping page '{self.current_page.title()}' because it is not in namespace 0")
return
text = self.current_page.text
old_text = text
parsed_wikitext = mwparserfromhell.parse(text)
self.subst_ref_tags(parsed_wikitext)
self.subst_templates(parsed_wikitext)
new_text = str(parsed_wikitext)
kozmetik_cebu = ""
if old_text != new_text:
if TESTING:
new_text = new_text
else:
cleaned_new_text, kozmetik_cebu = self.do_kozmetik(new_text)
new_text = cleaned_new_text
summary = f'[[{self.bot_name}|Bot]]: Şablonên ku otomatîk were [[{self.cat_title}|subst:kirin]] hat subst:kirin{kozmetik_cebu}'
self.put_current(
new_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
template_names = ['Cite book/Arabic', 'Cite book/Danish', 'Cite book/Dutch', 'Cite book/Finnish', 'Cite book/French', 'Cite book/German', 'Cite book/Italian or Spanish', 'Cite book/Norwegian', 'Cite book/Polish', 'Cite book/Portuguese', 'Cite book/Swedish', 'Cite book/Turkish', 'Cite journal/Danish', 'Cite journal/Dutch', 'Cite journal/Finnish', 'Cite journal/French', 'Cite journal/Italian', 'Cite journal/Norwegian', 'Cite journal/Polish', 'Cite journal/Russian', 'Cite journal/Spanish', 'Cite journal/Swedish', 'Cite news/Arabic', 'Cite news/Catalan', 'Cite news/Italian or Spanish', 'Cite news/Portuguese', 'Cite web/Arabic', 'Cite web/Catalan', 'Cite web/Danish', 'Cite web/Dutch', 'Cite web/Finnish', 'Cite web/French', 'Cite web/German', 'Cite web/Italian or Spanish', 'Cite web/Norwegian', 'Cite web/Polish', 'Cite web/Portuguese', 'Cite web/Swedish', 'Cite web/Turkish', 'استشهاد بكتاب', 'Kilde bog', 'Citeer boek', 'Kirjaviite', 'Ouvrage', 'Literatur', 'Cite book/Italian', 'Cite book/Spanish', 'Cita libro', 'Kilde bok', 'Cytuj książkę', 'Citar livro', 'Bokref', 'Kitap kaynağı', 'Citeer journal', 'Lehtiviite', 'Article', 'Cita pubblicazione', 'Kilde artikkel', 'Cytuj pismo', 'Статья', 'Cita publicación', 'Tidskriftsref', 'استشهاد بخبر', 'Ref-publicació', 'Cita news', 'Cite news/Italian', 'Cite news/Spanish', 'Citar jornal', 'استشهاد ويب', 'Ref-web', 'Citeer web', 'Verkkoviite', 'Lien web', 'Internetquelle', 'Internetquelle/subst', 'Cita web', 'Cytuj stronę', 'Cytuj', 'Citar web', 'Webbref', 'Web kaynağı'
]
if VERBOSE:
if template_names:
print(template_names)
else:
print("templates?")
# 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 = TemplSubstBot(generator=gen, templates=template_names, **options)
bot.run() # guess what it does
if __name__ == '__main__':
main()