Roundup Wiki

This is an example of adding an about page that provides info about how the system is configured. All of these changes are done in the tracker.

Add an html template.

In html/home.about.html put:

<tal:block metal:use-macro="templates/page/macros/icing">

<title metal:fill-slot="head_title" i18n:translate="" >                         
 About this Tracker                                                             
<tal:block metal:fill-slot="body_title" i18n:translate="">
  About this Tracker

<div class="content" metal:fill-slot="content">
  <span tal:condition="not:python:request.user.hasPermission('SeeAbout')"
        tal:omit-tag="python:1" i18n:translate="">
    Please login with your username and password to find out about
    this tracker.

  <div tal:condition="python:request.user.hasPermission('SeeAbout')"
       tal:omit-tag="python:1" i18n:translate="">

    <div tal:replace="structure python:utils.AboutPage(db)"></div>



in lib/ put:

Define the version of this tracker.                        
Manually maintained incremented at release.                                     
__version__ = "0.9"

Put the following in extensions/

import logging
logger = logging.getLogger('extension')

import tracker_version

import sys
from roundup import __version__ as roundup_version
def AboutPage(db):
    "report useful info about this tracker"

    def is_module_loaded(module):
        modules = sys.modules.keys()
        return module in modules

    def get_status_of_module(module, prefix=None, version=True):
        modules = sys.modules.keys()
        is_enabled = module in modules
        if is_enabled:
            if module == 'pyme':
                from pyme import version
                version="version %s"%version.versionstr
            elif module == 'pychart':
                from pychart import version
                version="version %s"%version.version
            elif module == 'sqlite3':
                from sqlite3 import version
                version="version %s"%version
            elif module == 'xapian':
                from xapian import version_string
                version="version %s"%version_string()
                if version:
                    m = __import__(module)
                        version="version %s"%m.__version__
                    except AttributeError:
                        version="version unavailable - exception thrown"
                    version="version unavailable"

            if prefix:
                return "%s %s %s enabled: %s"%(prefix, module, version, is_enab\
                return "Module: %s %s enabled: %s"%(module, version, is_enabled\
            if prefix:
                return "%s %s enabled: %s"%(prefix, module, is_enabled)
                return "Module: %s enabled: %s"%(module, is_enabled)

    info = []

    info.append("Tracker name: %s<br>"%db.config['TRACKER_NAME'])
    info.append("Tracker base version: %s"%tracker_version.__version__)

    info.append("<h2>Operating environment</h2>")
    info.append('<a href="">Roundup</a> version:\
    info.append("Python Version: %s<br>"%sys.version)


    backend = db.config['RDBMS_BACKEND']
    info.append("Roundup backend: %s<br>"%backend)
    if backend != 'anydbm':
        info.append("Roundup db cache: %s<br>"%db.config['RDBMS_CACHE_SIZE'])
        info.append("Roundup isolation_level: %s<br>"%db.config['RDBMS_ISOLATIO\

    info.append("Roundup template: %s<br>"%db.config['TEMPLATE_ENGINE'])

    info.append("<h2>Database modules</h2>")
    info.append(get_status_of_module('anydbm', version=False) + "<br>")
    info.append(get_status_of_module('sqlite3') + "<br>")
    info.append(get_status_of_module('MySQLdb') + "<br>")
    info.append(get_status_of_module('psycopg2') + "<br>")

    info.append("<h2>Other modules</h2>")

    indexer = db.config['INDEXER']
    if not indexer:
        if is_module_loaded('xapian'):
            indexer="unset using xapian"
        elif is_module_loaded('whoosh'):
            indexer="unset using woosh"
            indexer="unset using native"
        indexer="set to " + indexer

    info.append("Indexer used for full-text: %s<br>"%indexer)

    info.append("Available indexers:<br>")
    if is_module_loaded('xapian'):
        info.append(get_status_of_module('xapian', prefix="Indexer loaded:") +
    if is_module_loaded('whoosh'):
        info.append(get_status_of_module('whoosh', prefix="Indexer loaded:") +
    info.append("Indexer loaded: native: True<br>")

    info.append(get_status_of_module('pytz') + "<br>")
    info.append(get_status_of_module('pyme') + "<br>")
    info.append(get_status_of_module('OpenSSL') + "<br>")
    info.append(get_status_of_module('pychart') + "<br>")

    info.append(get_status_of_module('jinja2') + "<br>")

    if db._db.getuid() == "1":
        #may leak sensitive info about system, directory paths etc.             
        #and keys so require admin user access. Consider expanding              
        #to Admin rights for tracker.                                           
        info.append("Module Path: %r"%sys.path)

        info.append("<h2>Environment Variables</h2>")
        info.append("<pre>") # include pre to prevent wrapping of values        
        for key in db._client.env.keys():
            info.append("%s=%s"%(key,db._client.env[key]) + "<br>")
    return "\n".join(info)

def init(instance):
    instance.registerUtil('AboutPage', AboutPage)

To view the page go to the url: http://host/tracker/?@template=about I.E. append "?@template=about" to the base url of your tracker.

The page looks something like:


Hopefully I got all the important bits as I extracted this from my tracker.