Bikarhêner:Balyozxane/skrîpt/py/addwikiproje.py
Xuyakirin
#!/usr/bin/env python3
"""
Şablonên Wîkîprojeyan ji kategoriya [[Kategorî:Şablonên Wîkîprojeyan yên bi nirxandina kalîteyê]] derdixe û li rûpelê zêde dike eger eynî şablon tê de tinebe.
Tenê serê xwe wisa dixebite:
python pwb.py addwikiproje -recentchanges (li ser guhartinên dawî dixebite)
python pwb.py addwikiproje -page:"Navê rûpelê" (tenê li ser rûpelekê dixebite)
python pwb.py addwikiproje -file:listeyawikiprojeyan.txt (li serrûpelên di dosyeyê de ne dixebite)
Lîste ji aliyê [[Bikarhêner:Balyozxane/skrîpt/py/getwikiproje.py]] ve tê çêkirin.
"""
#
# (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 re
import mwparserfromhell
VERBOSE = False
TESTING = False
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_enwiki_title(kuwiki_title):
url = f"https://www.wikidata.org/w/api.php?action=wbgetentities&sites=kuwiki&titles={kuwiki_title}&props=sitelinks&format=json"
response = requests.get(url)
data = response.json()
entity = next(iter(data["entities"].values())) # Get the first (and only) entity
if "sitelinks" in entity and "enwiki" in entity["sitelinks"]:
enwiki_title = entity["sitelinks"]["enwiki"]["title"]
return enwiki_title
else:
return None
def get_assessment_info(page_title, projects):
base_url = 'https://en.wikipedia.org/w/api.php'
params = {
'action': 'query',
'prop': 'pageassessments',
'titles': page_title,
'format': 'json'
}
response = requests.get(base_url, params=params)
data = response.json()
try:
pages = data['query']['pages']
except KeyError:
if VERBOSE:
print(f"Error: 'query' key not found for {page_title} in API response.")
return {}
assessment_info = {}
for page_id, page_data in pages.items():
assessments = page_data.get('pageassessments', {})
if VERBOSE:
print("pageassessments:")
print(assessments)
for project in projects:
project_info = {}
project_found = False
for assessment_project, project_assessment in assessments.items():
if assessment_project.lower() == project.lower():
project_info['class'] = project_assessment.get('class', 'Unknown')
project_info['importance'] = project_assessment.get('importance', 'Unknown')
project_found = True
break
if not project_found:
project_info = None
assessment_info[project] = project_info
if VERBOSE:
print(f"Assessment Info for {page_title}:")
print(assessment_info)
return assessment_info
def get_class(page):
categories_list = list(page.categories())
sitil_to_check = "Kategorî:Hemû şitil"
liste_to_check = "Kategorî:Liste"
if sitil_to_check in [cat.title() for cat in categories_list]:
if VERBOSE:
print(f"The page is in the category: {sitil_to_check}")
class_value = "Şitil"
elif liste_to_check in [cat.title() for cat in categories_list]:
if VERBOSE:
print(f"The page is in the category: {liste_to_check}")
class_value = "Lîste"
else:
if VERBOSE:
print(f"The page is NOT in the given categories")
class_value = ""
return class_value
class WikiprojeBot(
SingleSiteBot,
ConfigParserBot,
AutomaticTWSummaryBot,
):
summary_key = 'basic-changing'
use_redirects = False
update_options = {
'summary': None,
'text': '',
'top': False,
}
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.bot_name = "Bikarhêner:Balyozxane/skrîpt/py/addwikiproje.py"
if not TESTING:
self.wikiproje = {}
self.create_wikiproje_dictionary()
else:
self.wikiproje = {
'Wîkîproje Almanya': {
'ku_proje': 'Almanya',
'en_proje': 'Germany',
'redirects': ['WikiProject Germany']
},
'Wîkîproje Fransa': {
'ku_proje': 'Fransa',
'en_proje': 'France',
'redirects': ['WikiProject France', 'WPFR', 'WPFRANCE']
},
'Wîkîproje Kurdistan': {
'ku_proje': 'Kurdistan',
'en_proje': 'Kurdistan',
'redirects': ['WPKU', 'WPKURDISTAN']
},
'Wîkîproje Mîtolojî': {
'ku_proje': 'Mîtolojî',
'en_proje': 'Mythology',
'redirects': ['WikiProject Mythology']
}
}
self.kalik_templates = ['Kalika wîkîprojeyê']
if not TESTING:
kalik_redirects = self.get_template_redirects("Şablon:Kalika wîkîprojeyê")
else:
kalik_redirects = ['WPB', 'WikiProject banner shell', 'WikiProject Shell', 'Bannershell', 'WPBS',
'WikiProject banner', 'Kalika Wîkîprojeyê']
if kalik_redirects:
self.kalik_templates.extend(kalik_redirects)
if VERBOSE:
print(self.kalik_templates)
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_wikiproje_dictionary(self):
self.wikiproje = {}
category_title = 'Kategorî:Şablonên Wîkîprojeyan yên bi nirxandina kalîteyê'
category_members = get_category_members(category_title)
for member in category_members:
ku_title = member
en_title = get_enwiki_title(member)
if en_title:
ku_proje = ku_title.replace("Şablon:Wîkîproje ", "")
en_proje = en_title.replace("Template:WikiProject ", "")
ku_template = ku_title.replace("Şablon:", "")
ku_template_key = ku_template.replace("Şablon:", "") # Use ku_template as the key
redirects = self.get_template_redirects(member)
self.wikiproje[ku_template_key] = {
'ku_proje': ku_proje,
'en_proje': en_proje,
'redirects': redirects # Store the redirects under each ku_template
}
if VERBOSE:
print(self.wikiproje)
def check_assessment_info(self, page_title):
"""
Check if the page requires modification based on assessment information.
Return a dictionary containing the found templates and their associated assessment_info, if any, else return None.
"""
en_page_title = get_enwiki_title(page_title)
# Get the en_proje keys from self.wikiproje as the projects list
projects = [info['en_proje'] for info in self.wikiproje.values()]
assessment_info = get_assessment_info(en_page_title, projects)
if not assessment_info:
if VERBOSE:
print(f"assessment_info not found for {page_title}")
return False
importance_translation = {
"Top": "Herî zêde",
"High": "Zêde",
"Mid": "Navîn",
"Low": "Kêm",
"Bottom": "Herî kêm",
"Unknown": "Nayê zanîn",
"NA": "NA"
}
# Check if any of the en_proje keys from self.wikiproje match any of the assessment_info keys
matching_projects = {}
for key, value in self.wikiproje.items():
if value['en_proje'] in assessment_info and assessment_info[value['en_proje']] is not None:
importance_en = assessment_info[value['en_proje']]['importance']
importance_ku = importance_translation.get(importance_en, 'Unknown')
matching_projects[key] = importance_ku
if matching_projects:
if VERBOSE:
print(f"Found matching_projects:\n{matching_projects}")
return matching_projects
else:
return False
@staticmethod
def reorder_templates(new_template, wikicode):
# Define the desired template order
template_order = [
"Kalika wîkîprojeyê",
"Dîtinên salane",
"Kopîkirî",
"Serê gotûbêjê",
"Talk header",
"Portal dîrok",
]
# Find the index of the first non-template node
idx = next(
(i for i, node in enumerate(wikicode.nodes) if
not isinstance(node, mwparserfromhell.nodes.template.Template)), 0)
wikicode.insert(idx, new_template) # Insert the new template at the index
# Insert a line break before adding the new template
wikicode.insert(idx, "\n")
# Reorder the remaining templates
for template_name in template_order:
templates = wikicode.filter_templates(matches=lambda template: template.name.matches(template_name))
if templates:
template = templates[0]
print("Reordering template:", template)
wikicode.remove(template)
wikicode.insert(idx, "\n") # Insert a line break after each template
wikicode.insert(idx, template) # Insert at the appropriate index
wikicode.insert(idx, "\n") # Insert a line break after each template
# Save the page with the modified text
updated_text = str(wikicode)
return updated_text
def add_new_wikiproje(self, talk_page, matching_projects):
"""
:param talk_page:
:param matching_projects: example {'Wîkîproje Mîtolojî': 'Herî zêde'} there might be more than one key
:return: this should add the new wikiproject to the existing talk page and save the page.
"""
if VERBOSE:
print(f"adding each wikiproject in {matching_projects} to existing {talk_page}")
# Create a list to store all wikiprojects added
added_wikiprojects = []
page_text = talk_page.text
wikicode = mwparserfromhell.parse(page_text)
for wikiproje, importance in matching_projects.items():
# Check if the WikiProject template or its redirects are already present on the talk page
existing_templates = [template.name.strip() for template in
wikicode.filter_templates()]
wikiproje_templates = [wikiproje] + self.wikiproje[wikiproje]['redirects']
if any(wikiproje_template in existing_templates for wikiproje_template in wikiproje_templates):
if VERBOSE:
print(f"WikiProject '{wikiproje}' or its redirects already exist on the talk page. Skipping.")
continue
# Check if there are Kalik templates present on the talk page
has_kalik_template = any(kalik_template in existing_templates for kalik_template in self.kalik_templates)
new_wikiproje = "\n{{"
new_wikiproje += f"{wikiproje}"
if importance:
if importance == "Nayê zanîn":
new_wikiproje += f"|muhîmî="
elif importance != "NA":
new_wikiproje += f"|muhîmî={importance}"
new_wikiproje += "}}\n"
# If there are Kalik templates, find and update the first empty parameter with the new WikiProject
if has_kalik_template:
if VERBOSE:
print(f"has_kalik_template: {has_kalik_template}")
for template in wikicode.filter_templates():
if template.name.strip() in self.kalik_templates:
if not template.has(1):
template.add(1, new_wikiproje, showkey=True)
else:
param_val = template.get(1).value.strip()
if param_val: # If parameter has value, append the new WikiProject
template.add(1, f"{param_val}{new_wikiproje}", showkey=True)
else:
template.add(1, new_wikiproje, showkey=True)
page_text = str(wikicode)
else:
# If there are no Kalik templates, create a new one with the new WikiProject
new_template = "{{Kalika wîkîprojeyê"
if self.current_page.namespace() == 0:
sinif = get_class(self.current_page)
new_template += f"|sinif={sinif}"
new_template += f"|1=\n{new_wikiproje}}}}}"
page_text = self.reorder_templates(new_template, wikicode)
if VERBOSE:
print(f"Added WikiProject '{wikiproje}' to the talk page.")
page_text = re.sub(r'1=\n\n\{', '1=\n{', page_text)
page_text = re.sub(r'\n\n\n*', '\n\n', page_text)
page_text = re.sub(r'^\n+', '', page_text)
# Add the added wikiproject to the list
added_wikiprojects.append(f"[[WP:{wikiproje}|{wikiproje}]]")
self.save_page(talk_page, page_text, added_wikiprojects)
def create_new_talk(self, page, matching_projects):
talk_page = page.toggleTalkPage()
added_wikiprojects = [] # Create a list to store added wikiprojects
new_template = "{{Serê gotûbêjê}}\n{{Kalika wîkîprojeyê"
if page.namespace() == 0:
sinif = get_class(page)
new_template += f"|sinif={sinif}"
new_template += "|1=\n"
for wikiproje, importance in matching_projects.items():
new_wikiproje = "\n{{"
new_wikiproje += f"{wikiproje}"
if importance:
if importance == "Nayê zanîn":
new_wikiproje += "|muhîmî="
elif importance != "NA":
new_wikiproje += f"|muhîmî={importance}"
new_wikiproje += "}}\n"
new_template += f"{new_wikiproje}"
added_wikiprojects.append(f"[[WP:{wikiproje}|{wikiproje}]]") # Append the added wikiproject to the list
new_template += "}}"
page_text = new_template
updated_text = re.sub(r'1=\n\n\{', '1=\n{', page_text)
self.save_page(talk_page, updated_text, added_wikiprojects)
def save_page(self, page, text, added_wikiprojects) -> None:
# Construct the summary including all added wikiprojects
summary = (f'[[{self.bot_name}|Bot]]: Wîkîproje lê '
f'{"hatin" if len(added_wikiprojects) > 1 else "hat"}'
f' zêdekirin: '
f'{", ".join(added_wikiprojects)}')
if page.text != text:
# Save the talk page
try:
if VERBOSE:
print(text)
print(summary)
page.text = text
page.save(summary=summary)
except Exception as e:
print(f"Error occurred while saving the talk page: {e}")
else:
print(f"No changes detected for {page.title()}")
def treat_page(self) -> None:
current_page = self.current_page
page_title = self.current_page.title()
# Get matching projects and check if modification needed
matching_projects = self.check_assessment_info(page_title)
if not matching_projects:
if VERBOSE:
print(f"Skipping {page_title} because no matching projects found.")
return
talk_page = current_page.toggleTalkPage()
if not talk_page.exists():
if VERBOSE:
print(f"{talk_page} doesn't exist creating for {matching_projects}")
self.create_new_talk(current_page, matching_projects)
else:
self.add_new_wikiproje(talk_page, matching_projects)
def main(*args: str) -> None:
local_args = pywikibot.handle_args(args)
gen_factory = pagegenerators.GeneratorFactory()
local_args = gen_factory.handle_args(local_args)
options = {'text': ''}
for arg in local_args:
option, _, value = arg.partition(':')
if option in ('summary', 'text'):
if not value:
pywikibot.input(f'Please enter a value for {option}')
options[option] = value
else:
options[option] = True
gen = gen_factory.getCombinedGenerator(preload=True)
if not pywikibot.bot.suggest_help(missing_generator=not gen):
bot = WikiprojeBot(generator=gen, **options)
bot.run()
if __name__ == '__main__':
main()