Szerkesztő:BinBot/disambcounter.py

A Wikipédiából, a szabad enciklopédiából

Ez a script az egyértelműsítő lapok listáját tölti fel a Szerkesztő:BinBot/Egyértelműsítő lapok oldalra a hivatkozások száma szerint rendezve.

This script collects disambiguation pages, orders them by decreasing count of references, and uploads the list to a given page (see the example above). Number of referring templates will be counted separately, because in many cases the number of references may be drastically decreased by manual edit of a few templates (navboxes, infoboxes, userboxes etc.).

The code is prepared for porting to other wikis. You may give the namespaces where references will be counted (typically where readers see the bad links), the limit above which the titles will show up, and groups of disambiguation pages that will be disclosed from listing (e.g. redirects to disambigutation pages). Users may write comments next to titles, and the bot will try to save them upon refreshing. In case of edit conflict the list will be uploaded to an emergency subpage.

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Counts links to disambiguation pages in relevant namespaces.
Syntax: trunk/compat, Python 2 & 3 (tested in 2)
"""
#
# (C) Bináris (hu:user:Bináris), 2018
#
# Distributed under the terms of the MIT license.
#
# Original source: https://hu.wikipedia.org/wiki/Szerkeszt%C5%91:BinBot/disambcounter.py
#

from __future__ import unicode_literals
from datetime import datetime, timedelta
import re
import wikipedia as pywikibot
from pagegenerators import CategorizedPageGenerator, ReferringPageGenerator
import catlib

# Project-dependent settings
namespaces = [0, 6, 10, 100]  # Main, file, template, portal.
namespaceNames = 'szócikk, file, sablon, portál'
namespaceTempl = 10
limit = 20  # Deal with disambiguation pages with at least <limit> links.
ending = ' (egyértelműsítő lap)'  # Standard name ending of disambiguation pages
disambCatName = 'Egyértelműsítő lapok'
recursive = True  # Whether or not to work in subcategories of disamb pages.
follow_redirects = True  # Count pages linking to redirects to disambpages?
uploadPage = 'user:BinBot/Egyértelműsítő lapok'
uploadComment = 'Az egyértelműsítő lapok listájának frissítése'
pretext = """{{tudnivalók eleje}}
Az egyértelműsítő lapok listáját látod a hivatkozások száma szerint rendezve.

Az oldalon azok az egyértelműsítő lapok láthatóak, amelyekre legalább % d
hivatkozás van a %s névterekben. Az első szám az összes hivatkozás a megjelölt
névterekből, a második a sablonokból való hivatkozások száma. Utána következik
a „mi hivatkozik erre” link.

Kézzel is érdemes javítani azokat a sablonokat, amelyek sok hivatkozást
generálnak, mivel ezzel drasztikusan csökkenthető az összes hivatkozás száma,
és így jobban látható lesz, melyik lappal érdemes a botgazdáknak foglalkozniuk
(tipikusan ilyenek a navigációs sablonok, infoboxok és userboxok).
A sablonok számába nem számítanak bele a „kezdőlapos” sablonok, mert javítási
szempontból ezek közönséges lapnak tekinthetők (a kezdőlap kiemelt cikkei és
érdekességei, ünnepek, évfordulók, napképesablonok).

A listázásból ki vannak zárva a buszok, villamosok, metrók és trolibuszok
egyértelműsítő lapjai, mivel ezekre a [[Sablon:Viszonylatok egyértelműsítő lapjai]]
szándékosan 3-400 közötti (a beillesztésekkel összesen több mint 110 ezer)
kereszthivatkozást hoz létre, és csak eltakarnák a kilátást.

