Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Offtrac is a distributed issue tracker that coordinates with Trac (proof-of-concept)
Python JavaScript Shell
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.



In order to have any hope of using this, you need a Trac instance with Trac XML-RPC Plugin installed.

That said, you probably shouldn't use this. Not yet.

The only usable part is probably the wrapper for the API in offtrac.dumptrac, but this will move to a more sensible module name.


What this does right now:


  • Runs with python -mofftrac.dumptrac
  • Requires simplejson
  • Create a folder './db' (see JSON File Database) and initialize it as a git repository and make an initial commit.
  • Connect to the Trac instance and sync everything to this database as JSON files. For changelogs and tickets, it will only download the changes since the last sync (but may re-download the latest change).
  • Commit the changes to the repository.

  • Manages the sqlite3 database schema (./db/offtrac.db)
  • Requires SQLAlchemy, SQLALchemy-migrate
  • First run: python version_control
  • Other runs: python upgrade


  • Runs with python -mofftrac.etl
  • Requires SQLAlchemy, simplejson
  • Create a sqlite3 database (./db/offtrac.db) from the JSON File Database using a subset of Trac's schema. This will be done incrementally by looking at changes in the git repository.


  • Runs with python -mofftrac.start
  • Requires SQLAlchemy, simplejson, Flask, Flask-SQLAlchemy
  • Starts read-only web UI at for the local sqlite3 database created by offtrac.etl

JSON File Database

This is a bunch of JSON files, dumped by simplejson with sorted keys and one character indent to make the diffs nice (canonical-ish). Note that wiki and attachments are not currently synchronized.

  • db/db.json - repository metadata, currently the last timestamp synced from Trac:

  • db/report/{{id}}.json - Stored reports in Trac. SQL based:

     "sql":"-- ## 1: Active Tickets ## --\n\n-- \n--  * List all active […]",
     "title":"Active Tickets"
  • db/ticket/{{id}}.json - Ticket data in the form of [ticket_id, created, changed, props]:

      "description":"We need a script […]",
      "milestone":"Triage Me",
      "summary":"Image banner to click SWF script",
  • db/changelog/{{ticket_id}}.json - The full changelog for a given ticket in the form of [isotime, author, field, oldvalue, newvalue, permanent]. permanent is used to distinguish changes that are not immutable (attachments):

  • db/field/{{field}}/{{name}}.json - when field is one of component, version, milestone. name is UTF-8 and URL encoded with urllib.quote_plus. These have several slightly different structures, but the common factor is that the primary key is name and it is text.


     "description":"Urgent issues that require the attention of a platform engineer.",


     "description":"All tickets that need to be triaged by a PM",
     "name":"Triage Me"
  • db/field/{{enum}}/{{name}}.json - when field is any enum, such as priority, resolution, severity, type. The value is simply the value of the enum. Name is encoded UTF-8 with quote_plus URL encoding as above:

Something went wrong with that request. Please try again.