You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by ma...@apache.org on 2013/08/20 11:39:55 UTC

svn commit: r1515751 [1/2] - in /bloodhound/branches/bep_0010_ticket_numbering: ./ bloodhound_dashboard/ bloodhound_dashboard/bhdashboard/ bloodhound_dashboard/bhdashboard/htdocs/css/ bloodhound_dashboard/bhdashboard/htdocs/js/ bloodhound_dashboard/bhd...

Author: matevz
Date: Tue Aug 20 09:39:51 2013
New Revision: 1515751

URL: http://svn.apache.org/r1515751
Log:
sync merge from trunk

Added:
    bloodhound/branches/bep_0010_ticket_numbering/.gitignore
      - copied unchanged from r1515737, bloodhound/trunk/.gitignore
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/batch.py
      - copied unchanged from r1515737, bloodhound/trunk/bloodhound_multiproduct/multiproduct/ticket/batch.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/templates/relations_manage.html
      - copied unchanged from r1515737, bloodhound/trunk/bloodhound_relations/bhrelations/templates/relations_manage.html
Removed:
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/templates/manage.html
Modified:
    bloodhound/branches/bep_0010_ticket_numbering/   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/RELEASE_NOTES
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/admin.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/htdocs/css/docs.css   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/htdocs/css/roadmap.css   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap.js   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/model.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/tests/widgets/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/tests/widgets/timeline.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/product.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/query.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/ticket.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/setup.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/cache.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/config.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/core.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/dbcursor.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/env.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/hooks.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/perm.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/templates/repository_links.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/query.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/util.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/versioncontrol.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/setup.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/console-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/console.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/product_admin.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/attachment.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/config.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/core.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/cursor.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/mysql.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/postgres.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/util.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/env.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/hooks.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/patch.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/pygments.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/perm.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-attachment-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-comment-link-tests.short.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-comment-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-milestone-link-tests.short.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-milestone-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.short.txt   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.txt   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query2-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-report-link-tests.short.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-report-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-search-link-tests.short.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-search-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-ticket-jira-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-ticket-link-tests.short.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-ticket-link-tests.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/resource.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/batch.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/conversion.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/model.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/notification.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/query.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/report.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/roadmap.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/ticket/wikisyntax.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/upgrade.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/upgrade_postgres.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/versioncontrol/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/versioncontrol/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/versioncontrol/cache.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/versioncontrol/svn_authz.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/web/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/web/chrome.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/web/session.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/web/wikisyntax.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/web_ui.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/wiki/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/wiki/formatter.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/wiki/macros.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/wiki/model.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/wiki/wikisyntax.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/wikisyntax.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/api.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/db_default.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/model.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/notification.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/templates/relation_notify_email.txt   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/base.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/mocks.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/notification.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/validation.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/tests/web_ui.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/utils.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/validation.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/web_ui.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/widgets/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/bhrelations/widgets/relations.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_relations/setup.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/admin.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/query_parser.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/query_suggestion.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/search_resources/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/search_resources/base.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/search_resources/changeset_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/search_resources/milestone_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/search_resources/ticket_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/search_resources/wiki_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/security.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/templates/bhsearch.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/templates/opensearch.xml   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/api.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/base.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/index_with_whoosh.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/query_parser.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/query_suggestion.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/real_index_view.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/search_resources/__init__.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/search_resources/base.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/security.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/web_ui.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/tests/whoosh_backend.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/utils.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/web_ui.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/whoosh_backend.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/bhsearch/whoosh_fixes.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_search/setup.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/htdocs/bloodhound.css
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_account_details.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_accountsconfig.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_accountsnotification.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_basics.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_logging.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_plugins.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_products.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_admin_users.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_browser.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_dir_entries.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_dirlist_thead.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_login.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_milestone_view.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_path_general.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_path_links.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_prefs_account.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_register.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_repository_index.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_reset_password.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_revisionlog.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_sortable_th.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_ticket.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_ticket_box.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_ticket_change.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_user_table.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_verify_email.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/templates/bh_wiki_view.html
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/bhtheme/theme.py
    bloodhound/branches/bep_0010_ticket_numbering/bloodhound_theme/setup.py
    bloodhound/branches/bep_0010_ticket_numbering/doc/html-templates/milestone.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/doc/html-templates/product.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/doc/html-templates/version.html   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/installer/bloodhound_setup.py   (contents, props changed)
    bloodhound/branches/bep_0010_ticket_numbering/installer/requirements-dev.txt
    bloodhound/branches/bep_0010_ticket_numbering/installer/requirements.txt
    bloodhound/branches/bep_0010_ticket_numbering/trac/   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/trac/trac/hooks.py   (props changed)
    bloodhound/branches/bep_0010_ticket_numbering/trac/trac/ticket/tests/query.py
    bloodhound/branches/bep_0010_ticket_numbering/trac/trac/ticket/tests/wikisyntax.py

Propchange: bloodhound/branches/bep_0010_ticket_numbering/
------------------------------------------------------------------------------
--- svn:auto-props (added)
+++ svn:auto-props Tue Aug 20 09:39:51 2013
@@ -0,0 +1,5 @@
+*.html = svn:eol-style=native
+*.js = svn:eol-style=native
+*.css = svn:eol-style=native
+*.py = svn:eol-style=native
+*.xml = svn:eol-style=native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/
------------------------------------------------------------------------------
  Merged /bloodhound/trunk:r1506462-1515737

