Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge [10910:10917] from 0.12-stable

git-svn-id: http://trac.edgewall.org/intertrac/log:/trunk@10924 af82e41b-90c4-0310-8c96-b1721e28e2e2
  • Loading branch information...
commit b70154b00d2c9e7591ef96d6d0ce0e7d05dda8d1 1 parent fcac061
cboos authored
Showing with 1,568 additions and 724 deletions.
  1. +1 −1  COPYING
  2. +1 −1  trac/admin/console.py
  3. +2 −1  trac/htdocs/js/expand_dir.js
  4. +2 −2 trac/locale/de/LC_MESSAGES/messages.po
  5. +1 −1  trac/templates/about.html
  6. +157 −37 trac/ticket/report.py
  7. +8 −2 trac/ticket/tests/report.py
  8. +8 −3 trac/versioncontrol/api.py
  9. +6 −9 trac/versioncontrol/svn_fs.py
  10. +3 −3 trac/versioncontrol/templates/browser.html
  11. +36 −2 trac/versioncontrol/templates/dir_entries.html
  12. +11 −7 trac/versioncontrol/tests/svn_fs.py
  13. +11 −8 trac/versioncontrol/web_ui/browser.py
  14. +3 −3 trac/web/api.py
  15. +23 −1 trac/web/tests/api.py
  16. +1 −1  trac/wiki/default-pages/CamelCase
  17. +7 −0 trac/wiki/default-pages/InterMapTxt
  18. +1 −1  trac/wiki/default-pages/PageTemplates
  19. +1 −1  trac/wiki/default-pages/SandBox
  20. +2 −0  trac/wiki/default-pages/TracAccessibility
  21. +2 −2 trac/wiki/default-pages/TracBrowser
  22. +6 −107 trac/wiki/default-pages/TracCgi
  23. +5 −6 trac/wiki/default-pages/TracChangeset
  24. +48 −21 trac/wiki/default-pages/TracFastCgi
  25. +122 −17 trac/wiki/default-pages/TracFineGrainedPermissions
  26. +36 −44 trac/wiki/default-pages/TracImport
  27. +7 −1 trac/wiki/default-pages/TracIni
  28. +122 −35 trac/wiki/default-pages/TracInstall
  29. +12 −12 trac/wiki/default-pages/TracInterfaceCustomization
  30. +5 −1 trac/wiki/default-pages/TracLinks
  31. +62 −85 trac/wiki/default-pages/TracModPython
  32. +292 −39 trac/wiki/default-pages/TracModWSGI
  33. +20 −4 trac/wiki/default-pages/TracNavigation
  34. +85 −19 trac/wiki/default-pages/TracNotification
  35. +1 −1  trac/wiki/default-pages/TracPermissions
  36. +68 −53 trac/wiki/default-pages/TracPlugins
  37. +10 −1 trac/wiki/default-pages/TracQuery
  38. +0 −1  trac/wiki/default-pages/TracReports
  39. +35 −12 trac/wiki/default-pages/TracRepositoryAdmin
  40. +8 −1 trac/wiki/default-pages/TracRoadmap
  41. +3 −1 trac/wiki/default-pages/TracSearch
  42. +65 −0 trac/wiki/default-pages/TracStandalone
  43. +10 −4 trac/wiki/default-pages/TracSyntaxColoring
  44. +33 −34 trac/wiki/default-pages/TracTickets
  45. +44 −19 trac/wiki/default-pages/TracUpgrade
  46. +7 −7 trac/wiki/default-pages/TracWiki
  47. +2 −2 trac/wiki/default-pages/WikiFormatting
  48. +44 −24 trac/wiki/default-pages/WikiHtml
  49. +2 −2 trac/wiki/default-pages/WikiMacros
  50. +2 −0  trac/wiki/default-pages/WikiNewPage
  51. +77 −55 trac/wiki/default-pages/WikiProcessors
  52. +12 −5 trac/wiki/macros.py
  53. +36 −25 trac/wiki/tests/macros.py
