Progetto:Bot/Programmi in Python per i bot/templateHandler.py

Da Wikisource.
Jump to navigation Jump to search
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# template.py, a simple library to handle wiki templates.
# Copyright (C) 2007  Roberto Zanon (http://it.wikisource.org/wiki/Utente:Qualc1)
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import re

class Template(list):
    """It rapresents a wiki template.

    A template is identified by
     a name (a string set by constructor),
     a list (can be empty) of:
      positional parameter (a string) and named parameter (a 2-tuple of strings)
      Parameters can be added/removed/accessed as element of list object.
    """

    def __init__(self, name=None, fromText=None):
        """Instanziate a template identified by "name",
            or instanziate a template importing it from text "fromText".
        """
        list.__init__(self)
        if name is not None and fromText is not None:
            raise ValueError('Do not set both "name" and "fromText"')
        if name is not None:
            self.name = name
        if fromText is not None:
            self.fromText(fromText)

    def fromText(self, text):
        """Import template information from text."""
        if text.startswith("{{"):
            text = text[len("{{"):]
        if text.endswith("}}"):
            text = text[:-len("}}")]

        # TODO Doesn't work if template has a link [[xx|yy]]
        templElements = [x.strip() for x in text.split("|")]
        if len(templElements) < 1:
            raise ValueError("Is a template empty?")

        self.name = templElements[0]
        for element in templElements[1:]:
            self._importParameter(element)

    def _importParameter(self, parameter):
        """Imports a temlate parameter,
            ie. a string like "name=Linus" (named par.) or "Linus" (positional par.).
        """
        divisorPos = parameter.find("=")
        if divisorPos == -1: # positional
            self.append(parameter)
        else: # named
            self.append( (parameter[:divisorPos], parameter[divisorPos+1:]) )

    def toText(self):
        """Return a string rapresenting template as text of a wiki page."""
        insertedParams = 0
        strTempl = u"{{" + self.name + "\n"

        posParameters = [par for par in self if isinstance(par, basestring)]
        for par in posParameters:
            strTempl += ( "|" + par )
            insertedParams += 1

        namParameters = [par for par in self if isinstance(par, tuple) and len(par)==2]
        for par in namParameters:
            strTempl += ( u"|" + par[0] + "=" + par[1] + "\n")
            insertedParams += 1

        strTempl += "}}"
        if insertedParams != len(self):
            raise UnexpectedElementWarning()
        else:
            return strTempl

    def removeByParamName(self, paramsName):
        """Remove a named parameters with names in list "paramName".
        """
        nameParameters = [par for par in self if isinstance(par, tuple) and len(par)==2]
        for param in nameParameters:
            if param[0] in paramsName:
                self.remove(param)


def templatesFromPage(pageText):
    """Returns a list of Template instance, rapresenting the templates found in "pageText."
    """
    compiledRegEx = re.compile(r'''\{\{.*?\}\}''',  re.DOTALL)
    templatesList = []
    for templateText in compiledRegEx.finditer(pageText):
        #print pageText[templateText.start, templateText.end]
        newTempalte = Template(fromText = templateText.group())
        templatesList.append(newTempalte)
    return templatesList

class UnexpectedElementWarning(Exception):
    """It's raised if is found an element in Template that isn't a valid parameter.
    (a valid parameter is an object of string or 2-tuple type)
    """
    pass


if __name__ == "__main__":
    # testing
    temp = Template(name="PAG_TEMPL")

    temp.append(("parN", "parV"))
    temp.append( "parccV")
    print temp.toText()

    print "------ test importazione -------"
    un_template = \
    """{{Autore
|nome=UNNOME
|cognome=UNCOGNOME
|test
}}"""
    temp2 = Template(fromText = un_template)
    print temp2.toText()

    print "------ test importazione PAGINA -------"
    un_testo = \
    """asdf sf fg r g {{Autore
|nome=UNNOME
|cognome=UNCOGNOME
|test
}} afgrg {{Testo|bo|pippo}}"""
    for templ in templatesFromPage(un_testo):
        print "START"
        print "Nome template: ",  templ.name
        print "Param 1: ",  templ[0]
        print "END"
[visualizza] [modifica] Documentazione


Descrizione

xxx

Nome del file

templateHandler.py

Comando

Il programma viene richiamato da altri programmi, quindi non va lanciato da solo