[Python-apps-commits] r3931 - in packages/trac/trunk/debian (6 files)

debacle at users.alioth.debian.org debacle at users.alioth.debian.org
Sat Oct 10 12:07:27 UTC 2009


    Date: Saturday, October 10, 2009 @ 12:07:23
  Author: debacle
Revision: 3931

Add some fixes of minor importance.

Added:
  packages/trac/trunk/debian/patches/40_timeline_author_filter.dpatch
  packages/trac/trunk/debian/patches/50_sqlitetopg_script.dpatch
Modified:
  packages/trac/trunk/debian/README.Debian
  packages/trac/trunk/debian/changelog
  packages/trac/trunk/debian/copyright
  packages/trac/trunk/debian/patches/00list

Modified: packages/trac/trunk/debian/README.Debian
===================================================================
--- packages/trac/trunk/debian/README.Debian	2009-10-10 11:09:24 UTC (rev 3930)
+++ packages/trac/trunk/debian/README.Debian	2009-10-10 12:07:23 UTC (rev 3931)
@@ -53,7 +53,7 @@
 
 Apache is the most used webserver, so it's preferred for Trac.
 It can be configured to be run as CGI application (CGI, WSGI, FCGI)
-or with mod-python.
+or with mod-python. WSGI is the recommended method.
 
 Configuring as CGI, WSGI, FastCGI
 ---------------------------------
@@ -133,12 +133,20 @@
 [1] https://coderanger.net/~coderanger/tracdoc/
 
 
-Notes for users upgrading from Trac 0.10.x to 0.11.x
-====================================================
+Notes for users upgrading Trac
+==============================
 
-SQLite
-------
+Running Trac via WSGI etc.
+--------------------------
 
+If you upgrade Trac and do not use the builtin HTTP daemon (tracd),
+you must restart your HTTPD manually. E.g. for Apache:
+
+# /etc/init.d/apache restart
+
+Upgrading from Trac 0.10.x to 0.11.x: SQLite
+--------------------------------------------
+
 Wookey at toby-churchill.com came across the issue, that the
 SQLite format between Trac 0.10.x (SQLite v2) and 0.11.x (SQLite
 v3) has changed. If you happen to use SQLite, use the following
@@ -147,6 +155,21 @@
 With the new file you should be able to run Trac as expected.
 See http://bugs.debian.org/501338 for details.
 
+
+Debian specifics
+================
+
+We added some patches and files, that are useful to most users:
+
+1. A patch, that already is applied upstream to allow filtering the
+   timeline for specific users.
+   See http://trac.edgewall.org/ticket/1198
+2. A sample script to migrate an SQLite Trac database to PostgreSQL.
+   See http://trac-hacks.org/wiki/SqliteToPgScript
+3. A patch to use UTF-8 per default, as this is the default and
+   preferred encoding on Debian systems.
+
+
 Enjoy!
 
 /The Trac Team
@@ -157,5 +180,5 @@
 Visit the Trac open source project at <http://trac.edgewall.com/>
 
 Jonas Borgstrom <jonas at edgewall.com>, Sat, 22 May 2004 20:49:22 +0200
-Luis Matos <gass at otiliamatos.ath.cx>  Mon, 21 Jul 2008 21:06:36 +0100
-
+Luis Matos <gass at otiliamatos.ath.cx>, Mon, 21 Jul 2008 21:06:36 +0100
+W. Martin Borgert <debacle at debian.org>, Sat, 2009-10-10, 11:39 +0000

