Purple exclamation mark.svg Planning the future of Botwiki! - Help us bring Botwiki up to date, contribute to our strategy discussion, add bot scripts, and contribute manuals, guides, and tutorials! Almost anything related to bots, particularly those used to edit mediawiki, is welcome.

Red exclamation mark.svg UNABLE TO EDIT? - We've experienced attacks by spambots lately and now require you to confirm your e-mail before you can edit (go to your preferences, enter an e-mail address, and request a confirmation e-mail, then go to your e-mail and click on the confirmation link). We also require new accounts to make a few edits and wait a few minutes before before you can create a page; however, if this is a problem contact us in #botwiki and we can manually confirm your account. Sorry for the inconvenience.

Python:Portale.py

From Botwiki
Jump to: navigation, search
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Questo script è stato scritto da Pietrodn & Filnik per it.wikipedia.
Serve per sistemare i vari template {{Portale}} presenti nelle voci in uno solo,
riposizionare correttamente il template {{Portale}}, rimuovere i duplicati,
mettere in ordine alfabetico gli argomenti, aggiungerli e togliergli a comando.
 
Se il bot non rileva nessun cambiamento nei portali utilizzati, non cambierà la pagina, a meno che non si specifichi l'attributo -force.
È possibile specificare delle regex per aggiungere delle eccezioni, con il comando -except.
 
Se si decide di aggiungere un argomento e nella pagina non è presente alcun template portale,
questo verrà aggiunto nel posto giusto.
Se si rimuove l'unico argomento presente nel template portale, questo verrà tolto completamente.
 
Lo script si basa su add_text.py di Filnik.
 
These command line parameters can be used to specify which pages to work on:
 
&params;
 
Furthermore, the following command line parameters are supported:
 
-always             Non chiede il consenso prima di editare. Usare con cautela.
-add:Foo            Aggiunge Foo alla lista di portali.
-remove:param       Toglie Foo dalla lista di portali, se presente
-except:regex       Non processa le pagine che matchano la regex.
-force              Processa comunque la pagina, anche se non ci sono cambiamenti nei portali.
 
--- Example ---
 
python portale.py -add:Foo -remove:Bar -add:Baz
python portale.py -add:Foo
python portale.py
 
--- Credits and Help ---
This script has been written by Botwiki's staff, if you want to help us
or you need some help regarding this script, you can find us here:
 
* http://botwiki.sno.cc
 
"""
 
import re, wikipedia, catlib
import pagegenerators
from add_text import add_text
 
class NoEnoughData(wikipedia.Error):
    """ Error class for when the user doesn't specify all the data needed. """
 
class Portale():
    def __init__(self, page, addPortals=[], removePortals=[], force=False):
        self.page = page
        self.oldtext = page.get()
        self.addPortals = addPortals
        # If I want to remove "informatica", I also want to remove "Informatica" (capitalized)
        self.removePortals = set(map(unicode.lower, removePortals) + map(unicode.capitalize, removePortals))
        self.force = force
        self.allArguments = set()
 
    def process(self):
        newtext = self.oldtext
        templates = self.page.templatesWithParams() # Get all the templates
 
        singleTemplate = "{{Portale"
        for template in templates:
            if template[0] == "Portale": # Select only {{Portale}} templates
                for argument in template[1]:
                    if argument != '': # elimina gli occhielli vuoti {{Portale|biografie|}}
                        self.allArguments.add(argument)
 
        # Backup for comparing (next...)
        oldArguments = list(self.allArguments)
        oldArguments.sort(key=unicode.lower)
 
        # case-insensitive difference
        diff = set()
        for arg in self.allArguments:
            found = False
            for toAdd in self.addPortals:
                if toAdd.lower() == arg.lower():
                    found = True
                    break
            if not found:
                diff.add(arg) # salvo gli occhielli non presenti in addPortals case-insensitive (scremando i doppi)
        self.allArguments = diff.union(self.addPortals) # Tutti gli occhielli da inserire
        self.allArguments = self.allArguments.difference(self.removePortals) # Remove all the templates to remove
        self.allArguments = list(self.allArguments) # Return to an ordered list
        self.allArguments.sort(key=unicode.lower) # Case-insensitive sort
 
        if self.allArguments == oldArguments and not self.force:
            return self.oldtext
 
        for arg in self.allArguments:
            singleTemplate += '|' + arg # Add arguments one by one
        singleTemplate += '}}' # Close the template
 
        newtext = re.sub("\{\{[Pp]ortale\|.*?\}\}", "", newtext)
        # If there aren't any arguments, don't put the template, just remove it!
        if len(self.allArguments)>0:
            newtext = add_text(page = self.page, addText = singleTemplate, putText = False, oldTextGiven = newtext)[1]
        return newtext
 
