Scrivere un plugin per Trac


Recentemente mi sta capitando spesso di dover mettere le mani su Trac, il gestore di progetti scritto in Python.
Ecco quindi un piccolo tutorial su come scrivere un plugin per questo sistema.

Creiamo le directory che conterranno il codice:

$ mkdir bonzo-plugin/
$ mkdir bonzo-plugin/bonzo/

 

Scriviamo il primo file, il quale conterrà il codice principale del plugin:

$ vim bonzo-plugin/bonzo/bonzo.py

 

Ecco il cuore del nostro plugin che semplicemente genera una nuova voce di menu “bonzo” che permette di aprire una nuova pagina di url [/bonzo].

# Bonzo plugin
import re
from genshi.builder import tag
from trac.core import *
from trac.web import IRequestHandler
from trac.web.chrome import INavigationContributor, ITemplateProvider
class BonzoPlugin(Component):
    implements(INavigationContributor, IRequestHandler, ITemplateProvider)
    # INavigationContributor methods
    def get_active_navigation_item(self, req):
        return 'Bonzo'
    def get_navigation_items(self, req):
        if 'TRAC_ADMIN' in req.perm: #QUESTO PERMETTE DI GESTIRE I PERMESSI DI QUESTO MENU
            yield ('mainnav', 'bonzo',
                tag.a('Bonzo', href=req.href.bonzo()))
    # IRequestHandler methods
    def match_request(self, req):
	if 'TRAC_ADMIN' in req.perm: #QUESTO PERMETTE DI GESTIRE I PERMESSI DI QUESTa pagina
        	return re.match(r'/bonzo(?:_trac)?(?:/.*)?$', req.path_info)
    def process_request(self, req):
        data = {}
        # This tuple is for Genshi (template_name, data, content_type)
        # Without data the trac layout will not appear.
        return 'bonzo.html', data, None
    # ITemplateProvider methods
    # Used to add the plugin's templates and htdocs
    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]
    def get_htdocs_dirs(self):
        return []

 

Per poter visualizzare la pagina dobbiamo scriver il nostro template che utilizza Genshi come template language.

$ vim bonzo-plugin/bonzo/templates/bonzo.html

 

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:py="http://genshi.edgewall.org/"
      xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="layout.html" />



    



Bonzo

</html>

 

A questo punto dobbiamo inserire il tutto in un modulo e per ciò ci basta fare un semplice file di una riga.

$ vim /bonzo-plugin$ vim bonzo/__init__.py

 

# Bonzo module
from bonzo import *

 

Finito, ora non ci resta che fare deploy del plugin.
Creiamo il file di setup dove andiamo a mettere il nome del Plugin, la sua versione e andiamo ad settare quale sarà la directory contenente i templates.

$ vim bonzo-plugin/setup.py 

 

from setuptools import find_packages, setup

# name can be any name.  This name will be used to create the .egg file.
# name that is used in packages is the one that is used in the trac.ini file.
# use package name as entry_points
setup(
    name='TracBonzo', version='0.1',
    packages=find_packages(exclude=['*.tests*']),
    entry_points = """
        [trac.plugins]
        bonzo = bonzo
    """,
    package_data={'bonzo': ['templates/*.html']},
)

 

Diamo il seguente comando per creare l’egg.

$ python setup.py bdist_egg

 

Se non ci sono errori ci ritroviamo una directory /dist con dentro un file .egg
Ora abbiamo due strade:

  • Installare direttamente il plugin nella istanza di trac
  • installare il plugin a livello di environment

Per il primo caso ci basta copiare il file .egg dentro la directory /plugins dell’istanza di Trac e riavviare il webserver.
Nel secondo caso, per installarlo nel virtual env posizionato in /var/trac-env, possiamo dare i seguenti comandi:

sudo mkdir /var/trac-env
cd /var/trac-env/
sudo virtualenv python
sudo /var/trac-env/python/bin/easy_install   http://svn.edgewall.org/repos/trac/tags/trac-0.11
sudo /var/trac-env/python/bin/easy_install dist/TracBonzo-0.1-py2.6.egg

 

Dopo aver riavviato il web server il plugin è disponibile nell’enviroment e basta attivarlo attraverso l’admin plugin.