You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by rj...@apache.org on 2014/11/14 12:06:31 UTC

svn commit: r1639602 [3/14] - in /bloodhound/vendor/trac/current: ./ contrib/workflow/ doc/dev/ sample-plugins/ sample-plugins/permissions/ sample-plugins/workflow/ trac/ trac/admin/ trac/admin/templates/ trac/admin/tests/ trac/db/ trac/db/tests/ trac/...

Modified: bloodhound/vendor/trac/current/trac/admin/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/admin/web_ui.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/admin/web_ui.py (original)
+++ bloodhound/vendor/trac/current/trac/admin/web_ui.py Fri Nov 14 11:06:23 2014
@@ -22,11 +22,6 @@ import pkg_resources
 import re
 import shutil
 
-try:
-    from babel.core import Locale
-except ImportError:
-    Locale = None
-
 from genshi import HTML
 from genshi.builder import tag
 
@@ -37,7 +32,7 @@ from trac.perm import PermissionSystem, 
 from trac.util.datefmt import all_timezones, pytz
 from trac.util.text import exception_to_unicode, \
                            unicode_to_base64, unicode_from_base64
-from trac.util.translation import _, get_available_locales, ngettext
+from trac.util.translation import _, Locale, get_available_locales, ngettext
 from trac.web import HTTPNotFound, IRequestHandler
 from trac.web.chrome import add_notice, add_stylesheet, \
                             add_warning, Chrome, INavigationContributor, \
@@ -71,8 +66,8 @@ class AdminModule(Component):
         # admin panel is available
         panels, providers = self._get_panels(req)
         if panels:
-            yield 'mainnav', 'admin', tag.a(_('Admin'), href=req.href.admin(),
-                                            title=_('Administration'))
+            yield 'mainnav', 'admin', tag.a(_("Admin"), href=req.href.admin(),
+                                            title=_("Administration"))
 
     # IRequestHandler methods
 
@@ -88,7 +83,7 @@ class AdminModule(Component):
     def process_request(self, req):
         panels, providers = self._get_panels(req)
         if not panels:
-            raise HTTPNotFound(_('No administration panels available'))
+            raise HTTPNotFound(_("No administration panels available"))
 
         def _panel_order(p1, p2):
             if p1[::2] == ('general', 'basics'):
@@ -114,11 +109,11 @@ class AdminModule(Component):
                 panel_id = \
                     filter(lambda panel: panel[0] == cat_id, panels)[0][2]
             except IndexError:
-                raise HTTPNotFound(_('Unknown administration panel'))
+                raise HTTPNotFound(_("Unknown administration panel"))
 
         provider = providers.get((cat_id, panel_id), None)
         if not provider:
