Posts for the month of December 2007

Populating ''Assign To'' Drop Down in Trac

When configuring a  Trac environment, you can set the following option:

[ticket]
restrict_owner = true

This will change the Assign To ticket filed into a select box that only contains existing users. However as it says on the  TracTickets page, the user must have logged, in at least once, and set their email address.

If you run multiple Trac sites, and have a set of common users across all Trac sites, it gets annoying to have to log into each one and set the email.

So, what is one to do? Well, there are two things that need to be entered into the database: a session record, and an email record.

To enter a session record, we need to add a row to the session table. The schema for the session table looks like

         Table "session"
    Column     |  Type   | Modifiers 
---------------+---------+-----------
 sid           | text    | not null
 authenticated | integer | not null
 last_visit    | integer | 

The sid is the username, authenticated will simply be 1, and last_visit needs to be set to a date, expressed as seconds since the epoch.

For example:

INSERT INTO session (sid, authenticated, last_visit) VALUES ('pacopablo', 1, 1195926785);

Now, to set the actual email address. That will go in the session_attribute table.

The schema for the session_attribute table is as follows:

    Table "session_attribute"
    Column     |  Type   | Modifiers 
---------------+---------+-----------
 sid           | text    | not null
 authenticated | integer | not null
 name          | text    | not null
 value         | text    | 

Once again, sid is the username, authenticated will be 1, name refers to the type of attribute this is, email in this case, and value will be the actual email adress.

For example:

INSERT INTO session_attribute (sid, authenticated, name, value) VALUES ('pacopablo', 1, 'email', 'pacopablo@pacopablo.com');

There is also a name attribute that is used which can be set:

INSERT INTO session_attribute (sid, authenticated, name, value) VALUES ('pacopablo', 1, 'name', 'Pacopablo Parangaricutirimicuaro');

Of course, going into a SQL interface to do this isn't really any better than logging into the Trac site and setting it yourself. It's also more error prone.

 Python to the rescue! We'll just whip up a simple little script that parses a command line, loads up the Trac environment, and creates the records for us. Behold:

from trac.env import Environment
from optparse import OptionParser
import sys
import os

def doArgs():
    """Parse command line options"""
    description = "%prog is used to seed the user's full name and email."

    parser = OptionParser(usage="usage: %prog [options] [username]",
                          version="1.0", description=description)
    parser.add_option("-e", "--env", dest="envpath", type="string",
                      help="Path to Trac environment", metavar="<path>",
                      default=".")
    parser.add_option("-m", "--email", dest="email", type="string",
                      help="Emal address", metavar="<email>", default=" ")
    parser.add_option("-f", "--fullname", dest="fullname", type="string",
                      help="Full Name", metavar="<name>", default=" ")
    (options, args) = parser.parse_args()
    if len(args) < 1:
        print "You must specify a username"
        sys.exit(1)
    options.user = args[0]
    if not os.path.exists(options.envpath):
        print "The path >%s< does not exist.  Please specify an existing path." % options.envpath
        sys.exit(1)
    options.args = args
    return options


if __name__ == '__main__':
    opts = doArgs()
    env = Environment(opts.envpath)
    cnx = env.get_db_cnx()
    cur = cnx.cursor()
    cur.execute("INSERT INTO session (sid, authenticated, last_visit) "
                "VALUES (%s, 1, 1195926785)", [opts.user])
    cur.execute("INSERT INTO session_attribute (sid, authenticated, name, "
                "value) VALUES (%s, 1, 'name', %s)",
                [opts.user, opts.fullname])
    cur.execute("INSERT INTO session_attribute (sid, authenticated, name, "
                "value) VALUES (%s, 1, 'email', %s)",
                [opts.user, opts.email])
    cnx.commit()
    cnx.close()
    sys.exit()

Most of the script is doing validation on input, and even then, it's not that much. So, save the script as trac_set_email.py, or some other such memorable name, fire it up1.

dev ~ # python trac_set_email.py -help                                                                                   
Usage: trac_set_email.py [options] [username]

trac_set_email.py is used to seed the user's full name and email.

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -e <path>, --env=<path>
                        Path to Trac environment
  -m <email>, --email=<email>
                        Emal address
  -f <name>, --fullname=<name>
                        Full Name


dev ~ # python trac_set_email.py --env /srv/trac/env/dev/ --fullname "Test User" --email pacopablo@pacopablo.com testuser

And there you have it. Enjoy2


  1. 1. If you're crazy like me, and install Trac into a different location than the system site-packages directory, you'll need to specify the PYTHON_PATH environment variable. For example: PYTHONPATH="/var/trac-0.11dev/lib/python2.5/site-packages/" \ python trac_set_email.py --env /srv/trac/env/dev/ --fullname "Test User" --email pacopablo@pacopablo.com testuser
  2. 2. And here's to hoping that Trac 0.12 has a better user management interface so that we don't have to manually enter records into the database