def decide(catname):
    generator = None
    cat = catlib.Category(wikipedia.getSite(), catname)
    for categorie in cat.subcategories():
        wikipedia.output(categorie.title())
        choice2 = wikipedia.inputChoice(u"Procedo?",  ['Yes', 'No'], ['y', 'N'], 'N')
        if choice2.lower() in ['n', 'no']:
            continue
        else:          
            generator = categorie.articles()
    return generator
 
def main():
    all = False
    force = False
    addPortals = []
    removePortals = []
    exceptions = []
    generator = None
    genFactory = pagegenerators.GeneratorFactory()
    catname = None
 
    for currentArgument in wikipedia.handleArgs():   
        if currentArgument.startswith("-always"):
            all = True
        if currentArgument.startswith("-force"):
            force = True
        elif currentArgument.startswith('-add:') and (len(currentArgument) > 5):
            addPortals.append(currentArgument[5:])
        elif currentArgument.startswith('-remove:') and (len(currentArgument) > 8):
            removePortals.append(currentArgument[8:])
        elif currentArgument.startswith('-except:') and (len(currentArgument) > 8):
            exceptions.append(currentArgument[8:])
        elif currentArgument.startswith('-subcatmod:') and (len(currentArgument) > 11):
            catname = currentArgument[11:]            
        else:
            gens = str(genFactory.handleArg(currentArgument))
            if gens != 'True' and gens != 'False' and gens != 'None':
                generator = genFactory.handleArg(currentArgument)
 
    if len(removePortals) == 0 and len(addPortals) == 0 and not force:
        raise wikipedia.Error("You haven't specified any portals to add or remove, and there is not the -force option.")
    if catname != None:
        generator = decide(catname)    
    # Check if pages on which the bot should work are specified.
    if not generator:
        raise NoEnoughData('You have to specify which pages the script has to work on!')
 
    # Builds the summary
    summary = u'[[WP:BOT|Bot]]: Sistemo sintassi [[Template:Portale|template Portale]].'
    if len(addPortals) > 0:
        summary += ' Aggiungo: '
        for portalToAdd in addPortals:
            summary += portalToAdd + ', '
        summary = summary[:len(summary)-2] + '.'
    if len(removePortals) > 0:
        summary += ' Tolgo: '
        for portalToRemove in removePortals:
            summary += portalToRemove + ', '
        summary = summary[:len(summary)-2] + '.'
 
    # Main Loop
    for page in generator:
        wikipedia.output(">>>>> " + page.title() + " <<<<<")
 
        try:
            oldtext = page.get()
        except wikipedia.IsRedirectPage:
            wikipedia.output(u"%s is a redirect, I'll ignore it." % page.title())
            continue
 
        stop = False    
        for exception in exceptions:
            if re.search(exception, oldtext):
                wikipedia.output('Exception "%s" found! Skipping.' % exception)
                stop = True
                break
        if stop:
            continue
 
        portale = Portale(page, addPortals, removePortals, force)
        newtext = portale.process()
 
        if oldtext != newtext or force:
            wikipedia.showDiff(oldtext, newtext)
            if not all:
                choice = wikipedia.inputChoice(u"Modificare?",  ['Yes', 'No', 'All'], ['y', 'N', 'a'], 'N')
                if choice in ['A', 'a']:
                    all = True
            if all or choice in ['Y', 'y']:
                page.put_async(newtext, comment=summary)
 
 
if __name__ == "__main__":
    try:
        main()
    finally:
        wikipedia.stopme()
Personal tools
Share