-            raise HTTPNotFound(_('Unknown administration panel'))
+            raise HTTPNotFound(_("Unknown administration panel"))
 
         if hasattr(provider, 'render_admin_panel'):
             template, data = provider.render_admin_panel(req, cat_id, panel_id,
@@ -189,14 +184,14 @@ def _save_config(config, req, log, notic
     try:
         config.save()
         if notices is None:
-            notices = [_('Your changes have been saved.')]
+            notices = [_("Your changes have been saved.")]
         for notice in notices:
             add_notice(req, notice)
     except Exception, e:
-        log.error('Error writing to trac.ini: %s', exception_to_unicode(e))
-        add_warning(req, _('Error writing to trac.ini, make sure it is '
-                           'writable by the web server. Your changes have '
-                           'not been saved.'))
+        log.error("Error writing to trac.ini: %s", exception_to_unicode(e))
+        add_warning(req, _("Error writing to trac.ini, make sure it is "
+                           "writable by the web server. Your changes have "
+                           "not been saved."))
 
 
 class BasicsAdminPanel(Component):
@@ -207,7 +202,7 @@ class BasicsAdminPanel(Component):
 
     def get_admin_panels(self, req):
         if 'TRAC_ADMIN' in req.perm('admin', 'general/basics'):
-            yield ('general', _('General'), 'basics', _('Basic Settings'))
+            yield ('general', _("General"), 'basics', _("Basic Settings"))
 
     def render_admin_panel(self, req, cat, page, path_info):
         if Locale:
@@ -267,7 +262,7 @@ class LoggingAdminPanel(Component):
 
     def get_admin_panels(self, req):
         if 'TRAC_ADMIN' in req.perm('admin', 'general/logging'):
-            yield ('general', _('General'), 'logging', _('Logging'))
+            yield ('general', _("General"), 'logging', _("Logging"))
 
     def render_admin_panel(self, req, cat, page, path_info):
         log_type = self.env.log_type
@@ -276,16 +271,18 @@ class LoggingAdminPanel(Component):
         log_dir = os.path.join(self.env.path, 'log')
 
         log_types = [
-            dict(name='none', label=_('None'), selected=log_type == 'none', disabled=False),
-            dict(name='stderr', label=_('Console'),
+            dict(name='none', label=_("None"),
+                 selected=log_type == 'none', disabled=False),
+            dict(name='stderr', label=_("Console"),
                  selected=log_type == 'stderr', disabled=False),
-            dict(name='file', label=_('File'), selected=log_type == 'file',
-                 disabled=False),
-            dict(name='syslog', label=_('Syslog'), disabled=os.name != 'posix',
-                 selected=log_type in ('unix', 'syslog')),
-            dict(name='eventlog', label=_('Windows event log'),
-                 disabled=os.name != 'nt',
-                 selected=log_type in ('winlog', 'eventlog', 'nteventlog')),
+            dict(name='file', label=_("File"),
+                 selected=log_type == 'file', disabled=False),
+            dict(name='syslog', label=_("Syslog"),
+                 selected=log_type in ('unix', 'syslog'),
+                 disabled=os.name != 'posix'),
+            dict(name='eventlog', label=_("Windows event log"),
+                 selected=log_type in ('winlog', 'eventlog', 'nteventlog'),
+                 disabled=os.name != 'nt'),
         ]
 
         log_levels = ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG']
@@ -296,8 +293,8 @@ class LoggingAdminPanel(Component):
             new_type = req.args.get('log_type')
             if new_type not in [t['name'] for t in log_types]:
                 raise TracError(
-                    _('Unknown log type %(type)s', type=new_type),
-                    _('Invalid log type')
+                    _("Unknown log type %(type)s", type=new_type),
+                    _("Invalid log type")
                 )
             if new_type != log_type:
                 self.config.set('logging', 'log_type', new_type)
@@ -311,8 +308,8 @@ class LoggingAdminPanel(Component):
                 new_level = req.args.get('log_level')
                 if new_level not in log_levels:
                     raise TracError(
-                        _('Unknown log level %(level)s', level=new_level),
-                        _('Invalid log level'))
+                        _("Unknown log level %(level)s", level=new_level),
+                        _("Invalid log level"))
                 if new_level != log_level:
                     self.config.set('logging', 'log_level', new_level)
                     changed = True
@@ -325,8 +322,8 @@ class LoggingAdminPanel(Component):
                     changed = True
                     log_file = new_file
                 if not log_file:
-                    raise TracError(_('You must specify a log file'),
-                                    _('Missing field'))
+                    raise TracError(_("You must specify a log file"),
+                                    _("Missing field"))
             else:
                 self.config.remove('logging', 'log_file')
                 changed = True
@@ -356,7 +353,7 @@ class PermissionAdminPanel(Component):
     def get_admin_panels(self, req):
         perm = req.perm('admin', 'general/perm')
         if 'PERMISSION_GRANT' in perm or 'PERMISSION_REVOKE' in perm:
-            yield ('general', _('General'), 'perm', _('Permissions'))
+            yield ('general', _("General"), 'perm', _("Permissions"))
 
     def render_admin_panel(self, req, cat, page, path_info):
         perm = PermissionSystem(self.env)
@@ -370,24 +367,24 @@ class PermissionAdminPanel(Component):
 
             if subject and subject.isupper() or \
                     group and group.isupper():
-                raise TracError(_('All upper-cased tokens are reserved for '
-                                  'permission names'))
+                raise TracError(_("All upper-cased tokens are reserved for "
+                                  "permission names"))
 
             # Grant permission to subject
             if req.args.get('add') and subject and action:
                 req.perm('admin', 'general/perm').require('PERMISSION_GRANT')
                 if action not in all_actions:
-                    raise TracError(_('Unknown action'))
+                    raise TracError(_("Unknown action"))
                 req.perm.require(action)
                 if (subject, action) not in all_permissions:
                     perm.grant_permission(subject, action)
-                    add_notice(req, _('The subject %(subject)s has been '
-                                      'granted the permission %(action)s.',
+                    add_notice(req, _("The subject %(subject)s has been "
+                                      "granted the permission %(action)s.",
                                       subject=subject, action=action))
                     req.redirect(req.href.admin(cat, page))
                 else:
-                    add_warning(req, _('The permission %(action)s was already '
-                                       'granted to %(subject)s.',
+                    add_warning(req, _("The permission %(action)s was already "
+                                       "granted to %(subject)s.",
                                        action=action, subject=subject))
 
             # Add subject to group
@@ -396,19 +393,25 @@ class PermissionAdminPanel(Component):
                 for action in perm.get_user_permissions(group):
                     if not action in all_actions: # plugin disabled?
                         self.env.log.warn("Adding %s to group %s: "
-                            "Permission %s unavailable, skipping perm check."
-                            % (subject, group, action))
+                            "Permission %s unavailable, skipping perm check.",
+                            subject, group, action)
                     else:
-                        req.perm.require(action)
+                        req.perm.require(action,
+                            message=_("The subject %(subject)s was not added "
+                                      "to the group %(group)s because the "
+                                      "group has %(perm)s permission and "
+                                      "users cannot grant permissions they "
+                                      "don't possess.", subject=subject,
+                                      group=group, perm=action))
                 if (subject, group) not in all_permissions:
                     perm.grant_permission(subject, group)
-                    add_notice(req, _('The subject %(subject)s has been added '
-                                      'to the group %(group)s.',
+                    add_notice(req, _("The subject %(subject)s has been added "
+                                      "to the group %(group)s.",
                                       subject=subject, group=group))
                     req.redirect(req.href.admin(cat, page))
                 else:
-                    add_warning(req, _('The subject %(subject)s was already '
-                                       'added to the group %(group)s.',
+                    add_warning(req, _("The subject %(subject)s was already "
+                                       "added to the group %(group)s.",
                                        subject=subject, group=group))
 
             # Remove permissions action
@@ -422,8 +425,8 @@ class PermissionAdminPanel(Component):
                     action = unicode_from_base64(action)
                     if (subject, action) in perm.get_all_permissions():
                         perm.revoke_permission(subject, action)
-                add_notice(req, _('The selected permissions have been '
-                                  'revoked.'))
+                add_notice(req, _("The selected permissions have been "
+                                  "revoked."))
                 req.redirect(req.href.admin(cat, page))
 
         perms = [perm for perm in all_permissions if perm[1].isupper()]
@@ -443,7 +446,7 @@ class PluginAdminPanel(Component):
 
     def get_admin_panels(self, req):
         if 'TRAC_ADMIN' in req.perm('admin', 'general/plugin'):
-            yield ('general', _('General'), 'plugin', _('Plugins'))
+            yield ('general', _("General"), 'plugin', _("Plugins"))
 
     def render_admin_panel(self, req, cat, page, path_info):
         if req.method == 'POST':
@@ -465,25 +468,25 @@ class PluginAdminPanel(Component):
     def _do_install(self, req):
         """Install a plugin."""
         if 'plugin_file' not in req.args:
-            raise TracError(_('No file uploaded'))
+            raise TracError(_("No file uploaded"))
         upload = req.args['plugin_file']
         if isinstance(upload, unicode) or not upload.filename:
-            raise TracError(_('No file uploaded'))
+            raise TracError(_("No file uploaded"))
         plugin_filename = upload.filename.replace('\\', '/').replace(':', '/')
         plugin_filename = os.path.basename(plugin_filename)
         if not plugin_filename:
-            raise TracError(_('No file uploaded'))
+            raise TracError(_("No file uploaded"))
         if not plugin_filename.endswith('.egg') and \
                 not plugin_filename.endswith('.py'):
-            raise TracError(_('Uploaded file is not a Python source file or '
-                              'egg'))
+            raise TracError(_("Uploaded file is not a Python source file or "
+                              "egg"))
 
         target_path = os.path.join(self.env.path, 'plugins', plugin_filename)
         if os.path.isfile(target_path):
-            raise TracError(_('Plugin %(name)s already installed',
+            raise TracError(_("Plugin %(name)s already installed",
                               name=plugin_filename))
 
-        self.log.info('Installing plugin %s', plugin_filename)
+        self.log.info("Installing plugin %s", plugin_filename)
         flags = os.O_CREAT + os.O_WRONLY + os.O_EXCL
         try:
             flags += os.O_BINARY
@@ -492,7 +495,7 @@ class PluginAdminPanel(Component):
             pass
         with os.fdopen(os.open(target_path, flags, 0666), 'w') as target_file:
             shutil.copyfileobj(upload.file, target_file)
-            self.log.info('Plugin %s installed to %s', plugin_filename,
+            self.log.info("Plugin %s installed to %s", plugin_filename,
                           target_path)
         # TODO: Validate that the uploaded file is actually a valid Trac plugin
 
@@ -507,7 +510,7 @@ class PluginAdminPanel(Component):
         plugin_path = os.path.join(self.env.path, 'plugins', plugin_filename)
         if not os.path.isfile(plugin_path):
             return
-        self.log.info('Uninstalling plugin %s', plugin_filename)
+        self.log.info("Uninstalling plugin %s", plugin_filename)
         os.remove(plugin_path)
 
         # Make the environment reset itself on the next request
@@ -528,8 +531,8 @@ class PluginAdminPanel(Component):
             if is_enabled != must_enable:
                 self.config.set('components', component,
                                 'disabled' if is_enabled else 'enabled')
-                self.log.info('%sabling component %s',
-                              'Dis' if is_enabled else 'En', component)
+                self.log.info("%sabling component %s",
+                              "Dis" if is_enabled else "En", component)
                 if must_enable:
                     added.append(component)
                 else:
@@ -547,13 +550,13 @@ class PluginAdminPanel(Component):
             removed.sort()
             notices = []
             if removed:
-                msg = ngettext('The following component has been disabled:',
-                               'The following components have been disabled:',
+                msg = ngettext("The following component has been disabled:",
+                               "The following components have been disabled:",
                                len(removed))
                 notices.append(tag(msg, make_list(removed)))
             if added:
-                msg = ngettext('The following component has been enabled:',
-                               'The following components have been enabled:',
+                msg = ngettext("The following component has been enabled:",
+                               "The following components have been enabled:",
                                len(added))
                 notices.append(tag(msg, make_list(added)))
 
@@ -566,7 +569,7 @@ class PluginAdminPanel(Component):
             try:
                 return format_to_html(self.env, context, text)
             except Exception, e:
-                self.log.error('Unable to render component documentation: %s',
+                self.log.error("Unable to render component documentation: %s",
                                exception_to_unicode(e, traceback=True))
                 return tag.pre(text)
 

Modified: bloodhound/vendor/trac/current/trac/cache.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/cache.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/cache.py (original)
+++ bloodhound/vendor/trac/current/trac/cache.py Fri Nov 14 11:06:23 2014
@@ -13,6 +13,8 @@
 
 from __future__ import with_statement
 
+import functools
+
 from .core import Component
 from .util import arity
 from .util.concurrency import ThreadLocal, threading
@@ -34,12 +36,15 @@ def key_to_id(s):
     return result
 
 
-class CachedPropertyBase(object):
-    """Base class for cached property descriptors"""
+class CachedPropertyBase(property):
+    """Base class for cached property descriptors.
+
+    :since 1.0.2: inherits from `property`.
+    """
 
     def __init__(self, retriever):
         self.retriever = retriever
-        self.__doc__ = retriever.__doc__
+        functools.update_wrapper(self, retriever)
 
     def make_key(self, cls):
         attr = self.retriever.__name__

Modified: bloodhound/vendor/trac/current/trac/db/api.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/api.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/api.py (original)
+++ bloodhound/vendor/trac/current/trac/db/api.py Fri Nov 14 11:06:23 2014
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C)2005-2009 Edgewall Software
+# Copyright (C)2005-2014 Edgewall Software
 # Copyright (C) 2005 Christopher Lenz <cm...@gmx.de>
 # All rights reserved.
 #
@@ -22,6 +22,7 @@ import urllib
 
 from trac.config import BoolOption, IntOption, Option
 from trac.core import *
+from trac.db.schema import Table
 from trac.util.concurrency import ThreadLocal
 from trac.util.text import unicode_passwd
 from trac.util.translation import _
@@ -61,9 +62,9 @@ def with_transaction(env, db=None):
 
     :deprecated: This decorator is in turn deprecated in favor of
                  context managers now that python 2.4 support has been
-                 dropped. Use instead the new context manager,
-                 `QueryContextManager` and
-                 `TransactionContextManager`, which makes for much
+                 dropped. It will be removed in Trac 1.3.1. Use instead
+                 the new context managers, `QueryContextManager` and
+                 `TransactionContextManager`, which make for much
                  simpler to write code:
 
     >>> def api_method(p1, p2):
@@ -250,6 +251,31 @@ class DatabaseManager(Component):
         args['schema'] = schema
         connector.init_db(**args)
 
+    def create_tables(self, schema):
+        """Create the specified tables.
+
+        :param schema: an iterable of table objects.
+
+        :since: version 1.0.2
+        """
+        connector = self.get_connector()[0]
+        with self.env.db_transaction as db:
+            for table in schema:
+                for sql in connector.to_sql(table):
+                    db(sql)
+
+    def drop_tables(self, schema):
+        """Drop the specified tables.
+
+        :param schema: an iterable of `Table` objects or table names.
+
+        :since: version 1.0.2
+        """
+        with self.env.db_transaction as db:
+            for table in schema:
+                table_name = table.name if isinstance(table, Table) else table
+                db.drop_table(table_name)
+
     def get_connection(self, readonly=False):
         """Get a database connection from the pool.
 
@@ -287,7 +313,7 @@ class DatabaseManager(Component):
                 backup_dir = os.path.join(self.env.path, backup_dir)
             db_str = self.config.get('trac', 'database')
             db_name, db_path = db_str.split(":", 1)
-            dest_name = '%s.%i.%d.bak' % (db_name, self.env.get_version(),
+            dest_name = '%s.%i.%d.bak' % (db_name, self.env.database_version,
                                           int(time.time()))
             dest = os.path.join(backup_dir, dest_name)
         else:

Modified: bloodhound/vendor/trac/current/trac/db/mysql_backend.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/mysql_backend.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/mysql_backend.py (original)
+++ bloodhound/vendor/trac/current/trac/db/mysql_backend.py Fri Nov 14 11:06:23 2014
@@ -361,6 +361,7 @@ class MySQLConnection(ConnectionWrapper)
                                  name)
         cnx = MySQLdb.connect(db=path, user=user, passwd=password, host=host,
                               port=port, charset='utf8', **opts)
+        self.schema = path
         if hasattr(cnx, 'encoders'):
             # 'encoders' undocumented but present since 1.2.1 (r422)
             cnx.encoders[Markup] = cnx.encoders[types.UnicodeType]
@@ -374,6 +375,24 @@ class MySQLConnection(ConnectionWrapper)
         ConnectionWrapper.__init__(self, cnx, log)
         self._is_closed = False
 
+    def cursor(self):
+        return IterableCursor(MySQLUnicodeCursor(self.cnx), self.log)
+
+    def rollback(self):
+        self.cnx.ping()
+        try:
+            self.cnx.rollback()
+        except MySQLdb.ProgrammingError:
+            self._is_closed = True
+
+    def close(self):
+        if not self._is_closed:
+            try:
+                self.cnx.close()
+            except MySQLdb.ProgrammingError:
+                pass # this error would mean it's already closed.  So, ignore
+            self._is_closed = True
+
     def cast(self, column, type):
         if type == 'int' or type == 'int64':
             type = 'signed'
@@ -384,6 +403,27 @@ class MySQLConnection(ConnectionWrapper)
     def concat(self, *args):
         return 'concat(%s)' % ', '.join(args)
 
+    def drop_table(self, table):
+        cursor = MySQLdb.cursors.Cursor(self.cnx)
+        cursor._defer_warnings = True  # ignore "Warning: Unknown table ..."
+        cursor.execute("DROP TABLE IF EXISTS " + self.quote(table))
+
+    def get_column_names(self, table):
+        rows = self.execute("""
+            SELECT column_name FROM information_schema.columns
+            WHERE table_schema=%s AND table_name=%s
+            """, (self.schema, table))
+        return [row[0] for row in rows]
+
+    def get_last_id(self, cursor, table, column='id'):
+        return cursor.lastrowid
+
+    def get_table_names(self):
+        rows = self.execute("""
+            SELECT table_name FROM information_schema.tables
+            WHERE table_schema=%s""", (self.schema,))
+        return [row[0] for row in rows]
+
     def like(self):
         """Return a case-insensitive LIKE clause."""
         return "LIKE %%s COLLATE %s_general_ci ESCAPE '/'" % self.charset
@@ -391,31 +431,18 @@ class MySQLConnection(ConnectionWrapper)
     def like_escape(self, text):
         return _like_escape_re.sub(r'/\1', text)
 
+    def prefix_match(self):
+        """Return a case sensitive prefix-matching operator."""
+        return "LIKE %s ESCAPE '/'"
+
+    def prefix_match_value(self, prefix):
+        """Return a value for case sensitive prefix-matching operator."""
+        return self.like_escape(prefix) + '%'
+
     def quote(self, identifier):
         """Return the quoted identifier."""
         return "`%s`" % identifier.replace('`', '``')
 
-    def get_last_id(self, cursor, table, column='id'):
-        return cursor.lastrowid
-
     def update_sequence(self, cursor, table, column='id'):
         # MySQL handles sequence updates automagically
         pass
-
-    def rollback(self):
-        self.cnx.ping()
-        try:
-            self.cnx.rollback()
-        except MySQLdb.ProgrammingError:
-            self._is_closed = True
-
-    def close(self):
-        if not self._is_closed:
-            try:
-                self.cnx.close()
-            except MySQLdb.ProgrammingError:
-                pass # this error would mean it's already closed.  So, ignore
-            self._is_closed = True
-
-    def cursor(self):
-        return IterableCursor(MySQLUnicodeCursor(self.cnx), self.log)

Modified: bloodhound/vendor/trac/current/trac/db/postgres_backend.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/postgres_backend.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/postgres_backend.py (original)
+++ bloodhound/vendor/trac/current/trac/db/postgres_backend.py Fri Nov 14 11:06:23 2014
@@ -22,7 +22,7 @@ from trac.core import *
 from trac.config import Option
 from trac.db.api import IDatabaseConnector, _parse_db_str
 from trac.db.util import ConnectionWrapper, IterableCursor
-from trac.util import get_pkginfo
+from trac.util import get_pkginfo, lazy
 from trac.util.compat import close_fds
 from trac.util.text import empty, exception_to_unicode, to_unicode
 from trac.util.translation import _
@@ -231,6 +231,9 @@ class PostgreSQLConnection(ConnectionWra
             cnx.rollback()
         ConnectionWrapper.__init__(self, cnx, log)
 
+    def cursor(self):
+        return IterableCursor(self.cnx.cursor(), self.log)
+
     def cast(self, column, type):
         # Temporary hack needed for the union of selects in the search module
         return 'CAST(%s AS %s)' % (column, _type_map.get(type, type))
@@ -238,6 +241,37 @@ class PostgreSQLConnection(ConnectionWra
     def concat(self, *args):
         return '||'.join(args)
 
+    def drop_table(self, table):
+        if (self._version or '').startswith(('8.0.', '8.1.')):
+            cursor = self.cursor()
+            cursor.execute("""SELECT table_name FROM information_schema.tables
+                              WHERE table_schema=current_schema()
+                              AND table_name=%s""", (table,))
+            for row in cursor:
+                if row[0] == table:
+                    self.execute("DROP TABLE " + self.quote(table))
+                    break
+        else:
+            self.execute("DROP TABLE IF EXISTS " + self.quote(table))
+
+    def get_column_names(self, table):
+        rows = self.execute("""
+            SELECT column_name FROM information_schema.columns
+            WHERE table_schema=%s AND table_name=%s
+            """, (self.schema, table))
+        return [row[0] for row in rows]
+
+    def get_last_id(self, cursor, table, column='id'):
+        cursor.execute("SELECT CURRVAL(%s)",
+                       (self.quote(self._sequence_name(table, column)),))
+        return cursor.fetchone()[0]
+
+    def get_table_names(self):
+        rows = self.execute("""
+            SELECT table_name FROM information_schema.tables
+            WHERE table_schema=%s""", (self.schema,))
+        return [row[0] for row in rows]
+
     def like(self):
         """Return a case-insensitive LIKE clause."""
         return "ILIKE %s ESCAPE '/'"
@@ -245,18 +279,31 @@ class PostgreSQLConnection(ConnectionWra
     def like_escape(self, text):
         return _like_escape_re.sub(r'/\1', text)
 
+    def prefix_match(self):
+        """Return a case sensitive prefix-matching operator."""
+        return "LIKE %s ESCAPE '/'"
+
+    def prefix_match_value(self, prefix):
+        """Return a value for case sensitive prefix-matching operator."""
+        return self.like_escape(prefix) + '%'
+
     def quote(self, identifier):
         """Return the quoted identifier."""
         return '"%s"' % identifier.replace('"', '""')
 
-    def get_last_id(self, cursor, table, column='id'):
-        cursor.execute("""SELECT CURRVAL('"%s_%s_seq"')""" % (table, column))
-        return cursor.fetchone()[0]
-
     def update_sequence(self, cursor, table, column='id'):
-        cursor.execute("""
-            SELECT setval('"%s_%s_seq"', (SELECT MAX(id) FROM %s))
-            """ % (table, column, table))
-
-    def cursor(self):
-        return IterableCursor(self.cnx.cursor(), self.log)
+        cursor.execute("SELECT SETVAL(%%s, (SELECT MAX(%s) FROM %s))"
+                       % (self.quote(column), self.quote(table)),
+                       (self.quote(self._sequence_name(table, column)),))
+
+    def _sequence_name(self, table, column):
+        return '%s_%s_seq' % (table, column)
+
+    @lazy
+    def _version(self):
+        cursor = self.cursor()
+        cursor.execute('SELECT version()')
+        for version, in cursor:
+            # retrieve "8.1.23" from "PostgreSQL 8.1.23 on ...."
+            if version.startswith('PostgreSQL '):
+                return version.split(' ', 2)[1]

Modified: bloodhound/vendor/trac/current/trac/db/sqlite_backend.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/sqlite_backend.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/sqlite_backend.py (original)
+++ bloodhound/vendor/trac/current/trac/db/sqlite_backend.py Fri Nov 14 11:06:23 2014
@@ -27,6 +27,8 @@ from trac.util.translation import _
 
 _like_escape_re = re.compile(r'([/_%])')
 
+_glob_escape_re = re.compile(r'[*?\[]')
+
 try:
     import pysqlite2.dbapi2 as sqlite
     have_pysqlite = 2
@@ -313,6 +315,24 @@ class SQLiteConnection(ConnectionWrapper
     def concat(self, *args):
         return '||'.join(args)
 
+    def drop_table(self, table):
+        cursor = self.cursor()
+        cursor.execute("DROP TABLE IF EXISTS " + self.quote(table))
+
+    def get_column_names(self, table):
+        cursor = self.cnx.cursor()
+        rows = cursor.execute("PRAGMA table_info(%s)"
+                              % self.quote(table))
+        return [row[1] for row in rows]
+
+    def get_last_id(self, cursor, table, column='id'):
+        return cursor.lastrowid
+
+    def get_table_names(self):
+        rows = self.execute("""
+            SELECT name FROM sqlite_master WHERE type='table'""")
+        return [row[0] for row in rows]
+
     def like(self):
         """Return a case-insensitive LIKE clause."""
         if sqlite_version >= (3, 1, 0):
@@ -326,13 +346,18 @@ class SQLiteConnection(ConnectionWrapper
         else:
             return text
 
+    def prefix_match(self):
+        """Return a case sensitive prefix-matching operator."""
+        return 'GLOB %s'
+
+    def prefix_match_value(self, prefix):
+        """Return a value for case sensitive prefix-matching operator."""
+        return _glob_escape_re.sub(lambda m: '[%s]' % m.group(0), prefix) + '*'
+
     def quote(self, identifier):
         """Return the quoted identifier."""
         return "`%s`" % identifier.replace('`', '``')
 
-    def get_last_id(self, cursor, table, column='id'):
-        return cursor.lastrowid
-
     def update_sequence(self, cursor, table, column='id'):
         # SQLite handles sequence updates automagically
         # http://www.sqlite.org/autoinc.html

Modified: bloodhound/vendor/trac/current/trac/db/tests/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/tests/__init__.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/tests/__init__.py (original)
+++ bloodhound/vendor/trac/current/trac/db/tests/__init__.py Fri Nov 14 11:06:23 2014
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2005-2013 Edgewall Software
+# Copyright (C) 2005-2014 Edgewall Software
 # All rights reserved.
 #
 # This software is licensed as described in the file COPYING, which
@@ -14,11 +14,10 @@
 import unittest
 
 from trac.db.tests import api, mysql_test, postgres_test, util
-
 from trac.db.tests.functional import functionalSuite
 
-def suite():
 
+def suite():
     suite = unittest.TestSuite()
     suite.addTest(api.suite())
     suite.addTest(mysql_test.suite())

Modified: bloodhound/vendor/trac/current/trac/db/tests/api.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/tests/api.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/tests/api.py (original)
+++ bloodhound/vendor/trac/current/trac/db/tests/api.py Fri Nov 14 11:06:23 2014
@@ -16,8 +16,11 @@ from __future__ import with_statement
 import os
 import unittest
 
+import trac.tests.compat
 from trac.db.api import DatabaseManager, _parse_db_str, get_column_names, \
                         with_transaction
+from trac.db_default import schema as default_schema
+from trac.db.schema import Column, Table
 from trac.test import EnvironmentStub, Mock
 from trac.util.concurrency import ThreadLocal
 
@@ -287,6 +290,9 @@ class StringsTestCase(unittest.TestCase)
     def setUp(self):
         self.env = EnvironmentStub()
 
+    def tearDown(self):
+        self.env.reset_db()
+
     def test_insert_unicode(self):
         self.env.db_transaction(
                 "INSERT INTO system (name,value) VALUES (%s,%s)",
@@ -318,41 +324,172 @@ class StringsTestCase(unittest.TestCase)
         self.assertEqual(r'alpha\`\"\'\\beta``gamma""delta',
                          get_column_names(cursor)[0])
 
+    def test_quoted_id_with_percent(self):
+        db = self.env.get_read_db()
+        name = """%?`%s"%'%%"""
+
+        def test(db, logging=False):
+            cursor = db.cursor()
+            if logging:
+                cursor.log = self.env.log
+
+            cursor.execute('SELECT 1 AS ' + db.quote(name))
+            self.assertEqual(name, get_column_names(cursor)[0])
+            cursor.execute('SELECT %s AS ' + db.quote(name), (42,))
+            self.assertEqual(name, get_column_names(cursor)[0])
+            cursor.executemany("UPDATE system SET value=%s WHERE "
+                               "1=(SELECT 0 AS " + db.quote(name) + ")",
+                               [])
+            cursor.executemany("UPDATE system SET value=%s WHERE "
+                               "1=(SELECT 0 AS " + db.quote(name) + ")",
+                               [('42',), ('43',)])
+
+        test(db)
+        test(db, logging=True)
+
+    def test_prefix_match_case_sensitive(self):
+        @self.env.with_transaction()
+        def do_insert(db):
+            cursor = db.cursor()
+            cursor.executemany("INSERT INTO system (name,value) VALUES (%s,1)",
+                               [('blahblah',), ('BlahBlah',), ('BLAHBLAH',),
+                                (u'BlähBlah',), (u'BlahBläh',)])
+
+        db = self.env.get_read_db()
+        cursor = db.cursor()
+        cursor.execute("SELECT name FROM system WHERE name %s" %
+                       db.prefix_match(),
+                       (db.prefix_match_value('Blah'),))
+        names = sorted(name for name, in cursor)
+        self.assertEqual('BlahBlah', names[0])
+        self.assertEqual(u'BlahBläh', names[1])
+        self.assertEqual(2, len(names))
+
+    def test_prefix_match_metachars(self):
+        def do_query(prefix):
+            db = self.env.get_read_db()
+            cursor = db.cursor()
+            cursor.execute("SELECT name FROM system WHERE name %s "
+                           "ORDER BY name" % db.prefix_match(),
+                           (db.prefix_match_value(prefix),))
+            return [name for name, in cursor]
+
+        @self.env.with_transaction()
+        def do_insert(db):
+            values = ['foo*bar', 'foo*bar!', 'foo?bar', 'foo?bar!',
+                      'foo[bar', 'foo[bar!', 'foo]bar', 'foo]bar!',
+                      'foo%bar', 'foo%bar!', 'foo_bar', 'foo_bar!',
+                      'foo/bar', 'foo/bar!', 'fo*ob?ar[fo]ob%ar_fo/obar']
+            cursor = db.cursor()
+            cursor.executemany("INSERT INTO system (name,value) VALUES (%s,1)",
+                               [(value,) for value in values])
+
+        self.assertEqual(['foo*bar', 'foo*bar!'], do_query('foo*'))
+        self.assertEqual(['foo?bar', 'foo?bar!'], do_query('foo?'))
+        self.assertEqual(['foo[bar', 'foo[bar!'], do_query('foo['))
+        self.assertEqual(['foo]bar', 'foo]bar!'], do_query('foo]'))
+        self.assertEqual(['foo%bar', 'foo%bar!'], do_query('foo%'))
+        self.assertEqual(['foo_bar', 'foo_bar!'], do_query('foo_'))
+        self.assertEqual(['foo/bar', 'foo/bar!'], do_query('foo/'))
+        self.assertEqual(['fo*ob?ar[fo]ob%ar_fo/obar'], do_query('fo*'))
+        self.assertEqual(['fo*ob?ar[fo]ob%ar_fo/obar'],
+                         do_query('fo*ob?ar[fo]ob%ar_fo/obar'))
+
 
 class ConnectionTestCase(unittest.TestCase):
     def setUp(self):
         self.env = EnvironmentStub()
+        self.schema = [
+            Table('HOURS', key='ID')[
+                Column('ID', auto_increment=True),
+                Column('AUTHOR')],
+            Table('blog', key='bid')[
+                Column('bid', auto_increment=True),
+                Column('author')
+            ]
+        ]
+        self.env.global_databasemanager.drop_tables(self.schema)
+        self.env.global_databasemanager.create_tables(self.schema)
 
     def tearDown(self):
+        self.env.global_databasemanager.drop_tables(self.schema)
         self.env.reset_db()
 
     def test_get_last_id(self):
-        id1 = id2 = None
         q = "INSERT INTO report (author) VALUES ('anonymous')"
         with self.env.db_transaction as db:
             cursor = db.cursor()
             cursor.execute(q)
             # Row ID correct before...
             id1 = db.get_last_id(cursor, 'report')
-            self.assertNotEqual(0, id1)
             db.commit()
             cursor.execute(q)
             # ... and after commit()
             db.commit()
             id2 = db.get_last_id(cursor, 'report')
-            self.assertEqual(id1 + 1, id2)
 
-    def test_update_sequence(self):
-        self.env.db_transaction(
-            "INSERT INTO report (id, author) VALUES (42, 'anonymous')")
+        self.assertNotEqual(0, id1)
+        self.assertEqual(id1 + 1, id2)
+
+    def test_update_sequence_default_column(self):
         with self.env.db_transaction as db:
+            db("INSERT INTO report (id, author) VALUES (42, 'anonymous')")
             cursor = db.cursor()
             db.update_sequence(cursor, 'report', 'id')
+
         self.env.db_transaction(
             "INSERT INTO report (author) VALUES ('next-id')")
+
         self.assertEqual(43, self.env.db_query(
                 "SELECT id FROM report WHERE author='next-id'")[0][0])
 
+    def test_update_sequence_nondefault_column(self):
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(
+                "INSERT INTO blog (bid, author) VALUES (42, 'anonymous')")
+            db.update_sequence(cursor, 'blog', 'bid')
+
+        self.env.db_transaction(
+            "INSERT INTO blog (author) VALUES ('next-id')")
+
+        self.assertEqual(43, self.env.db_query(
+            "SELECT bid FROM blog WHERE author='next-id'")[0][0])
+
+    def test_identifiers_need_quoting(self):
+        """Test for regression described in comment:4:ticket:11512."""
+        with self.env.db_transaction as db:
+            db("INSERT INTO %s (%s, %s) VALUES (42, 'anonymous')"
+               % (db.quote('HOURS'), db.quote('ID'), db.quote('AUTHOR')))
+            cursor = db.cursor()
+            db.update_sequence(cursor, 'HOURS', 'ID')
+
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute(
+                "INSERT INTO %s (%s) VALUES ('next-id')"
+                % (db.quote('HOURS'), db.quote('AUTHOR')))
+            last_id = db.get_last_id(cursor, 'HOURS', 'ID')
+
+        self.assertEqual(43, last_id)
+
+    def test_table_names(self):
+        schema = default_schema + self.schema
+        with self.env.db_query as db:
+            db_tables = db.get_table_names()
+            self.assertEqual(len(schema), len(db_tables))
+            for table in schema:
+                self.assertIn(table.name, db_tables)
+
+    def test_get_column_names(self):
+        schema = default_schema + self.schema
+        with self.env.db_transaction as db:
+            for table in schema:
+                db_columns = db.get_column_names(table.name)
+                self.assertEqual(len(table.columns), len(db_columns))
+                for column in table.columns:
+                    self.assertIn(column.name, db_columns)
+
 
 def suite():
     suite = unittest.TestSuite()

Modified: bloodhound/vendor/trac/current/trac/db/tests/mysql_test.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/tests/mysql_test.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/tests/mysql_test.py (original)
+++ bloodhound/vendor/trac/current/trac/db/tests/mysql_test.py Fri Nov 14 11:06:23 2014
@@ -13,10 +13,10 @@
 
 import unittest
 
+import trac.tests.compat
 from trac.db.mysql_backend import MySQLConnector
 from trac.db.schema import Table, Column, Index
 from trac.test import EnvironmentStub, Mock
-from trac.tests import compat
 
 
 class MySQLTableAlterationSQLTest(unittest.TestCase):

Modified: bloodhound/vendor/trac/current/trac/db/tests/util.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/tests/util.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/tests/util.py (original)
+++ bloodhound/vendor/trac/current/trac/db/tests/util.py Fri Nov 14 11:06:23 2014
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2010-2013 Edgewall Software
+# Copyright (C) 2010-2014 Edgewall Software
 # All rights reserved.
 #
 # This software is licensed as described in the file COPYING, which
@@ -31,6 +31,37 @@ class SQLEscapeTestCase(unittest.TestCas
         self.assertEqual("'%% %%'", sql_escape_percent("'% %'"))
         self.assertEqual("'%%s %%i'", sql_escape_percent("'%s %i'"))
 
+        self.assertEqual("%", sql_escape_percent("%"))
+        self.assertEqual("`%%`", sql_escape_percent("`%`"))
+        self.assertEqual("``%``", sql_escape_percent("``%``"))
+        self.assertEqual("```%%```", sql_escape_percent("```%```"))
+        self.assertEqual("```%%`", sql_escape_percent("```%`"))
+        self.assertEqual("%s", sql_escape_percent("%s"))
+        self.assertEqual("% %", sql_escape_percent("% %"))
+        self.assertEqual("%s %i", sql_escape_percent("%s %i"))
+        self.assertEqual("`%%s`", sql_escape_percent("`%s`"))
+        self.assertEqual("`%% %%`", sql_escape_percent("`% %`"))
+        self.assertEqual("`%%s %%i`", sql_escape_percent("`%s %i`"))
+
+        self.assertEqual('%', sql_escape_percent('%'))
+        self.assertEqual('"%%"', sql_escape_percent('"%"'))
+        self.assertEqual('""%""', sql_escape_percent('""%""'))
+        self.assertEqual('"""%%"""', sql_escape_percent('"""%"""'))
+        self.assertEqual('"""%%"', sql_escape_percent('"""%"'))
+        self.assertEqual('%s', sql_escape_percent('%s'))
+        self.assertEqual('% %', sql_escape_percent('% %'))
+        self.assertEqual('%s %i', sql_escape_percent('%s %i'))
+        self.assertEqual('"%%s"', sql_escape_percent('"%s"'))
+        self.assertEqual('"%% %%"', sql_escape_percent('"% %"'))
+        self.assertEqual('"%%s %%i"', sql_escape_percent('"%s %i"'))
+
+        self.assertEqual("""'%%?''"%%s`%%i`%%%%"%%S'""",
+                         sql_escape_percent("""'%?''"%s`%i`%%"%S'"""))
+        self.assertEqual("""`%%?``'%%s"%%i"%%%%'%%S`""",
+                         sql_escape_percent("""`%?``'%s"%i"%%'%S`"""))
+        self.assertEqual('''"%%?""`%%s'%%i'%%%%`%%S"''',
+                         sql_escape_percent('''"%?""`%s'%i'%%`%S"'''))
+
 
 def suite():
     suite = unittest.TestSuite()

Modified: bloodhound/vendor/trac/current/trac/db/util.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db/util.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db/util.py (original)
+++ bloodhound/vendor/trac/current/trac/db/util.py Fri Nov 14 11:06:23 2014
@@ -15,11 +15,18 @@
 #
 # Author: Christopher Lenz <cm...@gmx.de>
 
+import re
+
+_sql_escape_percent_re = re.compile("""
+    '(?:[^']+|'')*' |
+    `(?:[^`]+|``)*` |
+    "(?:[^"]+|"")*" """, re.VERBOSE)
+
 
 def sql_escape_percent(sql):
-    import re
-    return re.sub("'((?:[^']|(?:''))*)'",
-                  lambda m: m.group(0).replace('%', '%%'), sql)
+    def repl(match):
+        return match.group(0).replace('%', '%%')
+    return _sql_escape_percent_re.sub(repl, sql)
 
 
 class IterableCursor(object):
@@ -118,7 +125,7 @@ class ConnectionWrapper(object):
         """
         dql = self.check_select(query)
         cursor = self.cnx.cursor()
-        cursor.execute(query, params)
+        cursor.execute(query, params if params is not None else [])
         rows = cursor.fetchall() if dql else None
         cursor.close()
         return rows

Modified: bloodhound/vendor/trac/current/trac/db_default.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/db_default.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/db_default.py (original)
+++ bloodhound/vendor/trac/current/trac/db_default.py Fri Nov 14 11:06:23 2014
@@ -300,8 +300,7 @@ USER dynamic variable, replaced with the
 logged in user when executed.
 """,
 """\
-SELECT DISTINCT
-       p.value AS __color__,
+SELECT p.value AS __color__,
        (CASE
          WHEN owner = $USER AND status = 'accepted' THEN 'Accepted'
          WHEN owner = $USER THEN 'Owned'
@@ -313,12 +312,14 @@ SELECT DISTINCT
        reporter AS _reporter
   FROM ticket t
   LEFT JOIN enum p ON p.name = t.priority AND p.type = 'priority'
-  LEFT JOIN ticket_change tc ON tc.ticket = t.id AND tc.author = $USER
-                                AND tc.field = 'comment'
-  WHERE t.status <> 'closed'
-        AND (owner = $USER OR reporter = $USER OR author = $USER)
-  ORDER BY (owner = $USER AND status = 'accepted') DESC,
-           owner = $USER DESC, reporter = $USER DESC,
+  WHERE t.status <> 'closed' AND
+        (owner = $USER OR reporter = $USER OR
+         EXISTS (SELECT * FROM ticket_change tc
+                 WHERE tc.ticket = t.id AND tc.author = $USER AND
+                       tc.field = 'comment'))
+  ORDER BY (COALESCE(owner, '') = $USER AND status = 'accepted') DESC,
+           COALESCE(owner, '') = $USER DESC,
+           COALESCE(reporter, '') = $USER DESC,
            """ + db.cast('p.value', 'int') + """, milestone, t.type, t.time
 """),
 #----------------------------------------------------------------------------

Modified: bloodhound/vendor/trac/current/trac/dist.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/dist.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/dist.py (original)
+++ bloodhound/vendor/trac/current/trac/dist.py Fri Nov 14 11:06:23 2014
@@ -466,6 +466,17 @@ try:
                 self.run_command('compile_catalog')
             def run(self):
                 self.l10n_run()
+                # When bdist_egg is called on distribute 0.6.29 and later, the
+                # egg file includes no *.mo and *.js files which are generated
+                # in l10n_run() method.
+                # We remove build_py.data_files property to re-compute in order
+                # to avoid the issue (#11640).
+                build_py = self.get_finalized_command('build_py')
+                if 'data_files' in build_py.__dict__ and \
+                   not any(any(name.endswith('.mo') for name in filenames)
+                           for pkg, src_dir, build_dir, filenames
+                           in build_py.data_files):
+                    del build_py.__dict__['data_files']
                 _install_lib.run(self)
         return build, install_lib
 

Modified: bloodhound/vendor/trac/current/trac/env.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/env.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/env.py (original)
+++ bloodhound/vendor/trac/current/trac/env.py Fri Nov 14 11:06:23 2014
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2003-2011 Edgewall Software
+# Copyright (C) 2003-2014 Edgewall Software
 # Copyright (C) 2003-2007 Jonas Borgström <jo...@edgewall.com>
 # All rights reserved.
 #
@@ -26,7 +26,8 @@ from urlparse import urlsplit
 from trac import db_default
 from trac.admin import AdminCommandError, IAdminCommandProvider
 from trac.cache import CacheManager
-from trac.config import *
+from trac.config import BoolOption, ConfigSection, Configuration, Option, \
+                        PathOption
 from trac.core import Component, ComponentManager, implements, Interface, \
                       ExtensionPoint, TracError
 from trac.db.api import (DatabaseManager, QueryContextManager,
@@ -392,7 +393,8 @@ class Environment(Component, ComponentMa
     def get_db_cnx(self):
         """Return a database connection from the connection pool
 
-        :deprecated: Use :meth:`db_transaction` or :meth:`db_query` instead
+        :deprecated: Use :meth:`db_transaction` or :meth:`db_query` instead.
+                     Removed in Trac 1.1.2.
 
         `db_transaction` for obtaining the `db` database connection
         which can be used for performing any query
@@ -433,13 +435,21 @@ class Environment(Component, ComponentMa
         return DatabaseManager(self).get_exceptions()
 
     def with_transaction(self, db=None):
-        """Decorator for transaction functions :deprecated:"""
+        """Decorator for transaction functions.
+
+        :deprecated: Use the query and transaction context managers instead.
+                     Will be removed in Trac 1.3.1.
+        """
         return with_transaction(self, db)
 
     def get_read_db(self):
-        """Return a database connection for read purposes :deprecated:
+        """Return a database connection for read purposes.
 
-        See `trac.db.api.get_read_db` for detailed documentation."""
+        See `trac.db.api.get_read_db` for detailed documentation.
+
+        :deprecated: Use :meth:`db_query` instead.
+                     Will be removed in Trac 1.3.1.
+        """
         return DatabaseManager(self).get_connection(readonly=True)
 
     @property
@@ -581,6 +591,25 @@ class Environment(Component, ComponentMa
         # Create the database
         DatabaseManager(self).init_db()
 
+    @lazy
+    def database_version(self):
+        """Returns the current version of the database.
+
+        :since 1.0.2:
+        """
+        return self.get_version()
+
+    @lazy
+    def database_initial_version(self):
+        """Returns the version of the database at the time of creation.
+
+        In practice, for database created before 0.11, this will
+        return `False` which is "older" than any db version number.
+
+        :since 1.0.2:
+        """
+        return self.get_version(initial=True)
+
     def get_version(self, db=None, initial=False):
         """Return the current version of the database.  If the
         optional argument `initial` is set to `True`, the version of
@@ -593,6 +622,11 @@ class Environment(Component, ComponentMa
 
         :since 1.0: deprecation warning: the `db` parameter is no
                     longer used and will be removed in version 1.1.1
+
+        :since 1.0.2: The lazily-evaluated attributes `database_version` and
+                      `database_initial_version` should be used instead. This
+                      method will be renamed to a private method in
+                      release 1.3.1.
         """
         rows = self.db_query("""
                 SELECT value FROM system WHERE name='%sdatabase_version'
@@ -711,6 +745,7 @@ class Environment(Component, ComponentMa
                 participant.upgrade_environment(db)
             # Database schema may have changed, so close all connections
             DatabaseManager(self).shutdown()
+        del self.database_version
         return True
 
     @lazy
@@ -749,7 +784,7 @@ class EnvironmentSetup(Component):
         self._update_sample_config()
 
     def environment_needs_upgrade(self, db):
-        dbver = self.env.get_version()
+        dbver = self.env.database_version
         if dbver == db_default.db_version:
             return False
         elif dbver > db_default.db_version:
@@ -763,7 +798,7 @@ class EnvironmentSetup(Component):
         upgrades/dbN.py, where 'N' is the version number (int).
         """
         cursor = db.cursor()
-        dbver = self.env.get_version()
+        dbver = self.env.database_version
         for i in range(dbver + 1, db_default.db_version + 1):
             name  = 'db%i' % i
             try:
@@ -787,9 +822,8 @@ class EnvironmentSetup(Component):
         if not os.path.isfile(filename):
             return
         config = Configuration(filename)
-        for section, default_options in config.defaults().iteritems():
-            for name, value in default_options.iteritems():
-                config.set(section, name, value)
+        for (section, name), option in Option.get_registry().iteritems():
+            config.set(section, name, option.dumps(option.default))
         try:
             config.save()
             self.log.info("Wrote sample configuration file with the new "

Modified: bloodhound/vendor/trac/current/trac/htdocs/css/admin.css
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/css/admin.css?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/htdocs/css/admin.css (original)
+++ bloodhound/vendor/trac/current/trac/htdocs/css/admin.css Fri Nov 14 11:06:23 2014
@@ -132,4 +132,3 @@ table.trac-pluglist td { padding-left: 1
  padding: 0;
  white-space: nowrap;
 }
-fieldset tr.field th { text-align: right; }

Modified: bloodhound/vendor/trac/current/trac/htdocs/css/report.css
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/css/report.css?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/htdocs/css/report.css (original)
+++ bloodhound/vendor/trac/current/trac/htdocs/css/report.css Fri Nov 14 11:06:23 2014
@@ -25,7 +25,6 @@
 
 .report div.reports { clear: both }
 
-
 .report div.reports h2 {
  /* taken from .wikipage h2 */
  border-bottom: 1px solid #ddd;
@@ -81,8 +80,13 @@ h2.report-result {
 }
 #report-descr { margin: 0 2em; font-size: 90% }
 #report-notfound { margin: 2em; font-size: 110% }
+
+/* Report edit form */
+#content.report.edit form {
+ max-width: 54em;
+}
 #content.report .field { margin: 1em 0; }
-#content.report .field label { padding-bottom: .3em; }
+#content.report .field label { display: block; padding-bottom: .3em; }
 
 #query { clear: right }
 #query fieldset, #query fieldset input, #query fieldset select {
@@ -179,9 +183,9 @@ h2.report-result {
 .tickets tr.color2-even { background: #ffd; border-color: #dd8; color: #880 }
 .tickets tr.color3-odd  { background: #fbfbfb; border-color: #ddd; color: #444 }
 .tickets tr.color3-even { background: #f6f6f6; border-color: #ccc; color: #333 }
-.tickets tr.color4-odd { background: #e7ffff; border-color: #cee; color: #099 }
+.tickets tr.color4-odd  { background: #e7ffff; border-color: #cee; color: #099 }
 .tickets tr.color4-even { background: #dff; border-color: #bee; color: #099 }
-.tickets tr.color5-odd { background: #e7eeff; border-color: #cde; color: #469 }
+.tickets tr.color5-odd  { background: #e7eeff; border-color: #cde; color: #469 }
 .tickets tr.color5-even { background: #dde7ff; border-color: #cde; color: #469 }
 .tickets tr.color6-odd  { background: #f0f0f0; border-color: #ddd; color: #888 }
 .tickets tr.color6-even { background: #f7f7f7; border-color: #ddd; color: #888 }
@@ -207,7 +211,7 @@ table.tickets tbody tr.prio1 { backgroun
 table.tickets tbody tr.even.prio1 { background: #fed; border-color: #e99 }
 table.tickets tbody tr.prio2 { background: #ffb; border-color: #eea }
 table.tickets tbody tr.even.prio2 { background: #ffd; border-color: #dd8 }
-table.tickets tbody tr.prio3  { background: #fbfbfb; border-color: #ddd }
+table.tickets tbody tr.prio3 { background: #fbfbfb; border-color: #ddd }
 table.tickets tbody tr.even.prio3 { background: #f6f6f6; border-color: #ccc }
 table.tickets tbody tr.prio4 { background: #e7ffff; border-color: #cee }
 table.tickets tbody tr.even.prio4 { background: #dff; border-color: #bee }
@@ -216,10 +220,10 @@ table.tickets tbody tr.even.prio5 { back
 table.tickets tbody tr.prio6 { background: #f0f0f0; border-color: #ddd }
 table.tickets tbody tr.even.prio6 { background: #f7f7f7 }
 table.tickets tbody tr.fullrow th {
-  border: none;
-  vertical-align: middle;
-  text-align: center;
-  font-size: 85%;
+ border: none;
+ vertical-align: middle;
+ text-align: center;
+ font-size: 85%;
 }
 table.tickets tbody tr p:first-child { margin-top: 0 }
 table.tickets tbody tr p:last-child { margin-bottom: 0 }
@@ -227,7 +231,7 @@ table.tickets tbody tr p:last-child { ma
 /* Batchmod Form */
 
 #batchmod_form { display: none; }
-#batchmod_form fieldset input#batchmod_submit { font-size: 14px; }
+#batchmod_form fieldset input#batchmod_submit { font-size: 100% }
 #batchmod_form fieldset input[type="button"]{ padding: 0.1em 0.5em; }
 #batchmod_form > fieldset { margin-top: 1.5em }
 #batchmod_form fieldset.collapsed {
@@ -238,10 +242,8 @@ table.tickets tbody tr p:last-child { ma
 .batchmod_property { width: 100%; }
 .batchmod_required:before { content: " * "; }
 #batchmod_form fieldset input,
-#batchmod_form fieldset select,
-.batchmod_property,
-.batchmod_label {
-    font-size: 11px;
+#batchmod_form fieldset select, .batchmod_property, .batchmod_label {
+ font-size: 11px;
 }
 #batchmod_action { margin-top: 0; line-height: 2em; }
 #batchmod_form th {

Modified: bloodhound/vendor/trac/current/trac/htdocs/css/roadmap.css
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/css/roadmap.css?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/htdocs/css/roadmap.css (original)
+++ bloodhound/vendor/trac/current/trac/htdocs/css/roadmap.css Fri Nov 14 11:06:23 2014
@@ -95,6 +95,3 @@ p.percent {
 #edit .field { margin: 0.5em 0 }
 #edit label { padding-left: .2em }
 #edit fieldset { margin-left: 1px; margin-right: 1px }
-#edit textarea#description { margin-left: -1px; margin-right: -1px; padding: 0; width: 100% }
-#edit .wikitoolbar { margin-left: -1px }
-#edit div.trac-resizable { width: 100% }

Modified: bloodhound/vendor/trac/current/trac/htdocs/css/ticket.css
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/css/ticket.css?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/htdocs/css/ticket.css (original)
+++ bloodhound/vendor/trac/current/trac/htdocs/css/ticket.css Fri Nov 14 11:06:23 2014
@@ -8,7 +8,6 @@
 }
 
 #field-description-help { float: right }
-#properties div.trac-resizable, #field-description { width: 100% }
 
 #content.ticket .trac-topnav {
  float: none;
@@ -158,14 +157,7 @@ ul.children > li.child {
 
 /* Comment editor */
 #trac-comment-editor { margin-left: 2em; margin-bottom: 1em }
-#trac-comment-editor div.trac-resizable { width: 100% }
-#trac-comment-editor textarea {
- background: #ffffe0;
- margin-left: -1px;
- margin-right: -1px;
- width: 100%;
-}
-#trac-comment-editor .wikitoolbar { margin-left: -1px }
+#trac-comment-editor textarea { background: #ffffe0; }
 .trac-new { border-left: 0.31em solid #c0f0c0; padding-left: 0.31em; }
 
 .trac-loading {
@@ -208,22 +200,39 @@ button.trac-revert div { display: none; 
 form .field { margin-top: .75em; width: 100% }
 form .field fieldset { margin-left: 1px; margin-right: 1px }
 label[for=comment] { float: right }
-#comment { margin-left: -1px; margin-right: -1px; padding: 0; width: 100% }
-form .field .wikitoolbar { margin-left: -1px }
-form .field div.trac-resizable { width: 100% }
 
 #propertyform { margin-bottom: 2em; }
 #properties { white-space: nowrap; line-height: 160%; padding: .5em }
-#properties table { border-spacing: 0; width: 100%; padding: 0 .5em }
-#properties table th {
+#properties table {
+ border-spacing: 0;
+ padding: 0 .5em;
+ table-layout: fixed;
+ width: 100%;
+}
+#properties table th,
+#properties table col.th {
  padding: .4em;
  text-align: right;
- width: 20%;
  vertical-align: top;
+ white-space: normal;
+ width: 17%;
 }
 #properties table th.col2 { border-left: 1px dotted #d7d7d7 }
-#properties table td { vertical-align: middle; width: 30% }
-#properties table td.fullrow { vertical-align: middle; width: 80% }
+#properties table td,
+#properties table col.td {
+ padding-right: 0.6em;
+ vertical-align: middle;
+ width: 33%
+}
+#properties table td.fullrow { width: 83% }
+#properties table td input[type="text"] {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 100%;
+}
+#properties table td.col1 label,
+#properties table td.col2 label { float: left; margin-right: 0.5em; }
+#properties table td select { max-width: 100% }
 
 #action { line-height: 2em }
 

Modified: bloodhound/vendor/trac/current/trac/htdocs/css/trac.css
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/css/trac.css?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/htdocs/css/trac.css (original)
+++ bloodhound/vendor/trac/current/trac/htdocs/css/trac.css Fri Nov 14 11:06:23 2014
@@ -82,6 +82,11 @@ span:target {
 
 /* Forms */
 input, textarea, select { margin: 2px }
+/* Avoid respect to system font settings for controls on Firefox, #11607 */
+input, select, button {
+ font-family: Arial,Verdana,'Bitstream Vera Sans',Helvetica,sans-serif;
+ font-size: 100%;
+}
 /* Avoid to inherit white-space of its parent element for IE 11, #11376 */
 textarea { white-space: pre-wrap }
 input, select { vertical-align: middle }
@@ -178,6 +183,14 @@ input[type=button].trac-delete:hover,
 input[type=submit].trac-delete:hover {
  color: #e31313;
 }
+textarea.trac-fullwidth, input.trac-fullwidth {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ margin-left: 0;
+ margin-right: 0;
+ width: 100%;
+}
+textarea.trac-fullwidth { padding: 2px; }
 
 /* Header */
 #header hr { display: none }
@@ -239,7 +252,7 @@ input[type=submit].trac-delete:hover {
  outline: 0;
  background: transparent;
  font-family: inherit;
- font-size: inherit;
+ font-size: 100%;
  color: #b00;
  border-bottom: 1px dotted #bbb;
  cursor: pointer;
@@ -564,7 +577,6 @@ table.wiki tbody tr.odd { background-col
 
 .wikitoolbar {
  margin-top: 0.3em;
- margin-left: 2px;
  border: solid #d7d7d7;
  border-width: 1px 1px 1px 0;
  height: 18px;
@@ -595,7 +607,7 @@ table.wiki tbody tr.odd { background-col
 .wikitoolbar a#img { background-position: 0 -128px }
 
 /* Textarea resizer */
-div.trac-resizable { display: table; width: 1px }
+div.trac-resizable { display: table; width: 100% }
 div.trac-resizable > div { display: table-cell }
 div.trac-resizable textarea { display: block; margin-bottom: 0 }
 div.trac-grip {

Modified: bloodhound/vendor/trac/current/trac/htdocs/css/wiki.css
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/css/wiki.css?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/htdocs/css/wiki.css (original)
+++ bloodhound/vendor/trac/current/trac/htdocs/css/wiki.css Fri Nov 14 11:06:23 2014
@@ -50,15 +50,11 @@
 #edit fieldset { margin-left: 1px; margin-right: 1px }
 #edit #text {
  clear: both;
- margin-left: -1px;
- margin-right: -1px;
- padding: 0;
- width: 100%;
  min-height: 10em;
  resize: vertical;
 }
-#edit .wikitoolbar { float: left; margin-left: -1px }
-#edit div.trac-resizable { clear: both; width: 100% }
+#edit .wikitoolbar { float: left }
+#edit div.trac-resizable { clear: both }
 #edit + #info { margin-top: 1em }
 #edit + #attachments { margin-top: 1.5em }
 #changeinfo { padding: .5em }

Modified: bloodhound/vendor/trac/current/trac/htdocs/js/auto_preview.js
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/js/auto_preview.js?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
Binary files - no diff available.

Modified: bloodhound/vendor/trac/current/trac/htdocs/js/wikitoolbar.js
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/htdocs/js/wikitoolbar.js?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
Binary files - no diff available.

Modified: bloodhound/vendor/trac/current/trac/loader.py
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/loader.py?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/loader.py (original)
+++ bloodhound/vendor/trac/current/trac/loader.py Fri Nov 14 11:06:23 2014
@@ -182,7 +182,10 @@ def get_plugin_info(env, include_core=Fa
                 version = (getattr(module, 'version', '') or
                            getattr(module, 'revision', ''))
                 # special handling for "$Rev$" strings
-                version = version.replace('$', '').replace('Rev: ', 'r')
+                if version != '$Rev$':
+                    version = version.replace('$', '').replace('Rev: ', 'r')
+                else:  # keyword hasn't been expanded
+                    version = ''
             plugins[dist.project_name] = {
                 'name': dist.project_name, 'version': version,
                 'path': dist.location, 'plugin_filename': plugin_filename,

Modified: bloodhound/vendor/trac/current/trac/locale/de/LC_MESSAGES/messages.po
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/locale/de/LC_MESSAGES/messages.po?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/locale/de/LC_MESSAGES/messages.po (original)
+++ bloodhound/vendor/trac/current/trac/locale/de/LC_MESSAGES/messages.po Fri Nov 14 11:06:23 2014
@@ -4948,7 +4948,7 @@ msgstr "Repositorys"
 #, python-format
 msgid "You should now run %(resync)s to synchronize Trac with the repository."
 msgstr ""
-"Sie sollten jetzt %(resync)s ausführen, um Trac mit dem Reposiory zu "
+"Sie sollten jetzt %(resync)s ausführen, um Trac mit dem Repository zu "
 "synchronisieren."
 
 #: trac/versioncontrol/admin.py:225

Modified: bloodhound/vendor/trac/current/trac/locale/ja/LC_MESSAGES/messages-js.po
URL: http://svn.apache.org/viewvc/bloodhound/vendor/trac/current/trac/locale/ja/LC_MESSAGES/messages-js.po?rev=1639602&r1=1639601&r2=1639602&view=diff
==============================================================================
--- bloodhound/vendor/trac/current/trac/locale/ja/LC_MESSAGES/messages-js.po (original)
+++ bloodhound/vendor/trac/current/trac/locale/ja/LC_MESSAGES/messages-js.po Fri Nov 14 11:06:23 2014
@@ -1,13 +1,13 @@
 # Japanese translations for Trac.
-# Copyright (C) 2010-2013 Edgewall Software
+# Copyright (C) 2010-2014 Edgewall Software
 # This file is distributed under the same license as the Trac project.
-# Jun Omae <ju...@gmail.com>, 2010-2013.
+# Jun Omae <ju...@gmail.com>, 2010-2014.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: Trac 1.0\n"
+"Project-Id-Version: Trac 1.0.2\n"
 "Report-Msgid-Bugs-To: trac-dev@googlegroups.com\n"
-"POT-Creation-Date: 2013-03-21 22:54+0100\n"
+"POT-Creation-Date: 2014-09-01 12:43+0000\n"
 "PO-Revision-Date: 2010-05-25 18:45+0900\n"
 "Last-Translator: Jun Omae <ju...@gmail.com>\n"
 "Language-Team: ja <LL...@li.org>\n"
@@ -15,7 +15,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 0.9.6dev-r0\n"
+"Generated-By: Babel 0.9.6\n"
 
 #: trac/htdocs/js/blame.js:84
 msgid "(no changeset information)"
@@ -76,7 +76,7 @@ msgstr "$yearå¹´$month"
 
 #. TRANSLATOR: Link that closes the datepicker
 #. TRANSLATOR: Link that closes the timepicker
-#: trac/htdocs/js/jquery-ui-i18n.js:7 trac/htdocs/js/jquery-ui-i18n.js:39
+#: trac/htdocs/js/jquery-ui-i18n.js:7 trac/htdocs/js/jquery-ui-i18n.js:40
 msgid "Done"
 msgstr "閉じる"
 
@@ -101,34 +101,34 @@ msgid "Wk"
 msgstr "週"
 
 #. TRANSLATOR: Heading of the standalone timepicker
-#: trac/htdocs/js/jquery-ui-i18n.js:30
+#: trac/htdocs/js/jquery-ui-i18n.js:31
 msgid "Choose Time"
 msgstr "時間を選択"
 
 #. TRANSLATOR: Time selector label
-#: trac/htdocs/js/jquery-ui-i18n.js:32
+#: trac/htdocs/js/jquery-ui-i18n.js:33
 msgid "Time"
 msgstr "時間"
 
 #. TRANSLATOR: Time labels in the timepicker
-#: trac/htdocs/js/jquery-ui-i18n.js:34
+#: trac/htdocs/js/jquery-ui-i18n.js:35
 msgid "Hour"
 msgstr "時"
 
-#: trac/htdocs/js/jquery-ui-i18n.js:34
+#: trac/htdocs/js/jquery-ui-i18n.js:35
 msgid "Minute"
 msgstr "分"
 
-#: trac/htdocs/js/jquery-ui-i18n.js:34
+#: trac/htdocs/js/jquery-ui-i18n.js:35
 msgid "Second"
 msgstr "秒"
 
-#: trac/htdocs/js/jquery-ui-i18n.js:35
+#: trac/htdocs/js/jquery-ui-i18n.js:36
 msgid "Time Zone"
 msgstr "タイムゾーン"
 
 #. TRANSLATOR: Link to pick the current time in the timepicker
-#: trac/htdocs/js/jquery-ui-i18n.js:37
+#: trac/htdocs/js/jquery-ui-i18n.js:38
 msgid "Now"
 msgstr "現時刻"
 
@@ -169,7 +169,7 @@ msgstr " 追加:"
 msgid "Select ticket %(id)s for modification"
 msgstr "更新対象としてチケット %(id)s を選択する"
 
-#: trac/htdocs/js/query.js:387
+#: trac/htdocs/js/query.js:388
 msgid "Toggle selection of all tickets shown in this group"
 msgstr "このグループに表示しているすべてのチケットに対し、選択を切り替える"
 
@@ -177,39 +177,39 @@ msgstr "このグルーã
 msgid "Link here"
 msgstr "ここにリンクする"
 
-#: trac/htdocs/js/wikitoolbar.js:56
+#: trac/htdocs/js/wikitoolbar.js:59
 msgid "Bold text: '''Example'''"
 msgstr "太字: '''例'''"
 
-#: trac/htdocs/js/wikitoolbar.js:59
+#: trac/htdocs/js/wikitoolbar.js:62
 msgid "Italic text: ''Example''"
 msgstr "斜体: '''例'''"
 
-#: trac/htdocs/js/wikitoolbar.js:62
+#: trac/htdocs/js/wikitoolbar.js:65
 msgid "Heading: == Example =="
 msgstr "ヘッダ: == 例 =="
 
-#: trac/htdocs/js/wikitoolbar.js:65
+#: trac/htdocs/js/wikitoolbar.js:68
 msgid "Link: [http://www.example.com/ Example]"
 msgstr "リンク: [http://www.example.com/ 例]"
 
-#: trac/htdocs/js/wikitoolbar.js:68
+#: trac/htdocs/js/wikitoolbar.js:71
 msgid "Code block: {{{ example }}}"
 msgstr "コードブロック: {{{ 例 }}}"
 
-#: trac/htdocs/js/wikitoolbar.js:71
+#: trac/htdocs/js/wikitoolbar.js:74
 msgid "Horizontal rule: ----"
 msgstr "横罫線: ----"
 
-#: trac/htdocs/js/wikitoolbar.js:74
+#: trac/htdocs/js/wikitoolbar.js:77
 msgid "New paragraph"
 msgstr "段落"
 
-#: trac/htdocs/js/wikitoolbar.js:77
+#: trac/htdocs/js/wikitoolbar.js:80
 msgid "Line break: [[BR]]"
 msgstr "改行: [[BR]]"
 
-#: trac/htdocs/js/wikitoolbar.js:80
+#: trac/htdocs/js/wikitoolbar.js:83
 msgid "Image: [[Image()]]"
 msgstr "画像: [[Image()]]"