További információ: [[Wikipédia:Kocsmafal (egyéb)/Archív230#Segíthetsz az egyértelműsítésben bot nélkül is]].

Utolsó frissítés: ~~~~~. Futásidő: %s.

Összes átnézett lap: %d. Ebből eléri a limitet a hivatkozások számában: %d.
A megadott névterekben összesen %d egyértelműsítő lapra %d hivatkozás van.
<br>Kód: [[Szerkesztő:BinBot/disambcounter.py]].
{{tudnivalók vége}}

* """

# Project-independent settings
start_time = datetime.now()
site = pywikibot.getSite()
disambCat = catlib.Category(site, disambCatName)
disambGenerator = CategorizedPageGenerator(disambCat, recurse=recursive)#, start='Z')

def refPageGenerator(disambPage):
    return ReferringPageGenerator(disambPage, followRedirects=follow_redirects,
                                  withTemplateInclusion=True,
                                  onlyTemplateInclusion=False)


def nicetime(tdelta):
    tdelta += timedelta(seconds=.5)
    s = str(tdelta)
    s = s.replace('days,', 'nap').replace('day,', 'nap')  # For huwiki use only
    try:
        ind = s.index('.')
        ret = s[: ind]
    except ValueError:
        ret = s  # Whole seconds, no decimal points
    return ret

def disclosed(disambPage):
    # Use this function for disclosing pages by title in your wiki.
    # Feel free to rewrite it. The minimal content is "return False"
    # if you don't want to disclose anything.
    title = disambPage.title()
    if not title.endswith(ending):
        return True
    title = title[:-len(ending)]
    if title.endswith('busz') or title.endswith('villamos') \
            or title.endswith('metró'):
        return True
    return False

def notATemplate(refPage):
    # These pages are templates, but don't generate a lot of erroneous
    # references to the disambiguation page, as they don't have many
    # transclusions. So I won't count them into the number of template
    # references. In Hungarian Wikipedia these are identified with the
    # beginning of the title.
    excludedTitles = [
        'Évfordulók',
        'Kezdőlap',
        'A kezdőlap',
        'Napképe',
        'Ünnepek',
    ]
    title = refPage.title(withNamespace=False)
    for et in excludedTitles:
        if title.startswith(et):
            return True
    return False

def saveComments():
    # Try to mine the existing page for previous comments, and save them.
    regex = re.compile(
        r'^\* *\[\[(.*?%s)\]\] +\d+ +\d+ *(\S.*?) *$' % re.escape(ending))
    lines = oldtext.split('\n')
    for line in lines:
        try:
            g = regex.search(line).groups()
            storedComments[g[0]] = ' ' + g[1]
        except AttributeError:
            pass

# Do the job
i = 0
allReferredPages = 0
allReferences = 0
pageList = []
for disambPage in disambGenerator:
    if disclosed(disambPage):
        continue
    i += 1
    pages = 0
    templates = 0
    for p in refPageGenerator(disambPage):
        ns = p.namespace()
        if ns in namespaces:
            pages += 1
        if ns == namespaceTempl and not notATemplate(p):
            templates += 1
    if pages > 0:
        allReferredPages += 1
        allReferences += pages
    if pages >= limit:
        # pywikibot.output(disambPage.title() + ' %d' % pages)
        pageList.append([disambPage.title(), pages, templates])
pageList.sort(key = lambda x: str(100000 - x[1]) + x[0])

# Get the old comments
target = pywikibot.Page(site, uploadPage)
try:
    oldtext = target.get()
except pywikibot.NoPage:
    oldtext = ''
storedComments = {}
saveComments()
# print storedComments

# Final steps
text = '\n* '.join([
    '[[%s]] %d %d ([[Special:Whatlinkshere/%s|hiv.]])%s' % \
    (d[0], d[1], d[2], d[0], storedComments.get(d[0], '')) for d in pageList])
elapsed = nicetime(datetime.now() - start_time)
pretext = pretext % (limit, namespaceNames, elapsed, i, len(pageList),
                     allReferredPages, allReferences)
# pywikibot.output(pretext + text)
try:
    target.put(pretext + text, uploadComment)
except pywikibot.EditConflict:
    # Emergency saving, 'edit conflict' appended to subpage and edit comment
    target = pywikibot.Page(site, uploadPage + '/szerkütk')
    target.put(pretext + text, uploadComment + ' (szekesztési ütközés)')