View
2  COPYING
@@ -1,4 +1,4 @@
-Copyright (C) 2003-2011 Edgewall Software
+Copyright (C) 2003-2012 Edgewall Software
All rights reserved.
Redistribution and use in source and binary forms, with or without
View
2  trac/admin/console.py
@@ -129,7 +129,7 @@ def run(self):
self.interactive = True
printout(_("""Welcome to trac-admin %(version)s
Interactive Trac administration console.
-Copyright (C) 2003-2011 Edgewall Software
+Copyright (C) 2003-2012 Edgewall Software
Type: '?' or 'help' for help on commands.
""", version=TRAC_VERSION))
View
3  trac/htdocs/js/expand_dir.js
@@ -76,7 +76,8 @@
var a = expander.next("a");
if ( !autoexpand ) {
var pathname = window.location.pathname;
- var entry_href = a.attr("href");
+ // strip scheme and hostname, href is absolute with IE 6 and 7.
+ var entry_href = a.attr("href").replace(/^[^:]+:\/\/[^\/]+/, '');
// normalize (PATH_INFO possibly has squashed "/")
pathname = pathname.replace(/\/+/g, '/').replace(/\/$/, '');
entry_href = entry_href.replace(/\/+/g, '/');
View
4 trac/locale/de/LC_MESSAGES/messages.po
@@ -5465,8 +5465,8 @@ msgid ""
"Annotate each line with the last changed revision (this can be time "
"consuming...)"
msgstr ""
-"Jede Zeile mit der Revision der letzten Änderung markieren (dies kann "
-"lange dauern)"
+"Jede Zeile mit der Revision ihrer letzten Änderung anzeigen (dies kann lange "
+"dauern ...)"
#: trac/versioncontrol/web_ui/browser.py:472
msgid "Revision Log"
View
2  trac/templates/about.html
@@ -43,7 +43,7 @@
</a>
<p i18n:msg="">Please visit the Trac open source project:
<a href="http://trac.edgewall.org/">http://trac.edgewall.org/</a></p>
- <p class="copyright" xml:lang="en" i18n:msg="">Copyright &copy; 2003-2011
+ <p class="copyright" xml:lang="en" i18n:msg="">Copyright &copy; 2003-2012
<a href="http://www.edgewall.org/">Edgewall Software</a>
</p>
View
194 trac/ticket/report.py
@@ -43,6 +43,11 @@
from trac.wiki import IWikiSyntaxProvider, WikiParser
+
+SORT_COLUMN = '@SORT_COLUMN@'
+LIMIT_OFFSET = '@LIMIT_OFFSET@'
+
+
def cell_value(v):
"""Normalize a cell value for display.
>>> (cell_value(None), cell_value(0), cell_value(1), cell_value('v'))
@@ -51,6 +56,58 @@ def cell_value(v):
return '0' if v is 0 else unicode(v) if v else ''
+_sql_re = re.compile(r'''
+ --.*$ # single line "--" comment
+ | /\*([^*/]|\*[^/]|/[^*])*\*/ # C style comment
+ | '(\\.|[^'\\])*' # literal string
+ | \([^()]+\) # parenthesis group
+''', re.MULTILINE | re.VERBOSE)
+
+def _expand_with_space(m):
+ return ' ' * len(m.group(0))
+
+def sql_skeleton(sql):
+ """Strip an SQL query to leave only its toplevel structure.
+
+ This is probably not 100% robust but should be enough for most
+ needs.
+
+ >>> re.sub('\s+', lambda m: '<%d>' % len(m.group(0)), sql_skeleton(''' \\n\
+ SELECT a FROM (SELECT x FROM z ORDER BY COALESCE(u, ')/*(')) ORDER \\n\
+ /* SELECT a FROM (SELECT x /* FROM z \\n\
+ ORDER BY */ COALESCE(u, '\)X(')) ORDER */ \\n\
+ BY c, (SELECT s FROM f WHERE v in ('ORDER BY', '(\\')') \\n\
+ ORDER BY (1), '') -- LIMIT \\n\
+ '''))
+ '<10>SELECT<1>a<1>FROM<48>ORDER<164>BY<1>c,<144>'
+ """
+ old = None
+ while sql != old:
+ old = sql
+ sql = _sql_re.sub(_expand_with_space, old)
+ return old
+
+_order_by_re = re.compile(r'ORDER\s+BY', re.MULTILINE)
+
+def split_sql(sql, clause_re, skel=None):
+ """Split an SQL query according to a toplevel clause regexp.
+
+ We assume there's only one such clause present in the outer query.
+
+ >>> split_sql('''SELECT a FROM x ORDER \
+ BY u, v''', _order_by_re)
+ ('SELECT a FROM x ', ' u, v')
+ """
+ if skel is None:
+ skel = sql_skeleton(sql)
+ blocks = clause_re.split(skel.upper())
+ if len(blocks) == 2:
+ return sql[:len(blocks[0])], sql[-len(blocks[1]):] # (before, after)
+ else:
+ return sql, '' # no single clause separator
+
+
+
class ReportModule(Component):
implements(INavigationContributor, IPermissionRequestor, IRequestHandler,
@@ -373,21 +430,27 @@ def report_href(**kwargs):
'report_href': report_href,
}
+ res = None
with self.env.db_query as db:
- try:
- cols, results, num_items, missing_args = \
- self.execute_paginated_report(req, db, id, sql, args, limit,
- offset)
- results = [list(row) for row in results]
- numrows = len(results)
-
- except Exception, e:
- data['message'] = tag_('Report execution failed: %(error)s',
- error=tag.pre(exception_to_unicode(e, traceback=True)))
- return 'report_view.html', data, None
+ res = self.execute_paginated_report(req, db, id, sql, args, limit,
+ offset)
+
+ if len(res) == 2:
+ e, sql = res
+ data['message'] = \
+ tag_("Report execution failed: %(error)s %(sql)s",
+ error=tag.pre(exception_to_unicode(e)),
+ sql=tag(tag.hr(), tag.pre(sql, style="white-space: pre")))
+ return 'report_view.html', data, None
+
+ cols, results, num_items, missing_args, limit_offset = res
+ need_paginator = limit > 0 and limit_offset
+ need_reorder = limit_offset is None
+ results = [list(row) for row in results]
+ numrows = len(results)
paginator = None
- if limit > 0:
+ if need_paginator:
paginator = Paginator(results, page - 1, limit, num_items)
data['paginator'] = paginator
if paginator.has_next_page:
@@ -430,7 +493,7 @@ def report_href(**kwargs):
if col == sort_col:
header['asc'] = asc
- if not paginator:
+ if not paginator and need_reorder:
# this dict will have enum values for sorting
# and will be used in sortkey(), if non-empty:
sort_values = {}
@@ -541,7 +604,7 @@ def sortkey(row):
data.update({'header_groups': header_groups,
'row_groups': row_groups,
'numrows': numrows,
- 'sorting_enabled': len(row_groups) == 1})
+ 'sorting_enabled': True})
if format == 'rss':
data['email_map'] = chrome.get_email_map()
@@ -601,50 +664,107 @@ def execute_report(self, req, db, id, sql, args):
:see: ``execute_paginated_report``
"""
- return self.execute_paginated_report(req, db, id, sql, args)[:2]
+ res = self.execute_paginated_report(req, db, id, sql, args)
+ if len(res) == 2:
+ raise res[0]
+ return res[:5]
def execute_paginated_report(self, req, db, id, sql, args,
limit=0, offset=0):
sql, args, missing_args = self.sql_sub_vars(sql, args, db)
if not sql:
raise TracError(_("Report {%(num)s} has no SQL query.", num=id))
+ self.log.debug('Report {%d} with SQL "%s"', id, sql)
+ self.log.debug('Request args: %r', req.args)
cursor = db.cursor()
num_items = 0
- if id != -1 and limit > 0:
- cursor.execute("SELECT COUNT(*) FROM (%s) AS tab" % sql, args)
+ order_by = []
+ limit_offset = None
+ base_sql = sql.replace(SORT_COLUMN, '1').replace(LIMIT_OFFSET, '')
+ if id == -1 or limit == 0:
+ sql = base_sql
+ else:
+ # The number of tickets is obtained
+ count_sql = 'SELECT COUNT(*) FROM (\n%s\n) AS tab' % base_sql
+ self.log.debug("Report {%d} SQL (count): %s", id, count_sql)
+ try:
+ cursor.execute(count_sql, args)
+ except Exception, e:
+ return e, count_sql
num_items = cursor.fetchone()[0]
- # get the column names
- cursor.execute("SELECT * FROM (%s) AS tab LIMIT 1" % sql, args)
+ # The column names are obtained
+ colnames_sql = 'SELECT * FROM (\n%s\n) AS tab LIMIT 1' % base_sql
+ self.log.debug("Report {%d} SQL (col names): %s", id, colnames_sql)
+ try:
+ cursor.execute(colnames_sql, args)
+ except Exception, e:
+ return e, colnames_sql
cols = get_column_names(cursor)
+ # The ORDER BY columns are inserted
sort_col = req.args.get('sort', '')
+ asc = req.args.get('asc', '1')
+ self.log.debug("%r %s (%s)", cols, sort_col, asc and '^' or 'v')
order_cols = []
+ if sort_col and sort_col not in cols:
+ raise TracError(_('Query parameter "sort=%(sort_col)s" '
+ ' is invalid', sort_col=sort_col))
+ skel = None
if '__group__' in cols:
order_cols.append('__group__')
if sort_col:
- if sort_col in cols:
- order_cols.append(sort_col)
- else:
- raise TracError(_('Query parameter "sort=%(sort_col)s" '
- ' is invalid', sort_col=sort_col))
-
- # get the (partial) report results
- order_by = ''
- if order_cols:
- asc = req.args.get('asc', '1')
- order_by = " ORDER BY %s %s" % (
- ', '.join(db.quote(col) for col in order_cols),
- 'ASC' if asc == '1' else 'DESC')
- sql = "SELECT * FROM (%s) AS tab %s LIMIT %s OFFSET %s" % \
- (sql, order_by, str(limit), str(offset))
- self.log.debug("Query SQL: " + sql)
- cursor.execute(sql, args)
+ sort_col = '%s %s' % (db.quote(sort_col),
+ asc == '1' and 'ASC' or 'DESC')
+
+ if SORT_COLUMN in sql:
+ # Method 1: insert sort_col at specified position
+ sql = sql.replace(SORT_COLUMN, sort_col or '1')
+ elif sort_col:
+ # Method 2: automagically insert sort_col (and __group__
+ # before it, if __group__ was specified) as first criterions
+ if '__group__' in cols:
+ order_by.append('__group__ ASC')
+ order_by.append(sort_col)
+ # is there already an ORDER BY in the original sql?
+ skel = sql_skeleton(sql)
+ before, after = split_sql(sql, _order_by_re, skel)
+ if after: # there were some other criterions, keep them
+ order_by.append(after)
+ sql = ' '.join([before, 'ORDER BY', ', '.join(order_by)])
+
+ # Add LIMIT/OFFSET if pagination needed
+ limit_offset = ''
+ if num_items > limit:
+ limit_offset = ' '.join(['LIMIT', str(limit),
+ 'OFFSET', str(offset)])
+ if LIMIT_OFFSET in sql:
+ # Method 1: insert LIMIT/OFFSET at specified position
+ sql = sql.replace(LIMIT_OFFSET, limit_offset)
+ else:
+ # Method 2: limit/offset is added unless already present
+ skel = skel or sql_skeleton(sql)
+ if 'LIMIT' not in skel.upper():
+ sql = ' '.join([sql, limit_offset])
+ self.log.debug("Report {%d} SQL (order + limit): %s", id, sql)
+ try:
+ cursor.execute(sql, args)
+ except Exception, e:
+ if order_by or limit_offset:
+ add_notice(req, _("Hint: if the report failed due to automatic "
+ "modification of the ORDER BY clause or the "
+ "addition of LIMIT/OFFSET, please look up "
+ "%(sort_column)s and %(limit_offset)s in "
+ "TracReports to see how to gain complete "
+ "control over report rewriting.",
+ sort_column=SORT_COLUMN,
+ limit_offset=LIMIT_OFFSET))
+ return e, sql
rows = cursor.fetchall() or []
cols = get_column_names(cursor)
- return cols, rows, num_items, missing_args
+ return cols, rows, num_items, missing_args, limit_offset
def get_var_args(self, req):
# reuse somehow for #9574 (wiki vars)
View
10 trac/ticket/tests/report.py
@@ -1,9 +1,12 @@
# -*- coding: utf-8 -*-
+import doctest
+
from trac.db.mysql_backend import MySQLConnection
from trac.ticket.report import ReportModule
from trac.test import EnvironmentStub, Mock
from trac.web.api import Request, RequestDone
+import trac
import unittest
from StringIO import StringIO
@@ -98,7 +101,10 @@ def start_response(status, headers):
def suite():
- return unittest.makeSuite(ReportTestCase, 'test')
+ suite = unittest.TestSuite()
+ suite.addTest(doctest.DocTestSuite(trac.ticket.report))
+ suite.addTest(unittest.makeSuite(ReportTestCase, 'test'))
+ return suite
if __name__ == '__main__':
- unittest.main()
+ unittest.main(defaultTest='suite')
View
11 trac/versioncontrol/api.py
@@ -343,6 +343,11 @@ def pre_process_request(self, req, handler):
repo = self.get_repository(reponame)
if repo:
repo.sync()
+ else:
+ self.log.warning("Unable to find repository '%s' for "
+ "synchronization",
+ reponame or '(default)')
+ continue
except TracError, e:
add_warning(req,
_("Can't synchronize with repository \"%(name)s\" "
@@ -350,7 +355,7 @@ def pre_process_request(self, req, handler):
"information.", name=reponame or '(default)',
error=to_unicode(e.message)))
self.log.info("Synchronized '%s' repository in %0.2f seconds",
- reponame, time.time() - start)
+ reponame or '(default)', time.time() - start)
return handler
def post_process_request(self, req, template, data, content_type):
@@ -961,8 +966,8 @@ class Node(object):
DIRECTORY = "dir"
FILE = "file"
- resource = property(lambda self: Resource('source', self.created_path,
- version=self.created_rev,
+ resource = property(lambda self: Resource('source', self.path,
+ version=self.rev,
parent=self.repos.resource))
# created_path and created_rev properties refer to the Node "creation"
View
15 trac/versioncontrol/svn_fs.py
@@ -715,7 +715,6 @@ def __init__(self, path, rev, repos, pool=None, parent_root=None):
self.pool = Pool(pool)
pool = self.pool()
self._scoped_path_utf8 = _to_svn(pool, self.scope, path)
- self._requested_rev = rev
if parent_root:
self.root = parent_root
@@ -739,9 +738,8 @@ def __init__(self, path, rev, repos, pool=None, parent_root=None):
self.created_path = _path_within_scope(self.scope, cp)
else:
self.created_rev, self.created_path = rev, path
- self.rev = self.created_rev
# TODO: check node id
- Node.__init__(self, repos, path, self.rev, _kindmap[node_type])
+ Node.__init__(self, repos, path, rev, _kindmap[node_type])
def get_content(self):
"""Retrieve raw content as a "read()"able object."""
@@ -765,8 +763,8 @@ def get_entries(self):
entries = fs.dir_entries(self.root, self._scoped_path_utf8, pool())
for item in entries.keys():
path = posixpath.join(self.path, _from_svn(item))
- yield SubversionNode(path, self._requested_rev, self.repos,
- self.pool, self.root)
+ yield SubversionNode(path, self.rev, self.repos, self.pool,
+ self.root)
def get_history(self, limit=None):
"""Yield change events that happened on this path"""
@@ -774,8 +772,7 @@ def get_history(self, limit=None):
older = None # 'older' is the currently examined history tuple
pool = Pool(self.pool)
numrevs = 0
- for path, rev in self.repos._history(self.path, 1, self._requested_rev,
- pool):
+ for path, rev in self.repos._history(self.path, 1, self.rev, pool):
path = _path_within_scope(self.scope, path)
if rev > 0 and path:
older = (path, rev, Changeset.ADD)
@@ -802,7 +799,7 @@ def get_annotations(self):
def blame_receiver(line_no, revision, author, date, line, pool):
annotations.append(revision)
try:
- rev = _svn_rev(self._requested_rev)
+ rev = _svn_rev(self.rev)
start = _svn_rev(0)
file_url_utf8 = posixpath.join(self.repos.ra_url_utf8,
self._scoped_path_utf8)
@@ -881,7 +878,7 @@ def get_copy_ancestry(self):
operation was performed.
"""
ancestors = []
- previous = (self._scoped_path_utf8, self._requested_rev, self.root)
+ previous = (self._scoped_path_utf8, self.rev, self.root)
while previous:
(previous_path, previous_rev, previous_root) = previous
previous = None
View
6 trac/versioncontrol/templates/browser.html
@@ -127,9 +127,9 @@
<table py:if="properties or file" id="info" summary="Revision info">
<tr py:if="file">
- <th py:with="cset = href.changeset(rev, reponame);
- rcset = href.changeset(rev, reponame, created_path);
- drev = display_rev(rev);
+ <th py:with="cset = href.changeset(created_rev, reponame);
+ rcset = href.changeset(created_rev, reponame, created_path);
+ drev = display_rev(created_rev);
author = authorinfo(file.changeset.author);
age = pretty_dateinfo(file.changeset.date)">
<py:choose>
View
38 trac/versioncontrol/templates/dir_entries.html
@@ -2,8 +2,9 @@
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude" py:strip="">
+<<<<<<< .working
<py:for each="idx, entry in enumerate(dir.entries)"
- py:with="change = dir.changes[entry.rev];
+ py:with="change = dir.changes[entry.created_rev];
chgset_context = change and context.child('changeset', change.rev, parent=repos.resource);
chgset_view = change and change.is_viewable(perm);
isdir = entry.kind == 'dir'">
@@ -19,7 +20,7 @@
title="${_('Download as Zip archive') if isdir else _('Download')}">&#8203;</a>
</td>
<td class="rev">
- <a title="View Revision Log" href="${href.log(reponame, entry.path, rev=rev)}">${display_rev(entry.rev)}</a>
+ <a title="View Revision Log" href="${href.log(reponame, entry.path, rev=rev)}">${display_rev(entry.created_rev)}</a>
<a title="View Changeset" class="chgset" href="${href.changeset(change.rev, reponame)}">&nbsp;</a>
</td>
<td class="age" style="${chgset_view and dir.timerange and 'border-color: rgb(%s,%s,%s)' %
@@ -35,5 +36,38 @@
<py:otherwise>&ndash;</py:otherwise>
</td>
</tr>
+=======
+ <py:for each="idx, entry in enumerate(dir.entries)">
+ <py:with vars="change = dir.changes[entry.created_rev];
+ chgset_context = change and context('changeset', change.rev, parent=repos.resource);
+ chgset_view = change and change.can_view(perm)">
+ <tr class="${idx % 2 and 'even' or 'odd'}">
+ <td class="name">
+ <a class="$entry.kind" title="${entry.kind == 'dir' and _('View Directory') or _('View File')}"
+ href="${href.browser(reponame, entry.path, rev=stickyrev,
+ order=(order != 'name' and order or None), desc=desc)}">$entry.name</a>
+ </td>
+ <td class="size">
+ <span title="${_('%(size)s bytes', size=entry.content_length)}">${pretty_size(entry.content_length)}</span>
+ </td>
+ <td class="rev">
+ <a title="View Revision Log" href="${href.log(reponame, entry.path, rev=rev)}">${display_rev(entry.created_rev)}</a>
+ <a title="View Changeset" class="chgset" href="${href.changeset(change.rev, reponame)}">&nbsp;</a>
+ </td>
+ <td class="age" style="${chgset_view and dir.timerange and 'border-color: rgb(%s,%s,%s)' %
+ dir.colorize_age(dir.timerange.relative(change.date)) or None}">
+ ${chgset_view and dateinfo(change.date) or '&ndash;'}
+ </td>
+ <td class="author">${chgset_view and authorinfo_short(change.author) or '&ndash;'}</td>
+ <td class="change" py:choose="">
+ <py:when test="chgset_view" py:choose="">
+ <py:when test="wiki_format_messages">${wiki_to_oneliner(chgset_context, change.message, shorten=True)}</py:when>
+ <py:otherwise>${shorten_line(change.message)}</py:otherwise>
+ </py:when>
+ <py:otherwise>&ndash;</py:otherwise>
+ </td>
+ </tr>
+ </py:with>
+>>>>>>> .merge-right.r10917
</py:for>
</html>
View
18 trac/versioncontrol/tests/svn_fs.py
@@ -148,14 +148,16 @@ def test_get_node(self):
self.assertEqual(u'tête', node.name)
self.assertEqual(u'/tête', node.path)
self.assertEqual(Node.DIRECTORY, node.kind)
- self.assertEqual(TETE, node.rev)
+ self.assertEqual(HEAD, node.rev)
+ self.assertEqual(TETE, node.created_rev)
self.assertEqual(datetime(2007, 4, 30, 17, 45, 26, 234375, utc),
node.last_modified)
node = self.repos.get_node(u'/tête/README.txt')
self.assertEqual('README.txt', node.name)
self.assertEqual(u'/tête/README.txt', node.path)
self.assertEqual(Node.FILE, node.kind)
- self.assertEqual(3, node.rev)
+ self.assertEqual(HEAD, node.rev)
+ self.assertEqual(3, node.created_rev)
self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc),
node.last_modified)
@@ -216,14 +218,14 @@ def test_get_file_properties(self):
def test_created_path_rev(self):
node = self.repos.get_node(u'/tête/README3.txt', 15)
- self.assertEqual(14, node.rev)
+ self.assertEqual(15, node.rev)
self.assertEqual(u'/tête/README3.txt', node.path)
self.assertEqual(14, node.created_rev)
self.assertEqual(u'tête/README3.txt', node.created_path)
def test_created_path_rev_parent_copy(self):
node = self.repos.get_node('/tags/v1/README.txt', 15)
- self.assertEqual(3, node.rev)
+ self.assertEqual(15, node.rev)
self.assertEqual('/tags/v1/README.txt', node.path)
self.assertEqual(3, node.created_rev)
self.assertEqual(u'tête/README.txt', node.created_path)
@@ -357,7 +359,7 @@ def test_diff_dir_different_revs(self):
(Node.DIRECTORY, Changeset.ADD)), diffs.next())
self._cmp_diff((None, (u'tête/dir1/dir3', 8),
(Node.DIRECTORY, Changeset.ADD)), diffs.next())
- self._cmp_diff((None, (u'tête/README2.txt', 6),
+ self._cmp_diff((None, (u'tête/README2.txt', 8),
(Node.FILE, Changeset.ADD)), diffs.next())
self._cmp_diff(((u'tête/dir2', 4), None,
(Node.DIRECTORY, Changeset.DELETE)), diffs.next())
@@ -576,14 +578,16 @@ def test_get_node(self):
self.assertEqual('dir1', node.name)
self.assertEqual('/dir1', node.path)
self.assertEqual(Node.DIRECTORY, node.kind)
- self.assertEqual(5, node.rev)
+ self.assertEqual(TETE, node.rev)
+ self.assertEqual(5, node.created_rev)
self.assertEqual(datetime(2005, 4, 1, 16, 25, 39, 658099, utc),
node.last_modified)
node = self.repos.get_node('/README.txt')
self.assertEqual('README.txt', node.name)
self.assertEqual('/README.txt', node.path)
self.assertEqual(Node.FILE, node.kind)
- self.assertEqual(3, node.rev)
+ self.assertEqual(TETE, node.rev)
+ self.assertEqual(3, node.created_rev)
self.assertEqual(datetime(2005, 4, 1, 13, 24, 58, 234643, utc),
node.last_modified)
View
19 trac/versioncontrol/web_ui/browser.py
@@ -427,7 +427,7 @@ def process_request(self, req):
# Links for contextual navigation
if node:
if node.isfile:
- prev_rev = repos.previous_rev(rev=node.rev,
+ prev_rev = repos.previous_rev(rev=node.created_rev,
path=node.created_path)
if prev_rev:
href = req.href.browser(reponame,
@@ -437,7 +437,7 @@ def process_request(self, req):
if rev is not None:
add_link(req, 'up', req.href.browser(reponame,
node.created_path))
- next_rev = repos.next_rev(rev=node.rev,
+ next_rev = repos.next_rev(rev=node.created_rev,
path=node.created_path)
if next_rev:
href = req.href.browser(reponame, node.created_path,
@@ -451,7 +451,7 @@ def process_request(self, req):
add_link(req, 'up', path_links[-2]['href'],
_('Parent directory'))
add_ctxtnav(req, tag.a(_('Last Change'),
- href=req.href.changeset(node.rev, reponame,
+ href=req.href.changeset(node.created_rev, reponame,
node.created_path)))
if node.isfile:
annotate = data['file']['annotate']
@@ -547,8 +547,10 @@ def _render_dir(self, req, repos, node, rev, order, desc):
# Entries metadata
class entry(object):
- _copy = 'name rev kind isdir path content_length'.split()
+ _copy = 'name rev created_rev kind isdir path content_length' \
+ .split()
__slots__ = _copy + ['raw_href']
+
def __init__(self, node):
for f in entry._copy:
setattr(self, f, getattr(node, f))
@@ -556,7 +558,8 @@ def __init__(self, node):
entries = [entry(n) for n in node.get_entries()
if n.is_viewable(req.perm)]
- changes = get_changes(repos, [i.rev for i in entries], self.log)
+ changes = get_changes(repos, [i.created_rev for i in entries],
+ self.log)
if rev:
newest = repos.get_changeset(rev).date
@@ -579,7 +582,7 @@ def __init__(self, node):
# Ordering of entries
if order == 'date':
def file_order(a):
- return (changes[a.rev].date,
+ return (changes[a.created_rev].date,
embedded_numbers(a.name.lower()))
elif order == 'size':
def file_order(a):
@@ -587,7 +590,7 @@ def file_order(a):
embedded_numbers(a.name.lower()))
elif order == 'author':
def file_order(a):
- return (changes[a.rev].author.lower(),
+ return (changes[a.created_rev].author.lower(),
embedded_numbers(a.name.lower()))
else:
def file_order(a):
@@ -653,7 +656,7 @@ def _render_file(self, req, context, repos, node, rev=None):
else:
# The changeset corresponding to the last change on `node`
# is more interesting than the `rev` changeset.
- changeset = repos.get_changeset(node.rev)
+ changeset = repos.get_changeset(node.created_rev)
# add ''Plain Text'' alternate link if needed
if not is_binary(chunk) and mime_type != 'text/plain':
View
6 trac/web/api.py
@@ -203,10 +203,10 @@ def parse_arg_list(query_string):
else:
(name, value) = (nv[0], empty)
name = unquote(name.replace('+', ' '))
- if isinstance(name, unicode):
- name = name.encode('utf-8')
+ if isinstance(name, str):
+ name = unicode(name, 'utf-8')
value = unquote(value.replace('+', ' '))
- if not isinstance(value, unicode):
+ if isinstance(value, str):
value = unicode(value, 'utf-8')
args.append((name, value))
return args
View
24 trac/web/tests/api.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from trac.test import Mock
-from trac.web.api import Request, RequestDone
+from trac.web.api import Request, RequestDone, parse_arg_list
from StringIO import StringIO
import unittest
@@ -146,9 +146,31 @@ def test_qs_on_post(self):
self.assertEqual('bar', req.args['action'])
+class ParseArgListTestCase(unittest.TestCase):
+
+ def test_qs_str(self):
+ args = parse_arg_list('k%C3%A9y=resum%C3%A9&r%C3%A9sum%C3%A9')
+ self.assertTrue(unicode, type(args[0][0]))
+ self.assertTrue(unicode, type(args[0][1]))
+ self.assertEqual(u'kéy', args[0][0])
+ self.assertEqual(u'resumé', args[0][1])
+ self.assertTrue(unicode, type(args[1][0]))
+ self.assertEqual(u'résumé', args[1][0])
+
+ def test_qs_unicode(self):
+ args = parse_arg_list(u'%3Dy=re%26su=mé&résu%26mé')
+ self.assertTrue(unicode, type(args[0][0]))
+ self.assertTrue(unicode, type(args[0][1]))
+ self.assertEqual(u'ké=y', args[0][0])
+ self.assertEqual(u're&su=mé', args[0][1])
+ self.assertTrue(unicode, type(args[1][0]))
+ self.assertEqual(u'résu&mé', args[1][0])
+
+
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(RequestTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(ParseArgListTestCase, 'test'))
return suite
if __name__ == '__main__':
View
2  trac/wiki/default-pages/CamelCase
@@ -20,4 +20,4 @@ See TracIni for more information on the available options.
* http://en.wikipedia.org/wiki/CamelCase
----
-See also: WikiPageNames, WikiNewPage, WikiFormatting, TracWiki
+See also: WikiPageNames, WikiNewPage, WikiFormatting, TracWiki
View
7 trac/wiki/default-pages/InterMapTxt
@@ -70,6 +70,7 @@ Cache http://www.google.com/search?q=cache:
CPAN http://search.cpan.org/perldoc?
DebianBug http://bugs.debian.org/
DebianPackage http://packages.debian.org/
+DebianPTS http://packages.qa.debian.org/
Dictionary http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query=
Google http://www.google.com/search?q=
lmgtfy http://lmgtfy.com/?q= # Well, just search for "$1", follow the link to see how to do it...
@@ -79,8 +80,14 @@ MeatBall http://www.usemod.com/cgi-bin/mb.pl?
MetaWiki http://sunir.org/apps/meta.pl?
MetaWikiPedia http://meta.wikipedia.org/wiki/
MoinMoin http://moinmo.in/
+TracHacks http://trac-hacks.org/wiki/
+OSM http://www.openstreetmap.org/wiki/
WhoIs http://www.whois.sc/
Why http://clublet.com/c/c/why?
c2Wiki http://c2.com/cgi/wiki?
WikiPedia http://en.wikipedia.org/wiki/
}}}
+
+
+----
+See also: InterWiki, InterTrac
View
2  trac/wiki/default-pages/PageTemplates
@@ -16,4 +16,4 @@ After you have created your new template, a drop-down selection box will automat
Available templates:
[[TitleIndex(PageTemplates/)]]
----
-See also: TracWiki
+See also: TracWiki
View
2  trac/wiki/default-pages/SandBox
@@ -2,4 +2,4 @@
This is just a page to practice and learn WikiFormatting.
-Go ahead, edit it freely.
+Go ahead, edit it freely.
View
2  trac/wiki/default-pages/TracAccessibility
@@ -2,6 +2,8 @@
Not every user has a graphic environment with a mouse or other pointing device. Some users rely on keyboard, alternative keyboard or voice input to navigate links, activate form controls, etc. In Trac, we work to assure users may interact with devices other than a pointing device.
+The keyboard shortcuts must be enabled for a session through the [/prefs/keybindings Keyboard Shortcuts] preferences panel.
+
Trac supports accessibility keys for the most common operations. On Windows and Linux platforms, press any of the keys listed below in combination with the `<Alt>` key; on a Mac, use the `<ctrl>` key instead.
''Note that when using Internet Explorer on Windows, you need to hit `<Enter>` after having used the access key.''[[BR]]
View
4 trac/wiki/default-pages/TracBrowser
@@ -9,7 +9,7 @@ At the top-level of the repository browser is the '''Repository Index''',
listing all the configured repositories.
Each repository has a name which is used as a path prefix in a
"virtual" file hierarchy encompassing all the available repositories.
-If a default repository has been configured, its top-level files and directories
+One of the repositories can be configured with an empty name; this is the default repository. When such a default repository is present, its top-level files and directories
are also listed, in a '''Default Repository''' section placed before the
repository index. If the default repository is the only repository associated
with the Trac environment the '''Repository Index''' will be omitted ^[#note-multirepos (1)]^.
@@ -59,7 +59,7 @@ directory. Alternatively, the [trac:TracKeys keyboard] can also be used for this
- `'r'` can be used to force the reload of an already expanded directory
- `'A'` can be used to directly visit a file in annotate (blame) mode
- `'L'` to view the log for the selected entry
-If no row has been selected using `'j'` or `'k'` these keys will operate on the entry under the mouse .
+If no row has been selected using `'j'` or `'k'` these keys will operate on the entry under the mouse.
{{{#!comment
MMM: I guess that some keys are upper case and some lower to avoid conflicts with browser defined keys.
View
113 trac/wiki/default-pages/TracCgi
@@ -9,7 +9,7 @@ CGI script is the entrypoint that web-server calls when a web-request to an appl
{{{
trac-admin /path/to/env deploy /path/to/www/trac
}}}
-`trac.cgi` will be in the `cgi-bin` folder inside the given path. Make sure it is executable by your web server. This command also copies `static resource` files to a `htdocs` directory of a given destination.
+`trac.cgi` will be in the `cgi-bin` folder inside the given path. ''Make sure it is executable by your web server''. This command also copies `static resource` files to a `htdocs` directory of a given destination.
== Apache web-server configuration ==
@@ -57,118 +57,17 @@ If you are using the [http://httpd.apache.org/docs/suexec.html Apache suEXEC] fe
On some systems, you ''may'' need to edit the shebang line in the `trac.cgi` file to point to your real Python installation path. On a Windows system you may need to configure Windows to know how to execute a .cgi file (Explorer -> Tools -> Folder Options -> File Types -> CGI).
-== Mapping Static Resources ==
-
-Out of the box, Trac will pass static resources such as style sheets or images through itself. For a CGI setup this is '''highly undesirable''', because this way CGI script is invoked for documents that could be much more efficiently served directly by web server.
-
-Web servers such as [http://httpd.apache.org/ Apache] allow you to create “Aliases” to resources, giving them a virtual URL that doesn't necessarily reflect the layout of the servers file system. We already used this capability by defining a `ScriptAlias` for the CGI script. We also can map requests for static resources directly to the directory on the file system, avoiding processing these requests by CGI script.
-
-There are two primary URL paths for static resources - `/chrome/common` and `/chrome/site`. Plugins can add their own resources usually accessible by `/chrome/plugin` path, so its important to override only known paths and not try to make universal `/chrome` alias for everything.
-
-Add the following snippet to Apache configuration '''before''' the `ScriptAlias` for the CGI script, changing paths to match your deployment:
-{{{
-Alias /trac/chrome/common /path/to/trac/htdocs/common
-Alias /trac/chrome/site /path/to/trac/htdocs/site
-<Directory "/path/to/www/trac/htdocs">
- Order allow,deny
- Allow from all
-</Directory>
-}}}
-
-If using mod_python, you might want to add this too (otherwise, the alias will be ignored):
-{{{
-<Location "/trac/chrome/common/">
- SetHandler None
-</Location>
-}}}
+=== Using WSGI ===
-Note that we mapped `/trac` part of the URL to the `trac.cgi` script, and the path `/chrome/common` is the path you have to append to that location to intercept requests to the static resources.
-
-For example, if Trac is mapped to `/cgi-bin/trac.cgi` on your server, the URL of the Alias should be `/cgi-bin/trac.cgi/chrome/common`.
-
-Similarly, if you have static resources in a project's htdocs directory (which is referenced by /chrome/site URL in themes), you can configure Apache to serve those resources (again, put this '''before''' the `ScriptAlias` for the CGI script, and adjust names and locations to match your installation):
-
-{{{
-Alias /trac/chrome/site /path/to/projectenv/htdocs
-<Directory "/path/to/projectenv/htdocs">
- Order allow,deny
- Allow from all
-</Directory>
-}}}
-
-Alternatively to hacking `/trac/chrome/site`, you can directly specify path to static resources using `htdocs_location` configuration option in [wiki:TracIni trac.ini]:
-{{{
-[trac]
-htdocs_location = http://yourhost.example.org/trac-htdocs
-}}}
-
-Trac will then use this URL when embedding static resources into HTML pages. Of course, you still need to make the Trac `htdocs` directory available through the web server at the specified URL, for example by copying (or linking) the directory into the document root of the web server:
-{{{
-$ ln -s /path/to/www/trac/htdocs /var/www/yourhost.example.org/trac-htdocs
-}}}
+You can run a [http://henry.precheur.org/python/how_to_serve_cgi WSGI handler] [http://pythonweb.org/projects/webmodules/doc/0.5.3/html_multipage/lib/example-webserver-web-wsgi-simple-cgi.html under CGI]. You can [wiki:TracModWSGI#Thetrac.wsgiscript write your own application function], or use the deployed trac.wsgi's application.
-Note that in order to get this `htdocs` directory, you need first to extract the relevant Trac resources using the `deploy` command of TracAdmin:
-[[TracAdminHelp(deploy)]]
+== Mapping Static Resources ==
+See TracInstall#MappingStaticResources.
== Adding Authentication ==
-The simplest way to enable authentication with Apache is to create a password file. Use the `htpasswd` program to create the password file:
-{{{
-$ htpasswd -c /somewhere/trac.htpasswd admin
-New password: <type password>
-Re-type new password: <type password again>
-Adding password for user admin
-}}}
-
-After the first user, you dont need the "-c" option anymore:
-{{{
-$ htpasswd /somewhere/trac.htpasswd john
-New password: <type password>
-Re-type new password: <type password again>
-Adding password for user john
-}}}
-
- ''See the man page for `htpasswd` for full documentation.''
-
-After you've created the users, you can set their permissions using TracPermissions.
-
-Now, you'll need to enable authentication against the password file in the Apache configuration:
-{{{
-<Location "/trac/login">
- AuthType Basic
- AuthName "Trac"
- AuthUserFile /somewhere/trac.htpasswd
- Require valid-user
-</Location>
-}}}
-
-If you're hosting multiple projects you can use the same password file for all of them:
-{{{
-<LocationMatch "/trac/[^/]+/login">
- AuthType Basic
- AuthName "Trac"
- AuthUserFile /somewhere/trac.htpasswd
- Require valid-user
-</LocationMatch>
-}}}
-
-For better security, it is recommended that you either enable SSL or at least use the “digest” authentication scheme instead of “Basic”. Please read the [http://httpd.apache.org/docs/2.0/ Apache HTTPD documentation] to find out more. For example, on a Debian 4.0r1 (etch) system the relevant section in apache configuration can look like this:
-{{{
-<Location "/trac/login">
- LoadModule auth_digest_module /usr/lib/apache2/modules/mod_auth_digest.so
- AuthType Digest
- AuthName "trac"
- AuthDigestDomain /trac
- AuthUserFile /somewhere/trac.htpasswd
- Require valid-user
-</Location>
-}}}
-and you'll have to create your .htpasswd file with htdigest instead of htpasswd as follows:
-{{{
-# htdigest /somewhere/trac.htpasswd trac admin
-}}}
-where the "trac" parameter above is the same as !AuthName above ("Realm" in apache-docs).
+See TracInstall#ConfiguringAuthentication.
----
See also: TracGuide, TracInstall, [wiki:TracModWSGI], TracFastCgi, TracModPython
View
11 trac/wiki/default-pages/TracChangeset
@@ -29,12 +29,11 @@ won't be shown.
In front of each listed file, you'll find a colored rectangle. The color
indicates how the file is affected by the changeset.
- * Green: Added
- * Red: Removed
- * Yellow: Modified
- * Blue: Copied
- * Gray: Moved
-
+ * [[span(style=background:#bfb;border:1px solid #999,` `)]] Green: Added
+ * [[span(style=background:#f88;border:1px solid #999,` `)]] Red: Removed
+ * [[span(style=background:#fd8;border:1px solid #999,` `)]] Yellow: Modified
+ * [[span(style=background:#88f;border:1px solid #999,` `)]] Blue: Copied
+ * [[span(style=background:#ccc;border:1px solid #999,` `)]] Gray: Moved
The color legend is located below the header as a reminder.
== Diff Views ==
View
69 trac/wiki/default-pages/TracFastCgi
@@ -1,15 +1,26 @@
+[[PageOutline]]
+
= Trac with FastCGI =
-[http://www.fastcgi.com/ FastCGI] interface allows Trac to remain resident much like with [wiki:TracModPython mod_python]. It is faster than external CGI interfaces which must start a new process for each request. However, unlike mod_python, FastCGI supports [http://httpd.apache.org/docs/suexec.html Apache SuEXEC], i.e. run with different permissions than web server. Additionally, it is supported by much wider variety of web servers.
+[http://www.fastcgi.com/ FastCGI] interface allows Trac to remain resident much like with [wiki:TracModPython mod_python] or [wiki:TracModWSGI mod_wsgi]. It is faster than external CGI interfaces which must start a new process for each request. Additionally, it is supported by much wider variety of web servers.
+
+Note that unlike mod_python, FastCGI supports [http://httpd.apache.org/docs/suexec.html Apache SuEXEC], i.e. run with different permissions than web server running with (`mod_wsgi` supports the `WSGIDaemonProcess` with user / group parameters to achieve the same effect).
+
+'''Note for Windows:''' Trac's FastCGI does not run under Windows, as Windows does not implement `Socket.fromfd`, which is used by `_fcgi.py`. If you want to connect to IIS, you may want to try [trac:TracOnWindowsIisAjp AJP]/[trac:TracOnWindowsIisAjp ISAPI].
+
+[[PageOutline(2-3,Overview,inline)]]
-'''Note for Windows:''' Trac's FastCGI does not run under Windows, as Windows does not implement `Socket.fromfd`, which is used by `_fcgi.py`. If you want to connect to IIS, you may want to try [trac:TracOnWindowsIisAjp AJP].
== Simple Apache configuration ==
There are two FastCGI modules commonly available for Apache: `mod_fastcgi` and
`mod_fcgid` (preferred). The latter is more up-to-date.
-==== setup with `mod_fastcgi` ====
+The following sections focus on the FCGI specific setup, see also [wiki:TracModWSGI#ConfiguringAuthentication] for configuring the authentication in Apache.
+
+Regardless of which cgi module is used, be sure the web server has executable permissions on the cgi-bin folder. While FastCGI will throw specific permissions errors, mod_fcgid will throw an ambiguous error if this has not been done. (Connection reset by peer: mod_fcgid: error reading data from FastCGI server)
+
+=== Set up with `mod_fastcgi` ===
`mod_fastcgi` uses `FastCgiIpcDir` and `FastCgiConfig` directives that should be added to an appropriate Apache configuration file:
{{{
# Enable fastcgi for .fcgi files
@@ -26,24 +37,24 @@ Setting `FastCgiIpcDir` is optional if the default is suitable. Note that the `L
Configure `ScriptAlias` or similar options as described in TracCgi, but
calling `trac.fcgi` instead of `trac.cgi`.
-You can set up the `TRAC_ENV` as an overall default:
+Add the following to the Apache configuration file (below the `FastCgiIpcDir` line) if you intend to set up the `TRAC_ENV` as an overall default:
{{{
FastCgiConfig -initial-env TRAC_ENV=/path/to/env/trac
}}}
-Or you can serve multiple Trac projects in a directory like:
+Alternatively, you can serve multiple Trac projects in a directory by adding this:
{{{
FastCgiConfig -initial-env TRAC_ENV_PARENT_DIR=/parent/dir/of/projects
}}}
-==== setup with `mod_fcgid` ====
+=== Set up with `mod_fcgid` ===
Configure `ScriptAlias` (see TracCgi for details), but call `trac.fcgi`
instead of `trac.cgi`. Note that slash at the end - it is important.
{{{
ScriptAlias /trac /path/to/www/trac/cgi-bin/trac.fcgi/
}}}
-To setup Trac environment for `mod_fcgid` it is necessary to use
+To set up Trac environment for `mod_fcgid` it is necessary to use
`DefaultInitEnv` directive. It cannot be used in `Directory` or
`Location` context, so if you need to support multiple projects, try
alternative environment setup below.
@@ -52,8 +63,8 @@ alternative environment setup below.
DefaultInitEnv TRAC_ENV /path/to/env/trac/
}}}
-==== alternative environment setup ====
-A better method to specify path to Trac environment it to embed the path
+=== alternative environment setup ===
+A better method to specify path to Trac environment is to embed the path
into `trac.fcgi` script itself. That doesn't require configuration of server
environment variables, works for both FastCgi modules
(and for [http://www.lighttpd.net/ lighttpd] and CGI as well):
@@ -92,7 +103,7 @@ Interpreter:
If the port was not reachable, the interpreter command would be launched. Note that, in the definition of the information source, you will have to manually launch the spawner if you use a ''Remote host'' as ''Information source'' instead of a ''Local interpreter''.
After doing this, we will just have to create a new rule managed by the SCGI handler to access Trac. It can be created in a new virtual server, trac.example.net for instance, and will only need two rules. The '''default''' one will use the SCGI handler associated to the previously created information source.
-The second rule will be there to serve the few static files needed to correctly display the Trac interface. Create it as ''Directory rule'' for ''/chrome/common'' and just set it to the ''Static files'' handler and with a ''Document root'' that points to the appropriate files: ''/usr/share/trac/htdocs/''
+The second rule will be there to serve the few static files needed to correctly display the Trac interface. Create it as ''Directory rule'' for ''/common'' and just set it to the ''Static files'' handler and with a ''Document root'' that points to the appropriate files: ''$TRAC_LOCAL/htdocs/'' (where $TRAC_LOCAL is a directory defined by the user or the system administrator to place local trac resources).
Note:\\
If the tracd process fails to start up, and cherokee displays a 503 error page, you might be missing the [http://trac.saddi.com/flup python-flup] package.\\
@@ -101,6 +112,7 @@ Python-flup is a dependency which provides trac with SCGI capability. You can in
sudo apt-get install python-flup
}}}
+
== Simple Lighttpd Configuration ==
The FastCGI front-end was developed primarily for use with alternative webservers, such as [http://www.lighttpd.net/ lighttpd].
@@ -129,7 +141,7 @@ Note that you will need to add a new entry to `fastcgi.server` for each separate
and you may set one of the two in `trac.fcgi` instead of in `lighttpd.conf`
using `bin-environment` (as in the section above on Apache configuration).
-Note that lighttpd has a bug related to 'SCRIPT_NAME' and 'PATH_INFO' when the uri of fastcgi.server is '/' instead of '/trac' in this example, see #Trac2418. This should be fixed since lighttpd 1.4.23, and you may need to add `"fix-root-scriptname" => "enable"` as parameter of fastcgi.server.
+Note that lighttpd has a bug related to 'SCRIPT_NAME' and 'PATH_INFO' when the uri of fastcgi.server is '/' instead of '/trac' in this example (see [trac:#2418]). This should be fixed since lighttpd 1.4.23, and you may need to add `"fix-root-scriptname" => "enable"` as parameter of fastcgi.server.
For using two projects with lighttpd add the following to your `lighttpd.conf`:
{{{
@@ -158,10 +170,12 @@ variables in the `.fcgi` scripts, then copy/rename `trac.fcgi`, e.g., to
`first.fcgi` and `second.fcgi`, and reference them in the above settings.
Note that the above will result in different processes in any event, even
if both are running from the same `trac.fcgi` script.
+
{{{
#!div class=important
'''Note''' It's very important the order on which server.modules are loaded, if mod_auth is not loaded '''BEFORE''' mod_fastcgi, then the server will fail to authenticate the user.
}}}
+
For authentication you should enable mod_auth in lighttpd.conf 'server.modules', select auth.backend and auth rules:
{{{
server.modules = (
@@ -209,7 +223,7 @@ Conditional configuration is also useful for mapping static resources, i.e. serv
# Aliasing functionality is needed
server.modules += ("mod_alias")
-# Setup an alias for the static resources
+# Set up an alias for the static resources
alias.url = ("/trac/chrome/common" => "/usr/share/trac/htdocs")
# Use negative lookahead, matching all requests that ask for any resource under /trac, EXCEPT in
@@ -275,15 +289,14 @@ fastcgi.server = ("/trac" =>
}}}
For details about languages specification see [trac:TracFaq TracFaq] question 2.13.
-Other important information like [http://trac.lighttpd.net/trac/wiki/TracInstall this updated TracInstall page], [wiki:TracCgi#MappingStaticResources and this] are useful for non-fastcgi specific installation aspects.
-
-If you use trac-0.9, read [http://lists.edgewall.com/archive/trac/2005-November/005311.html about small bug]
+Other important information like the [wiki:TracInstall#MappingStaticResources mapping static resources advices] are useful for non-fastcgi specific installation aspects.
+]
Relaunch lighttpd, and browse to `http://yourhost.example.org/trac` to access Trac.
Note about running lighttpd with reduced permissions:
- If nothing else helps and trac.fcgi doesn't start with lighttpd settings `server.username = "www-data"`, `server.groupname = "www-data"`, then in the `bin-environment` section set `PYTHON_EGG_CACHE` to the home directory of `www-data` or some other directory accessible to this account for writing.
+If nothing else helps and trac.fcgi doesn't start with lighttpd settings `server.username = "www-data"`, `server.groupname = "www-data"`, then in the `bin-environment` section set `PYTHON_EGG_CACHE` to the home directory of `www-data` or some other directory accessible to this account for writing.
== Simple !LiteSpeed Configuration ==
@@ -292,8 +305,6 @@ The FastCGI front-end was developed primarily for use with alternative webserver
!LiteSpeed web server is an event-driven asynchronous Apache replacement designed from the ground-up to be secure, scalable, and operate with minimal resources. !LiteSpeed can operate directly from an Apache config file and is targeted for business-critical environments.
-=== Setup ===
-
1. Please make sure you have first have a working install of a Trac project. Test install with “tracd” first.
2. Create a Virtual Host for this setup. From now on we will refer to this vhost as !TracVhost. For this tutorial we will be assuming that your trac project will be accessible via:
@@ -353,9 +364,12 @@ link = http://yourdomain.com/trac/ <--- link of graphic logo
http://yourdomain.com/trac/
}}}
+
== Simple Nginx Configuration ==
- 1. Nginx configuration snippet - confirmed to work on 0.6.32
+Nginx is able to communicate with FastCGI processes, but can not spawn them. So you need to start FastCGI server for Trac separately.
+
+ 1. Nginx configuration with basic authentication handled by Nginx - confirmed to work on 0.6.32
{{{
server {
listen 10.9.8.7:443;
@@ -376,6 +390,11 @@ http://yourdomain.com/trac/
set $path_info /$1;
}
+ # it makes sense to serve static resources through Nginx
+ location /chrome/ {
+ alias /home/trac/instance/static/htdocs/;
+ }
+
# You can copy this whole location to ``location [/some/prefix]/login``
# and remove the auth entries below if you want Trac to enforce
# authorization where appropriate instead of needing to authenticate
@@ -402,11 +421,19 @@ http://yourdomain.com/trac/
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_PROTOCOL $server_protocol;
- fastcgi_param QUERY_STRING $query_string;
+ fastcgi_param QUERY_STRING $query_string;
- # for authentication to work
+ # For Nginx authentication to work - do not forget to comment these
+ # lines if not using Nginx for authentication
fastcgi_param AUTH_USER $remote_user;
fastcgi_param REMOTE_USER $remote_user;
+
+ # for ip to work
+ fastcgi_param REMOTE_ADDR $remote_addr;
+
+ # For attchments to work
+ fastcgi_param CONTENT_TYPE $content_type;
+ fastcgi_param CONTENT_LENGTH $content_length;
}
}
}}}
View
139 trac/wiki/default-pages/TracFineGrainedPermissions
@@ -28,23 +28,23 @@ See also [trac:source:branches/0.12-stable/sample-plugins/permissions sample-plu
=== !AuthzPolicy ===
-
- - Install [http://www.voidspace.org.uk/python/configobj.html ConfigObj] (required).
- - Copy authz_policy.py into your plugins directory.
- - Put a [http://swapoff.org/files/authzpolicy.conf authzpolicy.conf] file somewhere, preferably on a secured location on the server, not readable for others than the webuser. If the file contains non-ASCII characters, the UTF-8 encoding should be used.
- - Update your `trac.ini`:
- 1. modify the [TracIni#trac-section permission_policies] entry in the `[trac]` section
+==== Configuration ====
+* Install [http://www.voidspace.org.uk/python/configobj.html ConfigObj] (still needed for 0.12).
+* Copy authz_policy.py into your plugins directory.
+* Put a [http://swapoff.org/files/authzpolicy.conf authzpolicy.conf] file somewhere, preferably on a secured location on the server, not readable for others than the webuser. If the file contains non-ASCII characters, the UTF-8 encoding should be used.
+* Update your `trac.ini`:
+ 1. modify the [TracIni#trac-section permission_policies] entry in the `[trac]` section
{{{
[trac]
...
permission_policies = AuthzPolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy
}}}
- 2. add a new `[authz_policy]` section
+ 2. add a new `[authz_policy]` section
{{{
[authz_policy]
authz_file = /some/trac/env/conf/authzpolicy.conf
}}}
- 3. enable the single file plugin
+ 3. enable the single file plugin
{{{
[components]
...
@@ -53,14 +53,61 @@ tracopt.perm.authz_policy.* = enabled
# for Trac 0.11 use this
#authz_policy.* = enabled
}}}
-
+==== Usage Notes ====
Note that the order in which permission policies are specified is quite critical,
as policies will be examined in the sequence provided.
-A policy will return either `True`, `False` or `None` for a given permission check.
-Only if the return value is `None` will the ''next'' permission policy be consulted.
-If no policy explicitly grants the permission, the final result will be `False`
-(i.e. no permission).
+A policy will return either `True`, `False` or `None` for a given permission check. `True` is returned if the policy explicitly grants the permission. `False` is returned if the policy explicitly denies the permission. `None` is returned if the policy is unable to either grant or deny the permission.
+
+NOTE: Only if the return value is `None` will the ''next'' permission policy be consulted.
+If none of the policies explicitly grants the permission, the final result will be `False`
+(i.e. permission denied).
+
+The `authzpolicy.conf` file is a `.ini` style configuration file:
+{{{
+[wiki:PrivatePage@*]
+john = WIKI_VIEW, !WIKI_MODIFY
+jack = WIKI_VIEW
+* =
+}}}
+* Each section of the config is a glob pattern used to match against a Trac resource
+ descriptor. These descriptors are in the form:
+{{{
+<realm>:<id>@<version>[/<realm>:<id>@<version> ...]
+}}}
+ Resources are ordered left to right, from parent to child. If any
+ component is inapplicable, `*` is substituted. If the version pattern is
+ not specified explicitely, all versions (`@*`) is added implicitly
+
+ Example: Match the WikiStart page
+{{{
+[wiki:*]
+[wiki:WikiStart*]
+[wiki:WikiStart@*]
+[wiki:WikiStart]
+}}}
+
+ Example: Match the attachment `wiki:WikiStart@117/attachment/FOO.JPG@*`
+ on WikiStart
+{{{
+[wiki:*]
+[wiki:WikiStart*]
+[wiki:WikiStart@*]
+[wiki:WikiStart@*/attachment/*]
+[wiki:WikiStart@117/attachment/FOO.JPG]
+}}}
+
+* Sections are checked against the current Trac resource descriptor '''IN ORDER''' of
+ appearance in the configuration file. '''ORDER IS CRITICAL'''.
+
+* Once a section matches, the current username is matched against the keys
+ (usernames) of the section, '''IN ORDER'''.
+ * If a key (username) is prefixed with a `@`, it is treated as a group.
+ * If a value (permission) is prefixed with a `!`, the permission is
+ denied rather than granted.
+
+ The username will match any of 'anonymous',
+ 'authenticated', <username> or '*', using normal Trac permission rules.
For example, if the `authz_file` contains:
{{{
@@ -69,7 +116,7 @@ For example, if the `authz_file` contains:
[wiki:PrivatePage@*]
john = WIKI_VIEW
-* =
+* = !WIKI_VIEW
}}}
and the default permissions are set like this:
{{{
@@ -79,9 +126,67 @@ jack WIKI_VIEW
}}}
Then:
- - All versions of WikiStart will be viewable by everybody (including anonymous)
- - !PrivatePage will be viewable only by john
- - other pages will be viewable only by john and jack
+ * All versions of WikiStart will be viewable by everybody (including anonymous)
+ * !PrivatePage will be viewable only by john
+ * other pages will be viewable only by john and jack
+
+Groups:
+{{{
+[groups]
+admins = john, jack
+devs = alice, bob
+
+[wiki:Dev@*]
+@admins = TRAC_ADMIN
+@devs = WIKI_VIEW
+* =
+
+[*]
+@admins = TRAC_ADMIN
+* =
+}}}
+
+Then:
+- everything is blocked (whitelist approach), but
+- admins get all TRAC_ADMIN everywhere and
+- devs can view wiki pages.
+
+Some repository examples (Browse Source specific):
+{{{
+# A single repository:
+[repository:test_repo@*]
+john = BROWSER_VIEW, FILE_VIEW
+# John has BROWSER_VIEW and FILE_VIEW for the entire test_repo
+
+# All repositories:
+[repository:*@*]
+jack = BROWSER_VIEW, FILE_VIEW
+# John has BROWSER_VIEW and FILE_VIEW for all repositories
+}}}
+
+Very fine grain repository access:
+{{{
+# John has BROWSER_VIEW and FILE_VIEW access to trunk/src/some/location/ only
+[repository:test_repo@*/source:trunk/src/some/location/*@*]
+john = BROWSER_VIEW, FILE_VIEW
+
+
+# John has BROWSER_VIEW and FILE_VIEW access to only revision 1 of all files at trunk/src/some/location only
+[repository:test_repo@*/source:trunk/src/some/location/*@1]
+john = BROWSER_VIEW, FILE_VIEW
+
+
+# John has BROWSER_VIEW and FILE_VIEW access to all revisions of 'somefile' at trunk/src/some/location only
+[repository:test_repo@*/source:trunk/src/some/location/somefile@*]
+john = BROWSER_VIEW, FILE_VIEW
+
+
+# John has BROWSER_VIEW and FILE_VIEW access to only revision 1 of 'somefile' at trunk/src/some/location only
+[repository:test_repo@*/source:trunk/src/some/location/somefile@1]
+john = BROWSER_VIEW, FILE_VIEW
+}}}
+
+Note: In order for Timeline to work/visible for John, we must add CHANGESET_VIEW to the above permission list.
=== !AuthzSourcePolicy (mod_authz_svn-like permission policy) === #AuthzSourcePolicy
View
80 trac/wiki/default-pages/TracImport
@@ -1,7 +1,23 @@
= Importing ticket data =
+[[PageOutline]]
+
+By means of migrating from other issue-tracking systems, perform some external actions over tickets or simply synchronize different data bases, there are some available tools, plug-ins or scripts which lets you import or up-date tickets into Trac.
+
+Below, follows a collection of some of those.
+
+== !TicketImportPlugin ==
+
+ th:TicketImportPlugin:: mainly, but not only, this plug-in lets you import or up-date into Trac a series of tickets from a '''CSV file''' or (if the [http://pypi.python.org/pypi/xlrd xlrd library] is installed) from an '''Excel file'''.
+
+== !ExportImportXlsPlugin ==
+
+ th:ExportImportXlsPlugin:: this plug-in add an admin panel for export and import tickets via '''XLS file'''.
+ * It depends on the python packages xlwt/rxld.
== Bugzilla ==
+ th:BugzillaIssueTrackingPlugin:: integrates Bugzilla into Trac keeping TracLinks
+
Ticket data can be imported from Bugzilla using the [http://trac.edgewall.org/browser/trunk/contrib/bugzilla2trac.py bugzilla2trac.py] script, available in the contrib/ directory of the Trac distribution.
{{{
@@ -39,69 +55,45 @@ The script provides a number of features to ease the conversion, such as:
For more details on the available options, see the configuration section at the top of the script.
-== Sourceforge ==
-
-Ticket data can be imported from Sourceforge using the [http://trac.edgewall.org/browser/trunk/contrib/sourceforge2trac.py sourceforge2trac.py] script, available in the contrib/ directory of the Trac distribution.
+== Jira ==
-See #Trac3521 for an updated sourceforge2trac script.
+ th:JiraToTracIntegration:: provides tools to import Atlassian Jira backup files into Trac. The plug-in consists of a Python 3.1 commandline tool that:
+ - Parses the Jira backup XML file
+ - Sends the imported Jira data and attachments to Trac using the [http://trac-hacks.org/wiki/XmlRpcPlugin XmlRpcPlugin]
+ - Generates a htpasswd file containing the imported Jira users and their SHA-512 base64 encoded passwords
== Mantis ==
-The mantis2trac script now lives at http://trac-hacks.org/wiki/MantisImportScript. You can always get the latest version from http://trac-hacks.org/changeset/latest/mantisimportscript?old_path=/&filename=mantisimportscript&format=zip
-
-Mantis bugs can be imported using the attached script.
-
-Currently, the following data is imported from Mantis:
+ th:MantisImportScript:: script to import from Mantis into Trac the following data:
* bugs
* bug comments
* bug activity (field changes)
- * attachments (as long as the files live in the mantis db, not on the filesystem)
+ * attachments (as long as the files live in the mantis db, not on the filesystem) .
-If you use the script, please read the NOTES section (at the top of the file) and make sure you adjust the config parameters for your environment.
+== !PlanetForge ==
-mantis2trac.py has the same parameters as the bugzilla2trac.py script:
-{{{
-mantis2trac - Imports a bug database from Mantis into Trac.
-
-Usage: mantis2trac.py [options]
-
-Available Options:
- --db <MySQL dbname> - Mantis database
- --tracenv /path/to/trac/env - Full path to Trac db environment
- -h | --host <MySQL hostname> - Mantis DNS host name
- -u | --user <MySQL username> - Effective Mantis database user
- -p | --passwd <MySQL password> - Mantis database user password
- -c | --clean - Remove current Trac tickets before importing
- --help | help - This help info
+ th:PlanetForgeImportExportPlugin:: this plugin exports Trac data (wiki, tickets, compoments, permissions, repositories, etc.) using the open format designed by the COCLICO project. It extends the webadmin panel and the 'trac admin ...' command. Still has no 'import' feature.
-Additional configuration options can be defined directly in the script.
-}}}
+== Scarab ==
-== Jira ==
+ th:ScarabToTracScript:: script that migrates Scarab issues to Trac tickets
+ * Requires [http://trac-hacks.org/wiki/XmlRpcPlugin XmlRpcPlugin]
-The [http://trac-hacks.org/wiki/JiraToTracIntegration Jira2Trac plugin] provides you with tools to import Atlassian Jira backup files into Trac.
+== Sourceforge ==
-The plugin consists of a Python 3.1 commandline tool that:
+ th:SfnToTracScript:: importer of !SourceForge's new backup file (originated from #Trac3521)
- - Parses the Jira backup XML file
- - Sends the imported Jira data and attachments to Trac using the [http://trac-hacks.org/wiki/XmlRpcPlugin XmlRpcPlugin]
- - Generates a htpasswd file containing the imported Jira users and their SHA-512 base64 encoded passwords
+Also, ticket data can be imported from Sourceforge using the [http://trac.edgewall.org/browser/trunk/contrib/sourceforge2trac.py sourceforge2trac.py] script, available in the contrib/ directory of the Trac distribution.
== Other ==
Since trac uses a SQL database to store the data, you can import from other systems by examining the database tables. Just go into [http://www.sqlite.org/sqlite.html sqlite] command line to look at the tables and import into them from your application.
-=== Using a comma delimited file - CSV ===
+=== Comma delimited file - CSV ===
See [http://trac.edgewall.org/attachment/wiki/TracSynchronize/csv2trac.2.py] for details. This approach is particularly useful if one needs to enter a large number of tickets by hand. (note that the ticket type type field, (task etc...) is also needed for this script to work with more recent Trac releases)
Comments on script: The script has an error on line 168, ('Ticket' needs to be 'ticket'). Also, the listed values for severity and priority are swapped.
-=== Using an Excel (.xls) or comma delimited file (.csv) ===
-This plugin http://trac-hacks.org/wiki/TicketImportPlugin lets you import into Trac a series of tickets from a CSV file or (if the xlrd library is installed) from an Excel file.
-
-You can also use it to modify tickets in batch, by saving a report as CSV, editing the CSV file, and re-importing the tickets.
-
-This plugin is very useful when starting a new project: you can import a list of requirements that may have come from meeting notes, list of features, other ticketing systems... It's also great to review the tickets off-line, or to do massive changes to tickets.
-
-Based on the ticket id (or, if no id exists, on the summary) in the imported file, tickets are either created or updated.
-
-
+----
+See also:
+ * to import/export wiki pages: TracAdmin,
+ * to export tickets: TracTickets, TracQuery
View
8 trac/wiki/default-pages/TracIni
@@ -1,10 +1,11 @@
= The Trac Configuration File =
[[TracGuideToc]]
+[[PageOutline]]
Trac configuration is done by editing the '''`trac.ini`''' config file, located in `<projectenv>/conf/trac.ini`. Changes to the configuration are usually reflected immediately, though changes to the `[components]` or `[logging]` sections will require restarting the web server. You may also need to restart the web server after creating a global configuration file when none was previously present.
-The `trac.ini` configuration file should be writable by the web server, as Trac currently relies on the possibility to trigger a complete environment reload to flush its caches.
+The `trac.ini` configuration file and its parent directory should be writable by the web server, as Trac currently relies on the possibility to trigger a complete environment reload to flush its caches.
== Global Configuration ==
@@ -50,6 +51,11 @@ See the ''Plugins'' page on ''About Trac'' to get the list of active components
See also: TracPlugins
+=== [extra-permissions] === #extra-permissions-section
+''(since 0.12)''
+
+Custom additional permissions can be defined in this section when [wiki:ExtraPermissionsProvider] is enabled.
+
=== [milestone-groups] === #milestone-groups-section
''(since 0.11)''
View
157 trac/wiki/default-pages/TracInstall
@@ -3,11 +3,11 @@
Trac is written in the Python programming language and needs a database, [http://sqlite.org/ SQLite], [http://www.postgresql.org/ PostgreSQL], or [http://mysql.com/ MySQL]. For HTML rendering, Trac uses the [http://genshi.edgewall.org Genshi] templating system.
-Since version 0.12, Trac can also be localized, and there's probably a translation available for your language. If you want to be able to use the Trac interface in other languages, then make sure you **first** have installed the optional package [#OtherPythonPackages Babel]. Lacking Babel, you will only get the default english version, as usual. If you install Babel later on, you will need to re-install Trac.
+Since version 0.12, Trac can also be localized, and there's probably a translation available for your language. If you want to be able to use the Trac interface in other languages, then make sure you **first** have installed the optional package [#OtherPythonPackages Babel]. Lacking Babel, you will only get the default English version, as usual. If you install Babel later on, you will need to re-install Trac.
If you're interested in contributing new translations for other languages or enhance the existing translations, then please have a look at [trac:wiki:TracL10N TracL10N].
-What follows are generic instructions for installing and setting up Trac and its requirements. While you may find instructions for installing Trac on specific systems at TracInstallPlatforms on the main Trac site, please be sure to '''first read through these general instructions''' to get a good understanding of the tasks involved.
+What follows are generic instructions for installing and setting up Trac and its requirements. While you may find instructions for installing Trac on specific systems at [trac:wiki:TracInstallPlatforms TracInstallPlatforms] on the main Trac site, please be sure to '''first read through these general instructions''' to get a good understanding of the tasks involved.
[[PageOutline(2-3,Installation Steps,inline)]]
@@ -16,7 +16,7 @@ What follows are generic instructions for installing and setting up Trac and its
To install Trac, the following software packages must be installed:
* [http://www.python.org/ Python], version >= 2.4 and < 3.0
- (note that we dropped the support for Python 2.3 in this release)
+ //(note that we dropped the support for Python 2.3 in this release and that this will be the last Trac release supporting Python 2.4)//
* [http://peak.telecommunity.com/DevCenter/setuptools setuptools], version >= 0.6
* [http://genshi.edgewall.org/wiki/Download Genshi], version >= 0.6
@@ -74,14 +74,16 @@ It is '''very''' important to read carefully the [trac:MySqlDb] page before cre
==== Version Control System ====
===== Subversion =====
- * [http://subversion.apache.org/ Subversion], 1.5.x or 1.6.x and the '''''corresponding''''' Python bindings. Older versions starting from 1.4.0, etc. should still work. For troubleshooting information, check the [trac:TracSubversion#Troubleshooting TracSubversion] page. Versions prior to 1.4.0 won't probably work since trac uses svn core functionality (e.g. svn_path_canonicalize) that is not implemented in the python swig wrapper in svn <= 1.3.x (although it exists in the svn lib itself).
-There are [http://subversion.apache.org/packages.html pre-compiled SWIG bindings] available for various platforms. (Good luck finding precompiled SWIG bindings for any Windows package at that listing. TracSubversion points you to [http://alagazam.net Algazam], which works for me under Python 2.6.)
+[http://subversion.apache.org/ Subversion] 1.5.x or 1.6.x and the '''''corresponding''''' Python bindings.
-Note that Trac '''doesn't''' use [http://pysvn.tigris.org/ PySVN], neither does it work yet with the newer `ctype`-style bindings. [Is there a ticket for implementing ctype bindings?]
+There are [http://subversion.apache.org/packages.html pre-compiled SWIG bindings] available for various platforms. See also the TracSubversion page for details about Windows packages.
+Older versions starting from 1.4.0, etc. should still work. For troubleshooting information, check the [trac:TracSubversion#Troubleshooting TracSubversion] page. Versions prior to 1.4.0 won't probably work since trac uses svn core functionality (e.g. svn_path_canonicalize) that is not implemented in the python swig wrapper in svn <= 1.3.x (although it exists in the svn lib itself).
-'''Please note:''' if using Subversion, Trac must be installed on the '''same machine'''. Remote repositories are currently [trac:ticket:493 not supported].
+Note that Trac '''doesn't''' use [http://pysvn.tigris.org/ PySVN], neither does it work yet with the newer `ctype`-style bindings.
+
+'''Please note:''' if using Subversion, Trac must be installed on the '''same machine'''. Remote repositories are currently [trac:#493 not supported].
===== Others =====
@@ -93,19 +95,19 @@ A web server is optional because Trac is shipped with a server included, see the
Alternatively you configure Trac to run in any of the following environments.
* [http://httpd.apache.org/ Apache] with
- - [http://code.google.com/p/modwsgi/ mod_wsgi], see [wiki:TracModWSGI] and
- http://code.google.com/p/modwsgi/wiki/IntegrationWithTrac
- - [http://modpython.org/ mod_python 3.3.1], deprecated: see TracModPython)
- * a [http://www.fastcgi.com/ FastCGI]-capable web server (see TracFastCgi)
- * an [http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html AJP]-capable web
- server (see [trac:TracOnWindowsIisAjp])
- * a CGI-capable web server (see TracCgi), '''but usage of Trac as a cgi script
- is highly discouraged''', better use one of the previous options.
+ - [http://code.google.com/p/modwsgi/ mod_wsgi], see [wiki:TracModWSGI] (preferred)
+ - //[http://modpython.org/ mod_python 3.3.1], see TracModPython (deprecated)//
+ * any [http://www.fastcgi.com/ FastCGI]-capable web server, see TracFastCgi
+ * any [http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html AJP]-capable web
+ server, see [trac:TracOnWindowsIisAjp]
+ * IIS with [http://code.google.com/p/isapi-wsgi/ Isapi-wsgi], see [trac:TracOnWindowsIisIsapi]
+ * //as a last resort, a CGI-capable web server (see TracCgi), but usage of Trac as a cgi script
+ is highly discouraged, better use one of the previous options.//
==== Other Python Packages ====
- * [http://babel.edgewall.org Babel], version >= 0.9.5,
+ * [http://babel.edgewall.org Babel], version 0.9.5,
needed for localization support[[BR]]
''Note: '' If you want to be able to use the Trac interface in other languages, then make sure you first have installed the optional package Babel. Lacking Babel, you will only get the default english version, as usual. If you install Babel later on, you will need to re-install Trac.
* [http://docutils.sourceforge.net/ docutils], version >= 0.3.9
@@ -131,9 +133,9 @@ With setuptools you can install Trac from the subversion repository;
A few examples:
- - first install of the latest stable version Trac 0.12.1, with i18n support:
+ - first install of the latest stable version Trac 0.12.2, with i18n support:
{{{
- easy_install Babel==0.9.5 Genshi==0.6
+ easy_install Babel==0.9.5
easy_install Trac
}}}
''It's very important to run the two `easy_install` commands separately, otherwise the message catalogs won't be generated.''
@@ -153,14 +155,14 @@ For upgrades, reading the TracUpgrade page is mandatory, of course.
=== From source
If you want more control, you can download the source in archive form, or do a checkout from one of the official [[Trac:TracRepositories|source code repositories]].
-Be sure to have the prerequisites already installed. You can also obtain the Genshi and Babel source packages from http://www.edgewall.org and follow for them a similar installation procedure, or you can just easy_install those, see [#Usingeasy_install above].
+Be sure to have the prerequisites already installed. You can also obtain the Genshi and Babel source packages from http://www.edgewall.org and follow for them a similar installation procedure, or you can just `easy_install` those, see [#Usingeasy_install above].
Once you've unpacked the Trac archive or performed the checkout, move in the top-level folder and do:
{{{
$ python ./setup.py install
}}}
-''You'll need root permissions or equivalent for this step.''
+You'll need root permissions or equivalent for this step.
This will byte-compile the python source code and install it as an .egg file or folder in the `site-packages` directory
of your Python installation. The .egg will also contain all other resources needed by standard Trac, such as htdocs and templates.
@@ -175,6 +177,8 @@ Alternatively, you can do a `bdist_egg` and copy the .egg from dist/ to the plac
=== Advanced Options ===
+==== Custom location with `easy_install`
+
To install Trac to a custom location, or find out about other advanced installation options, run:
{{{
easy_install --help
@@ -194,7 +198,7 @@ Note: If installing on Mac OS X 10.6 running {{{ easy_install http://svn.edgewal
The above will place your `tracd` and `trac-admin` commands into `/usr/local/bin` and will install the Trac libraries and dependencies into `/Library/Python/2.5/site-packages`, which is Apple's preferred location for third-party Python application installations.
-=== Using `pip`
+==== Using `pip`
'pip' is an easy_install replacement that is very useful to quickly install python packages.
To get a trac installation up and running in less than 5 minutes:
@@ -248,7 +252,9 @@ Finally, make sure the user account under which the web front-end runs will have
}}}
-== Running the Standalone Server ==
+== Deploying Trac
+
+=== Running the Standalone Server ===
After having created a Trac environment, you can easily try the web interface by running the standalone server [wiki:TracStandalone tracd]:
{{{
@@ -260,13 +266,17 @@ Then, fire up a browser and visit `http://localhost:8000/`. You should get a sim
$ tracd -s --port 8000 /path/to/myproject
}}}
-== Running Trac on a Web Server ==
+=== Running Trac on a Web Server ===
-Trac provides various options for connecting to a "real" web server: [wiki:TracCgi CGI], [wiki:TracFastCgi FastCGI], [wiki:TracModWSGI mod_wsgi] and [wiki:TracModPython mod_python]. For decent performance, it is recommended that you use either FastCGI or mod_wsgi.
+Trac provides various options for connecting to a "real" web server:
+ - [wiki:TracFastCgi FastCGI]
+ - [wiki:TracModWSGI mod_wsgi]
+ - //[wiki:TracModPython mod_python] (no longer recommended, as mod_python is not actively maintained anymore)//
+ - //[wiki:TracCgi CGI] (should not be used, as the performance is far from optimal)//
-Trac also supports [trac:TracOnWindowsIisAjp AJP] which may be your choice if you want to connect to IIS.
+Trac also supports [trac:TracOnWindowsIisAjp AJP] which may be your choice if you want to connect to IIS. Other deployment scenarios are possible: [trac:TracNginxRecipe nginx], [http://projects.unbit.it/uwsgi/wiki/Example#Traconapacheinasub-uri uwsgi], [trac:TracOnWindowsIisIsapi Isapi-wsgi] etc.
-==== Generating the Trac cgi-bin directory ====
+==== Generating the Trac cgi-bin directory ==== #cgi-bin
In order for Trac to function properly with FastCGI you need to have a `trac.fcgi` file and for mod_wsgi a `trac.wsgi` file. These are Python scripts which load the appropriate Python code. They can be generated using the `deploy` option of [wiki:TracAdmin trac-admin].
@@ -278,21 +288,98 @@ trac-admin /usr/share/trac/projects/my-project deploy /tmp/deploy
mv /tmp/deploy/* /usr/share/trac
}}}
+
+==== Mapping Static Resources ====
+
+Out of the box, Trac will pass static resources such as style sheets or images through itself. For anything but a tracd only based deployment, this is far from optimal as the web server could be set up to directly serve those static resources (for CGI setup, this is '''highly undesirable''' and will cause abysmal performance).
+
+Web servers such as [http://httpd.apache.org/ Apache] allow you to create “Aliases” to resources, giving them a virtual URL that doesn't necessarily reflect the layout of the servers file system. We also can map requests for static resources directly to the directory on the file system, avoiding processing these requests by Trac itself.
+
+There are two primary URL paths for static resources - `/chrome/common` and `/chrome/site`. Plugins can add their own resources, usually accessible by `/chrome/<plugin>` path, so its important to override only known paths and not try to make universal `/chrome` alias for everything.
+
+Note that in order to get those static resources on the filesystem, you need first to extract the relevant resources from Trac using the [TracAdmin trac-admin]` <environment> deploy` command:
+[[TracAdminHelp(deploy)]]
+
+The target `<directory>` will then contain an `htdocs` directory with:
+ - `site/` - a copy of the environment's directory `htdocs/`
+ - `common/` - the static resources of Trac itself
+ - `<plugins>/` - one directory for each resource directory managed by the plugins enabled for this environment
+
+===== Example: Apache and `ScriptAlias` ===== #ScriptAlias-example
+
+Assuming the deployment has been done this way:
+{{{
+$ trac-admin /var/trac/env deploy /path/to/trac/htdocs/common
+}}}
+
+Add the following snippet to Apache configuration ''before'' the `ScriptAlias` or `WSGIScriptAlias` (which map all the other requests to the Trac application), changing paths to match your deployment:
+{{{
+Alias /trac/chrome/common /path/to/trac/htdocs/common
+Alias /trac/chrome/site /path/to/trac/htdocs/site
+
+<Directory "/path/to/www/trac/htdocs">
+ Order allow,deny
+ Allow from all
+</Directory>
+}}}
+
+If using mod_python, you might want to add this too (otherwise, the alias will be ignored):
+{{{
+<Location "/trac/chrome/common/">
+ SetHandler None
+</Location>
+}}}
+
+Note that we mapped `/trac` part of the URL to the `trac.*cgi` script, and the path `/trac/chrome/common` is the path you have to append to that location to intercept requests to the static resources.
+
+Similarly, if you have static resources in a project's `htdocs` directory (which is referenced by `/trac/chrome/site` URL in themes), you can configure Apache to serve those resources (again, put this ''before'' the `ScriptAlias` or `WSGIScriptAlias` for the .*cgi scripts, and adjust names and locations to match your installation):
+{{{
+Alias /trac/chrome/site /path/to/projectenv/htdocs
+
+<Directory "/path/to/projectenv/htdocs">
+ Order allow,deny
+ Allow from all
+</Directory>
+}}}
+
+Alternatively to aliasing `/trac/chrome/common`, you can tell Trac to generate direct links for those static resources (and only those), using the [[wiki:TracIni#trac-section| [trac] htdocs_location]] configuration setting:
+{{{
+[trac]
+htdocs_location = http://static.example.org/trac-common/
+}}}
+Note that this makes it easy to have a dedicated domain serve those static resources (preferentially [http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain cookie-less]).
+
+Of course, you still need to make the Trac `htdocs/common` directory available through the web server at the specified URL, for example by copying (or linking) the directory into the document root of the web server:
+{{{
+$ ln -s /path/to/trac/htdocs/common /var/www/static.example.org/trac-common
+}}}
+
+
==== Setting up the Plugin Cache ====
Some Python plugins need to be extracted to a cache directory. By default the cache resides in the home directory of the current user. When running Trac on a Web Server as a dedicated user (which is highly recommended) who has no home directory, this might prevent the plugins from starting. To override the cache location you can set the PYTHON_EGG_CACHE environment variable. Refer to your server documentation for detailed instructions on how to set environment variables.
== Configuring Authentication ==
-The process of adding, removing, and configuring user accounts for authentication depends on the specific way you run Trac. The basic procedure is described in the [wiki:TracCgi#AddingAuthentication "Adding Authentication"] section on the TracCgi page. To learn how to setup authentication for the frontend you're using, please refer to one of the following pages:
+Trac uses HTTP authentication. You'll need to configure your webserver to request authentication when the `.../login` URL is hit (the virtual path of the "login" button). Trac will automatically pick the REMOTE_USER variable up after you provide your credentials. Therefore, all user management goes through your web server configuration. Please consult the documentation of your web server for more info.
- * TracStandalone if you use the standalone server, `tracd`.
- * TracCgi if you use the CGI or FastCGI web front ends.
- * [wiki:TracModWSGI] if you use the Apache mod_wsgi web front end.
- * TracModPython if you use the Apache mod_python web front end.
+The process of adding, removing, and configuring user accounts for authentication depends on the specific way you run Trac.
+
+Please refer to one of the following sections:
+ * TracStandalone#UsingAuthentication if you use the standalone server, `tracd`.
+ * [wiki:TracModWSGI#ConfiguringAuthentication TracModWSGI#ConfiguringAuthentication] if you use the Apache web server, with any of its front end: `mod_wsgi` of course, but the same instructions applies also for `mod_python`, `mod_fcgi` or `mod_fastcgi`.
+ * TracFastCgi if you're using another web server with FCGI support (Cherokee, Lighttpd, !LiteSpeed, nginx)
+
+== Granting admin rights to the admin user
+Grant admin rights to user admin:
+{{{
+$ trac-admin /path/to/myproject permission add admin TRAC_ADMIN
+}}}
+This user will have an "Admin" entry menu that will allow you to admin your trac project.
+== Finishing the install
-== Automatic reference to the SVN changesets in Trac tickets ==
+=== Automatic reference to the SVN changesets in Trac tickets ===
You can configure SVN to automatically add a reference to the changeset into the ticket comments, whenever changes are committed to the repository. The description of the commit needs to contain one of the following formulas:
* '''`Refs #123`''' - to reference this changeset in `#123` ticket
@@ -304,15 +391,15 @@ tracopt.ticket.commit_updater.* = enabled
}}}
For more information, see the documentation of the `CommitTicketUpdater` component in the "Plugins" admin panel.
-== Using Trac ==
+=== Using Trac ===
Once you have your Trac site up and running, you should be able to create tickets, view the timeline, browse your version control repository if configured, etc.
-Keep in mind that anonymous (not logged in) users can by default access most but not all of the features. You will need to configure authentication and grant additional [wiki:TracPermissions permissions] to authenticated users to see the full set of features.
+Keep in mind that //anonymous// (not logged in) users can by default access only a few of the features, in particular they will have a read-only access to the resources. You will need to configure authentication and grant additional [wiki:TracPermissions permissions] to authenticated users to see the full set of features.
'' Enjoy! ''
[trac:TracTeam The Trac Team]
----
-See also: [trac:TracInstallPlatforms TracInstallPlatforms], TracGuide, TracCgi, TracFastCgi, TracModPython, [wiki:TracModWSGI], TracUpgrade, TracPermissions
+See also: [trac:TracInstallPlatforms TracInstallPlatforms], TracGuide, TracUpgrade, TracPermissions
View
24 trac/wiki/default-pages/TracInterfaceCustomization
@@ -1,5 +1,6 @@
= Customizing the Trac Interface =
[[TracGuideToc]]
+[[PageOutline]]
== Introduction ==
This page is meant to give users suggestions on how they can customize the look of Trac. Topics on this page cover editing the HTML templates and CSS files, but not the program code itself. The topics are intended to show users how they can modify the look of Trac to meet their specific needs. Suggestions for changes to Trac's interface applicable to all users should be filed as tickets, not listed on this page.
@@ -14,7 +15,7 @@ The logo or icon image should be put in a folder named "htdocs" in your project'
Now configure the appropriate section of your [wiki:TracIni trac.ini]:
=== Logo ===
-Change the `src` setting to `site/` followed by the name of your image file. The `width` and `height` settings should be modified to match your image's dimensions (the Trac chrome handler uses "`site/`" for files within the project directory `htdocs` and "`common/`" for the common ones). Note that 'site/' is not a placeholder for your project name, it is the actual prefix that should be used (literally). For example, if your project is named 'sandbox', and the image file is 'red_logo.gif' then the 'src' setting would be 'site/red_logo.gif', not 'sandbox/red_logo.gif'.
+Change the `src` setting to `site/` followed by the name of your image file. The `width` and `height` settings should be modified to match your image's dimensions (the Trac chrome handler uses "`site/`" for files within the project directory `htdocs`, and "`common/`" for the common `htdocs` directory belonging to a Trac installation). Note that 'site/' is not a placeholder for your project name, it is the actual prefix that should be used (literally). For example, if your project is named 'sandbox', and the image file is 'red_logo.gif' then the 'src' setting would be 'site/red_logo.gif', not 'sandbox/red_logo.gif'.
{{{
[header_logo]
@@ -25,7 +26,7 @@ height = 100
}}}
=== Icon ===
-Icons should be a 16x16 image in `.gif` or `.ico` format. Change the `icon` setting to `site/` followed by the name of your icon file. Icons will typically be displayed by your web browser next to the site's URL and in the `Bookmarks` menu.
+Icons should be a 32x32 image in `.gif` or `.ico` format. Change the `icon` setting to `site/` followed by the name of your icon file. Icons will typically be displayed by your web browser next to the site's URL and in the `Bookmarks` menu.
{{{
[project]
@@ -49,7 +50,7 @@ icon = /favicon.ico?
== Custom Navigation Entries ==
The new [mainnav] and [metanav] can now be used to customize the text and link used for the navigation items, or even to disable them (but not for adding new ones).
-In the following example, we rename the link to the Wiki start "Home", and hide the "Help/Guide". We also make the "View Tickets" entry link to a specific report .
+In the following example, we rename the link to the Wiki start "Home", and hide the "!Help/Guide". We also make the "View Tickets" entry link to a specific report .
{{{
[mainnav]
wiki.label = Home
@@ -66,7 +67,7 @@ See also TracNavigation for a more detailed explanation of the mainnav and metan
Trac is using [http://genshi.edgewall.org Genshi] as the templating engine. Documentation is yet to be written, in the meantime the following tip should work.
Say you want to add a link to a custom stylesheet, and then your own
-header and footer. Save the following content as 'site.html' inside your projects templates directory (each Trac project can have their own site.html), e.g. {{{/path/to/env/templates/site.html}}}:
+header and footer. Save the following content as `site.html` inside your projects `templates/` directory (each Trac project can have their own `site.html`), e.g. {{{/path/to/env/templates/site.html}}}:
{{{
#!xml
@@ -97,18 +98,17 @@ header and footer. Save the following content as 'site.html' inside your project
</html>
}}}
-Those who are familiar with XSLT may notice that Genshi templates bear some similarities. However, there are some Trac specific features - for example '''${href.chrome('site/style.css')}''' attribute references template placed into environment's ''htdocs/'' In a similar fashion '''${chrome.htdocs_location}''' is used to specify common ''htdocs/'' directory from Trac installation.
+Those who are familiar with XSLT may notice that Genshi templates bear some similarities. However, there are some Trac specific features - for example `${href.chrome('site/style.css')}` attribute references a CSS file placed into environment's `htdocs/` directory. In a similar fashion `${chrome.htdocs_location}` is used to specify the common `htdocs/` directory belonging to a Trac installation. That latter location can however be overriden using the [[TracIni#trac-config|[trac] htdocs_location]] configuration setting.
-`site.html` is one file to contain all your modifications. It usually works by the py:match (element or attribute), and it allows you to modify the page as it renders - the matches hook onto specific sections depending on what it tries to find
+`site.html` is one file to contain all your modifications. It usually works using the `py:match` directive (element or attribute), and it allows you to modify the page as it renders - the matches hook onto specific sections depending on what it tries to find
and modify them.
See [http://groups.google.com/group/trac-users/browse_thread/thread/70487fb2c406c937/ this thread] for a detailed explanation of the above example `site.html`.
-A site.html can contain any number of such py:match sections for whatever you need to modify. This is all [http://genshi.edgewall.org/ Genshi], so the docs on the exact syntax can be found there.
+A `site.html` can contain any number of such `py:match` sections for whatever you need to modify. This is all Genshi, so the [http://genshi.edgewall.org/wiki/Documentation/xml-templates.html docs on the exact syntax] can be found there.
-Example snippet of adding introduction text to the new ticket form (hide when preview):
+Example snippet of adding introduction text to the new ticket form (but not shown during preview):
-{{{
-#!xml
+{{{#!xml
<form py:match="div[@id='content' and @class='ticket']/form" py:attrs="select('@*')">
<py:if test="req.environ['PATH_INFO'] == '/newticket' and (not 'preview' in req.args)">
<p>Please make sure to search for existing tickets before reporting a new one!</p>
@@ -117,7 +117,7 @@ Example snippet of adding introduction text to the new ticket form (hide when pr
</form>
}}}
-This example illustrates a technique of using '''`req.environ['PATH_INFO']`''' to limit scope of changes to one view only. For instance, to make changes in site.html only for timeline and avoid modifying other sections - use ''`req.environ['PATH_INFO'] == '/timeline'`'' condition in <py:if> test.
+This example illustrates a technique of using `req.environ['PATH_INFO']` to limit scope of changes to one view only. For instance, to make changes in `site.html` only for timeline and avoid modifying other sections - use `req.environ['PATH_INFO'] == '/timeline'` condition in `<py:if>` test.
More examples snippets for `site.html` can be found at [trac:wiki:CookBook/SiteHtml CookBook/SiteHtml].
@@ -135,7 +135,7 @@ If the environment is upgraded from 0.10 and a `site_newticket.cs` file already
</form>
}}}
-Also note that the `site.html` (despite its name) can be put in a common templates directory - see the `[inherit] templates_dir` option. This could provide easier maintainence (and a migration path from 0.10 for larger installations) as one new global `site.html` file can be made to include any existing header, footer and newticket snippets.
+Also note that the `site.html` (despite its name) can be put in a common templates directory - see the [[TracIni#inherit-section|[inherit] templates_dir]] option. This could provide easier maintainence (and a migration path from 0.10 for larger installations) as one new global `site.html` file can be made to include any existing header, footer and newticket snippets.
== Project List == #ProjectList
View
6 trac/wiki/default-pages/TracLinks
@@ -255,6 +255,10 @@ It is also possible to link to the ticket's description using one of the followi
- `comment:description:ticket:123`
- `ticket:123#comment:description`
+=== htdocs: links ===
+
+Use `htdocs:path/to/file` to reference files in the `htdocs` directory of the Trac environment, the [TracEnvironment#DirectoryStructure web resource directory].
+
=== query: links ===
See TracQuery#UsingTracLinks and [#ticket:links].
@@ -288,7 +292,7 @@ Examples:
=== wiki: links ===
-See WikiPageNames and [#QuotingspaceinTracLinks quoting space in TracLinks] above.
+See WikiPageNames and [#QuotingspaceinTracLinks quoting space in TracLinks] above. It is possible to create a link to a specific page revision using the syntax WikiStart@1.
=== Version Control related links ===
View
147 trac/wiki/default-pages/TracModPython
@@ -3,13 +3,18 @@
Trac supports [http://www.modpython.org/ mod_python], which speeds up Trac's response times considerably, especially compared to [TracCgi CGI], and permits use of many Apache features not possible with [wiki:TracStandalone tracd]/mod_proxy.
-These instructions are for Apache 2; if you are still using Apache 1.3, you may have some luck with [trac:wiki:TracModPython2.7 TracModPython2.7].
-
-== A Word of Warning ==
+{{{#!div class="important"
+** A Word of Warning **
As of 16^th^ June 2010, the mod_python project is officially dead. If you are considering using mod_python for a new installation, '''please don't'''! There are known issues which will not be fixed and there are now better alternatives. Check out the main TracInstall pages for your target version for more information.
+}}}
+
+
+These instructions are for Apache 2; if you are still using Apache 1.3, you may have some luck with [trac:wiki:TracModPython2.7 TracModPython2.7], but you'll be totally on your own.
-== Simple configuration ==
+[[PageOutline(2-3,Overview,inline)]]
+
+== Simple configuration: single project == #Simpleconfiguration
If you just installed mod_python, you may have to add a line to load the module in the Apache configuration:
{{{
@@ -62,14 +67,19 @@ The options available are
{{{
# For a single project
PythonOption TracEnv /var/trac/myproject
+
# For multiple projects
PythonOption TracEnvParentDir /var/trac/myprojects
+
# For the index of multiple projects
PythonOption TracEnvIndexTemplate /srv/www/htdocs/trac/project_list_template.html
+
# A space delimitted list, with a "," between key and value pairs.
PythonOption TracTemplateVars key1,val1 key2,val2
+
# Useful to get the date in the wanted order
PythonOption TracLocale en_GB.UTF8
+
# See description above
PythonOption TracUriRoot /projects/myproject
}}}
@@ -82,80 +92,13 @@ PythonOption PYTHON_EGG_CACHE /var/trac/myprojects/egg-cache
}}}
or you can uncompress the Genshi egg to resolve problems extracting from it.
-=== Configuring Authentication ===
-
-Creating password files and configuring authentication works similar to the process for [wiki:TracCgi#AddingAuthentication CGI]:
-{{{
-#!xml
-<Location /projects/myproject/login>
- AuthType Basic
- AuthName "myproject"
- AuthUserFile /var/trac/myproject/.htpasswd
- Require valid-user
-</Location>
-}}}
-
-Configuration for mod_ldap authentication in Apache is a bit tricky (httpd 2.2.x and OpenLDAP: slapd 2.3.19)
-
-1. You need to load the following modules in Apache httpd.conf
-{{{
-LoadModule ldap_module modules/mod_ldap.so
-LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
-}}}
-
-2. Your httpd.conf also needs to look something like:
-
-{{{
-#!xml
-<Location /trac/>
- SetHandler mod_python
- PythonInterpreter main_interpreter
- PythonHandler trac.web.modpython_frontend
- PythonOption TracEnv /home/trac/
- PythonOption TracUriRoot /trac/
- Order deny,allow
- Deny from all
- Allow from 192.168.11.0/24
- AuthType Basic
- AuthName "Trac"
- AuthBasicProvider "ldap"
- AuthLDAPURL "ldap://127.0.0.1/dc=example,dc=co,dc=ke?uid?sub?(objectClass=inetOrgPerson)"
- authzldapauthoritative Off
- require valid-user
-</Location>
-}}}
-Or the LDAP interface to a Microsoft Active Directory:
-
-{{{
-#!xml
-<Location /trac/>
- SetHandler mod_python
- PythonInterpreter main_interpreter
- PythonHandler trac.web.modpython_frontend
- PythonOption TracEnv /home/trac/
- PythonOption TracUriRoot /trac/
- Order deny,allow
- Deny from all
- Allow from 192.168.11.0/24
- AuthType Basic
- AuthName "Trac"
- AuthBasicProvider "ldap"
- AuthLDAPURL "ldap://adserver.company.com:3268/DC=company,DC=com?sAMAccountName?sub?(objectClass=user)"
- AuthLDAPBindDN ldap-auth-user@company.com
- AuthLDAPBindPassword "the_password"
- authzldapauthoritative Off
- # require valid-user
- require ldap-group CN=Trac Users,CN=Users,DC=company,DC=com
-</Location>
-}}}
-
-Note 1: This is the case where the LDAP search will get around the multiple OUs, conecting to Global Catalog Server portion of AD (Notice the port is 3268, not the normal LDAP 389). The GCS is basically a "flattened" tree which allows searching for a user without knowing to which OU they belong.
+=== Configuring Authentication ===
-Note 2: Active Directory requires an authenticating user/password to access records (AuthLDAPBindDN and AuthLDAPBindPassword).
+See corresponding section in the [wiki:TracModWSGI#ConfiguringAuthentication] page.
-Note 3: The directive "require ldap-group ..." specifies an AD group whose members are allowed access.
+== Advanced Configuration
=== Setting the Python Egg Cache ===
@@ -185,7 +128,7 @@ If the Trac installation isn't installed in your Python path, you'll have to tel
Be careful about using the !PythonPath directive, and ''not'' `SetEnv PYTHONPATH`, as the latter won't work.
-== Setting up multiple projects ==
+=== Setting up multiple projects ===
The Trac mod_python handler supports a configuration option similar to Subversion's `SvnParentPath`, called `TracEnvParentDir`:
{{{
@@ -220,7 +163,7 @@ You can also use the same authentication realm for all of the projects using a `
</LocationMatch>
}}}
-== Virtual Host Configuration ==
+=== Virtual Host Configuration ===
Below is the sample configuration required to set up your trac as a virtual server (i.e. when you access it at the URLs like
!http://trac.mycompany.com):
@@ -268,6 +211,38 @@ In general, if you get server error pages, you can either check the Apache error
For multiple projects, try restarting the server as well.
+===Login Not Working===
+If you've used <Location /> directive, it will override any other directives, as well as <Location /Login>.
+The workaround is to use negation expression as follows (for multi project setups):
+{{{
+#!xml
+#this one for other pages
+<Location ~ "/*(?!login)">
+ SetHandler mod_python
+ PythonHandler trac.web.modpython_frontend
+ PythonOption TracEnvParentDir /projects
+ PythonOption TracUriRoot /
+
+</Location>
+#this one for login page
+<Location ~ "/[^/]+/login">
+ SetHandler mod_python
+ PythonHandler trac.web.modpython_frontend
+ PythonOption TracEnvParentDir /projects
+ PythonOption TracUriRoot /
+
+ #remove these if you don't want to force SSL
+ RewriteEngine On
+ RewriteCond %{HTTPS} off
+ RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
+
+ AuthType Basic
+ AuthName "Trac"
+ AuthUserFile /projects/.htpasswd
+ Require valid-user
+</Location>
+}}}
+
=== Expat-related segmentation faults === #expat
This problem will most certainly hit you on Unix when using Python 2.4.
@@ -303,7 +278,7 @@ Although it may seem trivial to rewrite the above configuration as a directory i
It may be possible to work around this with mod_rewrite, but I failed to get this working. In all, it is more hassle than it is worth. Stick to the provided instructions. :)
A success story: For me it worked out-of-box, with following trivial config:
-{{{
+{{{#!xml
SetHandler mod_python
PythonInterpreter main_interpreter
PythonHandler trac.web.modpython_frontend
@@ -328,16 +303,16 @@ If you are using the .htaccess method you may have additional problems if your t
</IfModule>
}}}
-
-=== Win32 Issues ===
+=== Platform specific issues
+==== Win32 Issues ====
If you run trac with mod_python < 3.2 on Windows, uploading attachments will '''not''' work. This problem is resolved in mod_python 3.1.4 or later, so please upgrade mod_python to fix this.
-=== OS X issues ===
+==== OS X issues ====
When using mod_python on OS X you will not be able to restart Apache using `apachectl restart`. This is apparently fixed in mod_python 3.2, but there's also a patch available for earlier versions [http://www.dscpl.com.au/projects/vampire/patches.html here].
-=== SELinux issues ===
+==== SELinux issues ====
If Trac reports something like: ''Cannot get shared lock on db.lock''
The security context on the repository may need to be set:
@@ -348,7 +323,7 @@ chcon -R -h -t httpd_sys_content_t PATH_TO_REPOSITORY
See also [http://subversion.tigris.org/faq.html#reposperms]
-=== FreeBSD issues ===
+==== FreeBSD issues ====
Pay attention to the version of the installed mod_python and sqlite packages. Ports have both the new and old ones, but earlier versions of pysqlite and mod_python won't integrate as the former requires threaded support in python, and the latter requires a threadless install.
If you compiled and installed apache2, apache wouldn´t support threads (cause it doesn´t work very well on FreeBSD). You could force thread support when running ./configure for apache, using --enable-threads, but this isn´t recommendable.
@@ -358,6 +333,11 @@ The best option [http://modpython.org/pipermail/mod_python/2006-September/021983
export LD_PRELOAD=/usr/lib/libc_r.so
}}}
+
+==== Fedora 7 Issues ====
+Make sure you install the 'python-sqlite2' package as it seems to be required for TracModPython but not for tracd
+
+
=== Subversion issues ===
If you get the following Trac Error `Unsupported version control system "svn"` only under mod_python, though it works well on the command-line and even with TracStandalone, chances are that you forgot to add the path to the Python bindings with the [TracModPython#ConfiguringPythonPath PythonPath] directive. (The better way is to add a link to the bindings in the Python `site-packages` directory, or create a `.pth` file in that directory.)
@@ -398,9 +378,6 @@ If you want to run Trac fully under https you might find that it tries to redire
</VirtualHost>
}}}
-=== Fedora 7 Issues ===
-Make sure you install the 'python-sqlite2' package as it seems to be required for TracModPython but not for tracd
-
=== Segmentation fault with php5-mhash or other php5 modules ===
You may encounter segfaults (reported on debian etch) if php5-mhash module is installed. Try to remove it to see if this solves the problem. See debian bug report [http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=411487]
View
331 trac/wiki/default-pages/TracModWSGI
@@ -1,13 +1,18 @@
= Trac and mod_wsgi =
-'''Important note:''' ''Please use either version 1.6, 2.4 or later of `mod_wsgi`. Versions prior to 2.4 in the 2.X branch have problems with some Apache configurations that use WSGI file wrapper extension. This extension is used in Trac to serve up attachments and static media files such as style sheets. If you are affected by this problem attachments will appear to be empty and formatting of HTML pages will appear not to work due to style sheet files not loading properly. See mod_wsgi tickets [http://code.google.com/p/modwsgi/issues/detail?id=100 #100] and [http://code.google.com/p/modwsgi/issues/detail?id=132 #132].''
-[http://code.google.com/p/modwsgi/ mod_wsgi] is an Apache module for running WSGI-compatible Python applications directly on top of Apache. The mod_wsgi adapter is written completely in C and provides significantly better performance than using existing WSGI adapters for mod_python or CGI.
+[http://code.google.com/p/modwsgi/ mod_wsgi] is an Apache module for running WSGI-compatible Python applications directly on top of the Apache webserver. The mod_wsgi adapter is written completely in C and provides very good performances.
-Trac can be run on top of mod_wsgi with the help of the following application script, which is just a Python file, though usually saved with a .wsgi extension). This file can be created using '''trac-admin <env> deploy <dir>''' command which automatically substitutes required paths.
+[[PageOutline(2-3,Overview,inline)]]
-{{{
-#!python
+== The `trac.wsgi` script
+
+Trac can be run on top of mod_wsgi with the help of the following application script, which is just a Python file, though usually saved with a `.wsgi` extension).
+
+=== A very basic script
+In its simplest form, the script could be:
+
+{{{#!python
import os
os.environ['TRAC_ENV'] = '/usr/local/trac/mysite'
@@ -19,10 +24,12 @@ application = trac.web.main.dispatch_request
The `TRAC_ENV` variable should naturally be the directory for your Trac environment (if you have several Trac environments in a directory, you can also use `TRAC_ENV_PARENT_DIR` instead), while the `PYTHON_EGG_CACHE` should be a directory where Python can temporarily extract Python eggs.
-'''Important note:''' If you're using multiple `.wsgi` files (for example one per Trac environment) you must ''not'' use `os.environ['TRAC_ENV']` to set the path to the Trac environment. Using this method may lead to Trac delivering the content of another Trac environment. (The variable may be filled with the path of a previously viewed Trac environment.) To solve this problem, use the following `.wsgi` file instead:
+=== A more elaborate script
-{{{
-#!python
+If you're using multiple `.wsgi` files (for example one per Trac environment) you must ''not'' use `os.environ['TRAC_ENV']` to set the path to the Trac environment. Using this method may lead to Trac delivering the content of another Trac environment, as the variable may be filled with the path of a previously viewed Trac environment.
+
+To solve this problem, use the following `.wsgi` file instead:
+{{{#!python
import os
os.environ['PYTHON_EGG_CACHE'] = '/usr/local/trac/mysite/eggs'
@@ -33,19 +40,25 @@ def application(environ, start_response):
return trac.web.main.dispatch_request(environ, start_response)
}}}
-For clarity, you should give this file a `.wsgi` extension. You should probably put the file in it's own directory, since you will open up its directory to Apache. You can create a .wsgi files which handles all this for you by running the TracAdmin command `deploy`.
+For clarity, you should give this file a `.wsgi` extension. You should probably put the file in its own directory, since you will expose it to Apache.