Modified: bloodhound/branches/bep_0010_ticket_numbering/RELEASE_NOTES
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/RELEASE_NOTES?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/RELEASE_NOTES (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/RELEASE_NOTES Tue Aug 20 09:39:51 2013
@@ -1,3 +1,11 @@
+0.7
+ * Duplicate ticket relation is integrated to the ticket workflow.
+ * Several fixes for multiproduct installations with products that map to subdomains.
+ * Numerous important fixes and minor enhancements.
+
+ * Not fixed for this release:
+   * No major outstanding issues
+
 0.6
 
  * Added support for multiple products.

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/admin.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/admin.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/admin.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/admin.py Tue Aug 20 09:39:51 2013
@@ -24,6 +24,7 @@ r"""Project dashboard for Apache(TM) Blo
 Administration commands for Bloodhound Dashboard.
 """
 import json
+import re
 from sys import stdout
 
 from trac.admin.api import IAdminCommandProvider, AdminCommandError
@@ -116,21 +117,24 @@ class BloodhoundAdmin(Component):
                     redirection.text = _('See [wiki:"%(name)s"].', name=new_name)
                     comment = 'Bloodhound guide update'
                     redirection.save('bloodhound', comment, '0.0.0.0')
-        self._do_wiki_rename_links('TracGuideToc', 'UserGuideToc')
+        self._do_wiki_rename_links('[[TracGuideToc]]', '[[UserGuideToc]]')
 
     def _do_wiki_rename_links(self, old_name, new_name):
-        import re
+        if old_name.startswith('[[') and old_name.endswith(']]'):
+            pattern = r'%s'
+        else:
+            pattern = r'\b%s\b'
         with self.env.db_transaction as db:
             pages = db("""SELECT name, text FROM wiki
                           WHERE text %s
                        """ % db.like(),
                        ('%' + db.like_escape(old_name) + '%',))
             for name, text in pages:
-                res = db("""UPDATE wiki
-                            SET text=%s
-                            WHERE name=%s
-                            """, 
-                         (re.sub(r'(?!\[\[)\b%s\b(?!\]\])' % old_name, new_name, text), name))
+                db("""UPDATE wiki
+                      SET text=%s
+                      WHERE name=%s
+                    """, (re.sub(pattern % re.escape(old_name),
+                                 new_name, text), name))
 
     def _get_tdump(self, db, table, fields):
         """Dumps all the data from a table for a known set of fields"""

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/htdocs/css/docs.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/htdocs/css/roadmap.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/htdocs/js/bootstrap.js
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_btnbar_full.html Tue Aug 20 09:39:51 2013
@@ -32,7 +32,7 @@
     <xi:include href="bs_btnbar.html" />
     <div id="ft" class="row">
       <div id="help" class="span8">
-        <strong>Note:</strong> See 
+        <span class="label label-info">Note:</span> See
         <a href="${href.wiki('BloodhoundDashboard')}">BloodhoundDashboard</a>
         for help on using the dashboard.
       </div>

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/layouts/templates/bs_grid_full.html Tue Aug 20 09:39:51 2013
@@ -34,7 +34,7 @@
     <xi:include href="bs_grid.html" />
     <div id="ft" class="row">
       <div id="help" class="span8">
-        <strong>Note:</strong> See 
+        <span class="label label-info">Note:</span> See
         <a href="${href.wiki('BloodhoundDashboard')}">BloodhoundDashboard</a>
         for help on using the dashboard.
       </div>

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/model.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/tests/widgets/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/tests/widgets/timeline.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/product.py
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/query.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/query.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/query.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/query.py Tue Aug 20 09:39:51 2013
@@ -42,7 +42,6 @@ from bhdashboard.util import WidgetBase,
                               trac_tags
 
 from multiproduct.env import ProductEnvironment
-from multiproduct.ticket.query import ProductQueryModule
 
 class TicketQueryWidget(WidgetBase):
     """Display tickets matching a TracQuery using a grid
@@ -94,12 +93,11 @@ class TicketQueryWidget(WidgetBase):
             more_link_href = req.href('query', args)
             args.update({'page' : page, 'max': maxrows})
 
-            qrymdl = self.env[QueryModule
-                if isinstance(self.env, ProductEnvironment)
-                else ProductQueryModule]
+            qrymdl = self.env[QueryModule]
             if qrymdl is None :
                 raise TracError('Query module not available (disabled?)')
-            data = qrymdl.process_request(fakereq)[1]
+
+            data = qrymdl.process_request(fakereq, self.env)[1]
         except TracError, exc:
             if data is not None:
                 exc.title = data.get('title', 'TracQuery')

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/templates/widget_product.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/templates/widget_relations.html
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/ticket.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/ticket.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/ticket.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/bhdashboard/widgets/ticket.py Tue Aug 20 09:39:51 2013
@@ -34,6 +34,7 @@ from trac.ticket.api import TicketSystem
 from trac.ticket.query import Query
 from trac.ticket.roadmap import apply_ticket_permissions, get_ticket_stats, \
                             ITicketGroupStatsProvider, RoadmapModule
+from trac.util.text import unicode_urlencode
 from trac.util.translation import _
 from trac.web.chrome import add_stylesheet
 
@@ -217,7 +218,7 @@ class TicketFieldValuesWidget(WidgetBase
 
             query_href = query.get_href(req.href)
             item_link= lambda item: query_href + \
-                    '&' + urlencode([(fieldnm, item[0])])
+                    '&' + unicode_urlencode([(fieldnm, item[0])])
 
         if fieldnm in self.DASH_ITEM_HREF_MAP:
             def dash_item_link(item):

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/setup.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/setup.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_dashboard/setup.py Tue Aug 20 09:39:51 2013
@@ -36,6 +36,7 @@ versions = [
     (0, 5, 0),
     (0, 6, 0),
     (0, 7, 0),
+    (0, 8, 0),
     ]
     
 latest = '.'.join(str(x) for x in versions[-1])

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/cache.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/config.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/core.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/dbcursor.py
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/env.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/env.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/env.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/env.py Tue Aug 20 09:39:51 2013
@@ -1,3 +1,5 @@
+# -*- coding: UTF-8 -*-
+#
 #  Licensed to the Apache Software Foundation (ASF) under one
 #  or more contributor license agreements.  See the NOTICE file
 #  distributed with this work for additional information
@@ -47,10 +49,12 @@ class ComponentEnvironmentContext(object
     def __init__(self, env, component):
         self._env = env
         self._component = component
+
     def __enter__(self):
         self._old_env = self._component.env
         self._env.component_activated(self._component)
         return self
+
     def __exit__(self, type, value, traceback):
         self._old_env.component_activated(self._component)
 
@@ -262,6 +266,7 @@ class Environment(trac.env.Environment):
 # replace trac.env.Environment with Environment
 trac.env.Environment = Environment
 
+
 # this must follow the monkey patch (trac.env.Environment) above, otherwise
 # trac.test.EnvironmentStub will not be correct as the class will derive from
 # not replaced trac.env.Environment
@@ -333,6 +338,7 @@ class EnvironmentStub(trac.test.Environm
 # replace trac.test.EnvironmentStub
 trac.test.EnvironmentStub = EnvironmentStub
 
+
 class ProductEnvironment(Component, ComponentManager):
     """Bloodhound product-aware environment manager.
 
@@ -342,7 +348,7 @@ class ProductEnvironment(Component, Comp
 
     Product environments contain among other things:
 
-    * configuration key-value pairs stored in the database, 
+    * configuration key-value pairs stored in the database,
     * product-aware clones of the wiki and ticket attachments files,
 
     Product environments do not have:
@@ -536,7 +542,6 @@ class ProductEnvironment(Component, Comp
         self.parent = env
         self.product = product
         self.systeminfo = []
-        self._href = self._abs_href = None
 
         self.setup_config()
 
@@ -852,44 +857,45 @@ class ProductEnvironment(Component, Comp
     @lazy
     def href(self):
         """The application root path"""
-        if not self._href:
-            self._href = Href(urlsplit(self.abs_href.base)[2])
-        return self._href
+        return Href(urlsplit(self.abs_href.base).path)
 
     @lazy
     def abs_href(self):
         """The application URL"""
-        if not self._abs_href:
-            if not self.base_url:
-                urlpattern = MultiProductSystem(self.parent).product_base_url
-                if not urlpattern:
-                    self.log.warn("product_base_url option not set in "
-                                  "configuration, generated links may be "
-                                  "incorrect")
-                    urlpattern = 'products/$(prefix)s'
-                envname = os.path.basename(self.parent.path)
-                prefix = unicode_quote(self.product.prefix, safe="")
-                name = unicode_quote(self.product.name, safe="")
-                url = urlpattern.replace('$(', '%(') \
-                                .replace('%(envname)s', envname) \
-                                .replace('%(prefix)s', prefix) \
-                                .replace('%(name)s', name)
-                if urlsplit(url).netloc:
-                    #  Absolute URLs
-                    self._abs_href = Href(url)
-                else:
-                    # Relative URLs
-                    parent_href = Href(self.parent.abs_href(),
-                                       path_safe="/!~*'()%",
-                                       query_safe="!~*'()%")
-                    self._abs_href = Href(parent_href(url))
+        if not self.base_url:
+            urlpattern = MultiProductSystem(self.parent).product_base_url
+            if not urlpattern:
+                self.log.warn("product_base_url option not set in "
+                              "configuration, generated links may be "
+                              "incorrect")
+                urlpattern = 'products/$(prefix)s'
+            envname = os.path.basename(self.parent.path)
+            prefix = unicode_quote(self.product.prefix, safe="")
+            name = unicode_quote(self.product.name, safe="")
+            url = urlpattern.replace('$(', '%(') \
+                            .replace('%(envname)s', envname) \
+                            .replace('%(prefix)s', prefix) \
+                            .replace('%(name)s', name)
+            if urlsplit(url).netloc:
+                #  Absolute URLs
+                _abs_href = Href(url)
             else:
-                self._abs_href = Href(self.base_url)
-        return self._abs_href
+                # Relative URLs
+                parent_href = Href(self.parent.abs_href(),
+                                   path_safe="/!~*'()%",
+                                   query_safe="!~*'()%")
+                _abs_href = Href(parent_href(url))
+        else:
+            _abs_href = Href(self.base_url)
+        return _abs_href
 
     # Multi-product API extensions
 
     @classmethod
+    def lookup_global_env(cls, env):
+        return env.parent if isinstance(env, ProductEnvironment) else env
+
+    @classmethod
     def lookup_env(cls, env, prefix=None, name=None):
         """Instantiate environment according to product prefix or name
 

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/env.py
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/hooks.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/hooks.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/hooks.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/hooks.py Tue Aug 20 09:39:51 2013
@@ -20,6 +20,8 @@
 import multiproduct.env
 import multiproduct.dbcursor
 import multiproduct.versioncontrol
+import multiproduct.ticket.query
+import multiproduct.ticket.batch
 
 import re
 
@@ -31,13 +33,15 @@ from trac.web.main import RequestWithSes
 
 PRODUCT_RE = re.compile(r'^/products(?:/(?P<pid>[^/]*)(?P<pathinfo>.*))?')
 REDIRECT_DEFAULT_RE = \
-    re.compile(r'^/(?P<section>milestone|roadmap|query|report|newticket|'
+    re.compile(r'^/(?P<section>milestone|roadmap|report|newticket|'
                r'ticket|qct|timeline|diff|batchmodify|search|'
                r'(raw-|zip-)?attachment/(ticket|milestone))(?P<pathinfo>.*)')
 
 
 class MultiProductEnvironmentFactory(EnvironmentFactoryBase):
     def open_environment(self, environ, env_path, global_env, use_cache=False):
+        environ.setdefault('SCRIPT_NAME', '')  # bh:ticket:594
+
         env = pid = None
         path_info = environ.get('PATH_INFO')
         if not path_info:

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/hooks.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/perm.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/templates/repository_links.html
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/query.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/query.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/query.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/query.py Tue Aug 20 09:39:51 2013
@@ -20,6 +20,8 @@
 
 from __future__ import with_statement
 
+import re
+
 from itertools import groupby
 from math import ceil
 from datetime import datetime, timedelta
@@ -52,6 +54,9 @@ class ProductQuery(Query):
     """
     
     def _count(self, sql, args):
+        if isinstance(self.env, ProductEnvironment):
+            return super(ProductQuery, self)._count(sql, args)
+
         cnt = self.env.db_direct_query("SELECT COUNT(*) FROM (%s) AS x"
                                 % sql, args)[0][0]
         # "AS x" is needed for MySQL ("Subqueries in the FROM Clause")
@@ -72,6 +77,13 @@ class ProductQuery(Query):
         href = resolve_product_href(env, self.env)
         return href.ticket(tid)
 
+    def get_href(self, href, id=None, order=None, desc=None, format=None,
+                 max=None, page=None):
+        from multiproduct.hooks import ProductizedHref
+        return super(ProductQuery, self).get_href(
+            ProductizedHref(href, self.env.href.base), id, order, desc,
+            format, max, page)
+
     def execute(self, req=None, db=None, cached_ids=None, authname=None,
                 tzinfo=None, href=None, locale=None):
         """Retrieve the list of matching tickets.
@@ -88,6 +100,8 @@ class ProductQuery(Query):
             sql, args = self.get_sql(req, cached_ids, authname, tzinfo, locale)
             if sql.startswith('SELECT ') and not sql.startswith('SELECT DISTINCT '):
                 sql = 'SELECT DISTINCT * FROM (' + sql + ') AS subquery'
+            if isinstance(self.env, ProductEnvironment):
+                sql = sql + """ WHERE product='%s'""" % (self.env.product.prefix, )
             self.num_items = self._count(sql, args)
 
             if self.num_items <= self.max:
@@ -122,12 +136,8 @@ class ProductQuery(Query):
                         val = val or 'anonymous'
                     elif name == 'id':
                         val = int(val)
-                        if not isinstance(self.env, ProductEnvironment):
-                            # global -> retrieve ProductizedHref()
-                            result['href'] = self._get_ticket_href(
-                                row[product_idx], val)
-                        elif href is not None:
-                            result['href'] = href.ticket(val)
+                        result['href'] = self._get_ticket_href(
+                            row[product_idx], val)
                     elif name in self.time_fields:
                         val = from_utimestamp(val)
                     elif field and field['type'] == 'checkbox':
@@ -142,184 +152,68 @@ class ProductQuery(Query):
             cursor.close()
             return results
 
+import trac.ticket.query
+trac.ticket.query.Query = ProductQuery
+trac.ticket.Query = ProductQuery
 
-class ProductQueryModule(QueryModule):
-    def process_request(self, req):
-        req.perm.assert_permission('TICKET_VIEW')
-
-        constraints = self._get_constraints(req)
-        args = req.args
-        if not constraints and not 'order' in req.args:
-            # If no constraints are given in the URL, use the default ones.
-            if req.authname and req.authname != 'anonymous':
-                qstring = self.default_query
-                user = req.authname
-            else:
-                email = req.session.get('email')
-                name = req.session.get('name')
-                qstring = self.default_anonymous_query
-                user = email or name or None
-
-            self.log.debug('QueryModule: Using default query: %s', str(qstring))
-            if qstring.startswith('?'):
-                arg_list = parse_arg_list(qstring[1:])
-                args = arg_list_to_args(arg_list)
-                constraints = self._get_constraints(arg_list=arg_list)
-            else:
-                query = ProductQuery.from_string(self.env, qstring)
-                args = {'order': query.order, 'group': query.group,
-                        'col': query.cols, 'max': query.max}
-                if query.desc:
-                    args['desc'] = '1'
-                if query.groupdesc:
-                    args['groupdesc'] = '1'
-                constraints = query.constraints
-
-            # Substitute $USER, or ensure no field constraints that depend
-            # on $USER are used if we have no username.
-            for clause in constraints:
-                for field, vals in clause.items():
-                    for (i, val) in enumerate(vals):
-                        if user:
-                            vals[i] = val.replace('$USER', user)
-                        elif val.endswith('$USER'):
-                            del clause[field]
-                            break
-
-        cols = args.get('col')
-        if isinstance(cols, basestring):
-            cols = [cols]
-        # Since we don't show 'id' as an option to the user,
-        # we need to re-insert it here.
-        if cols and 'id' not in cols:
-            cols.insert(0, 'id')
-        rows = args.get('row', [])
-        if isinstance(rows, basestring):
-            rows = [rows]
-        format = req.args.get('format')
-        max = args.get('max')
-        if max is None and format in ('csv', 'tab'):
-            max = 0 # unlimited unless specified explicitly
-        query = ProductQuery(self.env, req.args.get('report'),
-                      constraints, cols, args.get('order'),
-                      'desc' in args, args.get('group'),
-                      'groupdesc' in args, 'verbose' in args,
-                      rows,
-                      args.get('page'),
-                      max)
-
-        if 'update' in req.args:
-            # Reset session vars
-            for var in ('query_constraints', 'query_time', 'query_tickets'):
-                if var in req.session:
-                    del req.session[var]
-            req.redirect(query.get_href(req.href))
-
-        # Add registered converters
-        for conversion in Mimeview(self.env).get_supported_conversions(
-                                             'trac.ticket.Query'):
-            add_link(req, 'alternate',
-                     query.get_href(req.href, format=conversion[0]),
-                     conversion[1], conversion[4], conversion[0])
-
-        if format:
-            filename = 'query' if format != 'rss' else None
-            Mimeview(self.env).send_converted(req, 'trac.ticket.Query', query,
-                                              format, filename=filename)
-
-        return self.display_html(req, query)
-
-    def display_html(self, req, query):
-        # The most recent query is stored in the user session;
-        orig_list = None
-        orig_time = datetime.now(utc)
-        query_time = int(req.session.get('query_time', 0))
-        query_time = datetime.fromtimestamp(query_time, utc)
-        query_constraints = unicode(query.constraints)
-        try:
-            if query_constraints != req.session.get('query_constraints') \
-                    or query_time < orig_time - timedelta(hours=1):
-                tickets = query.execute(req)
-                # New or outdated query, (re-)initialize session vars
-                req.session['query_constraints'] = query_constraints
-                req.session['query_tickets'] = ' '.join([str(t['id'])
-                                                         for t in tickets])
-            else:
-                orig_list = [int(id) for id
-                             in req.session.get('query_tickets', '').split()]
-                tickets = query.execute(req, cached_ids=orig_list)
-                orig_time = query_time
-        except QueryValueError, e:
-            tickets = []
-            for error in e.errors:
-                add_warning(req, error)
-
-        context = web_context(req, 'query')
-        owner_field = [f for f in query.fields if f['name'] == 'owner']
-        if owner_field:
-            TicketSystem(self.env).eventually_restrict_owner(owner_field[0])
-        data = query.template_data(context, tickets, orig_list, orig_time, req)
-
-        req.session['query_href'] = query.get_href(context.href)
-        req.session['query_time'] = to_timestamp(orig_time)
-        req.session['query_tickets'] = ' '.join([str(t['id'])
-                                                 for t in tickets])
-        title = _('Custom Query')
-
-        # Only interact with the report module if it is actually enabled.
-        #
-        # Note that with saved custom queries, there will be some convergence
-        # between the report module and the query module.
-        from trac.ticket.report import ReportModule
-        if 'REPORT_VIEW' in req.perm and \
-               self.env.is_component_enabled(ReportModule):
-            data['report_href'] = req.href.report()
-            add_ctxtnav(req, _('Available Reports'), req.href.report())
-            add_ctxtnav(req, _('Custom Query'), req.href.query())
-            if query.id:
-                for title, description in self.env.db_query("""
-                        SELECT title, description FROM report WHERE id=%s
-                        """, (query.id,)):
-                    data['report_resource'] = Resource('report', query.id)
-                    data['description'] = description
-        else:
-            data['report_href'] = None
 
-        # Only interact with the batch modify module it it is enabled
-        # TODO: fix this for multiproduct
-        """
-        from trac.ticket.batch import BatchModifyModule
-        if 'TICKET_BATCH_MODIFY' in req.perm and \
-                self.env.is_component_enabled(BatchModifyModule):
-            self.env[BatchModifyModule].add_template_data(req, data, tickets)
-        """
-
-        data.setdefault('report', None)
-        data.setdefault('description', None)
-        data['title'] = title
-
-        data['all_columns'] = query.get_all_columns()
-        # Don't allow the user to remove the id column
-        data['all_columns'].remove('id')
-        data['all_textareas'] = query.get_all_textareas()
-
-        properties = dict((name, dict((key, field[key])
-                                      for key in ('type', 'label', 'options',
-                                                  'optgroups')
-                                      if key in field))
-                          for name, field in data['fields'].iteritems())
-        add_script_data(req, properties=properties, modes=data['modes'])
-
-        add_stylesheet(req, 'common/css/report.css')
-        Chrome(self.env).add_jquery_ui(req)
-        add_script(req, 'common/js/query.js')
+class ProductQueryModule(QueryModule):
+    def process_request(self, req, env=None):
+        tmpenv = self.env
+        if isinstance(self.env, ProductEnvironment) and env is not None:
+            self.env = env
+        result = super(ProductQueryModule, self).process_request(req)
+        self.env = tmpenv
+        return result
 
-        return 'query.html', data, None
+trac.ticket.query.QueryModule = ProductQueryModule
+trac.ticket.QueryModule = ProductQueryModule
 
 
 class ProductTicketQueryMacro(TicketQueryMacro):
     """TracQuery macro retrieving results across product boundaries. 
     """
+    @staticmethod
+    def parse_args(content):
+        """Parse macro arguments and translate them to a query string."""
+        clauses = [{}]
+        argv = []
+        kwargs = {}
+        for arg in TicketQueryMacro._comma_splitter.split(content):
+            arg = arg.replace(r'\,', ',')
+            m = re.match(r'\s*[^=]+=', arg)
+            if m:
+                kw = arg[:m.end() - 1].strip()
+                value = arg[m.end():]
+                if kw in ('order', 'max', 'format', 'col', 'product'):
+                    kwargs[kw] = value
+                else:
+                    clauses[-1][kw] = value
+            elif arg.strip() == 'or':
+                clauses.append({})
+            else:
+                argv.append(arg)
+        clauses = filter(None, clauses)
+
+        if len(argv) > 0 and not 'format' in kwargs: # 0.10 compatibility hack
+            kwargs['format'] = argv[0]
+        if 'order' not in kwargs:
+            kwargs['order'] = 'id'
+        if 'max' not in kwargs:
+            kwargs['max'] = '0' # unlimited by default
+
+        format = kwargs.pop('format', 'list').strip().lower()
+        if format in ('list', 'compact'): # we need 'status' and 'summary'
+            if 'col' in kwargs:
+                kwargs['col'] = 'status|summary|' + kwargs['col']
+            else:
+                kwargs['col'] = 'status|summary'
+
+        query_string = '&or&'.join('&'.join('%s=%s' % item
+                                            for item in clause.iteritems())
+                                   for clause in clauses)
+        return query_string, kwargs, format
+
     def expand_macro(self, formatter, name, content):
         req = formatter.req
         query_string, kwargs, format = self.parse_args(content)
@@ -327,7 +221,9 @@ class ProductTicketQueryMacro(TicketQuer
             query_string += '&'
         query_string += '&'.join('%s=%s' % item
                                  for item in kwargs.iteritems())
-        query = ProductQuery.from_string(self.env, query_string)
+
+        env = ProductEnvironment.lookup_global_env(self.env)
+        query = ProductQuery.from_string(env, query_string)
 
         if format == 'count':
             cnt = query.count(req)
@@ -342,7 +238,7 @@ class ProductTicketQueryMacro(TicketQuer
 
             add_stylesheet(req, 'common/css/report.css')
 
-            return Chrome(self.env).render_template(
+            return Chrome(env).render_template(
                 req, 'query_results.html', data, None, fragment=True)
 
         if format == 'progress':
@@ -354,7 +250,7 @@ class ProductTicketQueryMacro(TicketQuer
             add_stylesheet(req, 'common/css/roadmap.css')
 
             def query_href(extra_args, group_value = None):
-                q = Query.from_string(self.env, query_string)
+                q = ProductQuery.from_string(env, query_string)
                 if q.group:
                     extra_args[q.group] = group_value
                     q.group = None
@@ -363,9 +259,9 @@ class ProductTicketQueryMacro(TicketQuer
                 if not q.constraints:
                     q.constraints.append(extra_args)
                 return q.get_href(formatter.context)
-            chrome = Chrome(self.env)
-            tickets = apply_ticket_permissions(self.env, req, tickets)
-            stats_provider = RoadmapModule(self.env).stats_provider
+            chrome = Chrome(env)
+            tickets = apply_ticket_permissions(env, req, tickets)
+            stats_provider = RoadmapModule(env).stats_provider
             by = query.group
             if not by:
                 stat = get_ticket_stats(stats_provider, tickets)
@@ -393,7 +289,7 @@ class ProductTicketQueryMacro(TicketQuer
                     'legend': False,
                 }
 
-            groups = grouped_stats_data(self.env, stats_provider, tickets, by,
+            groups = grouped_stats_data(env, stats_provider, tickets, by,
                                         per_group_stats_data)
             data = {
                 'groups': groups, 'grouped_by': by,
@@ -438,7 +334,7 @@ class ProductTicketQueryMacro(TicketQuer
         def ticket_groups():
             groups = []
             for v, g in groupby(tickets, lambda t: t[query.group]):
-                q = Query.from_string(self.env, query_string)
+                q = ProductQuery.from_string(env, query_string)
                 # produce the hint for the group
                 q.group = q.groupdesc = None
                 order = q.order

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/ticket/query.py
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/util.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/util.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/util.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/util.py Tue Aug 20 09:39:51 2013
@@ -1,154 +1,154 @@
-
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing,
-#  software distributed under the License is distributed on an
-#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#  KIND, either express or implied.  See the License for the
-#  specific language governing permissions and limitations
-#  under the License.
-
-"""Bloodhound multiproduct utility APIs"""
-
-from genshi.builder import tag
-
-import trac.db.api
-from trac.util.text import unquote_label
-from trac.wiki.formatter import LinkFormatter
-from trac.core import Component, ComponentMeta
-
-#----------------------------
-# Component replacement base
-#----------------------------
-
-class ReplacementComponentMeta(ComponentMeta):
-    """Component replacement meta class"""
-    def __new__(mcs, name, bases, d):
-        if bases[0] != Component:
-            bases = bases[1:]
-            base_class = bases[0]
-
-            # undo what has been done by ComponentMeta.__new___ for the
-            # replacement component base class
-
-            # remove implemented interfaces from registry for the base class
-            for itf in base_class._implements:
-                ComponentMeta._registry[itf] = filter(lambda c: c != base_class,
-                                                      ComponentMeta._registry[itf])
-
-            # remove base class from components list
-            ComponentMeta._components = filter(lambda c: c != base_class,
-                                               ComponentMeta._components)
-
-            base_class._implements = []
-            base_class.abstract = True
-
-        return ComponentMeta.__new__(mcs, name, bases, d)
-
-class ReplacementComponent(Component):
-    """Base class for components that replace existing trac
-    implementations"""
-    __metaclass__ = ReplacementComponentMeta
-
-#--------------------------
-# Custom wiki formatters
-#--------------------------
-
-class EmbeddedLinkFormatter(LinkFormatter):
-    """Format the inner TracLinks expression corresponding to resources 
-    in compound links e.g. product:PREFIX:ticket:1 , global:ticket:1
-    """
-
-    def __init__(self, env, context, parent_match=None):
-        """Extend initializer signature to accept parent match
-        
-        @param parent_match: mapping object containing the following keys
-                        - ns : namespace of parent resolver
-                        - target : target supplied in to parent resolver
-                        - label: label supplied in to parent resolver
-                        - fullmatch : parent regex match (optional)
-        """
-        super(EmbeddedLinkFormatter, self).__init__(env, context)
-        self.parent_match = parent_match
-        self.auto_quote = False
-
-    def match(self, wikitext):
-        if self.auto_quote:
-            parts = tuple(wikitext.split(':', 1))
-            if len(parts) == 2:
-                if parts[1]:
-                    _wikitext = '%s:"%s"' % parts
-                else:
-                    _wikitext = '[%s:]' % parts[:1]
-            else:
-                _wikitext = wikitext
-        return super(EmbeddedLinkFormatter, self).match(_wikitext)
-
-    @staticmethod
-    def enhance_link(link):
-        return link
-
-    def handle_match(self, fullmatch):
-        if self.parent_match is None:
-            return super(EmbeddedLinkFormatter, self).handle_match(fullmatch)
-
-        for itype, match in fullmatch.groupdict().items():
-            if match and not itype in self.wikiparser.helper_patterns:
-                # Check for preceding escape character '!'
-                if match[0] == '!':
-                    # Erroneous expression. Nested link would be escaped 
-                    return tag.a(self.parent_match['label'], class_='missing')
-                if itype in self.wikiparser.external_handlers:
-                    #TODO: Important! Add product prefix in label (when needed?)
-                    external_handler = self.wikiparser.external_handlers[itype]
-                    link = external_handler(self, match, fullmatch)
-                else:
-                    internal_handler = getattr(self, '_%s_formatter' % itype)
-                    link = internal_handler(match, fullmatch)
-                return self.enhance_link(link)
-
-    # Overridden formatter methods
-    # TODO : Override more if necessary
-    def _shref_formatter(self, match, fullmatch):
-        if self.parent_match is None:
-            return super(EmbeddedLinkFormatter, self)._shref_formatter(
-                    match, fullmatch)
-        ns = fullmatch.group('sns')
-        target = unquote_label(fullmatch.group('stgt'))
-        label = (self.parent_match['label']
-                 if self.parent_match['label'] != self.parent_match['target']
-                 else target)
-        return self._make_link(ns, target, match, label, fullmatch)
-
-    def _lhref_formatter(self, match, fullmatch):
-        if self.parent_match is None:
-            return super(EmbeddedLinkFormatter, self)._lhref_formatter(
-                    match, fullmatch)
-        rel = fullmatch.group('rel')
-        ns = fullmatch.group('lns')
-        target = unquote_label(fullmatch.group('ltgt'))
-        label = (self.parent_match['label']
-                 if self.parent_match['label'] != self.parent_match['target']
-                 else fullmatch.group('label'))
-        return self._make_lhref_link(match, fullmatch, rel, ns, target, label)
-
-
-def using_sqlite_backend(env):
-    connector, arg = trac.db.api._parse_db_str(
-        trac.db.api.DatabaseManager(env).connection_uri
-    )
-    return connector == 'sqlite'
-
-#----------------------
-# Useful regex
-#----------------------
-
-IDENTIFIER = r'(?!\d)\w+'
+
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+
+"""Bloodhound multiproduct utility APIs"""
+
+from genshi.builder import tag
+
+import trac.db.api
+from trac.util.text import unquote_label
+from trac.wiki.formatter import LinkFormatter
+from trac.core import Component, ComponentMeta
+
+#----------------------------
+# Component replacement base
+#----------------------------
+
+class ReplacementComponentMeta(ComponentMeta):
+    """Component replacement meta class"""
+    def __new__(mcs, name, bases, d):
+        if bases[0] != Component:
+            bases = bases[1:]
+            base_class = bases[0]
+
+            # undo what has been done by ComponentMeta.__new___ for the
+            # replacement component base class
+
+            # remove implemented interfaces from registry for the base class
+            for itf in base_class._implements:
+                ComponentMeta._registry[itf] = filter(lambda c: c != base_class,
+                                                      ComponentMeta._registry[itf])
+
+            # remove base class from components list
+            ComponentMeta._components = filter(lambda c: c != base_class,
+                                               ComponentMeta._components)
+
+            base_class._implements = []
+            base_class.abstract = True
+
+        return ComponentMeta.__new__(mcs, name, bases, d)
+
+class ReplacementComponent(Component):
+    """Base class for components that replace existing trac
+    implementations"""
+    __metaclass__ = ReplacementComponentMeta
+
+#--------------------------
+# Custom wiki formatters
+#--------------------------
+
+class EmbeddedLinkFormatter(LinkFormatter):
+    """Format the inner TracLinks expression corresponding to resources 
+    in compound links e.g. product:PREFIX:ticket:1 , global:ticket:1
+    """
+
+    def __init__(self, env, context, parent_match=None):
+        """Extend initializer signature to accept parent match
+        
+        @param parent_match: mapping object containing the following keys
+                        - ns : namespace of parent resolver
+                        - target : target supplied in to parent resolver
+                        - label: label supplied in to parent resolver
+                        - fullmatch : parent regex match (optional)
+        """
+        super(EmbeddedLinkFormatter, self).__init__(env, context)
+        self.parent_match = parent_match
+        self.auto_quote = False
+
+    def match(self, wikitext):
+        if self.auto_quote:
+            parts = tuple(wikitext.split(':', 1))
+            if len(parts) == 2:
+                if parts[1]:
+                    _wikitext = '%s:"%s"' % parts
+                else:
+                    _wikitext = '[%s:]' % parts[:1]
+            else:
+                _wikitext = wikitext
+        return super(EmbeddedLinkFormatter, self).match(_wikitext)
+
+    @staticmethod
+    def enhance_link(link):
+        return link
+
+    def handle_match(self, fullmatch):
+        if self.parent_match is None:
+            return super(EmbeddedLinkFormatter, self).handle_match(fullmatch)
+
+        for itype, match in fullmatch.groupdict().items():
+            if match and not itype in self.wikiparser.helper_patterns:
+                # Check for preceding escape character '!'
+                if match[0] == '!':
+                    # Erroneous expression. Nested link would be escaped 
+                    return tag.a(self.parent_match['label'], class_='missing')
+                if itype in self.wikiparser.external_handlers:
+                    #TODO: Important! Add product prefix in label (when needed?)
+                    external_handler = self.wikiparser.external_handlers[itype]
+                    link = external_handler(self, match, fullmatch)
+                else:
+                    internal_handler = getattr(self, '_%s_formatter' % itype)
+                    link = internal_handler(match, fullmatch)
+                return self.enhance_link(link)
+
+    # Overridden formatter methods
+    # TODO : Override more if necessary
+    def _shref_formatter(self, match, fullmatch):
+        if self.parent_match is None:
+            return super(EmbeddedLinkFormatter, self)._shref_formatter(
+                    match, fullmatch)
+        ns = fullmatch.group('sns')
+        target = unquote_label(fullmatch.group('stgt'))
+        label = (self.parent_match['label']
+                 if self.parent_match['label'] != self.parent_match['target']
+                 else target)
+        return self._make_link(ns, target, match, label, fullmatch)
+
+    def _lhref_formatter(self, match, fullmatch):
+        if self.parent_match is None:
+            return super(EmbeddedLinkFormatter, self)._lhref_formatter(
+                    match, fullmatch)
+        rel = fullmatch.group('rel')
+        ns = fullmatch.group('lns')
+        target = unquote_label(fullmatch.group('ltgt'))
+        label = (self.parent_match['label']
+                 if self.parent_match['label'] != self.parent_match['target']
+                 else fullmatch.group('label'))
+        return self._make_lhref_link(match, fullmatch, rel, ns, target, label)
+
+
+def using_sqlite_backend(env):
+    connector, arg = trac.db.api._parse_db_str(
+        trac.db.api.DatabaseManager(env).connection_uri
+    )
+    return connector == 'sqlite'
+
+#----------------------
+# Useful regex
+#----------------------
+
+IDENTIFIER = r'(?!\d)\w+'

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/util.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/multiproduct/versioncontrol.py
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/setup.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/setup.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/setup.py Tue Aug 20 09:39:51 2013
@@ -17,13 +17,25 @@
 #  under the License.
 
 """setup for multi product plugin"""
-import sys
+import sys, codecs
 from pkg_resources import parse_version
 from setuptools import setup
 
+
+# Force UTF-8 for stdout/err if --utf8 option is specified.
+# For some reason python doesn't obey LANG/LC_CTYPE settings
+# if output is not a terminal (e.g. pipes don't work).
+if __name__ == '__main__':
+    for ac,av in enumerate(sys.argv):
+        if av == '--utf8':
+            sys.stdout = codecs.getwriter('utf8')(sys.stdout)
+            sys.stderr = codecs.getwriter('utf8')(sys.stderr)
+            del sys.argv[ac]
+            break
+
 setup(
     name = 'BloodhoundMultiProduct',
-    version = '0.7.0',
+    version = '0.8.0',
     description = "Multiproduct support for Apache(TM) Bloodhound.",
     author = "Apache Bloodhound",
     license = "Apache License v2",
@@ -34,6 +46,7 @@ setup(
             'multiproduct.model = multiproduct.model',
             'multiproduct.perm = multiproduct.perm',
             'multiproduct.product_admin = multiproduct.product_admin',
+            'multiproduct.ticket.batch = multiproduct.ticket.batch',
             'multiproduct.ticket.query = multiproduct.ticket.query',
             'multiproduct.ticket.web_ui = multiproduct.ticket.web_ui',
             'multiproduct.web_ui = multiproduct.web_ui',

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/console-tests.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/console.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/admin/product_admin.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/attachment.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/config.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/core.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/api.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/cursor.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/mysql.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/postgres.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/db/util.py
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/env.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/env.py?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/env.py (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/env.py Tue Aug 20 09:39:51 2013
@@ -486,6 +486,18 @@ class ProductEnvApiTestCase(Multiproduct
         # Unregister class C as its fake module might break something else.
         ComponentMeta._components.remove(C)
 
+    def test_href_is_lazy(self):
+        href = self.product_env.href
+        self.assertIs(href, self.product_env.href)
+
+    def test_abs_href_is_lazy(self):
+        abs_href = self.product_env.abs_href
+        self.assertIs(abs_href, self.product_env.abs_href)
+
+    def test_path_is_lazy(self):
+        path = self.product_env.path
+        self.assertIs(path, self.product_env.path)
+
     def test_path(self):
         """Testing env.path"""
         self.assertEqual(self.product_env.path,
@@ -582,12 +594,15 @@ class ProductEnvHrefTestCase(Multiproduc
     def test_href_subdomain(self):
         """Test product sub domain base URL
         """
+        self.assertEqual('/', self.product_env.href())
         self.assertEqual('http://tp1.domain.tld', self.product_env.abs_href())
 
     @product_base_url('/path/to/bloodhound/$(prefix)s')
     def test_href_sibling_paths(self):
         """Test product base URL at sibling paths
         """
+        self.assertEqual('/trac.cgi/path/to/bloodhound/tp1',
+                         self.product_env.href())
         self.assertEqual('http://globalenv.com/trac.cgi/path/to/bloodhound/tp1',
                          self.product_env.abs_href())
 
@@ -595,6 +610,7 @@ class ProductEnvHrefTestCase(Multiproduc
     def test_href_inherit_sibling_paths(self):
         """Test product base URL at sibling paths inheriting configuration.
         """
+        self.assertEqual('/trac.cgi/env/tp1', self.product_env.href())
         self.assertEqual('http://globalenv.com/trac.cgi/env/tp1',
                          self.product_env.abs_href())
 
@@ -602,6 +618,7 @@ class ProductEnvHrefTestCase(Multiproduc
     def test_href_default(self):
         """Test product base URL is to a default
         """
+        self.assertEqual('/trac.cgi/products/tp1', self.product_env.href())
         self.assertEqual('http://globalenv.com/trac.cgi/products/tp1',
                          self.product_env.abs_href())
 
@@ -609,6 +626,7 @@ class ProductEnvHrefTestCase(Multiproduc
     def test_href_embed(self):
         """Test default product base URL /products/prefix
         """
+        self.assertEqual('/trac.cgi/products/tp1', self.product_env.href())
         self.assertEqual('http://globalenv.com/trac.cgi/products/tp1',
                          self.product_env.abs_href())
 
@@ -616,6 +634,7 @@ class ProductEnvHrefTestCase(Multiproduc
     def test_href_complex(self):
         """Test complex product base URL
         """
+        self.assertEqual('/bh/tp1', self.product_env.href())
         self.assertEqual('http://env.tld/bh/tp1', self.product_env.abs_href())
 
     @product_base_url('http://$(prefix)s.$(envname)s.tld/')
@@ -626,10 +645,12 @@ class ProductEnvHrefTestCase(Multiproduc
         """
         # Global URLs
         self.assertEqual('http://globalenv.com/trac.cgi', self.env.base_url)
+        self.assertEqual('/trac.cgi', self.env.href())
         self.assertEqual('http://globalenv.com/trac.cgi', self.env.abs_href())
 
         # Product URLs
         self.assertEqual('', self.product_env.base_url)
+        self.assertEqual('/', self.product_env.href())
         self.assertEqual('http://tp1.env.tld', self.product_env.abs_href())
 
     @product_base_url('http://$(prefix)s.$(envname)s.tld/')
@@ -643,6 +664,7 @@ class ProductEnvHrefTestCase(Multiproduc
         self.product_env.config.save()
 
         self.assertEqual('http://productenv.com', self.product_env.base_url)
+        self.assertEqual('/', self.product_env.href())
         self.assertEqual('http://productenv.com', self.product_env.abs_href())
 
     @product_base_url('http://$(prefix)s.$(envname)s.tld/')
@@ -656,6 +678,7 @@ class ProductEnvHrefTestCase(Multiproduc
         self.product_env.config.save()
 
         self.assertEqual('', self.product_env.base_url)
+        self.assertEqual('/', self.product_env.href())
         self.assertEqual('http://tp1.env.tld', self.product_env.abs_href())
 
     product_base_url = staticmethod(product_base_url)

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/env.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/hooks.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/__init__.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/api.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/patch.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/mimeview/pygments.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/perm.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-attachment-link-tests.short.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-attachment-link-tests.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-comment-link-tests.short.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-comment-link-tests.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-link-tests.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-milestone-link-tests.short.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-milestone-link-tests.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-nomatch-link-tests.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.short.txt
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.short.txt?rev=1515751&r1=1515750&r2=1515751&view=diff
==============================================================================
--- bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.short.txt (original)
+++ bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.short.txt Tue Aug 20 09:39:51 2013
@@ -43,7 +43,7 @@
 <a class="query" href="%(path_prefix)s/query?group=owner&amp;order=priority">%(link_prefix_escaped)squery:group=owner</a>
 </p>
 <p>
-<a class="query" href="%(path_prefix)s/query?order=priority&amp;row=description">%(link_prefix_escaped)squery:verbose=1</a>
+<a class="query" href="%(path_prefix)s/query?row=description&amp;order=priority">%(link_prefix_escaped)squery:verbose=1</a>
 </p>
 <p>
 <a class="query" href="%(path_prefix)s/query?summary=r%%C3%%A9sum%%C3%%A9&amp;order=priority">%(link_prefix_escaped)squery:summary=résumé</a>

Propchange: bloodhound/branches/bep_0010_ticket_numbering/bloodhound_multiproduct/tests/product-query-link-tests.short.txt
------------------------------------------------------------------------------
    svn:eol-style = native