Modified: packages/trac/trunk/debian/changelog
===================================================================
--- packages/trac/trunk/debian/changelog	2009-10-10 11:09:24 UTC (rev 3930)
+++ packages/trac/trunk/debian/changelog	2009-10-10 12:07:23 UTC (rev 3931)
@@ -1,3 +1,12 @@
+trac (0.11.5-5) NOT YET unstable; urgency=low
+
+  * Include SqliteToPg script in contrib (Closes: #505680).
+  * Advice user to restart HTTPD after upgrade in README.Debian
+    (Closes: #519670).
+  * Add patch to support user filter for timeline (Closes: #550469).
+
+ -- W. Martin Borgert <debacle at debian.org>  Sat, 10 Oct 2009 12:00:50 +0000
+
 trac (0.11.5-4) unstable; urgency=low
 
   * Revert the change: Depend on python-setuptools instead of

Modified: packages/trac/trunk/debian/copyright
===================================================================
--- packages/trac/trunk/debian/copyright	2009-10-10 11:09:24 UTC (rev 3930)
+++ packages/trac/trunk/debian/copyright	2009-10-10 12:07:23 UTC (rev 3931)
@@ -30,3 +30,9 @@
 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The SqliteToPg script is copyright by
+John Hampton <pacopablo at pacopablo.com>,
+licensed under the same conditions as Trac.
+It has been downloaded from
+http://trac-hacks.org/wiki/SqliteToPgScript

Modified: packages/trac/trunk/debian/patches/00list
===================================================================
--- packages/trac/trunk/debian/patches/00list	2009-10-10 11:09:24 UTC (rev 3930)
+++ packages/trac/trunk/debian/patches/00list	2009-10-10 12:07:23 UTC (rev 3931)
@@ -1,3 +1,5 @@
 15_remove_jquery_file.dpatch
 20_add_interpreter_line.dpatch
 30_default_charset_utf8.dpatch
+40_timeline_author_filter.dpatch
+50_sqlitetopg_script.dpatch

Added: packages/trac/trunk/debian/patches/40_timeline_author_filter.dpatch
===================================================================
--- packages/trac/trunk/debian/patches/40_timeline_author_filter.dpatch	                        (rev 0)
+++ packages/trac/trunk/debian/patches/40_timeline_author_filter.dpatch	2009-10-10 12:07:23 UTC (rev 3931)
@@ -0,0 +1,68 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 40_timeline_author_filter.dpatch by  <wmb at beron.tangosoft.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: add author filter to timeline
+
+ at DPATCH@
+
+Index: trac/trac/timeline/web_ui.py
+===================================================================
+--- trac/trac/timeline/web_ui.py	(revision 7937)
++++ trac/trac/timeline/web_ui.py	(working copy)
+@@ -118,8 +118,12 @@
+         daysback = max(0, daysback)
+         if self.max_daysback >= 0:
+             daysback = min(self.max_daysback, daysback)
++        author = req.args.get('author',
++                              req.session.get('timeline.author', ''))
++        author = author.strip()
+ 
+         data = {'fromdate': fromdate, 'daysback': daysback,
++                'author': author,
+                 'today': format_date(today),
+                 'yesterday': format_date(today - timedelta(days=1)),
+                 'precisedate': precisedate, 'precision': precision,
+@@ -158,7 +162,9 @@
+             try:
+                 for event in provider.get_timeline_events(req, start, stop,
+                                                           filters):
+-                    events.append(self._event_data(provider, event))
++                    author_index = len(event) < 6 and 2 or 4    # 0.10 events
++                    if not author or event[author_index] == author:
++                        events.append(self._event_data(provider, event))
+             except Exception, e: # cope with a failure of that provider
+                 self._provider_failure(e, req, provider, filters,
+                                        [f[0] for f in available_filters])
+@@ -185,6 +191,7 @@
+             return 'timeline.rss', data, 'application/rss+xml'
+         else:
+             req.session['timeline.daysback'] = daysback
++            req.session['timeline.author'] = author
+             html_context = Context.from_request(req)
+             html_context.set_hints(wiki_flavor='oneliner', 
+                                    shorten_lines=self.abbreviated_messages)
+@@ -192,7 +199,8 @@
+ 
+         add_stylesheet(req, 'common/css/timeline.css')
+         rss_href = req.href.timeline([(f, 'on') for f in filters],
+-                                     daysback=90, max=50, format='rss')
++                                     daysback=90, max=50, author=author,
++                                     format='rss')
+         add_link(req, 'alternate', rss_href, _('RSS Feed'),
+                  'application/rss+xml', 'rss')
+ 
+Index: trac/trac/timeline/templates/timeline.html
+===================================================================
+--- trac/trac/timeline/templates/timeline.html	(revision 7937)
++++ trac/trac/timeline/templates/timeline.html	(working copy)
+@@ -18,7 +18,8 @@
+       <form id="prefs" method="get" action="">
+        <div>
+         <label>View changes from <input type="text" size="10" name="from" value="${format_date(fromdate)}" /></label> <br />
+-        and <label><input type="text" size="3" name="daysback" value="$daysback" /> days back</label>.
++        and <label><input type="text" size="3" name="daysback" value="$daysback" /> days back</label><br />
++        <label>done by <input type="text" size="16" name="author" value="$author" /></label>
+        </div>
+        <fieldset>
+         <label py:for="filter in filters">


Property changes on: packages/trac/trunk/debian/patches/40_timeline_author_filter.dpatch
___________________________________________________________________
Added: svn:executable
   + *

Added: packages/trac/trunk/debian/patches/50_sqlitetopg_script.dpatch
===================================================================
--- packages/trac/trunk/debian/patches/50_sqlitetopg_script.dpatch	                        (rev 0)
+++ packages/trac/trunk/debian/patches/50_sqlitetopg_script.dpatch	2009-10-10 12:07:23 UTC (rev 3931)
@@ -0,0 +1,380 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 50_sqlitetopostgresql_script.dpatch by  <wmb at beron.tangosoft.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: add script to migrate from SQlite to PostgreSQL
+
+ at DPATCH@
+
+diff -uraN trac-0.11.5.orig/contrib/sqlitetopgscript/COPYING trac-0.11.5/contrib/sqlitetopgscript/COPYING
+--- trac-0.11.5.orig/contrib/sqlitetopgscript/COPYING	1970-01-01 01:00:00.000000000 +0100
++++ trac-0.11.5/contrib/sqlitetopgscript/COPYING	2006-09-13 06:42:50.000000000 +0200
+@@ -0,0 +1,28 @@
++Copyright (C) 2003-2006 Edgewall Software
++All rights reserved.
++
++Redistribution and use in source and binary forms, with or without
++modification, are permitted provided that the following conditions
++are met:
++
++ 1. Redistributions of source code must retain the above copyright
++    notice, this list of conditions and the following disclaimer.
++ 2. Redistributions in binary form must reproduce the above copyright
++    notice, this list of conditions and the following disclaimer in
++    the documentation and/or other materials provided with the
++    distribution.
++ 3. The name of the author may not be used to endorse or promote
++    products derived from this software without specific prior
++    written permission.
++
++THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
++OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
++IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
++IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+diff -uraN trac-0.11.5.orig/contrib/sqlitetopgscript/sqlite2pg trac-0.11.5/contrib/sqlitetopgscript/sqlite2pg
+--- trac-0.11.5.orig/contrib/sqlitetopgscript/sqlite2pg	1970-01-01 01:00:00.000000000 +0100
++++ trac-0.11.5/contrib/sqlitetopgscript/sqlite2pg	2008-06-12 05:06:56.000000000 +0200
+@@ -0,0 +1,336 @@
++#!/usr/bin/env python
++
++# -*- coding: utf-8 -*-
++#
++# Copyright (C) 2008 John Hampton <pacopablo at pacopablo.com>
++# All rights reserved.
++#
++# This software is licensed as described in the file COPYING, which
++# you should have received as part of this distribution. The terms
++# are also available at http://trac.edgewall.com/license.html.
++#
++# This software consists of voluntary contributions made by many
++# individuals. For the exact contribution history, see the revision
++# history and logs, available at:
++# http://trac-hacks.org/wiki/SqliteToPgScript
++#
++# Basically, it boils down to: feel free to use/modify/distribute/etc.
++# However, give me credit where due.  Also, if you like the script and
++# find it useful, buy me a soda or candy bar or something if ever we
++# meet. Thanks and enjoy.
++#
++# Author: John Hampton <pacopablo at pacopablo.com>
++
++
++import os, os.path, sys
++from trac.env import Environment, EnvironmentSetup, IEnvironmentSetupParticipant
++from trac.core import ComponentMeta
++from trac.db import DatabaseManager
++from optparse import OptionParser
++from psycopg2 import ProgrammingError, IntegrityError
++from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
++
++VERSION='0.10'
++
++class TableMigration(object):
++    """
++        Class to conatin all table migration functions
++    """
++    def __init__(self, sqlenv, pgenv, opts):
++        """ Create a TableMigration instance.  Required are SQLite and
++            PostgreSQL environment objects
++        """
++        self.sqlenv = sqlenv
++        self.pgenv = pgenv
++        self.opts = opts
++        self.sdb = self.sqlenv.get_db_cnx()
++        self.pgdb = self.pgenv.get_db_cnx()
++        self.pgdb_schema = self.pgdb.schema
++        pass
++
++    def lookupMethod(self, table):
++        """ Get a reference to the function that handles migration for the
++            specified table
++        """
++        m = getattr(self, ''.join(['migrate_', table.upper()]), None)
++        if not m:
++            m = self.default_copy 
++        return m
++
++    def cleanTable(self, table):
++        """ Clear the contents of the table """
++        cur = self.pgdb.cursor()
++        delete_from = "DELETE FROM %s" % table
++        cur.execute(delete_from)
++
++    def migrateTable(self, table):
++        """ Migrate the table specified. """
++        if not self.opts.noclean:
++            self.cleanTable(table)
++        m = getattr(self, ''.join(['migrate_', table.upper()]), None)
++        if not m:
++            rc = self.default_copy(table)
++        else:
++            rc = m()
++        return rc
++
++    def default_copy(self, table):
++        """ Copy the table from the sqlite db to the postgresql db """
++        select_all = "SELECT * FROM %s" % table
++        scur = self.sdb.cursor()
++        pgcur = self.pgdb.cursor()
++        scur.execute(select_all)
++        cols = scur.description
++        if not cols:
++            return True
++        subs = ["%s" for x in range(len(cols))]
++        insert_into = ''.join([ "INSERT INTO ", table, " VALUES (",
++                                ','.join(subs), ")"])
++        rows = row_exists = 0
++        for row in scur:
++            rows += 1
++            try:
++                pgcur.execute(insert_into, row)
++            except (ProgrammingError, IntegrityError):
++                row_exists += 1
++            continue
++        if row_exists:
++            print "%s of %s rows already existed in the %s table" % \
++                  (str(row_exists), str(rows), table)
++        self.pgdb.commit()
++        return row_exists > 0
++
++    def migrate_TICKET(self):
++        """ Migrate the ticket table and adjust the sequences properly """
++        self.default_copy('ticket')
++        select_maxticket = "SELECT max(id) FROM ticket"
++        pgcur = self.pgdb.cursor()
++        pgcur.execute(select_maxticket)
++        r = pgcur.fetchone()
++        if r:
++            pgcur.execute("SELECT setval('ticket_id_seq', %s)", r)
++        self.pgdb.commit()
++        
++    def migrate_REPORT(self):
++        """ Migrate the report table and adjust the sequences properly """
++        self.default_copy('report')
++        select_maxreport = "SELECT max(id) FROM report"
++        pgcur = self.pgdb.cursor()
++        pgcur.execute(select_maxreport)
++        r = pgcur.fetchone()
++        if r:
++            pgcur.execute("SELECT setval('report_id_seq', %s)", r)
++        self.pgdb.commit()
++    
++    def migrate_PERMISSION(self):
++        """
++            Migrate permission table
++        """
++        scur = self.sdb.cursor()
++        pgcur = self.pgdb.cursor()
++        rows = row_exists = 0
++        if not self.opts.plist:
++            sql_select = "SELECT * FROM permission"
++        else:
++            subs = []
++            for x in range(len(self.opts.plist)):
++                subs.append("%s")
++                continue
++            sql_select = ''.join([  "SELECT * FROM permission ",
++                                    "WHERE username NOT IN (",
++                                    ','.join(subs),
++                                    ")",
++                                 ])
++        
++        scur.execute(sql_select, self.opts.plist)
++        sql_insert = "INSERT INTO permission VALUES (%s, %s)"
++        for row in scur:
++            rows += 1
++            try:
++                pgcur.execute(sql_insert, row)
++            except (ProgrammingError, IntegrityError):
++                row_exists += 1
++            continue
++        if row_exists:
++            print "%s of %s rows already existed in the permission table" % (str(row_exists), str(rows))
++        self.pgdb.commit()
++        return row_exists > 0
++
++    def migrate_WIKI(self):
++        """
++            Migrate wiki table
++        """
++        scur = self.sdb.cursor()
++        pgcur = self.pgdb.cursor()
++        rows = row_exists = 0
++        if not self.opts.wlist:
++            sql_select = "SELECT * FROM wiki"
++        else:
++            subs = []
++            for x in range(len(self.opts.wlist)):
++                subs.append("%s")
++                continue
++            sql_select = ''.join([  "SELECT * FROM wiki ",
++                                    "WHERE name NOT IN (",
++                                    ','.join(subs),
++                                    ")",
++                                 ])
++        
++        scur.execute(sql_select, self.opts.wlist)
++        sql_insert = "INSERT INTO wiki VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"
++        for row in scur:
++            rows += 1
++            try:
++                pgcur.execute(sql_insert, row)
++            except (ProgrammingError, IntegrityError):
++                row_exists += 1
++            continue
++        if row_exists:
++            print "%s of %s rows already existed in the wiki table" % (str(row_exists), str(rows))
++        self.pgdb.commit()
++        return row_exists > 0
++
++
++def getSQLiteEnvironment(opts): 
++    """ Create an Environment connected to the SQLite database """
++
++    dburi = opts.sqlite_uri
++    env = Environment(opts.tracenv)
++    env.config.set('trac', 'database', dburi)
++    return env
++
++def getPostgreSQLEnvironment(opts):
++    """ Create an Environment connected to the PostgreSQL database """
++
++    dburi = opts.pg_uri
++    env = Environment(opts.tracenv)
++    env.config.set('trac', 'database', dburi)
++    try:
++        cnx = env.get_db_cnx()
++        cur = cnx.cursor()
++        cur.execute("select value from system where name = 'database_version'");
++    except ProgrammingError:
++        cnx.rollback()
++        DatabaseManager(env).init_db()
++        DatabaseManager(env).shutdown()
++        for x in filter(None, [env.compmgr[cls] for cls in 
++                        ComponentMeta._registry.get(
++                        IEnvironmentSetupParticipant, [])]):
++            if isinstance(x, EnvironmentSetup):
++                x.environment_created()        
++    if env.needs_upgrade():
++        env.upgrade()
++    return env
++
++def getAllTables(env):
++    """ Queries the PostgreSQL database for a list of tables """
++    cnx = env.get_db_cnx()
++    schema = cnx.schema or u'public'
++    cur = cnx.cursor()
++    select_tables = """SELECT tablename 
++                         FROM pg_catalog.pg_tables 
++                        WHERE schemaname = %s"""
++    cur.execute(select_tables, (schema,))
++    cnx.commit()
++    return [table[0] for table in cur]
++
++def Main(opts):
++    """
++        Migrate data from SQLite to PostgreSQL
++    """
++    rc = 0
++
++    sqlenv = getSQLiteEnvironment(opts)
++    pgenv = getPostgreSQLEnvironment(opts)
++    tmigration = TableMigration(sqlenv, pgenv, opts)
++    if not opts.tlist:
++        opts.tlist = getAllTables(pgenv)
++    for tname in opts.tlist:
++        try:
++            rc = tmigration.migrateTable(tname) or rc
++        except AttributeError:
++            print "Migration of %s has not been implemented" % tname
++            pass
++        continue
++   
++    return rc
++
++def doArgs(argv):
++    """ Look if you can't guess what this function does, just give up now. """
++    global VERSION
++   
++    version = "%%prog %s" % VERSION
++    usage ="usage: %prog [options] [site]"
++    description="%prog is used to migrate data from SQLite to PostgreSQL."
++   
++    parser = OptionParser(usage=usage, version=version, description=description)
++   
++    parser.add_option("-t", "--tracbase", dest="tracbase", type="string",
++                        help="Parent path for trac sites",
++                        metavar="<path>")
++    parser.add_option("-e", "--tracenv", dest="tracenv", type="string",
++                        help="Path to trac environment",
++                        metavar="<path>")
++    parser.add_option("-m", "--migrate", dest="migrate", type="string",
++                        help="Comma separated list of tables to migrate",
++                        metavar="<list>", default=None)
++    parser.add_option("", "--exclude_perms", dest="perms_exclude", 
++                        type="string", help="Comma separated list of users to "
++                        "exclude from permission migration", metavar="<list>")
++    parser.add_option("-w", "--wikipages", dest="wikipages", type="string",
++                        help="Comma separated list of wiki page names to "
++                        "ommit from the migration", metavar="<list>")
++    parser.add_option("-p", "--pg_uri", dest="pg_uri", type="string",
++                        help="DB URI for PostgreSQL database",
++                        metavar="<uri>")
++    parser.add_option("-s", "--sqlite_uri", dest="sqlite_uri", type="string",
++                        help="DB URI for SQLite database",
++                        metavar="<uri>", default="sqlite:db/trac.db")
++    parser.add_option("", "--noclean", dest="noclean", action="store_true",
++                        help="Do not clear PostgreSQL tables before transfer",
++                        default=False)
++   
++    (options, args) = parser.parse_args(argv)
++    if not options.tracenv:
++        if  not options.tracbase:
++            print ("You must specify the --tracenv or the --tracbase option")
++            sys.exit(1)
++        else:
++            if len(args) < 1:
++                print ("You must specify a project name\n")
++                sys.exit(1)
++            options.project = args[0]
++            options.tracenv = os.path.join(options.tracbase, args[0])
++
++    if not options.pg_uri or not options.pg_uri.startswith('postgres://'):
++        print ("You must specify a valid URI for the PostgreSQL database.")
++        print ("  eg. postgres://user:password@localhost/dbname")
++        sys.exit(1)
++ 
++    if not options.sqlite_uri or not options.sqlite_uri.startswith('sqlite:'):
++        print ("You must specify a valid URI for the SQLite database.")
++        print ("  eg. sqlite:db/trac.db")
++        sys.exit(1)
++
++
++    options.args = args
++    options.tlist = options.migrate and \
++                    [t.strip() for t in options.migrate.strip().split(',')]
++    options.wlist = options.wikipages and \
++                    [w.strip() for w in options.wikipages.strip().split(',')] \
++                    or []
++    options.plist = options.perms_exclude and \
++                    [p.strip() for p in options.perms_exclude.strip().split(',')] \
++                    or []
++
++    return options
++
++
++def main(argv):
++    opts = doArgs(argv)
++    Main(opts)
++    return 0
++
++if __name__ == '__main__':
++    sys.exit(main(sys.argv[1:]))
++    


Property changes on: packages/trac/trunk/debian/patches/50_sqlitetopg_script.dpatch
___________________________________________________________________
Added: svn:executable
   + *




More information about the Python-apps-commits mailing list