You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2013/05/03 23:57:31 UTC

[01/50] git commit: [#5655] Added test for site_stats EP discovery

Updated Branches:
  refs/heads/db/6007 d8c7c1866 -> b6914fbb6 (forced update)


[#5655] Added test for site_stats EP discovery

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c40ddaf6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c40ddaf6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c40ddaf6

Branch: refs/heads/db/6007
Commit: c40ddaf69d11d20955e78a1d2ba86c52861595a4
Parents: 7225f73
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Apr 26 15:28:09 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Fri Apr 26 15:33:52 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_rest.py |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c40ddaf6/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 68f769f..a08e8f7 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -19,7 +19,10 @@
 
 from datetime import datetime, timedelta
 
+from pylons import app_globals as g
 from nose.tools import assert_equal
+import mock
+import json
 
 from allura.tests import decorators as td
 from alluratest.controller import TestRestApiBase
@@ -96,3 +99,21 @@ class TestRestHome(TestRestApiBase):
         self.app.get('/rest/p/test/wiki/Home/',
                      extra_environ={'username': 'test-user-0'},
                      status=401)
+
+    def test_index(self):
+        eps = {
+                'site_stats': {
+                    'foo_24hr': lambda: 42,
+                    'bar_24hr': lambda: 84,
+                    'qux_24hr': lambda: 0,
+                },
+            }
+        with mock.patch.dict(g.entry_points, eps):
+            response = self.app.get('/rest/')
+            assert_equal(response.json, {
+                'site_stats': {
+                        'foo_24hr': 42,
+                        'bar_24hr': 84,
+                        'qux_24hr': 0,
+                    },
+                })


[45/50] git commit: [#5998] avoid very deep recursion during tests

Posted by br...@apache.org.
[#5998] avoid very deep recursion during tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/b4fa50de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b4fa50de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b4fa50de

Branch: refs/heads/db/6007
Commit: b4fa50de705735bc4bff6e84edd1caacb84db7cb
Parents: 7a332c6
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri May 3 17:52:24 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri May 3 17:52:24 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/patches.py |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b4fa50de/Allura/allura/lib/patches.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/patches.py b/Allura/allura/lib/patches.py
index ef6fba5..60c4648 100644
--- a/Allura/allura/lib/patches.py
+++ b/Allura/allura/lib/patches.py
@@ -78,13 +78,16 @@ def apply():
         return func(*args, **kwargs)
 
 
-def newrelic():
-    old_call = tg.controllers.DecoratedController._call
+# must be saved outside the newrelic() method so that multiple newrelic()
+# calls (e.g. during tests) don't cause the patching to get applied to itself
+# over and over
+old_controller_call = tg.controllers.DecoratedController._call
 
+def newrelic():
     @h.monkeypatch(tg.controllers.DecoratedController,
                    tg.controllers.decoratedcontroller.DecoratedController)
     def _call(self, controller, *args, **kwargs):
         '''Set NewRelic transaction name to actual controller name'''
         import newrelic.agent
         newrelic.agent.set_transaction_name(newrelic.agent.callable_name(controller))
-        return old_call(self, controller, *args, **kwargs)
+        return old_controller_call(self, controller, *args, **kwargs)


[37/50] git commit: add newrelic to requirements-sf.txt

Posted by br...@apache.org.
add newrelic to requirements-sf.txt


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a9b5b119
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a9b5b119
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a9b5b119

Branch: refs/heads/db/6007
Commit: a9b5b119b611b712e5ae9f656a647b7bcee41a1d
Parents: 17617e6
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu May 2 20:13:54 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:13:54 2013 +0000

----------------------------------------------------------------------
 requirements-sf.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a9b5b119/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index 351f054..939dca3 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -8,6 +8,7 @@ ForgeHg==0.1.9
 ForgePastebin==0.2.6
 mechanize==0.2.4
 MySQL-python==1.2.3c1
+newrelic==1.11.0.55
 phpserialize==1.2
 psycopg2==2.2.2
 sf.phpsession==0.1


[12/50] git commit: [#5332] Restrict project name length to 15 chars

Posted by br...@apache.org.
[#5332] Restrict project name length to 15 chars

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f8475cd4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f8475cd4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f8475cd4

Branch: refs/heads/db/6007
Commit: f8475cd4ade6176edcf20be1cf07a0d8c57bf6fc
Parents: cec8151
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Mon Apr 29 14:33:13 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 14:44:08 2013 +0000

----------------------------------------------------------------------
 .../allura/ext/admin/templates/project_tools.html  |    2 +-
 Allura/allura/lib/helpers.py                       |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f8475cd4/Allura/allura/ext/admin/templates/project_tools.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_tools.html b/Allura/allura/ext/admin/templates/project_tools.html
index a607cfd..0c8046d 100644
--- a/Allura/allura/ext/admin/templates/project_tools.html
+++ b/Allura/allura/ext/admin/templates/project_tools.html
@@ -64,7 +64,7 @@
         </span>
         <span class="mount-point-name-rules subproject">
           A valid subproject mount point must begin with a letter, contain only letters,
-          numbers, and dashes, and be from 3-63 characters in length.
+          numbers, and dashes, and be from 3-15 characters in length.
         </span>
       </small>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f8475cd4/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 691204a..9ddad18 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -54,7 +54,7 @@ from .security import has_access
 
 
 # validates project, subproject, and user names
-re_project_name = re.compile(r'^[a-z][-a-z0-9]{2,62}$')
+re_project_name = re.compile(r'^[a-z][-a-z0-9]{2,14}$')
 
 # validates tool mount point names
 re_tool_mount_point = re.compile(r'^[a-z][-a-z0-9]{0,62}$')


[23/50] git commit: [#6172] Rename new Feed object to FeedArgs

Posted by br...@apache.org.
[#6172] Rename new Feed object to FeedArgs

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d34331e8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d34331e8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d34331e8

Branch: refs/heads/db/6007
Commit: d34331e8d500e77a8f390222606e62758b10638a
Parents: 391aa92
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Apr 30 19:44:46 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Apr 30 19:45:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py               |   10 +++++-----
 Allura/allura/controllers/feed.py                  |    8 ++++----
 Allura/allura/controllers/project.py               |    6 +++---
 Allura/allura/ext/user_profile/user_main.py        |    6 +++---
 ForgeBlog/forgeblog/main.py                        |    6 +++---
 .../forgediscussion/controllers/root.py            |    6 +++---
 ForgeTracker/forgetracker/tracker_main.py          |    6 +++---
 ForgeWiki/forgewiki/wiki_main.py                   |    6 +++---
 8 files changed, 27 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index b37d880..96f8979 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -38,7 +38,7 @@ from allura.lib.helpers import DateTimeConverter
 
 from allura.lib.widgets import discuss as DW
 from .attachments import AttachmentsController, AttachmentController
-from .feed import Feed, FeedController
+from .feed import FeedArgs, FeedController
 
 log = logging.getLogger(__name__)
 
@@ -106,13 +106,13 @@ class DiscussionController(BaseController, FeedController):
         redirect(request.referer)
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
 
         """
-        return Feed(
+        return FeedArgs(
             dict(ref_id={'$in': [t.index_id() for t in self.discussion.threads]}),
             'Recent posts to %s' % self.discussion.name,
             self.discussion.url())
@@ -224,13 +224,13 @@ class ThreadController(BaseController, FeedController):
         redirect(self.discussion.url())
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
 
         """
-        return Feed(
+        return FeedArgs(
             dict(ref_id=self.thread.index_id()),
             'Recent posts to %s' % (self.thread.subject or '(no subject)'),
             self.thread.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/Allura/allura/controllers/feed.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/feed.py b/Allura/allura/controllers/feed.py
index f014b21..9be693d 100644
--- a/Allura/allura/controllers/feed.py
+++ b/Allura/allura/controllers/feed.py
@@ -25,7 +25,7 @@ from allura import model as M
 from allura.lib import helpers as h
 
 
-class Feed(object):
+class FeedArgs(object):
     """A facade for the arguments required by
     :meth:`allura.model.artifact.Feed.feed`.
 
@@ -92,17 +92,17 @@ class FeedController(object):
         return feed.writeString('utf-8')
 
     def get_feed(self, project, app, user):
-        """Return a default :class:`Feed` for this controller.
+        """Return a default :class:`FeedArgs` for this controller.
 
         Subclasses should override to customize the feed.
 
         :param project: :class:`allura.model.project.Project`
         :param app: :class:`allura.app.Application`
         :param user: :class:`allura.model.auth.User`
-        :rtype: :class:`Feed`
+        :rtype: :class:`FeedArgs`
 
         """
-        return Feed(
+        return FeedArgs(
             dict(project_id=project._id, app_config_id=app.config._id),
             'Recent changes to %s' % app.config.options.mount_point,
             app.url)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 3bfe0ca..e60b494 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -40,7 +40,7 @@ from allura.lib import helpers as h
 from allura.lib import utils
 from allura.lib.decorators import require_post
 from allura.controllers.error import ErrorController
-from allura.controllers.feed import Feed, FeedController
+from allura.controllers.feed import FeedArgs, FeedController
 from allura.lib.security import require_access, has_access
 from allura.lib.security import RoleCache
 from allura.lib.widgets import forms as ff
@@ -367,13 +367,13 @@ class ProjectController(FeedController):
             redirect(c.project.app_configs[0].options.mount_point + '/')
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
 
         """
-        return Feed(
+        return FeedArgs(
             dict(project_id=project._id),
             'Recent changes to Project %s' % project.name,
             project.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/Allura/allura/ext/user_profile/user_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index c6e2402..54baebf 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -32,7 +32,7 @@ from allura.lib.helpers import DateTimeConverter
 from allura.lib.security import require_access
 from allura.model import User, Feed, ACE
 from allura.controllers import BaseController
-from allura.controllers.feed import Feed, FeedController
+from allura.controllers.feed import FeedArgs, FeedController
 from allura.lib.decorators import require_post
 
 log = logging.getLogger(__name__)
@@ -93,14 +93,14 @@ class UserProfileController(BaseController, FeedController):
         return dict(user=user)
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
 
         """
         user = project.user_project_of
-        return Feed(
+        return FeedArgs(
             {'author_link': user.url()},
             'Recent posts by %s' % user.display_name,
             project.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 0c7af13..24b0bf2 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -46,7 +46,7 @@ from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.search import SearchResults, SearchHelp
 from allura import model as M
 from allura.controllers import BaseController, AppDiscussionController
-from allura.controllers.feed import Feed, FeedController
+from allura.controllers.feed import FeedArgs, FeedController
 
 # Local imports
 from forgeblog import model as BM
@@ -354,13 +354,13 @@ class PostController(BaseController, FeedController):
         redirect(h.really_unicode(request.referer).encode('utf-8'))
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
 
         """
-        return Feed(
+        return FeedArgs(
             dict(ref_id=self.post.index_id()),
             'Recent changes to %s' % self.post.title,
             self.post.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index f731da3..8e074aa 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -33,7 +33,7 @@ from allura.lib import helpers as h
 from allura.lib.utils import AntiSpam
 from allura.lib.decorators import require_post
 from allura.controllers import BaseController, DispatchIndex
-from allura.controllers.feed import Feed, FeedController
+from allura.controllers.feed import FeedArgs, FeedController
 
 from .forum import ForumController
 from forgediscussion import import_support
@@ -187,13 +187,13 @@ class RootController(BaseController, DispatchIndex, FeedController):
         redirect(request.referer)
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
 
         """
-        return Feed(
+        return FeedArgs(
             dict(project_id=project._id, app_config_id=app.config._id),
              'Recent posts to %s' % app.config.options.mount_label,
             app.url)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 6270e96..0f266aa 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -61,7 +61,7 @@ from allura.lib.zarkov_helpers import zero_fill_zarkov_result
 from allura.controllers import AppDiscussionController, AppDiscussionRestController
 from allura.controllers import attachments as ac
 from allura.controllers import BaseController
-from allura.controllers.feed import Feed, FeedController
+from allura.controllers.feed import FeedArgs, FeedController
 from allura.tasks import mail_tasks
 
 # Local imports
@@ -1259,7 +1259,7 @@ class TicketController(BaseController, FeedController):
             raise exc.HTTPNotFound, 'Ticket #%s does not exist.' % self.ticket_num
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
@@ -1267,7 +1267,7 @@ class TicketController(BaseController, FeedController):
         """
         title = 'Recent changes to %d: %s' % (
             self.ticket.ticket_num, self.ticket.summary)
-        return Feed(
+        return FeedArgs(
             {'ref_id': self.ticket.index_id()},
             title,
             self.ticket.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d34331e8/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index dfb982b..0f5151e 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -41,7 +41,7 @@ from allura.lib.security import require_access, has_access
 from allura.controllers import AppDiscussionController, BaseController
 from allura.controllers import DispatchIndex
 from allura.controllers import attachments as ac
-from allura.controllers.feed import Feed, FeedController
+from allura.controllers.feed import FeedArgs, FeedController
 from allura.lib import widgets as w
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.subscriptions import SubscribeForm
@@ -558,7 +558,7 @@ class PageController(BaseController, FeedController):
         return pformat(self.page)
 
     def get_feed(self, project, app, user):
-        """Return a :class:`allura.controllers.feed.Feed` object describing
+        """Return a :class:`allura.controllers.feed.FeedArgs` object describing
         the xml feed for this controller.
 
         Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
@@ -566,7 +566,7 @@ class PageController(BaseController, FeedController):
         """
         if not self.page:
             return None
-        return Feed(
+        return FeedArgs(
             {'ref_id': self.page.index_id()},
             'Recent changes to %s' % self.page.title,
             self.page.url())


[47/50] git commit: [#6007] Add helpful text and a list of projects to the default nbhd wikis

Posted by br...@apache.org.
[#6007] Add helpful text and a list of projects to the default nbhd wikis


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a9a7a729
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a9a7a729
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a9a7a729

Branch: refs/heads/db/6007
Commit: a9a7a729c01b5740ae1a5902c614e914126b0853
Parents: 94cd1ed
Author: Dave Brondsema <db...@geek.net>
Authored: Mon Mar 25 13:53:08 2013 -0700
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri May 3 15:23:01 2013 -0400

----------------------------------------------------------------------
 Allura/allura/model/index.py                       |    2 +-
 .../allura/tests/functional/test_neighborhood.py   |    2 +-
 Allura/allura/websetup/bootstrap.py                |   35 ++++++++++++++-
 3 files changed, 36 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a9a7a729/Allura/allura/model/index.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/index.py b/Allura/allura/model/index.py
index 2dedf4d..f7e3538 100644
--- a/Allura/allura/model/index.py
+++ b/Allura/allura/model/index.py
@@ -199,7 +199,7 @@ class Shortlink(object):
         p_shortname = None
         p_id = None
         p_nbhd = None
-        if hasattr(c, 'project'):
+        if getattr(c, 'project', None):
             p_shortname = getattr(c.project, 'shortname', None)
             p_id = getattr(c.project, '_id', None)
             p_nbhd = c.project.neighborhood_id

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a9a7a729/Allura/allura/tests/functional/test_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index a641f74..1d7db26 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -51,7 +51,7 @@ class TestNeighborhood(TestController):
         r = self.app.get('/adobe/wiki/')
         assert r.location.endswith('/adobe/wiki/Home/')
         r = r.follow()
-        assert 'Welcome' in str(r), str(r)
+        assert 'This is the "Adobe" neighborhood' in str(r), str(r)
         r = self.app.get('/adobe/admin/', extra_environ=dict(username='test-user'),
                          status=403)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a9a7a729/Allura/allura/websetup/bootstrap.py
----------------------------------------------------------------------
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index dd98580..5e8ab1e 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -23,7 +23,7 @@ import sys
 import logging
 import shutil
 from collections import defaultdict
-from datetime import datetime
+from textwrap import dedent
 
 import tg
 from pylons import tmpl_context as c, app_globals as g
@@ -40,6 +40,8 @@ from allura.websetup import schema
 from allura.command import EnsureIndexCommand
 from allura.command import CreateTroveCategoriesCommand
 
+from forgewiki import model as WM
+
 log = logging.getLogger(__name__)
 
 def cache_test_data():
@@ -121,6 +123,37 @@ def bootstrap(command, conf, vars):
     p_projects = project_reg.register_neighborhood_project(n_projects, [root], allow_register=True)
     p_users = project_reg.register_neighborhood_project(n_users, [root])
     p_adobe = project_reg.register_neighborhood_project(n_adobe, [root])
+
+    def set_nbhd_wiki_content(nbhd_proj, content):
+        wiki = nbhd_proj.app_instance('wiki')
+        page = WM.Page.query.get(app_config_id=wiki.config._id, title=wiki.root_page_name)
+        page.text = content
+
+    set_nbhd_wiki_content(p_projects, dedent('''
+        Welcome to the "Projects" neighborhood.  It is the default neighborhood in Allura.
+        You can edit this wiki page as you see fit.  Here's a few ways to get started:
+
+        [Register a new project](/p/add_project)
+
+        [Neighborhood administration](/p/admin)
+
+        [[projects show_total=yes]]
+        '''))
+    set_nbhd_wiki_content(p_users, dedent('''
+        This is the "Users" neighborhood.  All users automatically get a user-project created for them, using their username.
+
+        [Neighborhood administration](/u/admin)
+
+        [[projects show_total=yes]]
+        '''))
+    set_nbhd_wiki_content(p_adobe, dedent('''
+        This is the "Adobe" neighborhood.  It is just an example of having projects in a different neighborhood.
+
+        [Neighborhood administration](/adobe/admin)
+
+        [[projects show_total=yes]]
+        '''))
+
     ThreadLocalORMSession.flush_all()
     ThreadLocalORMSession.close_all()
 


[41/50] git commit: [#5773] ticket:328 refactored log widget

Posted by br...@apache.org.
[#5773]  ticket:328  refactored log widget


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/cf331123
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/cf331123
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/cf331123

Branch: refs/heads/db/6007
Commit: cf33112318ea778be43d46fa1827a26c016b75a6
Parents: d7bcc22
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Wed May 1 14:50:55 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:37:05 2013 +0000

----------------------------------------------------------------------
 Allura/allura/config/app_cfg.py               |    1 +
 Allura/allura/lib/helpers.py                  |    6 +++++-
 Allura/allura/nf/allura/css/allura.css        |    3 +++
 Allura/allura/templates/widgets/repo/log.html |   16 ++++++++--------
 Allura/allura/tests/test_helpers.py           |    4 ++++
 5 files changed, 21 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cf331123/Allura/allura/config/app_cfg.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index f6b11e4..86c65b4 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -101,6 +101,7 @@ class ForgeConfig(AppConfig):
             extensions=['jinja2.ext.do', 'jinja2.ext.i18n'])
         jinja2_env.install_gettext_translations(pylons.i18n)
         jinja2_env.filters['filesizeformat'] = helpers.do_filesizeformat
+        jinja2_env.filters['datetimeformat'] = helpers.datetimeformat
         jinja2_env.globals.update({'hasattr': hasattr})
         config['pylons.app_globals'].jinja2_env = jinja2_env
         # Jinja's unable to request c's attributes without strict_c

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cf331123/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 29cf44e..9d97c02 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -701,4 +701,8 @@ def get_first(d, key):
     v = d.get(key)
     if isinstance(v, list):
         return v[0] if len(v) > 0 else None
-    return v
\ No newline at end of file
+    return v
+
+
+def datetimeformat(value, format='%Y-%m-%d %H:%M:%S'):
+    return value.strftime(format)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cf331123/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index d468b1a..7b0471c 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -211,3 +211,6 @@ b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
 .pagination_size {
     height: 40px;
 }
+tr.rev div.markdown_content p {
+    padding: 0;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cf331123/Allura/allura/templates/widgets/repo/log.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/log.html b/Allura/allura/templates/widgets/repo/log.html
index bdeeda2..50affe6 100644
--- a/Allura/allura/templates/widgets/repo/log.html
+++ b/Allura/allura/templates/widgets/repo/log.html
@@ -33,10 +33,16 @@
       {% for commit in value %}
         <tr class="rev">
           <td>
-            <div class="grid-14">
+            <div>
                 {%if is_file%}
                     <div class="grid-1"><input type="checkbox" class="revision" revision="{{commit._id.split(':')[-1]}}" url_commit="{{commit.url()}}"></div>
                 {%endif%}
+                <a href="{{c.app.repo.url_for_commit(commit)}}">{{commit.shorthand_id()}}</a>
+                {% if c.app.repo.symbolics_for_commit(commit)[1] %}
+                    ({% for tag in c.app.repo.symbolics_for_commit(commit)[1] -%}
+                        <a href="{{c.app.repo.url_for_commit(tag)}}">{{tag}}</a>{% if not loop.last %}&nbsp;{% endif %}
+                    {%- endfor %})
+                {% endif %}
                 {% if commit.committed.email != commit.authored.email %}
                 {% if commit.committer_url %}
                 <a href="{{commit.committer_url}}">{{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}}
@@ -47,12 +53,6 @@
                 pushed
                 {% endif %}
                 {% endif %}
-                <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a>
-                {% if c.app.repo.symbolics_for_commit(commit)[1] %}
-                    ({% for tag in c.app.repo.symbolics_for_commit(commit)[1] -%}
-                        <a href="{{c.app.repo.url()}}ci/{{tag}}/tree{{request.params.get('path')}}">{{tag}}</a>{% if not loop.last %}&nbsp;{% endif %}
-                    {%- endfor %})
-                {% endif %}
                 by
                 {{email_gravatar(commit.authored.email, title=commit.authored.name, size=16)}} {{commit.authored.name}}
                 {%if is_file%}
@@ -62,7 +62,7 @@
             </div>
           </td>
           <td style="vertical-align: text-top">
-            {% if commit.committed.date %}{{commit.committed.date}}{% endif %}
+            {% if commit.committed.date %}{{commit.committed.date|datetimeformat}}{% endif %}
           </td>
           <td style="text-align: left; vertical-align: text-top">
             <a href="{{commit.url()}}tree{{request.params.get('path')}}">

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cf331123/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index ed40cfc..40c0e96 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -238,3 +238,7 @@ def test_inject_user(context):
     context.user = Mock(username='*anonymous')
     result = inject_user('reported_by_s:$USER OR assigned_to_s:$USER')
     assert_equals(result, 'reported_by_s:"*anonymous" OR assigned_to_s:"*anonymous"')
+
+def test_datetimeformat():
+    from datetime import date
+    assert h.datetimeformat(date(2013, 01, 01)) == '2013-01-01 00:00:00'


[50/50] git commit: [#6007] fix more test failures

Posted by br...@apache.org.
[#6007] fix more test failures


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/b6914fbb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b6914fbb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b6914fbb

Branch: refs/heads/db/6007
Commit: b6914fbb6a8b13f01dc3446d9c2df39fe16cb72d
Parents: 8d01a3b
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri May 3 17:57:09 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri May 3 17:57:09 2013 -0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py               |    3 +-
 Allura/allura/lib/app_globals.py                   |    5 +++-
 .../forgediscussion/tests/functional/test_forum.py |   20 +++++++-------
 3 files changed, 16 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b6914fbb/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 96f8979..44262f9 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -300,7 +300,8 @@ class PostController(BaseController):
                     thread=self.post.thread,
                     reply_subject=self.post.reply_subject,
                     attachments=self.post.attachments,
-                    related_artifacts=self.post.related_artifacts
+                    related_artifacts=self.post.related_artifacts,
+                    parent_security_context=lambda: None,
                     )
             else:
                 post=self.post

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b6914fbb/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index c6004d3..daac282 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -327,7 +327,10 @@ class Globals(object):
                 c.user.set_pref('results_per_page', int(limit))
         else:
             if c.user in (None, M.User.anonymous()):
-                limit = 'results_per_page' in session and session['results_per_page'] or default
+                try:
+                    limit = session['results_per_page']
+                except (KeyError, TypeError):  # TypeError if no session registered for thread
+                    limit = default
             else:
                 limit = c.user.get_pref('results_per_page') or default
         return limit

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b6914fbb/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 73b6682..1645dcf 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -139,7 +139,7 @@ class TestForumAsync(TestController):
         r = self.app.get('/admin/discussion/forums')
         assert 'Test Forum 1' in r
         h.set_context('test', 'discussion', neighborhood='Projects')
-        self.user_id = M.User.query.get(username='root')._id
+        self.user = M.User.query.get(username='root')
 
     def test_has_access(self):
         assert False == c.app.has_access(M.User.anonymous(), 'testforum')
@@ -248,15 +248,15 @@ class TestForumAsync(TestController):
 
     def _post(self, topic, subject, body, **kw):
         message_id = kw.pop('message_id', '%s@test.com' % random.random())
-        c.app.handle_message(
-            topic,
-            dict(kw,
-                 project_id=c.project._id,
-                 mount_point='discussion',
-                 headers=dict(Subject=subject),
-                 user_id=self.user_id,
-                 payload=body,
-                 message_id=message_id))
+        with h.push_config(c, user=self.user):
+            c.app.handle_message(
+                topic,
+                dict(kw,
+                     project_id=c.project._id,
+                     mount_point='discussion',
+                     headers=dict(Subject=subject),
+                     payload=body,
+                     message_id=message_id))
         M.artifact_orm_session.flush()
 
 class TestForum(TestController):


[29/50] git commit: [#5913] Updated html for new nav

Posted by br...@apache.org.
[#5913] Updated html for new nav


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c853c466
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c853c466
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c853c466

Branch: refs/heads/db/6007
Commit: c853c4663b7b25b4a9fca65347af251de769771e
Parents: 833aa4a
Author: Jenny Steele <js...@geek.net>
Authored: Wed Mar 20 12:44:51 2013 -0700
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:37 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/top_nav.html |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c853c466/Allura/allura/templates/jinja_master/top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index 7304f4c..599eb3e 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -32,11 +32,13 @@
     {% endif %}
     <li{% if selected %} class="selected"{% endif %}>
       <a href="{{s.url}}">
+        <span>
         {{s.label}}
         {% set grouped_tool_count = s.matching_urls|length %}
         {% if grouped_tool_count %}
           <span class="tool-count">{{grouped_tool_count}}</span>
         {% endif %}
+        </span>
       </a>
     </li>
 	{% endfor %}


[07/50] git commit: [#5294] ticket:320 Check permissions on project REST controller

Posted by br...@apache.org.
[#5294] ticket:320 Check permissions on project REST controller


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c8311bbe
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c8311bbe
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c8311bbe

Branch: refs/heads/db/6007
Commit: c8311bbe6cec1b58edfc8ef577e0c1f992f45ac5
Parents: 974fa9f
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Apr 22 09:26:53 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Apr 26 20:31:33 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c8311bbe/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index c90a1ef..cf03733 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -281,5 +281,5 @@ class ProjectRestController(object):
         return dict(
             name=c.project.shortname,
             tools=[dict(name=t.tool_name, mount_point=t.options.mount_point, label=t.options.mount_label)
-                   for t in c.project.app_configs]
+                   for t in c.project.app_configs if h.has_access(t, 'read')]
         )


[11/50] git commit: [#5332] Miscellaneous code cleanup

Posted by br...@apache.org.
[#5332] Miscellaneous code cleanup

- Rename project name regex to something logical
- Update make_safe_path_portion() to work in strict and relaxed modes

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/cec8151f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/cec8151f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/cec8151f

Branch: refs/heads/db/6007
Commit: cec8151f3d2a9a7a9602816e7f9eb6d3b7a70359
Parents: ba32ac7
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Fri Apr 26 20:37:36 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 14:44:07 2013 +0000

----------------------------------------------------------------------
 .../controllers/basetest_neighborhood_root.py      |    2 +-
 Allura/allura/controllers/basetest_project_root.py |    2 +-
 Allura/allura/controllers/project.py               |    4 +-
 Allura/allura/controllers/rest.py                  |    2 +-
 .../allura/ext/admin/templates/project_tools.html  |    2 +-
 Allura/allura/lib/helpers.py                       |   27 +++++++++---
 Allura/allura/lib/plugin.py                        |    4 +-
 Allura/allura/lib/widgets/forms.py                 |    2 +-
 Allura/allura/model/project.py                     |    2 +-
 Allura/allura/tests/test_helpers.py                |   33 +++++++++++---
 10 files changed, 56 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/controllers/basetest_neighborhood_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/basetest_neighborhood_root.py b/Allura/allura/controllers/basetest_neighborhood_root.py
index cf36aed..b4ef16b 100644
--- a/Allura/allura/controllers/basetest_neighborhood_root.py
+++ b/Allura/allura/controllers/basetest_neighborhood_root.py
@@ -88,7 +88,7 @@ class BasetestNeighborhoodRootController(WsgiDispatchController, NeighborhoodCon
     @expose()
     def _lookup(self, pname, *remainder):
         pname = unquote(pname)
-        if not h.re_path_portion.match(pname):
+        if not h.re_project_name.match(pname):
             raise exc.HTTPNotFound, pname
         project = M.Project.query.get(shortname=self.prefix + pname, neighborhood_id=self.neighborhood._id)
         if project is None:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/controllers/basetest_project_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/basetest_project_root.py b/Allura/allura/controllers/basetest_project_root.py
index 359984c..f9ec3d5 100644
--- a/Allura/allura/controllers/basetest_project_root.py
+++ b/Allura/allura/controllers/basetest_project_root.py
@@ -99,7 +99,7 @@ class BasetestProjectRootController(WsgiDispatchController, ProjectController):
 
     @expose()
     def _lookup(self, name, *remainder):
-        if not h.re_path_portion.match(name):
+        if not h.re_project_name.match(name):
             raise exc.HTTPNotFound, name
         subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
                                          neighborhood_id=self.p_nbhd._id)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 75e7792..4f02632 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -79,7 +79,7 @@ class NeighborhoodController(object):
     @expose()
     def _lookup(self, pname, *remainder):
         pname = unquote(pname)
-        if not h.re_path_portion.match(pname):
+        if not h.re_project_name.match(pname):
             raise exc.HTTPNotFound, pname
         project = M.Project.query.get(shortname=self.prefix + pname, neighborhood_id=self.neighborhood._id)
         if project is None and self.prefix == 'u/':
@@ -185,7 +185,7 @@ class NeighborhoodController(object):
             W.add_project.fields['project_name'].validate(project_name, '')
         except Invalid as e:
             result['name_message'] = str(e)
-        if not h.re_path_portion.match(unix_name) or not (3 <= len(unix_name) <= 15):
+        if not h.re_project_name.match(unix_name) or not (3 <= len(unix_name) <= 15):
             result['unixname_message'] = 'Please use only letters, numbers, and dashes 3-15 characters long.'
         else:
             result['unixname_message'] = plugin.ProjectRegistrationProvider.get().name_taken(unix_name, self.neighborhood)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 8ae0c70..c976c21 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -243,7 +243,7 @@ class NeighborhoodRestController(object):
 
     @expose()
     def _lookup(self, name, *remainder):
-        if not h.re_path_portion.match(name):
+        if not h.re_project_name.match(name):
             raise exc.HTTPNotFound, name
         name = self._neighborhood.shortname_prefix + name
         project = M.Project.query.get(shortname=name, neighborhood_id=self._neighborhood._id, deleted=False)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/ext/admin/templates/project_tools.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_tools.html b/Allura/allura/ext/admin/templates/project_tools.html
index dc7646c..a607cfd 100644
--- a/Allura/allura/ext/admin/templates/project_tools.html
+++ b/Allura/allura/ext/admin/templates/project_tools.html
@@ -30,7 +30,7 @@
   <div class="nested-grid-container">
     {% for tool in installable_tools %}
       <span class="tcenter grid-4 installable_tool">
-        <a class="install_trig" data-tool="{{ tool['name'] }}" data-relaxed-mount-points="{{ tool.app.relaxed_mount_points and 'true' or 'false' }}">
+        <a class="install_trig" data-tool="{{ tool['name'] }}" data-relaxed-mount-points="{{ 'true' if tool.app.relaxed_mount_points else 'false' }}">
           <span class="tool_title">{{ tool['app'].tool_label }}{{' (%s)' % tool.app.status if tool.app.status != 'production' else ''}}</span><br />
           <img src="{{ g.theme.app_icon_url(tool['app'], 32) or 'unk.png' }}" alt="">
         </a>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index b118efe..691204a 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -52,10 +52,16 @@ from allura.lib.decorators import exceptionless
 from allura.lib import AsciiDammit
 from .security import has_access
 
-re_path_portion_fragment = re.compile(r'[a-z][-a-z0-9]*')
-re_path_portion = re.compile(r'^[a-z][-a-z0-9]{2,62}$')
+
+# validates project, subproject, and user names
+re_project_name = re.compile(r'^[a-z][-a-z0-9]{2,62}$')
+
+# validates tool mount point names
 re_tool_mount_point = re.compile(r'^[a-z][-a-z0-9]{0,62}$')
+re_tool_mount_point_fragment = re.compile(r'[a-z][-a-z0-9]*')
 re_relaxed_tool_mount_point = re.compile(r'^[a-z0-9][-a-z0-9_\.\+]{0,62}$')
+re_relaxed_tool_mount_point_fragment = re.compile(r'[a-z0-9][-a-z0-9_\.\+]*')
+
 re_clean_vardec_key = re.compile(r'''\A
 ( # first part
 \w+# name...
@@ -67,17 +73,24 @@ re_clean_vardec_key = re.compile(r'''\A
 )+
 \Z''', re.VERBOSE)
 
-def make_safe_path_portion(ustr):
-    """Return an ascii representation of `ustr`
+def make_safe_path_portion(ustr, relaxed=True):
+    """Return an ascii representation of ``ustr`` that conforms to mount point
+    naming :attr:`rules <re_tool_mount_point_fragment>`.
+
+    Will return an empty string if no char in ``ustr`` is latin1-encodable.
+
+    :param relaxed: Use relaxed mount point naming rules (allows more
+        characters. See :attr:`re_relaxed_tool_mount_point_fragment`.
+    :returns: The converted string.
 
-    Will return an empty string if no char in `ustr`
-    is latin1-encodable.
     """
+    regex = (re_relaxed_tool_mount_point_fragment if relaxed else
+                re_tool_mount_point_fragment)
     ustr = really_unicode(ustr)
     s = ustr.encode('latin1', 'ignore')
     s = AsciiDammit.asciiDammit(s)
     s = s.lower()
-    s = '-'.join(re_path_portion_fragment.findall(s))
+    s = '-'.join(regex.findall(s))
     s = s.replace('--', '-')
     return s
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 48aa04b..b7722d2 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -464,7 +464,7 @@ class ProjectRegistrationProvider(object):
 
         self.rate_limit(user, neighborhood)
 
-        if not h.re_path_portion.match(shortname.replace('/', '')):
+        if not h.re_project_name.match(shortname.replace('/', '')):
             raise ValueError('Invalid project shortname: %s' % shortname)
 
         p = M.Project.query.get(shortname=shortname, neighborhood_id=neighborhood._id)
@@ -582,7 +582,7 @@ class ProjectRegistrationProvider(object):
 
     def register_subproject(self, project, name, user, install_apps):
         from allura import model as M
-        assert h.re_path_portion.match(name), 'Invalid subproject shortname'
+        assert h.re_project_name.match(name), 'Invalid subproject shortname'
         shortname = project.shortname + '/' + name
         sp = M.Project(
             parent_id=project._id,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/lib/widgets/forms.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index 43c6dd4..9501b70 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -618,7 +618,7 @@ class RegistrationForm(ForgeForm):
         username = ew.TextField(
             label='Desired Username',
             validator=fev.Regex(
-                h.re_path_portion))
+                h.re_project_name))
         username.validator._messages['invalid'] = (
             'Usernames must include only letters, numbers, and dashes.'
             ' They must also start with a letter and be at least 3 characters'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index b3f1131..350f353 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -606,7 +606,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                 return ac
 
     def new_subproject(self, name, install_apps=True, user=None):
-        if not h.re_path_portion.match(name):
+        if not h.re_project_name.match(name):
             raise exceptions.ToolError, 'Mount point "%s" is invalid' % name
         provider = plugin.ProjectRegistrationProvider.get()
         return provider.register_subproject(self, name, user or c.user, install_apps)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cec8151f/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 2b8e179..ed40cfc 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -17,6 +17,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+from unittest import TestCase
 from os import path
 from mock import Mock, patch
 
@@ -34,13 +35,31 @@ def setUp(self):
     """Method called by nose before running each test"""
     setup_basic_test()
 
-def test_make_safe_path_portion():
-    s = u'Задачи'
-    new_s = h.make_safe_path_portion(s)
-    assert len(new_s) == 0
-    s = 'åß∂ƒ'
-    new_s = h.make_safe_path_portion(s)
-    assert new_s == 'ab'
+
+class TestMakeSafePathPortion(TestCase):
+    def setUp(self):
+        self.f = h.make_safe_path_portion
+
+    def test_no_latin1_chars(self):
+        s = self.f(u'Задачи')
+        self.assertEqual(s, '')
+
+    def test_some_latin1_chars(self):
+        s = self.f('åß∂ƒ')
+        self.assertEqual(s, 'ab')
+
+    def test_strict_mount_point_names(self):
+        s = self.f('1this+is.illegal', relaxed=False)
+        self.assertEqual(s, 'this-is-illegal')
+        s = self.f('this-1-is-legal', relaxed=False)
+        self.assertEqual(s, 'this-1-is-legal')
+
+    def test_relaxed_mount_point_names(self):
+        s = self.f('1_this+is.legal')
+        self.assertEqual(s, '1_this+is.legal')
+        s = self.f('not*_legal')
+        self.assertEqual(s, 'not-legal')
+
 
 def test_really_unicode():
     here_dir = path.dirname(__file__)


[28/50] git commit: [#5599] ticket:296 drop-down for grouped menu items

Posted by br...@apache.org.
[#5599] ticket:296 drop-down for grouped menu items


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a028f972
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a028f972
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a028f972

Branch: refs/heads/db/6007
Commit: a028f972b9c73eef5cc73e7be2d199e1188aa0de
Parents: 4469a52
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Apr 15 10:28:57 2013 +0400
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:37 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/project.py               |    8 +-
 Allura/allura/model/project.py                     |    9 ++
 Allura/allura/nf/allura/css/site_style.css         |   78 +++++++++++----
 Allura/allura/templates/award.html                 |    2 +-
 .../templates/jinja_master/neigh_top_nav.html      |   40 --------
 Allura/allura/templates/jinja_master/top_nav.html  |   20 ++--
 .../templates/neighborhood_admin_accolades.html    |    2 +-
 .../templates/neighborhood_admin_overview.html     |    2 +-
 Allura/allura/templates/neighborhood_help.html     |    2 +-
 Allura/allura/templates/neighborhood_moderate.html |    2 +-
 .../templates/neighborhood_project_list.html       |    2 +-
 Allura/allura/templates/neighborhood_stats.html    |    2 +-
 .../templates/neighborhood_stats_adminlist.html    |    2 +-
 Allura/allura/tests/functional/test_admin.py       |   17 ++--
 Allura/allura/tests/functional/test_home.py        |   30 ++++++
 .../allura/tests/functional/test_neighborhood.py   |   16 ++--
 16 files changed, 138 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index e60b494..f8789a3 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -309,9 +309,11 @@ class ProjectController(FeedController):
 
     @expose('json:')
     def _nav(self):
-        return dict(menu=[
-                dict(name=s.label, url=s.url, icon=s.ui_icon)
-                for s in c.project.grouped_navbar_entries()])
+        menu = []
+        for s in c.project.grouped_navbar_entries():
+            children = [dict(name=child.label, url=child.url, icon=child.ui_icon) for child in s.children]
+            menu.append(dict(name=s.label, url=s.url, icon=s.ui_icon, children=children))
+        return dict(menu=menu)
 
     @expose()
     def _lookup(self, name, *remainder):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 350f353..73894e3 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -18,6 +18,7 @@
 import logging
 from collections import Counter, OrderedDict
 from datetime import datetime
+from copy import deepcopy
 
 from tg import config
 from pylons import tmpl_context as c, app_globals as g
@@ -493,6 +494,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             else:
                 # tool of a type we don't have in the navbar yet
                 if tool_name not in grouped_nav:
+                    child = deepcopy(e)
                     # change label to be the tool name (type)
                     e.label = tool_name.capitalize()
                     # add tool url to list of urls that will match this nav entry
@@ -500,10 +502,17 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                     e.matching_urls.append(e.url)
                     # change url to point to tool list page
                     e.url = self.url() + '_list/' + tool_name
+                    e.children.append(child)
                     grouped_nav[tool_name] = e
                 else:
                     # add tool url to list of urls that will match this nav entry
                     grouped_nav[tool_name].matching_urls.append(e.url)
+                    if len(grouped_nav[tool_name].children) < 10:
+                        grouped_nav[tool_name].children.append(e)
+                    elif len(grouped_nav[tool_name].children) == 10:
+                        e.url = self.url() + '_list/' + tool_name
+                        e.label = '...more...'
+                        grouped_nav[tool_name].children.append(e)
         return grouped_nav.values()
 
     def parent_iter(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index df703d9..98938e8 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -370,25 +370,6 @@ td, td img {
   vertical-align: middle;
 }
 
-.diamond {
-  z-index: 1;
-  height: 20px;
-  width: 20px;
-  display: block;
-  position: absolute;
-  bottom: -20px;
-  left: 50%;
-  margin-left: -10px;
-  overflow: hidden;
-  background: #e5e5e5;
-  border-left: 1px solid #aaaaaa;
-  border-top: 1px solid #aaaaaa;
-  -moz-transform: rotate(45deg);
-  -webkit-transform: rotate(45deg);
-  -o-transform: rotate(45deg);
-  transform: rotate(45deg);
-}
-
 .tool-count {
   display: block;
   position: absolute;
@@ -1013,6 +994,7 @@ a.btn:active {
   text-align: center;
   position: relative;
   margin: 0 0 20px;
+  height: 50px;
 }
 .btn-bar.pop, .pop#top_nav {
   height: 150px;
@@ -2905,3 +2887,61 @@ table thead tr th.narrow, table tr td.narrow {
   bottom: -5px;
   left: 45%;
 }
+ul.dropdown,
+ul.dropdown li,
+ul.dropdown ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+ul.dropdown {
+    position: relative;
+    z-index: 597;
+    float: left;
+}
+
+ul.dropdown li {
+    float: left;
+    vertical-align: middle;
+    zoom: 1;
+}
+
+ul.dropdown li.hover,
+ul.dropdown li:hover {
+    position: relative;
+    z-index: 599;
+    cursor: default;
+}
+
+ul.dropdown ul {
+    visibility: hidden;
+    position: absolute;
+    top:50px;
+    left: 0;
+    z-index: 598;
+    background-color: #ffffff;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+    border-width: 1px;
+    border-style: solid;
+    border-color: #E6EFC2;
+}
+
+ul.dropdown ul li {
+    float: left;
+    margin: 5px;
+    min-width: 100px;
+}
+
+ul.dropdown li:hover > ul {
+    visibility: visible;
+}
+ul.dropdown ul li a {
+    height: 20px !important;
+    font-weight:normal;
+}
+li.selected {
+    font-weight:bold;
+}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/award.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/award.html b/Allura/allura/templates/award.html
index 3cb2b72..503714f 100644
--- a/Allura/allura/templates/award.html
+++ b/Allura/allura/templates/award.html
@@ -27,7 +27,7 @@
 {% endblock %}
 
 {% block top_nav %}
-{% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+{% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/jinja_master/neigh_top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/neigh_top_nav.html b/Allura/allura/templates/jinja_master/neigh_top_nav.html
deleted file mode 100644
index 39b37b9..0000000
--- a/Allura/allura/templates/jinja_master/neigh_top_nav.html
+++ /dev/null
@@ -1,40 +0,0 @@
-{#-
-       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.
--#}
-{% if neighborhood and neighborhood.neighborhood_project %}
-  {% for s in neighborhood.neighborhood_project.sitemap() %}
-    <a href="{{s.url}}" class="ui-icon-{{s.ui_icon or 'admin'}}">
-      {{s.label}}
-      {% if s.label == 'Home' %}
-        {% set url_length = s.url|length %}
-        {% if request.url.rfind(s.url, -url_length) != -1 %}
-          <span class="diamond"></span>
-        {% endif %}
-      {% elif s.label == 'Admin' %}
-        {% if s.url in request.url or c.project.neighborhood.url()+'_admin' in request.url %}
-          <span class="diamond"></span>
-        {% endif %}
-      {% else %}
-        {% if s.url in request.url %}
-          <span class="diamond"></span>
-        {% endif %}
-      {% endif %}
-    </a>
-        {% endfor %}
-        <div style="clear:both"></div>
-{% endif %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/jinja_master/top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index 1b17d11..aeec126 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -17,7 +17,7 @@
        under the License.
 -#}
 {% if c.project %}
-  <div><ul>
+<ul class="dropdown">
   {% for s in c.project.grouped_navbar_entries() %}
     {% set selected = False %}
     {% if s.label == 'Home' %}
@@ -30,17 +30,19 @@
         {% set selected = True %}
       {% endif %}
     {% endif %}
-    <li class="ui-icon-{{s.ui_icon or 'admin'}}{% if selected %} selected{% endif %}">
-      <a href="{{s.url}}">
-        <span>
-        {{s.label}}
+    <li class="{% if selected %}selected{% endif %}">
+        <a href="{{s.url}}" class="ui-icon-{{s.ui_icon or 'admin'}}">
+            {{s.label}}
+        </a>
         {% set grouped_tool_count = s.matching_urls|length %}
         {% if grouped_tool_count %}
-          <span class="tool-count">{{grouped_tool_count}}</span>
+          <ul>
+              {%for tool in s.children%}
+                <li><span><a href="{{tool.url}}">{{tool.label}}</a></span></li>
+              {%endfor%}
+          </ul>
         {% endif %}
-        </span>
-      </a>
     </li>
 	{% endfor %}
-	</div></ul>
+</ul>
 {% endif %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_admin_accolades.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_admin_accolades.html b/Allura/allura/templates/neighborhood_admin_accolades.html
index 63264bc..2f6d82f 100644
--- a/Allura/allura/templates/neighborhood_admin_accolades.html
+++ b/Allura/allura/templates/neighborhood_admin_accolades.html
@@ -27,7 +27,7 @@
 {% endblock %}
 
 {% block top_nav %}
-{% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+{% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_admin_overview.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_admin_overview.html b/Allura/allura/templates/neighborhood_admin_overview.html
index 07489e9..8944b22 100644
--- a/Allura/allura/templates/neighborhood_admin_overview.html
+++ b/Allura/allura/templates/neighborhood_admin_overview.html
@@ -27,7 +27,7 @@
 {% endblock %}
 
 {% block top_nav %}
-{% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+{% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_help.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_help.html b/Allura/allura/templates/neighborhood_help.html
index 6ad8163..ed57b53 100644
--- a/Allura/allura/templates/neighborhood_help.html
+++ b/Allura/allura/templates/neighborhood_help.html
@@ -27,7 +27,7 @@
 {% endblock %}
 
 {% block top_nav %}
-    {% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+    {% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_moderate.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_moderate.html b/Allura/allura/templates/neighborhood_moderate.html
index 7beea44..5fe5c3f 100644
--- a/Allura/allura/templates/neighborhood_moderate.html
+++ b/Allura/allura/templates/neighborhood_moderate.html
@@ -28,7 +28,7 @@
 {% endblock %}
 
 {% block top_nav %}
-{% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+{% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_project_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_project_list.html b/Allura/allura/templates/neighborhood_project_list.html
index 1f2939e..b747af0 100644
--- a/Allura/allura/templates/neighborhood_project_list.html
+++ b/Allura/allura/templates/neighborhood_project_list.html
@@ -42,7 +42,7 @@
 {% endblock %}
 
 {% block top_nav %}
-{% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+{% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block inner_grid %}{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_stats.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_stats.html b/Allura/allura/templates/neighborhood_stats.html
index fa0e68f..3b0b0ee 100644
--- a/Allura/allura/templates/neighborhood_stats.html
+++ b/Allura/allura/templates/neighborhood_stats.html
@@ -19,7 +19,7 @@
 {% extends g.theme.master %}
 
 {% block top_nav %}
-    {% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+    {% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block title %}Neighborhood Statistics{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/templates/neighborhood_stats_adminlist.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_stats_adminlist.html b/Allura/allura/templates/neighborhood_stats_adminlist.html
index 4e3afe0..4deafe1 100644
--- a/Allura/allura/templates/neighborhood_stats_adminlist.html
+++ b/Allura/allura/templates/neighborhood_stats_adminlist.html
@@ -23,7 +23,7 @@
 {% block header %}Admins list{% endblock %}
 
 {% block top_nav %}
-    {% include 'allura:templates/jinja_master/neigh_top_nav.html' %}
+    {% include 'allura:templates/jinja_master/top_nav.html' %}
 {% endblock %}
 
 {% block content %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index ac63ffe..1752707 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -105,9 +105,9 @@ class TestProjectAdmin(TestController):
         assert 'error' not in self.webflash(r)
         # check tool in the nav
         r = self.app.get('/p/test/test-tool/').follow()
-        active_link = r.html.findAll('span',{'class':'diamond'})
-        assert len(active_link) == 1
-        assert active_link[0].parent['href'] == '/p/test/test-tool/'
+        active_link = r.html.findAll('li',{'class':'selected'})
+        assert_equals(len(active_link), 1)
+        assert active_link[0].contents[1]['href'] == '/p/test/test-tool/'
         with audits('install tool test-tool2'):
             r = self.app.post('/admin/update_mounts', params={
                     'new.install':'install',
@@ -118,13 +118,12 @@ class TestProjectAdmin(TestController):
         assert 'error' not in self.webflash(r)
         # check the nav - tools of same type are grouped
         r = self.app.get('/p/test/test-tool/Home/')
-        active_link = r.html.findAll('span', {'class':'diamond'})
+        active_link = r.html.findAll('li',{'class':'selected'})
         assert len(active_link) == 1
-        assert active_link[0].parent['href'] == '/p/test/_list/wiki'
-        # check tool-count of grouped tools
-        tool_count = active_link[0].findNextSibling('span')
-        assert tool_count['class'] == u'tool-count', tool_count['class']
-        assert tool_count.text == u'2', tool_count.text
+        assert active_link[0].contents[1]['href'] == '/p/test/_list/wiki'
+        assert r.html.findAll('a', {'href':'/p/test/test-tool2/'})
+        assert r.html.findAll('a', {'href':'/p/test/test-tool/'})
+
         # check can't create dup tool
         r = self.app.post('/admin/update_mounts', params={
                 'new.install':'install',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/tests/functional/test_home.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_home.py b/Allura/allura/tests/functional/test_home.py
index 88b2c0d..4904394 100644
--- a/Allura/allura/tests/functional/test_home.py
+++ b/Allura/allura/tests/functional/test_home.py
@@ -18,6 +18,8 @@
 import json
 import re
 
+from pylons import tmpl_context as c
+
 from allura.tests import TestController
 from allura.tests import decorators as td
 from allura import model as M
@@ -38,6 +40,34 @@ class TestProjectHome(TestController):
             assert nl['href'] == entry['url']
 
     @td.with_wiki
+    def test_project_group_nav(self):
+        c.user = M.User.by_username('test-admin')
+        p = M.Project.query.get(shortname='test')
+        c.project = p
+        if 'wiki2' and not p.app_instance('wiki2'):
+            c.app = p.install_app('wiki', 'wiki2', 'wiki2', 9)
+
+        response = self.app.get('/p/test/_nav.json')
+        menu = response.json['menu']
+        assert_equal(len(menu[1]['children']), 2)
+        assert {u'url': u'/p/test/wiki/', u'name': u'Wiki', u'icon': u'tool-wiki'} in menu[1]['children'], menu[1]['children']
+        assert {u'url': u'/p/test/wiki2/', u'name': u'wiki2', u'icon': u'tool-wiki'} in menu[1]['children'], menu[1]['children']
+
+    @td.with_wiki
+    def test_project_group_nav_more_than_ten(self):
+        for i in range(1,15):
+            tool_name = "wiki%s" % str(i)
+            c.user = M.User.by_username('test-admin')
+            p = M.Project.query.get(shortname='test')
+            c.project = p
+            if tool_name and not p.app_instance(tool_name):
+                c.app = p.install_app('wiki', tool_name, tool_name, i)
+        response = self.app.get('/p/test/_nav.json')
+        menu = response.json['menu']
+        assert_equal(len(menu[1]['children']), 11)
+        assert {u'url': u'/p/test/_list/wiki', u'name': u'...more...', u'icon': u'tool-wiki'} in menu[1]['children']
+
+    @td.with_wiki
     def test_neighborhood_home(self):
         self.app.get('/p/test/wiki/', status=302)
         self.app.get('/adobe/test/wiki/', status=404)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a028f972/Allura/allura/tests/functional/test_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index f91b5cb..a641f74 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -638,14 +638,14 @@ class TestNeighborhood(TestController):
         p = M.Project.query.get(shortname='testtemp')
         # make sure the correct tools got installed in the right order
         top_nav = r.html.find('div', {'id':'top_nav'})
-        assert top_nav.contents[1]['href'] == '/adobe/testtemp/wiki/'
-        assert 'Wiki' in top_nav.contents[1].contents[0]
-        assert top_nav.contents[3]['href'] == '/adobe/testtemp/discussion/'
-        assert 'Discussion' in top_nav.contents[3].contents[0]
-        assert top_nav.contents[5]['href'] == '/adobe/testtemp/news/'
-        assert 'News' in top_nav.contents[5].contents[0]
-        assert top_nav.contents[7]['href'] == '/adobe/testtemp/admin/'
-        assert 'Admin' in top_nav.contents[7].contents[0]
+        assert top_nav.contents[1].contents[1].contents[1]['href'] == '/adobe/testtemp/wiki/'
+        assert 'Wiki' in top_nav.contents[1].contents[1].contents[1].contents[0]
+        assert top_nav.contents[1].contents[3].contents[1]['href'] == '/adobe/testtemp/discussion/'
+        assert 'Discussion' in top_nav.contents[1].contents[3].contents[1].contents[0]
+        assert top_nav.contents[1].contents[5].contents[1]['href'] == '/adobe/testtemp/news/'
+        assert 'News' in top_nav.contents[1].contents[5].contents[1].contents[0]
+        assert top_nav.contents[1].contents[7].contents[1]['href'] == '/adobe/testtemp/admin/'
+        assert 'Admin' in top_nav.contents[1].contents[7].contents[1].contents[0]
         # make sure project is private
         r = self.app.get(
             '/adobe/testtemp/wiki/',


[18/50] git commit: [#5891] ticket:316 add attachments to replies

Posted by br...@apache.org.
[#5891] ticket:316 add attachments to replies


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/57d4e6fb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/57d4e6fb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/57d4e6fb

Branch: refs/heads/db/6007
Commit: 57d4e6fb9af1eabbf5cb16acbafbe0c00550db39
Parents: 5fb297e
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Apr 22 14:25:23 2013 +0400
Committer: Yuriy Arhipov <yu...@yandex.ru>
Committed: Tue Apr 30 11:16:44 2013 +0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py           |   11 ++++++++++-
 Allura/allura/tests/functional/test_discuss.py |   18 ++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/57d4e6fb/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 2ef1df4..b0bb426 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -344,11 +344,20 @@ class PostController(BaseController):
     @validate(pass_validator, error_handler=index)
     @utils.AntiSpam.validate('Spambot protection engaged')
     @require_post(redir='.')
-    def reply(self, **kw):
+    def reply(self, file_info=None, **kw):
         require_access(self.thread, 'post')
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
         is_spam = g.spam_checker.check(kw['text'], artifact=p, user=c.user)
+        if hasattr(file_info, 'file'):
+            mime_type = file_info.type
+            if not mime_type or '/' not in mime_type:
+                mime_type = utils.guess_mime_type(file_info.filename)
+            p.attach(
+                file_info.filename, file_info.file, content_type=mime_type,
+                post_id=p._id,
+                thread_id=p.thread_id,
+                discussion_id=p.discussion_id)
         redirect(request.referer)
 
     @h.vardec

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/57d4e6fb/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 83910e9..633f078 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -220,3 +220,21 @@ class TestAttachment(TestController):
         r = self.app.post(self.post_link + 'attach',
                           upload_files=[('file_info', 'test.o12', 'HiThere!')])
         r = self.app.post(alink, params=dict(delete='on'))
+
+    @patch('allura.model.discuss.Post.notify')
+    def test_reply_attach(self, notify):
+        notify.return_value = True
+        r = self.app.get(self.thread_link)
+        post_form = r.html.find('form', {'action':self.post_link + 'reply'})
+        params = dict()
+        inputs = post_form.findAll('input')
+
+        for field in inputs:
+            if field.has_key('name') and (field['name']!='file_info'):
+                params[field['name']] = field.has_key('value') and field['value'] or ''
+        params[post_form.find('textarea')['name']] = 'Reply'
+        r = self.app.post(self.post_link + 'reply',
+                          params=params,
+                          upload_files=[('file_info', 'test.txt', 'HiThere!')])
+        r = self.app.get(self.thread_link)
+        assert "test.txt" in r


[30/50] git commit: [#5913] change id back to top_nav

Posted by br...@apache.org.
[#5913] change id back to top_nav


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/22df7b42
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/22df7b42
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/22df7b42

Branch: refs/heads/db/6007
Commit: 22df7b4299e2c7ff5ae0dfd56b465c545c0f4de2
Parents: c853c46
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Apr 1 19:05:33 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:37 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/master.html |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/22df7b42/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index 00052c1..11482a7 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -82,7 +82,7 @@
             {% include g.theme.nav_menu %}
             {% endblock %}
       </div>
-      <div id="main_nav" class="">
+      <div id="top_nav" class="">
         {% block top_nav %}
         {% include g.theme.top_nav %}
         {% endblock %}


[06/50] git commit: [#5294] ticket:320 Test for permissions on project REST controller

Posted by br...@apache.org.
[#5294] ticket:320 Test for permissions on project REST controller


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/974fa9f9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/974fa9f9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/974fa9f9

Branch: refs/heads/db/6007
Commit: 974fa9f9a60406763a024fe4636bc64f9d81ea83
Parents: c0629be
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Apr 22 09:17:00 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Apr 26 20:31:30 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_rest.py |   28 ++++++++++++++++++++-
 1 files changed, 26 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/974fa9f9/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index a08e8f7..fcfb373 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -18,11 +18,11 @@
 #       under the License.
 
 from datetime import datetime, timedelta
+import json
 
 from pylons import app_globals as g
-from nose.tools import assert_equal
 import mock
-import json
+from nose.tools import assert_equal, assert_in, assert_not_in
 
 from allura.tests import decorators as td
 from alluratest.controller import TestRestApiBase
@@ -71,6 +71,30 @@ class TestRestHome(TestRestApiBase):
         r = self.api_get('/rest/p/test/')
         assert r.status_int == 200
 
+    @td.with_tool('test', 'Tickets', 'bugs')
+    @td.with_tool('test', 'Tickets', 'private-bugs')
+    def test_project_data(self):
+        # Deny anonymous to see 'private-bugs' tool
+        role = M.ProjectRole.by_name('*anonymous')._id
+        read_permission = M.ACE.allow(role, 'read')
+        app = M.Project.query.get(shortname='test').app_instance('private-bugs')
+        if read_permission in app.config.acl:
+            app.config.acl.remove(read_permission)
+
+        # admin sees both 'Tickets' tools
+        r = self.api_get('/rest/p/test/')
+        assert_equal(r.json['name'], 'test')
+        tool_mounts = [t['mount_point'] for t in r.json['tools']]
+        assert_in('bugs', tool_mounts)
+        assert_in('private-bugs', tool_mounts)
+
+        # anonymous sees only non-private tool
+        r = self.app.get('/rest/p/test/', extra_environ={'username': '*anonymous'})
+        assert_equal(r.json['name'], 'test')
+        tool_mounts = [t['mount_point'] for t in r.json['tools']]
+        assert_in('bugs', tool_mounts)
+        assert_not_in('private-bugs', tool_mounts)
+
     def test_unicode(self):
         self.app.post(
             '/wiki/tést/update',


[31/50] git commit: [#5913] restore ui-icon-* classes in top menu

Posted by br...@apache.org.
[#5913] restore ui-icon-* classes in top menu


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/4469a52b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/4469a52b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/4469a52b

Branch: refs/heads/db/6007
Commit: 4469a52b876042a2017b229b606e8c5dbf2257d1
Parents: 22df7b4
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Apr 1 19:30:10 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:37 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/top_nav.html |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/4469a52b/Allura/allura/templates/jinja_master/top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index 599eb3e..1b17d11 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -30,7 +30,7 @@
         {% set selected = True %}
       {% endif %}
     {% endif %}
-    <li{% if selected %} class="selected"{% endif %}>
+    <li class="ui-icon-{{s.ui_icon or 'admin'}}{% if selected %} selected{% endif %}">
       <a href="{{s.url}}">
         <span>
         {{s.label}}


[32/50] git commit: [#5599] Fixed and cleaned up nav-bar selection logic

Posted by br...@apache.org.
[#5599] Fixed and cleaned up nav-bar selection logic

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/323b7d93
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/323b7d93
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/323b7d93

Branch: refs/heads/db/6007
Commit: 323b7d93786f8d79b2070e5193b4a6f1e58f1845
Parents: be11653
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed May 1 20:37:09 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:38 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py                    |    2 +
 Allura/allura/templates/jinja_master/top_nav.html |   19 +--------------
 2 files changed, 4 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/323b7d93/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 8a06566..f95aae0 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -445,6 +445,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                         ordinal = anchored_tools.keys().index(entry.tool_name.lower())
                     else:
                         ordinal = int(ac.options.get('ordinal', 0)) + delta_ordinal
+                    if self.is_nbhd_project and entry.label == 'Admin':
+                        entry.matching_urls.append('%s_admin/' % self.url())
                     if ordinal > max_ordinal:
                         max_ordinal = ordinal
                     entries.append({'ordinal':ordinal,'entry':entry})

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/323b7d93/Allura/allura/templates/jinja_master/top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index 47ef332..8ef4621 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -19,18 +19,7 @@
 {% if c.project %}
 <ul class="dropdown">
   {% for s in c.project.grouped_navbar_entries() %}
-    {% set selected = False %}
-    {% if s.label == 'Home' %}
-      {% set url_length = s.url|length %}
-      {% if request.url.rfind(s.url, -url_length) != -1 %}
-        {% set selected = True %}
-      {% endif %}
-    {% else %}
-      {% if s.matches_url(request) or c.project.neighborhood.url()+'_admin' in request.upath_info %}
-        {% set selected = True %}
-      {% endif %}
-    {% endif %}
-    <li class="{% if selected %}selected{% endif %}">
+    <li class="{% if s.matches_url(request) %}selected{% endif %}">
         <a href="{{s.url}}" class="ui-icon-{{s.ui_icon or 'admin'}}">
             {{s.label}}
         </a>
@@ -38,11 +27,7 @@
         {% if grouped_tool_count %}
             <ul>
                 {%for tool in s.children%}
-                    {% set selected = False %}
-                    {% if tool.matches_url(request) or c.project.neighborhood.url()+'_admin' in request.upath_info%}
-                        {% set selected = True %}
-                    {% endif %}
-                    <li class="{% if selected %}selected{% endif %}"><a href="{{tool.url}}">{{tool.label}}</a></li>
+                    <li class="{% if tool.matches_url(request) %}selected{% endif %}"><a href="{{tool.url}}">{{tool.label}}</a></li>
                 {%endfor%}
             </ul>
         {% endif %}


[05/50] git commit: [#5998] Switched newrelic to use-if-present and added test

Posted by br...@apache.org.
[#5998] Switched newrelic to use-if-present and added test

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c0629be4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c0629be4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c0629be4

Branch: refs/heads/db/6007
Commit: c0629be43185e8b9b389645fe9abc25605e6795f
Parents: 57fadd1
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Apr 26 19:49:30 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Fri Apr 26 20:00:28 2013 +0000

----------------------------------------------------------------------
 Allura/allura/config/middleware.py          |    6 +++++-
 Allura/allura/tests/functional/test_root.py |   13 +++++++++++++
 2 files changed, 18 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c0629be4/Allura/allura/config/middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/middleware.py b/Allura/allura/config/middleware.py
index 09849a1..5bcb32b 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -84,7 +84,11 @@ def _make_core_app(root, global_conf, full_stack=True, **app_conf):
         [pkg_resources.resource_filename('allura', 'etc/mime.types')]
         + mimetypes.knownfiles)
     patches.apply()
-    if asbool(app_conf.get('newrelic')):
+    try:
+        import newrelic
+    except ImportError:
+        pass
+    else:
         patches.newrelic()
     # Configure MongoDB
     ming.configure(**app_conf)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c0629be4/Allura/allura/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index c38710f..707fb12 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -31,6 +31,8 @@ Please read http://pythonpaste.org/webtest/ for more information.
 from tg import config
 from nose.tools import assert_equal
 from ming.orm.ormsession import ThreadLocalORMSession
+import mock
+from IPython.testing.decorators import module_not_available, skipif
 
 from allura.tests import decorators as td
 from allura.tests import TestController
@@ -146,3 +148,14 @@ class TestRootController(TestController):
     def test_slash_redirect(self):
         r = self.app.get('/p',status=301)
         r = self.app.get('/p/',status=302)
+
+    @skipif(module_not_available('newrelic'))
+    def test_newrelic_set_transaction_name(self):
+        from allura.controllers.project import NeighborhoodController
+        with mock.patch('newrelic.agent.callable_name') as callable_name,\
+             mock.patch('newrelic.agent.set_transaction_name') as set_transaction_name:
+            callable_name.return_value = 'foo'
+            r = self.app.get('/p/')
+            arg = callable_name.call_args[0][0]
+            assert_equal(arg.undecorated, NeighborhoodController.index.undecorated)
+            set_transaction_name.assert_called_with('foo')


[42/50] git commit: [#5773] ticket:328 fixed css for log widget

Posted by br...@apache.org.
[#5773]  ticket:328  fixed css for log widget


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/5a51840a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/5a51840a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/5a51840a

Branch: refs/heads/db/6007
Commit: 5a51840a77960d13fe96f897290d0eee09fbe963
Parents: cf33112
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Wed May 1 18:19:25 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:37:05 2013 +0000

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/allura.css        |    2 ++
 Allura/allura/templates/widgets/repo/log.html |    6 ++++--
 2 files changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5a51840a/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index 7b0471c..1334b0c 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -211,6 +211,8 @@ b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
 .pagination_size {
     height: 40px;
 }
+
 tr.rev div.markdown_content p {
     padding: 0;
+    margin-bottom: 0;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5a51840a/Allura/allura/templates/widgets/repo/log.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/log.html b/Allura/allura/templates/widgets/repo/log.html
index 50affe6..c46b425 100644
--- a/Allura/allura/templates/widgets/repo/log.html
+++ b/Allura/allura/templates/widgets/repo/log.html
@@ -45,11 +45,13 @@
                 {% endif %}
                 {% if commit.committed.email != commit.authored.email %}
                 {% if commit.committer_url %}
+                by
                 <a href="{{commit.committer_url}}">{{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}}
-                    {{commit.committed.name}}</a>
+                    {{commit.committed.name}}</a>,
                 pushed
                 {% else %}
-                {{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}} {{commit.committed.name}}
+                by
+                {{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}} {{commit.committed.name}},
                 pushed
                 {% endif %}
                 {% endif %}


[26/50] git commit: [#6186] make SMTP timeouts configurable

Posted by br...@apache.org.
[#6186] make SMTP timeouts configurable


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/404b1528
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/404b1528
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/404b1528

Branch: refs/heads/db/6007
Commit: 404b152838b0ba65de2adc59f721c0a0c291302a
Parents: d34331e
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed May 1 18:33:57 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed May 1 18:33:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/mail_util.py |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/404b1528/Allura/allura/lib/mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index 166bc92..db7ddb3 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -218,11 +218,15 @@ class SMTPClient(object):
         if asbool(tg.config.get('smtp_ssl', False)):
             smtp_client = smtplib.SMTP_SSL(
                 tg.config.get('smtp_server', 'localhost'),
-                asint(tg.config.get('smtp_port', 25)))
+                asint(tg.config.get('smtp_port', 25)),
+                timeout=float(tg.config.get('smtp_timeout', 10)),
+            )
         else:
             smtp_client = smtplib.SMTP(
                 tg.config.get('smtp_server', 'localhost'),
-                asint(tg.config.get('smtp_port', 465)))
+                asint(tg.config.get('smtp_port', 465)),
+                timeout=float(tg.config.get('smtp_timeout', 10)),
+            )
         if tg.config.get('smtp_user', None):
             smtp_client.login(tg.config['smtp_user'], tg.config['smtp_password'])
         if asbool(tg.config.get('smtp_tls', False)):


[38/50] git commit: [#5773] ticket:314 added full commit message, full date, download link in History view

Posted by br...@apache.org.
[#5773] ticket:314 added full commit message, full date, download link in History view


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/e14b56ee
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/e14b56ee
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/e14b56ee

Branch: refs/heads/db/6007
Commit: e14b56ee7bcdc4a1abca954351caa5ef1135cfc2
Parents: a9b5b11
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Apr 19 11:38:44 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:37:02 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/widgets/repo/log.html      |   59 ++++++++++----
 .../forgegit/tests/functional/test_controllers.py  |   12 ++-
 .../forgesvn/tests/functional/test_controllers.py  |    4 +-
 3 files changed, 53 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e14b56ee/Allura/allura/templates/widgets/repo/log.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/log.html b/Allura/allura/templates/widgets/repo/log.html
index d7307a5..11fa918 100644
--- a/Allura/allura/templates/widgets/repo/log.html
+++ b/Allura/allura/templates/widgets/repo/log.html
@@ -33,30 +33,55 @@
       {% for commit in value %}
         <tr class="rev">
           <td>
-            {%if is_file%}
+            <div class="grid-14">
+                {%if is_file%}
                 <div class="grid-1"><input type="checkbox" class="revision" revision="{{commit._id.split(':')[-1]}}" url_commit="{{commit.url()}}"></div>
-            {%endif%}
-            {{commit.summary}}
-            <br/>
-            {% if commit.committed.email != commit.authored.email %}
-              {% if commit.committer_url %}
+                {%endif%}
+                {%for tag in c.app.repo.symbolics_for_commit(commit)[1]%}
+                        <a href="{{c.app.repo.url()}}ci/{{tag}}/tree{{request.params.get('path')}}">{{tag}}</a>
+                {%endfor%}
+                {% if commit.committed.email != commit.authored.email %}
+                {% if commit.committer_url %}
                 <a href="{{commit.committer_url}}">{{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}}
-                {{commit.committed.name}}</a>
+                    {{commit.committed.name}}</a>
                 pushed
-              {% else %}
+                {% else %}
                 {{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}} {{commit.committed.name}}
                 pushed
-              {% endif %}
-            {% endif %}
-             <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a>
-            by
-              {{email_gravatar(commit.authored.email, title=commit.authored.name, size=16)}} {{commit.authored.name}}
+                {% endif %}
+                {% endif %}
+                <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a>
+                by
+                {{email_gravatar(commit.authored.email, title=commit.authored.name, size=16)}} {{commit.authored.name}}
+                {%if is_file%}
+                    {%if request.params.get('path')[:1]=='/'%}
+                        {%set path = request.params.get('path')[1:]%}
+                    {%else%}
+                        {%set path = request.params.get('path')%}
+                    {%endif%}
+
+                    {{commit.tree.get_blob(path).size}} Bytes
+                {%endif%}
+            </div>
+            <div>
+              {{g.markdown.convert(commit.message)}}
+            </div>
           </td>
-          <td>
-            {% if commit.committed.date %}{{abbr_date(commit.committed.date)}}{% endif %}
+          <td style="vertical-align: text-top">
+            {% if commit.committed.date %}{{commit.committed.date}}{% endif %}
           </td>
-          <td style="text-align: right">
-            <a href="{{commit.url()}}tree/">Tree</a>
+          <td style="text-align: left; vertical-align: text-top">
+            <a href="{{commit.url()}}tree{{request.params.get('path')}}">
+            {%if is_file%}
+                View
+            {% else %}
+                Tree
+            {%endif%}
+            </a>
+              {%if is_file%}
+              <br/>
+              <a href="{{commit.url()}}tree{{request.params.get('path')}}?format=raw ">Download</a>
+              {%endif%}
           </td>
         </tr>
       {% endfor %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e14b56ee/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 186b46a..78ff5a9 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -110,10 +110,16 @@ class TestRootController(_TestCase):
     def test_log(self):
         resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
         assert 'Initial commit' in resp
-        assert 'Change README' in resp
+        assert '<div class="markdown_content"><p>Change README</p></div>' in resp
+        assert 'tree/README?format=raw ">Download</a>' not in resp
+        assert'28 Bytes' not in resp.html.find('td').contents[1].text
+        assert 'Tree' in resp.html.findAll('td')[2].text, resp.html.findAll('td')[2].text
         resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
-        assert 'Change README ' in resp
-        assert 'Add README ' in resp
+        assert'28 Bytes' in resp.html.find('td').contents[1].text
+        assert 'View' in resp.html.findAll('td')[2].text
+        assert 'Change README' in resp
+        assert 'tree/README?format=raw ">Download</a>' in resp
+        assert 'Add README' in resp
         assert "Initial commit " not in resp
         resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/a/b/c/')
         assert 'Remove file' in resp

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e14b56ee/ForgeSVN/forgesvn/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/functional/test_controllers.py b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
index 90af545..9ab3b57 100644
--- a/ForgeSVN/forgesvn/tests/functional/test_controllers.py
+++ b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
@@ -138,10 +138,10 @@ class TestRootController(SVNTestController):
         assert 'Create readme' in r
         r = self.app.get('/src/2/log/?path=')
         assert "Create readme" in r
-        assert "Add path " in r
+        assert "Add path" in r
         r = self.app.get('/src/2/log/?path=README')
         assert "Modify readme" not in r
-        assert "Create readme " in r
+        assert "Create readme" in r
         r = self.app.get('/src/2/log/?path=/a/b/c/')
         assert 'Add path' in r
         assert 'Remove hello.txt' not in r


[34/50] git commit: [#5599] Removed empty children list from _nav.json

Posted by br...@apache.org.
[#5599] Removed empty children list from _nav.json

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/dbee43f2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/dbee43f2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/dbee43f2

Branch: refs/heads/db/6007
Commit: dbee43f23c3ae07ced764f33392fe199409f76ce
Parents: 323b7d9
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Thu May 2 15:32:56 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu May 2 15:41:56 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/project.py |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dbee43f2/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index f8789a3..d47caf4 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -311,8 +311,10 @@ class ProjectController(FeedController):
     def _nav(self):
         menu = []
         for s in c.project.grouped_navbar_entries():
-            children = [dict(name=child.label, url=child.url, icon=child.ui_icon) for child in s.children]
-            menu.append(dict(name=s.label, url=s.url, icon=s.ui_icon, children=children))
+            entry = dict(name=s.label, url=s.url, icon=s.ui_icon)
+            if s.children:
+                entry['children'] = [dict(name=child.label, url=child.url, icon=child.ui_icon) for child in s.children]
+            menu.append(entry)
         return dict(menu=menu)
 
     @expose()


[49/50] git commit: [#6007] Better installation of subproject in bootstrap. Don't leave a c.user/project

Posted by br...@apache.org.
[#6007] Better installation of subproject in bootstrap.  Don't leave a c.user/project

Default subproject is now named, not first tool in test project,
and with a wiki instead of no tools.

This also stops leaving a c.user and c.project around.  So many tests
are updated to explicitly set up a c.user or c.project if they were
relying on that.


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8d01a3b8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8d01a3b8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8d01a3b8

Branch: refs/heads/db/6007
Commit: 8d01a3b8b016d1dfbf5f045d994a33937b6eb437
Parents: 632df87
Author: Dave Brondsema <db...@geek.net>
Authored: Mon Mar 25 14:39:49 2013 -0700
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri May 3 15:50:36 2013 -0400

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py                   |    4 +-
 Allura/allura/lib/plugin.py                        |    9 +-
 Allura/allura/model/discuss.py                     |    2 +-
 Allura/allura/model/project.py                     |    4 +-
 Allura/allura/tests/functional/test_discuss.py     |    3 +-
 Allura/allura/tests/functional/test_home.py        |    5 +-
 .../allura/tests/functional/test_neighborhood.py   |    4 +-
 Allura/allura/tests/functional/test_root.py        |   10 +-
 Allura/allura/tests/model/test_project.py          |   45 +++--
 Allura/allura/tests/test_globals.py                |  152 ++++++++-------
 Allura/allura/tests/test_mail_util.py              |    2 +-
 Allura/allura/tests/unit/test_post_model.py        |    8 +-
 Allura/allura/websetup/bootstrap.py                |   25 ++-
 13 files changed, 156 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index b030d6f..c6004d3 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -27,6 +27,7 @@ import json
 import datetime
 from urllib import urlencode
 from subprocess import Popen, PIPE
+import traceback
 
 import activitystream
 import pkg_resources
@@ -71,7 +72,8 @@ class ForgeMarkdown(markdown.Markdown):
         try:
             return markdown.Markdown.convert(self, source)
         except Exception:
-            log.info('Invalid markdown: %s', source, exc_info=True)
+            log.info('Invalid markdown: %s  Upwards trace is %s', source,
+                     ''.join(traceback.format_stack()), exc_info=True)
             escaped = h.really_unicode(source)
             escaped = cgi.escape(escaped)
             return h.html.literal(u"""<p><strong>ERROR!</strong> The markdown supplied could not be parsed correctly.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 3bb1655..4bbf557 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -584,18 +584,21 @@ class ProjectRegistrationProvider(object):
             g.post_event('project_created')
         return p
 
-    def register_subproject(self, project, name, user, install_apps):
+    def register_subproject(self, project, name, user, install_apps, project_name=None):
         from allura import model as M
         assert h.re_project_name.match(name), 'Invalid subproject shortname'
         shortname = project.shortname + '/' + name
+        ordinal = int(project.ordered_mounts(include_hidden=True)[-1]['ordinal']) + 1
         sp = M.Project(
             parent_id=project._id,
             neighborhood_id=project.neighborhood_id,
             shortname=shortname,
-            name=name,
+            name=project_name or name,
             database_uri=project.database_uri,
             last_updated = datetime.utcnow(),
-            is_root=False)
+            is_root=False,
+            ordinal=ordinal,
+        )
         with h.push_config(c, project=sp):
             M.AppConfig.query.remove(dict(project_id=c.project._id))
             if install_apps:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 4375077..06efbdd 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -604,7 +604,7 @@ class Post(Message, VersionedArtifact, ActivityObject):
         self.status = 'ok'
         author = self.author()
         security.simple_grant(
-            self.acl, author.project_role()._id, 'moderate')
+            self.acl, author.project_role(self.project)._id, 'moderate')
         self.commit()
         if (c.app.config.options.get('PostingPolicy') == 'ApproveOnceModerated'
             and author._id != None):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 982dad8..c90b7ac 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -616,11 +616,11 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             if ac.tool_name == tool_type:
                 return ac
 
-    def new_subproject(self, name, install_apps=True, user=None):
+    def new_subproject(self, name, install_apps=True, user=None, project_name=None):
         if not h.re_project_name.match(name):
             raise exceptions.ToolError, 'Mount point "%s" is invalid' % name
         provider = plugin.ProjectRegistrationProvider.get()
-        return provider.register_subproject(self, name, user or c.user, install_apps)
+        return provider.register_subproject(self, name, user or c.user, install_apps, project_name=project_name)
 
     def ordered_mounts(self, include_hidden=False):
         '''Returns an array of a projects mounts (tools and sub-projects) in

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 633f078..81055f5 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -125,7 +125,8 @@ class TestDiscuss(TestController):
         # set wiki page private
         from forgewiki.model import Page
         page = Page.query.get(_id=thread.ref.artifact._id)  # need to look up the page directly, so ming is aware of our change
-        role_admin = M.ProjectRole.by_name('Admin')._id
+        project = M.Project.query.get(shortname='test')
+        role_admin = M.ProjectRole.by_name('Admin', project)._id
         page.acl = [
             M.ACE.allow(role_admin, M.ALL_PERMISSIONS),
             M.DENY_ALL,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/functional/test_home.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_home.py b/Allura/allura/tests/functional/test_home.py
index 3e11437..03e6860 100644
--- a/Allura/allura/tests/functional/test_home.py
+++ b/Allura/allura/tests/functional/test_home.py
@@ -64,8 +64,8 @@ class TestProjectHome(TestController):
                 c.app = p.install_app('wiki', tool_name, tool_name, i)
         response = self.app.get('/p/test/_nav.json')
         menu = response.json['menu']
-        assert_equal(len(menu[1]['children']), 11)
-        assert {u'url': u'/p/test/_list/wiki', u'name': u'More...', u'icon': u'tool-wiki'} in menu[1]['children']
+        assert_equal(len(menu[0]['children']), 11)
+        assert {u'url': u'/p/test/_list/wiki', u'name': u'More...', u'icon': u'tool-wiki'} in menu[0]['children']
 
     @td.with_wiki
     def test_neighborhood_home(self):
@@ -115,4 +115,3 @@ class TestProjectHome(TestController):
         assert '<td>Test Admin</td>' in r
         assert '<td><a href="/u/test-admin/">test-admin</a></td>' in r
         assert '<td>Admin</td>' in r
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/functional/test_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index 1d7db26..8a53896 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -800,10 +800,12 @@ class TestNeighborhood(TestController):
                           extra_environ=dict(username='root'))
 
     def test_add_a_project_link(self):
+        from pylons import tmpl_context as c
         # Install Home tool for all neighborhoods
         for nb in M.Neighborhood.query.find().all():
             p = nb.neighborhood_project
-            p.install_app('home', 'home', 'Home', ordinal=0)
+            with h.push_config(c, user=M.User.query.get()):
+                p.install_app('home', 'home', 'Home', ordinal=0)
         r = self.app.get('/p/')
         assert 'Add a Project' in r
         r = self.app.get('/u/', extra_environ=dict(username='test-user'))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index 707fb12..aa77873 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -29,6 +29,7 @@ Please read http://pythonpaste.org/webtest/ for more information.
 
 """
 from tg import config
+from pylons import tmpl_context as c
 from nose.tools import assert_equal
 from ming.orm.ormsession import ThreadLocalORMSession
 import mock
@@ -82,7 +83,7 @@ class TestRootController(TestController):
     def test_project_browse(self):
         com_cat = M.ProjectCategory.query.find(dict(label='Communications')).first()
         fax_cat = M.ProjectCategory.query.find(dict(label='Fax')).first()
-        M.Project.query.find(dict(name='adobe-1')).first().category_id = com_cat._id
+        M.Project.query.find(dict(shortname='adobe-1')).first().category_id = com_cat._id
         response = self.app.get('/browse')
         assert len(response.html.findAll('a',{'href':'/adobe/adobe-1/'})) == 1
         assert len(response.html.findAll('a',{'href':'/adobe/adobe-2/'})) == 1
@@ -114,7 +115,8 @@ class TestRootController(TestController):
         # Install home app
         nb = M.Neighborhood.query.get(name='Adobe')
         p = nb.neighborhood_project
-        p.install_app('home', 'home', 'Home', ordinal=0)
+        with push_config(c, user=M.User.query.get(username='test-admin')):
+            p.install_app('home', 'home', 'Home', ordinal=0)
 
         response = self.app.get('/adobe/')
         projects = response.html.findAll('div',{'class':'border card'})
@@ -127,8 +129,8 @@ class TestRootController(TestController):
     def test_neighborhood_project_browse(self):
         com_cat = M.ProjectCategory.query.find(dict(label='Communications')).first()
         fax_cat = M.ProjectCategory.query.find(dict(label='Fax')).first()
-        M.Project.query.find(dict(name='adobe-1')).first().category_id = com_cat._id
-        M.Project.query.find(dict(name='adobe-2')).first().category_id = fax_cat._id
+        M.Project.query.find(dict(shortname='adobe-1')).first().category_id = com_cat._id
+        M.Project.query.find(dict(shortname='adobe-2')).first().category_id = fax_cat._id
         response = self.app.get('/adobe/browse')
         assert len(response.html.findAll('a',{'href':'/adobe/adobe-1/'})) == 1
         assert len(response.html.findAll('a',{'href':'/adobe/adobe-2/'})) == 1

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/model/test_project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index 16f5a97..d88fbdd 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -20,7 +20,7 @@
 """
 Model tests for project
 """
-from nose.tools import with_setup, assert_equal
+from nose.tools import with_setup, assert_equals, assert_in
 from pylons import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 
@@ -40,29 +40,28 @@ def setUp():
 def setup_with_tools():
     setup_global_objects()
 
-@with_setup(setUp)
 def test_project():
-    assert type(c.project.sidebar_menu()) == list
-    assert c.project.script_name in c.project.url()
+    assert_equals(type(c.project.sidebar_menu()), list)
+    assert_in(c.project.script_name, c.project.url())
     old_proj = c.project
     h.set_context('test/sub1', neighborhood='Projects')
-    assert type(c.project.sidebar_menu()) == list
-    assert type(c.project.sitemap()) == list
-    assert c.project.sitemap()[0].label == 'Admin'
-    assert old_proj in list(c.project.parent_iter())
+    assert_equals(type(c.project.sidebar_menu()), list)
+    assert_equals(type(c.project.sitemap()), list)
+    assert_equals(c.project.sitemap()[1].label, 'Admin')
+    assert_in(old_proj, list(c.project.parent_iter()))
     h.set_context('test', 'wiki', neighborhood='Projects')
     adobe_nbhd = M.Neighborhood.query.get(name='Adobe')
     p = M.Project.query.get(shortname='adobe-1', neighborhood_id=adobe_nbhd._id)
     # assert 'http' in p.url() # We moved adobe into /adobe/, not http://adobe....
-    assert p.script_name in p.url()
-    assert c.project.shortname == 'test'
-    assert '<p>' in c.project.description_html
+    assert_in(p.script_name, p.url())
+    assert_equals(c.project.shortname, 'test')
+    assert_in('<p>', c.project.description_html)
     c.project.uninstall_app('hello-test-mount-point')
     ThreadLocalORMSession.flush_all()
 
     c.project.install_app('Wiki', 'hello-test-mount-point')
     c.project.support_page = 'hello-test-mount-point'
-    assert_equal(c.project.app_config('wiki').tool_name, 'wiki')
+    assert_equals(c.project.app_config('wiki').tool_name, 'wiki')
     ThreadLocalORMSession.flush_all()
     with td.raises(ToolError):
         # already installed
@@ -92,10 +91,11 @@ def test_project():
     c.app.config.breadcrumbs()
 
 def test_subproject():
+    project = M.Project.query.get(shortname='test')
     with td.raises(ToolError):
         # name exceeds 15 chars
-        sp = c.project.new_subproject('test-project-nose')
-    sp = c.project.new_subproject('test-proj-nose')
+        sp = project.new_subproject('test-project-nose')
+    sp = project.new_subproject('test-proj-nose')
     spp = sp.new_subproject('spp')
     ThreadLocalORMSession.flush_all()
     sp.delete()
@@ -105,18 +105,21 @@ def test_subproject():
 def test_anchored_tools():
     c.project.neighborhood.anchored_tools = 'wiki:Wiki, tickets:Ticket'
     c.project.install_app = MagicMock()
-    assert c.project.sitemap()[0].label == 'Wiki'
-    assert c.project.install_app.call_args[0][0] == 'tickets'
-    assert c.project.ordered_mounts()[0]['ac'].tool_name == 'wiki'
+    assert_equals(c.project.sitemap()[0].label, 'Wiki')
+    assert_equals(c.project.install_app.call_args[0][0], 'tickets')
+    assert_equals(c.project.ordered_mounts()[0]['ac'].tool_name, 'wiki')
 
 
 def test_set_ordinal_to_admin_tool():
-    assert c.project.sitemap()
-    assert c.project.app_config('admin').options.ordinal == 100
+    with h.push_config(c,
+                       user=M.User.anonymous(),
+                       project=M.Project.query.get(shortname='test')):
+        assert c.project.sitemap()
+        assert c.project.app_config('admin').options.ordinal == 100
 
 def test_users_and_roles():
-    p = c.project
-    sub = c.project.direct_subprojects.next()
+    p = M.Project.query.get(shortname='test')
+    sub = p.direct_subprojects.next()
     u = M.User.by_username('test-admin')
     assert p.users_with_role('Admin') == [u]
     assert p.users_with_role('Admin') == sub.users_with_role('Admin')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index bf17979..6f37cd0 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -59,10 +59,9 @@ def test_app_globals():
 
 
 @with_setup(teardown=setUp) # reset everything we changed
-def test_macros():
+def test_macro_projects():
     file_name = 'neo-icon-set-454545-256x350.png'
     file_path = os.path.join(allura.__path__[0],'nf','allura','images',file_name)
-    curr_project = c.project
 
     p_nbhd = M.Neighborhood.query.get(name='Projects')
     p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
@@ -98,74 +97,87 @@ def test_macros():
 
     ThreadLocalORMSession.flush_all()
 
-    with h.push_context(p_nbhd.neighborhood_project._id):
+    with h.push_config(c,
+                       project=p_nbhd.neighborhood_project,
+                       user=M.User.by_username('test-admin')):
         r = g.markdown_wiki.convert('[[projects]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' in r, r
         r = g.markdown_wiki.convert('[[projects labels=root]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' not in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' not in r, r
         r = g.markdown_wiki.convert('[[projects labels=sub1]]')
-        assert '<img alt="test Logo"' not in r, r
-        assert '<img alt="sub1 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' not in r, r
+        assert '<img alt="A Subproject Logo"' in r, r
         r = g.markdown_wiki.convert('[[projects labels=test]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' in r, r
         r = g.markdown_wiki.convert('[[projects labels=test,root]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' not in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' not in r, r
         r = g.markdown_wiki.convert('[[projects labels=test,sub1]]')
-        assert '<img alt="test Logo"' not in r, r
-        assert '<img alt="sub1 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' not in r, r
+        assert '<img alt="A Subproject Logo"' in r, r
         r = g.markdown_wiki.convert('[[projects labels=root|sub1]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' in r, r
         r = g.markdown_wiki.convert('[[projects labels=test,root|root,sub1]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' not in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' not in r, r
         r = g.markdown_wiki.convert('[[projects labels=test,root|test,sub1]]')
-        assert '<img alt="test Logo"' in r, r
-        assert '<img alt="sub1 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' in r, r
+        assert '<img alt="A Subproject Logo"' in r, r
         r = g.markdown_wiki.convert('[[projects show_total=True sort=random]]')
         assert '<p class="macro_projects_total">3 Projects</p>' in r, r
         r = g.markdown_wiki.convert('[[projects show_total=True private=True sort=random]]')
         assert '<p class="macro_projects_total">1 Projects</p>' in r, r
-        assert '<img alt="test2 Logo"' in r, r
-        assert '<img alt="test Logo"' not in r, r
-        assert '<img alt="sub1 Logo"' not in r, r
+        assert '<img alt="Test 2 Logo"' in r, r
+        assert '<img alt="Test Project Logo"' not in r, r
+        assert '<img alt="A Subproject Logo"' not in r, r
 
         r = g.markdown_wiki.convert('[[projects show_proj_icon=True]]')
-        assert '<img alt="test Logo"' in r
+        assert '<img alt="Test Project Logo"' in r
         r = g.markdown_wiki.convert('[[projects show_proj_icon=False]]')
-        assert '<img alt="test Logo"' not in r
+        assert '<img alt="Test Project Logo"' not in r
+
 
-    c.project = curr_project
-    r = g.markdown_wiki.convert('[[download_button]]')
+def test_macro_download_button():
+    p_nbhd = M.Neighborhood.query.get(name='Projects')
+    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
+    with h.push_config(c, project=p_test):
+        r = g.markdown_wiki.convert('[[download_button]]')
     assert_equal(r, '<div class="markdown_content"><p><span class="download-button-%s" style="margin-bottom: 1em; display: block;"></span></p>\n</div>' % p_test._id)
-    h.set_context('--init--', 'wiki', neighborhood='Projects')
-    r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
-    assert 'Home modified by' in r, r
-    orig_len = len(r)
-    # Make project private & verify we don't see its new feed items
-    proj = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
-    c.user = M.User.anonymous()
-    proj.acl.insert(0, M.ACE.deny(
-            c.user.project_role(proj)._id, 'read'))
-    ThreadLocalORMSession.flush_all()
-    pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id)
-    pg.text = 'Change'
-    pg.commit()
-    r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
-    new_len = len(r)
-    assert new_len == orig_len
-    p = BM.BlogPost(title='test me', neighborhood_id=p_test.neighborhood_id)
-    p.text = 'test content'
-    p.state = 'published'
-    p.make_slug()
-    p.commit()
-    ThreadLocalORMSession.flush_all()
-    r = g.markdown_wiki.convert('[[neighborhood_blog_posts]]')
-    assert 'test content' in r
+
+
+def test_macro_neighborhood_feeds():
+    p_nbhd = M.Neighborhood.query.get(name='Projects')
+    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
+    with h.push_context('--init--', 'wiki', neighborhood='Projects'):
+        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
+        assert 'Home modified by' in r, r
+        orig_len = len(r)
+        # Make project private & verify we don't see its new feed items
+        anon = M.User.anonymous()
+        p_test.acl.insert(0, M.ACE.deny(
+                anon.project_role(p_test)._id, 'read'))
+        ThreadLocalORMSession.flush_all()
+        pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id)
+        pg.text = 'Change'
+        with h.push_config(c, user=M.User.by_username('test-admin')):
+            pg.commit()
+        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
+        new_len = len(r)
+        assert new_len == orig_len
+        p = BM.BlogPost(title='test me', neighborhood_id=p_test.neighborhood_id)
+        p.text = 'test content'
+        p.state = 'published'
+        p.make_slug()
+        with h.push_config(c, user=M.User.by_username('test-admin')):
+            p.commit()
+        ThreadLocalORMSession.flush_all()
+        with h.push_config(c, user=anon):
+            r = g.markdown_wiki.convert('[[neighborhood_blog_posts]]')
+        assert 'test content' in r
 
 @with_setup(teardown=setUp) # reset everything we changed
 def test_macro_members():
@@ -189,7 +201,8 @@ def test_macro_members():
 def test_macro_project_admins():
     user = M.User.by_username('test-admin')
     user.display_name = u'Test Ådmin'
-    r = g.markdown_wiki.convert('[[project_admins]]')
+    with h.push_context('test', neighborhood='Projects'):
+        r = g.markdown_wiki.convert('[[project_admins]]')
     assert_equal(r, u'<div class="markdown_content"><h6>Project Admins:</h6><ul class="md-users-list"><li><a href="/u/test-admin/">Test Ådmin</a></li></ul>\n</div>')
 
 @with_setup(teardown=setUp) # reset everything we changed
@@ -198,7 +211,8 @@ def test_macro_project_admins_one_br():
     p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
     p_test.add_user(M.User.by_username('test-user'), ['Admin'])
     ThreadLocalORMSession.flush_all()
-    r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]')
+    with h.push_config(c, project=p_test):
+        r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]')
 
     assert not '</a><br /><br /><a href=' in r, r
     assert '</a></li><li><a href=' in r, r
@@ -236,7 +250,8 @@ def test_macro_include_extra_br():
 
 
 def test_markdown_toc():
-    r = g.markdown_wiki.convert("""[TOC]
+    with h.push_context('test', neighborhood='Projects'):
+        r = g.markdown_wiki.convert("""[TOC]
 
 # Header 1
 
@@ -272,12 +287,14 @@ def test_markdown_links():
     assert_in('href="http://foobar.sf.net/">http://foobar.sf.net/</a> about', text)
 
 def test_markdown_and_html():
-    r = g.markdown_wiki.convert('<div style="float:left">blah</div>')
+    with h.push_context('test', neighborhood='Projects'):
+        r = g.markdown_wiki.convert('<div style="float:left">blah</div>')
     assert '<div style="float: left;">blah</div>' in r, r
 
 
 def test_markdown_within_html():
-    r = g.markdown_wiki.convert('<div style="float:left" markdown>**blah**</div>')
+    with h.push_context('test', neighborhood='Projects'):
+        r = g.markdown_wiki.convert('<div style="float:left" markdown>**blah**</div>')
     assert '''<div style="float: left;">
 <p><strong>blah</strong></p>
 </div>''' in r, r
@@ -344,13 +361,6 @@ def test_markdown_autolink_with_escape():
     assert 'href="http://www.phpmyadmin.net/home_page/security/#target"' in r, r
 
 
-def test_macro_projects():
-    r = g.markdown.convert('[[projects]]')
-    assert '[[projects]]' in r, r
-    with h.push_context(M.Neighborhood.query.get(name='Projects').neighborhood_project._id):
-        r = g.markdown_wiki.convert('[[projects]]')
-        assert '<div class="border card">' in r, r
-
 @td.with_wiki
 def test_macro_include():
     r = g.markdown.convert('[[include ref=Home id=foo]]')
@@ -398,23 +408,27 @@ def test_filtering():
     # set up for test
     from random import choice
     random_trove = choice(M.TroveCategory.query.find().all())
-    test_project = M.Project.query.get(name='test')
+    test_project = M.Project.query.get(shortname='test')
     test_project_troves = getattr(test_project, 'trove_' + random_trove.type)
     test_project_troves.append(random_trove._id)
     ThreadLocalORMSession.flush_all()
 
     p_nbhd = M.Neighborhood.query.get(name='Projects')
-    with h.push_context(p_nbhd.neighborhood_project._id):
+    with h.push_config(c,
+                       project=p_nbhd.neighborhood_project,
+                       user=M.User.by_username('test-admin')):
         r = g.markdown_wiki.convert('[[projects category="%s"]]' % random_trove.fullpath)
         project_names = get_project_names(r)
-        assert [test_project.name, ] == project_names
+        assert_equal([test_project.name], project_names)
 
 
 def test_projects_macro():
     two_column_style = 'width: 330px;'
 
     p_nbhd = M.Neighborhood.query.get(name='Projects')
-    with h.push_context(p_nbhd.neighborhood_project._id):
+    with h.push_config(c,
+                       project=p_nbhd.neighborhood_project,
+                       user=M.User.anonymous()):
         # test columns
         r = g.markdown_wiki.convert('[[projects display_mode=list columns=2]]')
         assert two_column_style in r
@@ -471,7 +485,7 @@ def test_hideawards_macro():
     award.full = u'Award full'
     award.created_by_neighborhood_id = p_nbhd._id
 
-    project = M.Project.query.get(neighborhood_id=p_nbhd._id, name=u'test')
+    project = M.Project.query.get(neighborhood_id=p_nbhd._id, shortname=u'test')
 
     award_grant = M.AwardGrant(award=award,
                                granted_by_neighborhood=p_nbhd,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/test_mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py
index a80155e..bb22ac6 100644
--- a/Allura/allura/tests/test_mail_util.py
+++ b/Allura/allura/tests/test_mail_util.py
@@ -64,7 +64,7 @@ class TestReactor(unittest.TestCase):
     def test_parse_address_good(self):
         topic, project, app = parse_address('foo@wiki.test.p' + config.common_suffix)
         assert_equal(topic, 'foo')
-        assert_equal(project.name, 'test')
+        assert_equal(project.shortname, 'test')
         assert_equal(app.__class__.__name__, 'ForgeWikiApp')
 
     def test_unicode_simple_message(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/tests/unit/test_post_model.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_post_model.py b/Allura/allura/tests/unit/test_post_model.py
index bb1cbe0..9ac2256 100644
--- a/Allura/allura/tests/unit/test_post_model.py
+++ b/Allura/allura/tests/unit/test_post_model.py
@@ -15,6 +15,10 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+from pylons import tmpl_context as c
+
+from allura.lib import helpers as h
+from allura import model as M
 from allura.tests.unit import WithDatabase
 from allura.tests.unit import patches
 from allura.tests.unit.factories import create_post
@@ -32,6 +36,6 @@ class TestPostModel(WithDatabase):
         assert self.post.status == 'pending'
 
     def test_that_it_can_be_approved(self):
-        self.post.approve()
+        with h.push_config(c, user=M.User()):
+            self.post.approve()
         assert self.post.status == 'ok'
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8d01a3b8/Allura/allura/websetup/bootstrap.py
----------------------------------------------------------------------
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index f518463..9d09927 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -35,6 +35,7 @@ from ming.orm.ormsession import ThreadLocalORMSession
 
 import allura
 from allura.lib import plugin
+from allura.lib import helpers as h
 from allura import model as M
 from allura.websetup import schema
 from allura.command import EnsureIndexCommand
@@ -87,7 +88,6 @@ def bootstrap(command, conf, vars):
         log.error('Error clearing solr index')
     if asbool(conf.get('cache_test_data')):
         if restore_test_data():
-            from allura.lib import helpers as h
             h.set_context('test', neighborhood='Projects')
             return
     log.info('Initializing search')
@@ -209,10 +209,8 @@ def bootstrap(command, conf, vars):
         # TODO: Hope that Ming can be improved to at least avoid stuff below
         sess.flush(x)
 
-    c.project = p0
-    c.user = u_admin
-    p1 = p0.new_subproject('sub1')
     ThreadLocalORMSession.flush_all()
+
     if asbool(conf.get('load_test_data')):
         if asbool(conf.get('cache_test_data')):
             cache_test_data()
@@ -220,10 +218,21 @@ def bootstrap(command, conf, vars):
         # regular first-time setup
         p0.add_user(u_admin, ['Admin'])
         log.info('Registering initial apps')
-        for ep_name, app in g.entry_points['tool'].iteritems():
-            if not app.installable:
-                continue
-            p0.install_app(ep_name)
+        with h.push_config(c, user=u_admin):
+            for ep_name, app in g.entry_points['tool'].iteritems():
+                if not app.installable:
+                    continue
+                p0.install_app(ep_name)
+
+    # reload our p0 project so that p0.app_configs is accurate with all the newly installed apps
+    ThreadLocalORMSession.flush_all()
+    ThreadLocalORMSession.close_all()
+    p0 = M.Project.query.get(_id=p0._id)
+    sub = p0.new_subproject('sub1', project_name='A Subproject')
+    with h.push_config(c, user=u_admin):
+        sub.install_app('wiki')
+
+
     ThreadLocalORMSession.flush_all()
     ThreadLocalORMSession.close_all()
 


[21/50] git commit: [#6179] don't change 'shortname' var

Posted by br...@apache.org.
[#6179] don't change 'shortname' var


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/3d3f1997
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3d3f1997
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3d3f1997

Branch: refs/heads/db/6007
Commit: 3d3f199782450d1c497a8146528dfe17b2f8c62f
Parents: f746109
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Apr 30 18:30:58 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Apr 30 18:30:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3d3f1997/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 02aae3a..3bb1655 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -465,8 +465,10 @@ class ProjectRegistrationProvider(object):
         self.rate_limit(user, neighborhood)
 
         if user_project and shortname.startswith('u/'):
-            shortname = shortname.replace('u/', '', 1)
-        if not h.re_project_name.match(shortname):
+            check_shortname = shortname.replace('u/', '', 1)
+        else:
+            check_shortname = shortname
+        if not h.re_project_name.match(check_shortname):
             raise ValueError('Invalid project shortname: %s' % shortname)
 
         p = M.Project.query.get(shortname=shortname, neighborhood_id=neighborhood._id)


[40/50] git commit: [#5773] ticket:314 fixed filesize errors

Posted by br...@apache.org.
[#5773] ticket:314 fixed filesize errors


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/94b70cea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/94b70cea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/94b70cea

Branch: refs/heads/db/6007
Commit: 94b70cea70a115851b40446780efc17fc96222be
Parents: e14b56e
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Apr 19 17:11:58 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:37:04 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/widgets/repo/log.html      |   24 +++++---------
 .../forgegit/tests/functional/test_controllers.py  |    8 ++--
 2 files changed, 13 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94b70cea/Allura/allura/templates/widgets/repo/log.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/log.html b/Allura/allura/templates/widgets/repo/log.html
index 11fa918..086b0b3 100644
--- a/Allura/allura/templates/widgets/repo/log.html
+++ b/Allura/allura/templates/widgets/repo/log.html
@@ -34,12 +34,10 @@
         <tr class="rev">
           <td>
             <div class="grid-14">
+                {{g.markdown.convert(commit.message)}}
                 {%if is_file%}
-                <div class="grid-1"><input type="checkbox" class="revision" revision="{{commit._id.split(':')[-1]}}" url_commit="{{commit.url()}}"></div>
+                    <div class="grid-1"><input type="checkbox" class="revision" revision="{{commit._id.split(':')[-1]}}" url_commit="{{commit.url()}}"></div>
                 {%endif%}
-                {%for tag in c.app.repo.symbolics_for_commit(commit)[1]%}
-                        <a href="{{c.app.repo.url()}}ci/{{tag}}/tree{{request.params.get('path')}}">{{tag}}</a>
-                {%endfor%}
                 {% if commit.committed.email != commit.authored.email %}
                 {% if commit.committer_url %}
                 <a href="{{commit.committer_url}}">{{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}}
@@ -51,21 +49,17 @@
                 {% endif %}
                 {% endif %}
                 <a href="{{commit.url()}}">{{commit.shorthand_id()}}</a>
+                {% if c.app.repo.symbolics_for_commit(commit)[1] %}
+                    ({% for tag in c.app.repo.symbolics_for_commit(commit)[1] -%}
+                        <a href="{{c.app.repo.url()}}ci/{{tag}}/tree{{request.params.get('path')}}">{{tag}}</a>{% if not loop.last %}&nbsp;{% endif %}
+                    {%- endfor %})
+                {% endif %}
                 by
                 {{email_gravatar(commit.authored.email, title=commit.authored.name, size=16)}} {{commit.authored.name}}
                 {%if is_file%}
-                    {%if request.params.get('path')[:1]=='/'%}
-                        {%set path = request.params.get('path')[1:]%}
-                    {%else%}
-                        {%set path = request.params.get('path')%}
-                    {%endif%}
-
-                    {{commit.tree.get_blob(path).size}} Bytes
+                    ({{commit.tree.get_obj_by_path(request.params.get('path')).size|filesizeformat}})
                 {%endif%}
             </div>
-            <div>
-              {{g.markdown.convert(commit.message)}}
-            </div>
           </td>
           <td style="vertical-align: text-top">
             {% if commit.committed.date %}{{commit.committed.date}}{% endif %}
@@ -80,7 +74,7 @@
             </a>
               {%if is_file%}
               <br/>
-              <a href="{{commit.url()}}tree{{request.params.get('path')}}?format=raw ">Download</a>
+              <a href="{{commit.url()}}tree{{request.params.get('path')}}?format=raw">Download</a>
               {%endif%}
           </td>
         </tr>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94b70cea/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 78ff5a9..d5c8365 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -111,14 +111,14 @@ class TestRootController(_TestCase):
         resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/')
         assert 'Initial commit' in resp
         assert '<div class="markdown_content"><p>Change README</p></div>' in resp
-        assert 'tree/README?format=raw ">Download</a>' not in resp
-        assert'28 Bytes' not in resp.html.find('td').contents[1].text
+        assert 'tree/README?format=raw">Download</a>' not in resp
+        assert '28 Bytes' not in resp.html.find('td').contents[1].text
         assert 'Tree' in resp.html.findAll('td')[2].text, resp.html.findAll('td')[2].text
         resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/README')
-        assert'28 Bytes' in resp.html.find('td').contents[1].text
+        assert '28 Bytes' in resp.html.find('td').contents[1].text
         assert 'View' in resp.html.findAll('td')[2].text
         assert 'Change README' in resp
-        assert 'tree/README?format=raw ">Download</a>' in resp
+        assert 'tree/README?format=raw">Download</a>' in resp
         assert 'Add README' in resp
         assert "Initial commit " not in resp
         resp = self.app.get('/src-git/ci/1e146e67985dcd71c74de79613719bef7bddca4a/log/?path=/a/b/c/')


[02/50] git commit: [#5655] Refactored site_stats and added ticket and post 24hr stats

Posted by br...@apache.org.
[#5655] Refactored site_stats and added ticket and post 24hr stats

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7225f737
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7225f737
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7225f737

Branch: refs/heads/db/6007
Commit: 7225f73733b27e283982bf0975afe4d852c923b7
Parents: 68a3547
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Apr 24 22:30:06 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Fri Apr 26 15:33:52 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py             |   11 +++++++----
 ForgeDiscussion/forgediscussion/site_stats.py |    8 ++++++++
 ForgeDiscussion/setup.py                      |    3 +++
 ForgeTracker/forgetracker/site_stats.py       |   10 ++++++++++
 ForgeTracker/setup.py                         |    3 +++
 5 files changed, 31 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7225f737/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 0d519cc..70e3ac7 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -62,10 +62,13 @@ class RestController(object):
 
     @expose('json:')
     def index(self, **kw):
-        provider = g.entry_points['site_stats'].get('provider')
-        if provider:
-            return provider()
-        return dict()
+        summary = dict()
+        stats = dict()
+        for stat, provider in g.entry_points['site_stats'].iteritems():
+            stats[stat] = provider()
+        if stats:
+            summary['site_stats'] = stats
+        return summary
 
     @expose()
     def _lookup(self, name, *remainder):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7225f737/ForgeDiscussion/forgediscussion/site_stats.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/site_stats.py b/ForgeDiscussion/forgediscussion/site_stats.py
new file mode 100644
index 0000000..e76201d
--- /dev/null
+++ b/ForgeDiscussion/forgediscussion/site_stats.py
@@ -0,0 +1,8 @@
+from datetime import datetime, timedelta
+
+from . import model as DM
+
+
+def posts_24hr():
+    window = datetime.utcnow() - timedelta(hours=24)
+    return DM.ForumPost.query.find({'timestamp': {'$gte': window}}).count()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7225f737/ForgeDiscussion/setup.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/setup.py b/ForgeDiscussion/setup.py
index 5c58b7a..812c8a0 100644
--- a/ForgeDiscussion/setup.py
+++ b/ForgeDiscussion/setup.py
@@ -44,5 +44,8 @@ setup(name='ForgeDiscussion',
       # -*- Entry points: -*-
       [allura]
       Discussion=forgediscussion.forum_main:ForgeDiscussionApp
+
+      [allura.site_stats]
+      posts_24hr=forgediscussion.site_stats:posts_24hr
       """,
       )

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7225f737/ForgeTracker/forgetracker/site_stats.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/site_stats.py b/ForgeTracker/forgetracker/site_stats.py
new file mode 100644
index 0000000..e0baa63
--- /dev/null
+++ b/ForgeTracker/forgetracker/site_stats.py
@@ -0,0 +1,10 @@
+from datetime import datetime, timedelta
+
+from bson import ObjectId
+
+from . import model as TM
+
+
+def tickets_stats_24hr():
+    window = datetime.utcnow() - timedelta(hours=24)
+    return TM.Ticket.query.find({'_id': {'$gte': ObjectId.from_datetime(window)}}).count()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7225f737/ForgeTracker/setup.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/setup.py b/ForgeTracker/setup.py
index 57e5d45..1934cc2 100644
--- a/ForgeTracker/setup.py
+++ b/ForgeTracker/setup.py
@@ -43,6 +43,9 @@ setup(name='ForgeTracker',
       [allura]
       Tickets=forgetracker.tracker_main:ForgeTrackerApp
 
+      [allura.site_stats]
+      tickets_24hr=forgetracker.site_stats:tickets_stats_24hr
+
       [easy_widgets.resources]
       ew_resources=forgetracker.config.resources:register_ew_resources
 


[25/50] git commit: [#6172] Remove default TG file extension handling.

Posted by br...@apache.org.
[#6172] Remove default TG file extension handling.

Repo names can now have dots in them, and TG was stripping the
dot and everything after it from the repo name in the url.
Rather than adding another hack to piece the URL back
together, we're turning off this behavior.

Some controllers were relying on the extension stripping to
automatically forward `feed.{rss|atom}` -> `feed`. In these cases,
explicit attrs for rss and atom were added to the controller.

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7244932d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7244932d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7244932d

Branch: refs/heads/db/6007
Commit: 7244932d5eee45ec5289b90b78c8b3d98df22226
Parents: 50f9a49
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Apr 30 13:45:41 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Apr 30 19:45:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/config/app_cfg.py                    |    1 +
 Allura/allura/controllers/discuss.py               |    4 ++++
 Allura/allura/controllers/repository.py            |   10 ++++------
 Allura/allura/ext/user_profile/user_main.py        |    4 ++++
 Allura/allura/lib/base.py                          |   15 +++++++++++++++
 Allura/allura/lib/patches.py                       |    8 ++++++--
 .../allura/tests/functional/test_user_profile.py   |    7 ++++---
 .../forgediscussion/controllers/root.py            |    4 ++++
 .../forgediscussion/tests/functional/test_forum.py |    4 +++-
 .../forgegit/tests/functional/test_controllers.py  |    3 ++-
 ForgeLink/forgelink/link_main.py                   |    5 -----
 ForgeSVN/forgesvn/svn_main.py                      |    2 ++
 .../forgesvn/tests/functional/test_controllers.py  |    4 ++--
 .../forgetracker/tests/functional/test_root.py     |    7 +++----
 ForgeTracker/forgetracker/tracker_main.py          |    2 ++
 ForgeWiki/forgewiki/tests/functional/test_root.py  |    4 ++++
 ForgeWiki/forgewiki/wiki_main.py                   |    5 -----
 17 files changed, 60 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/config/app_cfg.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index c947fe1..f6b11e4 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -61,6 +61,7 @@ class ForgeConfig(AppConfig):
         self.use_transaction_manager = False
         # self.handle_status_codes = [ 403, 404 ]
         self.handle_status_codes = [ 403, 404 ]
+        self.disable_request_extensions = True
 
     def after_init_config(self):
         config['pylons.strict_c'] = True

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 218f9b4..5abb3a2 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -73,6 +73,8 @@ class DiscussionController(BaseController):
     W=WidgetConfig
 
     def __init__(self):
+        setattr(self, 'feed.rss', self.feed)
+        setattr(self, 'feed.atom', self.feed)
         if not hasattr(self, 'ThreadController'):
             self.ThreadController = ThreadController
         if not hasattr(self, 'PostController'):
@@ -168,6 +170,8 @@ class ThreadController(BaseController):
             require_access(self.thread.ref.artifact, 'read')
 
     def __init__(self, discussion_controller, thread_id):
+        setattr(self, 'feed.rss', self.feed)
+        setattr(self, 'feed.atom', self.feed)
         self._discussion_controller = discussion_controller
         self.discussion = discussion_controller.discussion
         self.thread = self.M.Thread.query.get(_id=thread_id)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 319506e..5e006ba 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -65,6 +65,10 @@ class RepoRootController(BaseController):
     _discuss = AppDiscussionController()
     commit_browser_widget=SCMCommitBrowserWidget()
 
+    def __init__(self):
+        setattr(self, 'feed.atom', self.feed)
+        setattr(self, 'feed.rss', self.feed)
+
     def _check_security(self):
         security.require(security.has_access(c.app, 'read'))
 
@@ -538,12 +542,6 @@ class TreeBrowser(BaseController, DispatchIndex):
 
     @expose()
     def _lookup(self, next, *rest):
-        if not rest and request.response_ext:
-            # Directory name may ends with file extension (e.g. `dir.rdf`)
-            # dispatching system will cut extension, so we need to restore it
-            next = "%s%s" % (next, request.response_ext)
-            request.response_ext = None
-            request.response_type = None
         next = h.really_unicode(unquote(next))
         if not rest:
             # Might be a file rather than a dir

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/ext/user_profile/user_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index bc2b942..0491199 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -81,6 +81,10 @@ class UserProfileApp(Application):
 
 class UserProfileController(BaseController):
 
+    def __init__(self):
+        setattr(self, 'feed.rss', self.feed)
+        setattr(self, 'feed.atom', self.feed)
+
     def _check_security(self):
         require_access(c.project, 'read')
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/lib/base.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/base.py b/Allura/allura/lib/base.py
index 4bd5a63..409b77c 100644
--- a/Allura/allura/lib/base.py
+++ b/Allura/allura/lib/base.py
@@ -19,6 +19,7 @@
 
 """The base Controller API."""
 from webob import exc
+import pylons
 from tg import TGController, config
 
 __all__ = ['WsgiDispatchController']
@@ -51,4 +52,18 @@ class WsgiDispatchController(TGController):
         for chunk in response: yield chunk
         self._cleanup_request()
 
+    def _get_dispatchable(self, url_path):
+        """Patch ``TGController._get_dispatchable`` by overriding.
 
+        This fixes a bug in TG 2.1.5 that causes ``request.response_type``
+        to not be created if ``disable_request_extensions = True`` (see
+        allura/config/app_cfg.py).
+
+        ``request.response_type`` must be set because the "trailing slash"
+        decorators use it (see allura/lib/patches.py).
+
+        This entire method can be removed if/when we upgrade to TG >= 2.2.1
+
+        """
+        pylons.request.response_type = None
+        return super(WsgiDispatchController, self)._get_dispatchable(url_path)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/lib/patches.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/patches.py b/Allura/allura/lib/patches.py
index adbc4bc..ef6fba5 100644
--- a/Allura/allura/lib/patches.py
+++ b/Allura/allura/lib/patches.py
@@ -61,7 +61,9 @@ def apply():
     @decorator
     def without_trailing_slash(func, *args, **kwargs):
         '''Monkey-patched to use 301 redirects for SEO'''
-        if request.method == 'GET' and request.path.endswith('/') and not(request.response_type) and len(request.params)==0:
+        response_type = getattr(request, 'response_type', None)
+        if (request.method == 'GET' and request.path.endswith('/')
+                and not response_type and len(request.params)==0):
             raise webob.exc.HTTPMovedPermanently(location=request.url[:-1])
         return func(*args, **kwargs)
 
@@ -69,7 +71,9 @@ def apply():
     @decorator
     def with_trailing_slash(func, *args, **kwargs):
         '''Monkey-patched to use 301 redirects for SEO'''
-        if request.method == 'GET' and not(request.path.endswith('/')) and not(request.response_type) and len(request.params)==0:
+        response_type = getattr(request, 'response_type', None)
+        if (request.method == 'GET' and not(request.path.endswith('/'))
+                and not response_type and len(request.params)==0):
             raise webob.exc.HTTPMovedPermanently(location=request.url+'/')
         return func(*args, **kwargs)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/Allura/allura/tests/functional/test_user_profile.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index a8d724a..e5a9aef 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -53,6 +53,7 @@ class TestUserProfile(TestController):
     @td.with_user_project('test-admin')
     @td.with_wiki
     def test_feed(self):
-        response = self.app.get('/u/test-admin/profile/feed')
-        assert 'Recent posts by Test Admin' in response
-        assert 'Home modified by Test Admin' in response
+        for ext in ['', '.rss', '.atom']:
+            r = self.app.get('/u/test-admin/profile/feed%s' % ext, status=200)
+            assert 'Recent posts by Test Admin' in r
+            assert 'Home modified by Test Admin' in r

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index d9058fb..02c3cde 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -58,6 +58,10 @@ class RootController(BaseController, DispatchIndex):
         search_results = SearchResults()
         search_help = SearchHelp(comments=False, history=False)
 
+    def __init__(self):
+        setattr(self, 'feed.rss', self.feed)
+        setattr(self, 'feed.atom', self.feed)
+
     def _check_security(self):
         require_access(c.app, 'read')
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index e408189..73b6682 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -730,4 +730,6 @@ class TestForum(TestController):
         assert '<a href="flag_as_spam" class="sidebar_thread_spam"><b data-icon="^" class="ico ico-flag"></b> <span>Mark as Spam</span></a>' not in thread_sidebarmenu
 
     def test_feed(self):
-        r = self.app.get('/discussion/general/feed', status=200)
+        for ext in ['', '.rss', '.atom']:
+            self.app.get('/discussion/feed%s' % ext, status=200)
+            self.app.get('/discussion/general/feed%s' % ext, status=200)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 78a8d7e..186b46a 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -156,7 +156,8 @@ class TestRootController(_TestCase):
         assert 'Rick' in resp, resp.showbrowser()
 
     def test_feed(self):
-        assert 'Add README' in self.app.get('/feed')
+        for ext in ['', '.rss', '.atom']:
+            assert 'Add README' in self.app.get('/feed%s' % ext)
 
     def test_tree(self):
         ci = self._get_ci()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeLink/forgelink/link_main.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index 121c8cf..1f5fb2e 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -104,11 +104,6 @@ class RootController(BaseController):
     @expose()
     def _lookup(self, *remainder):
         path = "/".join(remainder)
-        # HACK: The TG request extension machinery will strip off the end of
-        # a dotted wiki page name if it matches a known file extension. Here,
-        # we reassemble the original page name.
-        if request.response_ext:
-            path += request.response_ext
         url = c.app.config.options.get('url')
         if url:
             permanent_redirect(url + h.really_unicode(path).encode('utf-8'))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeSVN/forgesvn/svn_main.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/svn_main.py b/ForgeSVN/forgesvn/svn_main.py
index cca94f7..ef7d008 100644
--- a/ForgeSVN/forgesvn/svn_main.py
+++ b/ForgeSVN/forgesvn/svn_main.py
@@ -65,6 +65,8 @@ class ForgeSVNApp(RepositoryApp):
         default_root = RepoRootController()
         self.root.refresh = default_root.refresh
         self.root.feed = default_root.feed
+        setattr(self.root, 'feed.rss', self.root.feed)
+        setattr(self.root, 'feed.atom', self.root.feed)
         self.root.commit_browser = default_root.commit_browser
         self.root.commit_browser_data = default_root.commit_browser_data
         self.root.status = default_root.status

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeSVN/forgesvn/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/functional/test_controllers.py b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
index c5d340c..90af545 100644
--- a/ForgeSVN/forgesvn/tests/functional/test_controllers.py
+++ b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
@@ -90,8 +90,8 @@ class TestRootController(SVNTestController):
                 assert val['message'] == 'Create readme'
 
     def test_feed(self):
-        r = self.app.get('/src/feed.rss')
-        assert 'Remove hello.txt' in str(r), r
+        for ext in ['', '.rss', '.atom']:
+            assert 'Remove hello.txt' in self.app.get('/src/feed%s' % ext)
 
     def test_commit(self):
         resp = self.app.get('/src/3/tree/')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index e193a10..dfaaba1 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -828,10 +828,9 @@ class TestFunctionalController(TrackerTestController):
         ThreadLocalORMSession.flush_all()
         M.MonQTask.run_ready()
         ThreadLocalORMSession.flush_all()
-        response = self.app.get('/p/test/bugs/search_feed?q=test')
-        assert '<title>test first ticket</title>' in response
-        response = self.app.get('/p/test/bugs/search_feed.atom?q=test')
-        assert '<title>test first ticket</title>' in response
+        for ext in ['', '.rss', '.atom']:
+            assert '<title>test first ticket</title>' in \
+                    self.app.get('/p/test/bugs/search_feed%s?q=test' % ext)
 
     def test_search_current_user(self):
         self.new_ticket(summary='test first ticket')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 8d786d9..349ef1e 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -472,6 +472,8 @@ class RootController(BaseController):
     def __init__(self):
         setattr(self, 'feed.atom', self.feed)
         setattr(self, 'feed.rss', self.feed)
+        setattr(self, 'search_feed.atom', self.search_feed)
+        setattr(self, 'search_feed.rss', self.search_feed)
         self._discuss = AppDiscussionController()
 
     def _check_security(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 14e70c6..d928e70 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -80,6 +80,10 @@ class TestRootController(TestController):
         response = self.app.get('/wiki/search?q=tést')
         assert 'Search wiki: tést' in response
 
+    def test_feed(self):
+        for ext in ['', '.rss', '.atom']:
+            self.app.get('/wiki/feed%s' % ext, status=200)
+
     @patch('allura.lib.search.search')
     def test_search(self, search):
         r = self.app.get('/wiki/search?q=test')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7244932d/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 23ca7f2..b923350 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -296,11 +296,6 @@ class RootController(BaseController, DispatchIndex):
     @expose()
     def _lookup(self, pname, *remainder):
         """Instantiate a Page object, and continue dispatch there."""
-        # HACK: The TG request extension machinery will strip off the end of
-        # a dotted wiki page name if it matches a known file extension. Here,
-        # we reassemble the original page name.
-        if request.response_ext and not remainder:
-            pname += request.response_ext
         return PageController(pname), remainder
 
     @expose()


[22/50] git commit: [#6179] Fix openid user creation

Posted by br...@apache.org.
[#6179] Fix openid user creation

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/50f9a49f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/50f9a49f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/50f9a49f

Branch: refs/heads/db/6007
Commit: 50f9a49f435f26a0eb32a9ec997683a7eb24a9e0
Parents: 3d3f199
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Apr 30 19:25:37 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Apr 30 19:25:37 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/50f9a49f/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index a792bb9..4dc83e7 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -188,7 +188,7 @@ class AuthController(BaseController):
         c.user.set_pref('display_name', display_name)
         if u is None:
             n = M.Neighborhood.query.get(name='Users')
-            n.register_project('u/' + username)
+            n.register_project('u/' + username, user_project=True)
         flash('Your username has been set to %s.' % username)
         redirect('/')
 


[48/50] git commit: [#6007] Give full names to the default projects

Posted by br...@apache.org.
[#6007] Give full names to the default projects


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/632df879
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/632df879
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/632df879

Branch: refs/heads/db/6007
Commit: 632df87975195c45a4fbc40fc015f7417fa42ab8
Parents: a9a7a72
Author: Dave Brondsema <db...@geek.net>
Authored: Mon Mar 25 13:56:43 2013 -0700
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri May 3 15:23:02 2013 -0400

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_admin.py |    6 +++---
 Allura/allura/websetup/bootstrap.py          |    8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/632df879/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 3197386..1ad962a 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -44,7 +44,7 @@ def audits(*messages):
         import pdb; pdb.set_trace()
     for message in messages:
         assert M.AuditLog.query.find(dict(
-            message=re.compile(message))).count()
+            message=re.compile(message))).count(), 'Could not find "%s"' % message
 
 class TestProjectAdmin(TestController):
 
@@ -52,10 +52,10 @@ class TestProjectAdmin(TestController):
         self.app.get('/admin/')
         with audits(
             'change summary to Milkshakes are for crazy monkeys',
-            'change project name to Test Project',
+            'change project name to My Test Project',
             u'change short description to (\u00bf A Test Project \?){45}'):
             self.app.post('/admin/update', params=dict(
-                    name='Test Project',
+                    name='My Test Project',
                     shortname='test',
                     summary='Milkshakes are for crazy monkeys',
                     short_description=u'\u00bf A Test Project ?'.encode('utf-8') * 45,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/632df879/Allura/allura/websetup/bootstrap.py
----------------------------------------------------------------------
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index 5e8ab1e..f518463 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -194,12 +194,12 @@ def bootstrap(command, conf, vars):
         p_projects.add_user(u_admin, ['Admin'])
         p_users.add_user(u_admin, ['Admin'])
 
-        p_allura = n_projects.register_project('allura', u_admin)
+        p_allura = n_projects.register_project('allura', u_admin, 'Allura')
     u1 = make_user('Test User')
-    p_adobe1 = n_adobe.register_project('adobe-1', u_admin)
+    p_adobe1 = n_adobe.register_project('adobe-1', u_admin, 'Adobe project 1')
     p_adobe.add_user(u_admin, ['Admin'])
-    p0 = n_projects.register_project('test', u_admin)
-    p1 = n_projects.register_project('test2', u_admin)
+    p0 = n_projects.register_project('test', u_admin, 'Test Project')
+    p1 = n_projects.register_project('test2', u_admin, 'Test 2')
     p0._extra_tool_status = [ 'alpha', 'beta' ]
 
     sess = session(M.Neighborhood) # all the sessions are the same


[20/50] git commit: [#6179] ignore the u/ prefix of user-projects so that a 15-char username can have their user project created successfully

Posted by br...@apache.org.
[#6179] ignore the u/ prefix of user-projects so that a 15-char username can have their user project created successfully


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f7461097
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f7461097
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f7461097

Branch: refs/heads/db/6007
Commit: f7461097b15347cb3ae196fd0e486844d017e381
Parents: 5c8db54
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Apr 30 18:16:50 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Apr 30 18:16:50 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py        |    4 ++-
 Allura/allura/tests/test_plugin.py |   40 +++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f7461097/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index b7722d2..02aae3a 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -464,7 +464,9 @@ class ProjectRegistrationProvider(object):
 
         self.rate_limit(user, neighborhood)
 
-        if not h.re_project_name.match(shortname.replace('/', '')):
+        if user_project and shortname.startswith('u/'):
+            shortname = shortname.replace('u/', '', 1)
+        if not h.re_project_name.match(shortname):
             raise ValueError('Invalid project shortname: %s' % shortname)
 
         p = M.Project.query.get(shortname=shortname, neighborhood_id=neighborhood._id)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f7461097/Allura/allura/tests/test_plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
new file mode 100644
index 0000000..6e1a07a
--- /dev/null
+++ b/Allura/allura/tests/test_plugin.py
@@ -0,0 +1,40 @@
+#       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.
+
+from nose.tools import assert_equals
+from mock import MagicMock, patch
+
+from allura import model as M
+from allura.lib.utils import TruthyCallable
+from allura.lib.plugin import ProjectRegistrationProvider
+
+
+class TestProjectRegistrationProvider(object):
+
+    @patch('allura.lib.security.has_access')
+    def test_validate_project_15char_user(self, has_access):
+        has_access.return_value = TruthyCallable(lambda: True)
+        provider = ProjectRegistrationProvider()
+        nbhd = M.Neighborhood()
+        provider.validate_project(
+            neighborhood=nbhd,
+            shortname='u/' + ('a' * 15),
+            project_name='15 char username',
+            user=MagicMock(),
+            user_project=True,
+            private_project=False,
+        )
\ No newline at end of file


[39/50] git commit: [#5773] ticket:314 Move commit message back to the bottom

Posted by br...@apache.org.
[#5773] ticket:314 Move commit message back to the bottom


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d7bcc228
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d7bcc228
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d7bcc228

Branch: refs/heads/db/6007
Commit: d7bcc2286ea81d13dab8019df40db657531e83c6
Parents: 94b70ce
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Apr 19 14:15:14 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:37:04 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/widgets/repo/log.html |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d7bcc228/Allura/allura/templates/widgets/repo/log.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/log.html b/Allura/allura/templates/widgets/repo/log.html
index 086b0b3..bdeeda2 100644
--- a/Allura/allura/templates/widgets/repo/log.html
+++ b/Allura/allura/templates/widgets/repo/log.html
@@ -34,7 +34,6 @@
         <tr class="rev">
           <td>
             <div class="grid-14">
-                {{g.markdown.convert(commit.message)}}
                 {%if is_file%}
                     <div class="grid-1"><input type="checkbox" class="revision" revision="{{commit._id.split(':')[-1]}}" url_commit="{{commit.url()}}"></div>
                 {%endif%}
@@ -59,6 +58,7 @@
                 {%if is_file%}
                     ({{commit.tree.get_obj_by_path(request.params.get('path')).size|filesizeformat}})
                 {%endif%}
+                {{g.markdown.convert(commit.message)}}
             </div>
           </td>
           <td style="vertical-align: text-top">


[13/50] git commit: [#5332] Fix test

Posted by br...@apache.org.
[#5332] Fix test

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/2c50ad0c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/2c50ad0c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/2c50ad0c

Branch: refs/heads/db/6007
Commit: 2c50ad0c57a3555d5c81bb3fdfc65633b8789aca
Parents: f8475cd
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Mon Apr 29 15:27:11 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Mon Apr 29 15:27:11 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/model/test_project.py |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2c50ad0c/Allura/allura/tests/model/test_project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index 0a218b1..bbff251 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -91,7 +91,10 @@ def test_project():
     c.app.config.breadcrumbs()
 
 def test_subproject():
-    sp = c.project.new_subproject('test-project-nose')
+    with td.raises(ToolError):
+        # name exceeds 15 chars
+        sp = c.project.new_subproject('test-project-nose')
+    sp = c.project.new_subproject('test-proj-nose')
     spp = sp.new_subproject('spp')
     ThreadLocalORMSession.flush_all()
     sp.delete()


[19/50] git commit: [#5891] ticket:327 removed add_attach from helpers, and put it to Post

Posted by br...@apache.org.
[#5891]  ticket:327  removed add_attach from helpers, and put it to Post


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/5c8db545
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/5c8db545
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/5c8db545

Branch: refs/heads/db/6007
Commit: 5c8db5459133394fbfe82828fcab82d42bd785ad
Parents: c40773b
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Apr 30 15:10:11 2013 +0400
Committer: Yuriy Arhipov <yu...@yandex.ru>
Committed: Tue Apr 30 15:10:11 2013 +0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py         |    8 ++++----
 Allura/allura/lib/helpers.py                 |   15 +--------------
 Allura/allura/model/discuss.py               |   12 ++++++++++++
 Allura/allura/tests/model/test_discussion.py |    7 +++++--
 4 files changed, 22 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5c8db545/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index eb34981..218f9b4 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -211,7 +211,7 @@ class ThreadController(BaseController):
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
         is_spam = g.spam_checker.check(kw['text'], artifact=p, user=c.user)
-        h.attach_to_post(p, file_info)
+        p.add_attachment(file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -294,7 +294,7 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            h.attach_to_post(self.post, file_info)
+            self.post.add_attachment(file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -339,7 +339,7 @@ class PostController(BaseController):
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
         is_spam = g.spam_checker.check(kw['text'], artifact=p, user=c.user)
-        h.attach_to_post(p, file_info)
+        p.add_attachment(file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -373,7 +373,7 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        h.attach_to_post(self.post, file_info)
+        self.post.add_attachment(file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5c8db545/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index deed268..29cf44e 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -51,7 +51,6 @@ from allura.lib import exceptions as exc
 from allura.lib.decorators import exceptionless
 from allura.lib import AsciiDammit
 from .security import has_access
-from allura.lib import utils
 
 
 # validates project, subproject, and user names
@@ -702,16 +701,4 @@ def get_first(d, key):
     v = d.get(key)
     if isinstance(v, list):
         return v[0] if len(v) > 0 else None
-    return v
-
-
-def attach_to_post(post, file_info):
-    if hasattr(file_info, 'file'):
-        mime_type = file_info.type
-        if not mime_type or '/' not in mime_type:
-            mime_type = utils.guess_mime_type(file_info.filename)
-        post.attach(
-            file_info.filename, file_info.file, content_type=mime_type,
-            post_id=post._id,
-            thread_id=post.thread_id,
-            discussion_id=post.discussion_id)
+    return v
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5c8db545/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index d169e1b..4375077 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -31,6 +31,7 @@ from ming.utils import LazyProperty
 from allura.lib import helpers as h
 from allura.lib import security
 from allura.lib.security import require_access, has_access
+from allura.lib import utils
 from allura.model.notification import Notification, Mailbox
 from .artifact import Artifact, ArtifactReference, VersionedArtifact, Snapshot, Message, Feed
 from .attachments import BaseAttachment
@@ -513,6 +514,17 @@ class Post(Message, VersionedArtifact, ActivityObject):
         return self.attachment_class().query.find(dict(
             post_id=self._id, type='attachment'))
 
+    def add_attachment(self, file_info):
+        if hasattr(file_info, 'file'):
+            mime_type = file_info.type
+            if not mime_type or '/' not in mime_type:
+                mime_type = utils.guess_mime_type(file_info.filename)
+            self.attach(
+                file_info.filename, file_info.file, content_type=mime_type,
+                post_id=self._id,
+                thread_id=self.thread_id,
+                discussion_id=self.discussion_id)
+
     def last_edit_by(self):
         return User.query.get(_id=self.last_edit_by_id) or User.anonymous()
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5c8db545/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 2ab4b2a..35c5594 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -206,7 +206,7 @@ def test_attachment_methods():
     assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
 
 @with_setup(setUp, tearDown)
-def test_attach_to_post():
+def test_add_attachment():
     test_file = FieldStorage()
     test_file.name = 'file_info'
     test_file.filename = 'test.txt'
@@ -215,9 +215,12 @@ def test_attach_to_post():
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
     test_post = t.post('test post')
-    h.attach_to_post(test_post, test_file)
+    test_post.add_attachment(test_file)
     ThreadLocalORMSession.flush_all()
     assert test_post.attachments.count() == 1, test_post.attachments.count()
+    attach = test_post.attachments.first()
+    assert attach.filename == 'test.txt', attach.filename
+    assert attach.content_type == 'text/plain', attach.content_type
 
 @with_setup(setUp, tearDown)
 def test_discussion_delete():


[36/50] git commit: [#6138] more updates to transition stored tool_names to lowercase

Posted by br...@apache.org.
[#6138] more updates to transition stored tool_names to lowercase


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/17617e6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/17617e6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/17617e6e

Branch: refs/heads/db/6007
Commit: 17617e6ebd6c1aad2b7f198526c6811d17b14d7d
Parents: 7cc8df7
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu May 2 20:08:01 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:08:01 2013 +0000

----------------------------------------------------------------------
 .../templates/admin_widgets/metadata_admin.html    |    2 +-
 .../allura/ext/admin/templates/project_admin.html  |    4 ++--
 Allura/allura/templates/jinja_master/lib.html      |    2 +-
 Allura/allura/tests/model/test_project.py          |    2 +-
 Allura/allura/tests/test_globals.py                |    6 +++---
 5 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/17617e6e/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html b/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
index 738428f..ff60ab3 100644
--- a/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
+++ b/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
@@ -46,7 +46,7 @@
     <input name="support_page" type="radio" value=""{% if value.support_page == '' %} checked{% endif %} id="support_page_none">
     <label for="support_page_none">None</label><br>
     {% for ac in value.app_configs %}
-      {% if ac.tool_name in ['Wiki', 'Tickets', 'Discussion'] %}
+      {% if ac.tool_name.lower() in ['wiki', 'tickets', 'discussion'] %}
         <input name="support_page" type="radio" value="{{ac.options.mount_point}}" id="support_page_{{ac.options.mount_point}}"
                {% if value.support_page == ac.options.mount_point %} checked{% endif %}>
         <label for="support_page_{{ac.options.mount_point}}">{{ac.options.mount_label}}</label><br>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/17617e6e/Allura/allura/ext/admin/templates/project_admin.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_admin.html b/Allura/allura/ext/admin/templates/project_admin.html
index 3da1c0c..f8453f2 100644
--- a/Allura/allura/ext/admin/templates/project_admin.html
+++ b/Allura/allura/ext/admin/templates/project_admin.html
@@ -49,7 +49,7 @@
   </div>
   <div class="grid-4">
     {% for tool in c.project.app_configs %}
-      {% if tool.tool_name == 'Wiki' and not wiki_found %}
+      {% if tool.tool_name.lower() == 'wiki' and not wiki_found %}
         <a href="{{c.project.url()}}{{tool.options.mount_point}}/add">Add Page</a><br>
         <a href="{{c.project.url()}}{{tool.options.mount_point}}/">View Wiki</a>
         {% set wiki_found = True %}
@@ -82,7 +82,7 @@
   </div>
   <div class="grid-4">
     {% for tool in c.project.app_configs %}
-      {% if tool.tool_name == 'Tickets' and not tracker_found %}
+      {% if tool.tool_name.lower() == 'tickets' and not tracker_found %}
         <a href="{{c.project.url()}}{{tool.options.mount_point}}/new">Create Ticket</a><br>
         <a href="{{c.project.url()}}{{tool.options.mount_point}}/milestones">Edit Milestones</a><br>
         <a href="{{c.project.url()}}{{tool.options.mount_point}}/">View Tickets</a>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/17617e6e/Allura/allura/templates/jinja_master/lib.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index 0e4938a..48934d3 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -659,7 +659,7 @@ allowed, permitting basic styling and layout: &lt;div markdown style="float:left
 <h2 id="md_ex_neighborhood_notes{{id}}">Neighborhood Notifications</h2>
 <p>You can list updates from all projects in a neighborhood by tool type. Max_number (default is 5) and sort (default is pubdate) are optional:</p>
 <div class="codehilite"><pre>
-[[neighborhood_feeds tool_name=Wiki max_number=10 sort=pubdate]]
+[[neighborhood_feeds tool_name=wiki max_number=10 sort=pubdate]]
 </pre></div>
 </div>
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/17617e6e/Allura/allura/tests/model/test_project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index 232dec5..16f5a97 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -107,7 +107,7 @@ def test_anchored_tools():
     c.project.install_app = MagicMock()
     assert c.project.sitemap()[0].label == 'Wiki'
     assert c.project.install_app.call_args[0][0] == 'tickets'
-    assert c.project.ordered_mounts()[0]['ac'].tool_name == 'Wiki'
+    assert c.project.ordered_mounts()[0]['ac'].tool_name == 'wiki'
 
 
 def test_set_ordinal_to_admin_tool():

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/17617e6e/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 2adc64c..bf17979 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -143,7 +143,7 @@ def test_macros():
     r = g.markdown_wiki.convert('[[download_button]]')
     assert_equal(r, '<div class="markdown_content"><p><span class="download-button-%s" style="margin-bottom: 1em; display: block;"></span></p>\n</div>' % p_test._id)
     h.set_context('--init--', 'wiki', neighborhood='Projects')
-    r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=Wiki]]')
+    r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
     assert 'Home modified by' in r, r
     orig_len = len(r)
     # Make project private & verify we don't see its new feed items
@@ -155,7 +155,7 @@ def test_macros():
     pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id)
     pg.text = 'Change'
     pg.commit()
-    r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=Wiki]]')
+    r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
     new_len = len(r)
     assert new_len == orig_len
     p = BM.BlogPost(title='test me', neighborhood_id=p_test.neighborhood_id)
@@ -361,7 +361,7 @@ def test_macro_include():
 
 def test_macro_nbhd_feeds():
     with h.push_context('--init--', 'wiki', neighborhood='Projects'):
-        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=Wiki]]')
+        r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]')
         assert 'Home modified by ' in r, r
 
 


[10/50] git commit: [#5332] Relax mount point name rules for repos

Posted by br...@apache.org.
[#5332] Relax mount point name rules for repos

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ba32ac79
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ba32ac79
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ba32ac79

Branch: refs/heads/db/6007
Commit: ba32ac79881cb1ba74cea0ea279a426c5e416801
Parents: f2c3475
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Thu Apr 25 18:34:31 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 14:44:04 2013 +0000

----------------------------------------------------------------------
 Allura/allura/app.py                               |   30 +++++++++++++--
 Allura/allura/controllers/project.py               |    4 +-
 Allura/allura/controllers/rest.py                  |    2 -
 .../allura/ext/admin/templates/project_tools.html  |   23 +++++++++--
 Allura/allura/lib/helpers.py                       |    3 +-
 Allura/allura/lib/repository.py                    |    1 +
 Allura/allura/model/project.py                     |    2 +-
 Allura/allura/public/nf/js/project_tools.js        |   12 +++++-
 Allura/allura/tests/unit/test_app.py               |   13 ++++++
 9 files changed, 74 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index bf874bf..124f084 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -28,7 +28,7 @@ from bson import ObjectId
 from ming.orm import session, state
 from ming.utils import LazyProperty
 
-from allura.lib.helpers import push_config, vardec
+from allura.lib import helpers as h
 from allura.lib.security import require, has_access, require_access
 from allura import model
 from allura.controllers import BaseController
@@ -144,6 +144,10 @@ class Application(object):
     :cvar bool hidden: Default is False, Application is not hidden from the
         list of a project's installed tools.
     :cvar str tool_description: Text description of this Application.
+    :cvar bool relaxed_mount_points: Set to True to relax the default mount point
+        naming restrictions for this Application. Default is False. See
+        :attr:`default mount point naming rules <allura.lib.helpers.re_tool_mount_point>` and
+        :attr:`relaxed mount point naming rules <allura.lib.helpers.re_relaxed_tool_mount_point>`.
     :cvar Controller root: Serves content at
         /<neighborhood>/<project>/<app>/. Default is None - subclasses should
         override.
@@ -154,7 +158,6 @@ class Application(object):
         /<neighborhood>/<project>/<admin>/<app>/. Default is a
         :class:`DefaultAdminController` instance.
     :cvar dict icons: Mapping of icon sizes to application-specific icon paths.
-
     """
 
     __version__ = None
@@ -178,6 +181,7 @@ class Application(object):
     tool_description="This is a tool for Allura forge."
     default_mount_label='Tool Name'
     default_mount_point='tool'
+    relaxed_mount_points=False
     ordinal=0
     hidden = False
     icons={
@@ -203,6 +207,24 @@ class Application(object):
         return self.config.parent_security_context()
 
     @classmethod
+    def validate_mount_point(cls, mount_point):
+        """Check if ``mount_point`` is valid for this Application.
+
+        In general, subclasses should not override this, but rather toggle
+        the strictness of allowed mount point names by toggling
+        :attr:`Application.relaxed_mount_points`.
+
+        :param mount_point: the mount point to validate
+        :type mount_point: str
+        :rtype: A :class:`regex Match object <_sre.SRE_Match>` if the mount
+                point is valid, else None
+
+        """
+        re = (h.re_relaxed_tool_mount_point if cls.relaxed_mount_points
+                else h.re_tool_mount_point)
+        return re.match(mount_point)
+
+    @classmethod
     def status_int(self):
         return self.status_map.index(self.status)
 
@@ -450,7 +472,7 @@ class DefaultAdminController(BaseController):
     @expose()
     @require_post()
     def configure(self, **kw):
-        with push_config(c, app=self.app):
+        with h.push_config(c, app=self.app):
             require_access(self.app, 'configure')
             is_admin = self.app.config.tool_name == 'admin'
             if kw.pop('delete', False):
@@ -481,7 +503,7 @@ class DefaultAdminController(BaseController):
 
     @without_trailing_slash
     @expose()
-    @vardec
+    @h.vardec
     @require_post()
     def update(self, card=None, **kw):
         self.app.config.acl = []

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 2f59a38..75e7792 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -317,8 +317,6 @@ class ProjectController(object):
     @expose()
     def _lookup(self, name, *remainder):
         name = unquote(name)
-        if not h.re_path_portion.match(name):
-            raise exc.HTTPNotFound, name
         subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
                                          neighborhood_id=c.project.neighborhood_id)
         if subproject:
@@ -592,7 +590,7 @@ class NeighborhoodAdminController(object):
 
 
         for tool in validate_tools.keys():
-            if not h.re_tool_mount_point.match(tool):
+            if tool not in g.entry_points['tool']:
                 flash('Anchored tools "%s" is invalid' % anchored_tools,'error')
                 result = False
         if result:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index cf03733..8ae0c70 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -257,8 +257,6 @@ class ProjectRestController(object):
     def _lookup(self, name, *remainder):
         if not name:
             return self, ()
-        if not h.re_path_portion.match(name):
-            raise exc.HTTPNotFound, name
         subproject = M.Project.query.get(shortname=c.project.shortname + '/' + name,
                                          neighborhood_id=c.project.neighborhood_id,
                                          deleted=False)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/ext/admin/templates/project_tools.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_tools.html b/Allura/allura/ext/admin/templates/project_tools.html
index 6516039..dc7646c 100644
--- a/Allura/allura/ext/admin/templates/project_tools.html
+++ b/Allura/allura/ext/admin/templates/project_tools.html
@@ -30,7 +30,7 @@
   <div class="nested-grid-container">
     {% for tool in installable_tools %}
       <span class="tcenter grid-4 installable_tool">
-        <a class="install_trig" data-tool="{{ tool['name'] }}">
+        <a class="install_trig" data-tool="{{ tool['name'] }}" data-relaxed-mount-points="{{ tool.app.relaxed_mount_points and 'true' or 'false' }}">
           <span class="tool_title">{{ tool['app'].tool_label }}{{' (%s)' % tool.app.status if tool.app.status != 'production' else ''}}</span><br />
           <img src="{{ g.theme.app_icon_url(tool['app'], 32) or 'unk.png' }}" alt="">
         </a>
@@ -50,9 +50,24 @@
     <div class="grid-13"><input type="text" name="new.mount_label" class="new_mount_label"></div>
     <label class="grid-13">Mount Point</label>
     <div class="grid-13"><input type="text" name="new.mount_point" class="new_mount_point"></div>
-    <div class="grid-13"><small>* The mount point is the name of the tool as it will appear in a URL.
-      A valid mount point must begin with a letter, contain only letters, numbers, and dashes,
-      and be from 1-63 characters in length.</small></div>
+    <div class="grid-13">
+      <small>
+        * The mount point is the name of the tool as it will appear in a URL.
+        <span class="mount-point-name-rules tool">
+          A valid mount point for this tool must begin with a letter, contain only letters,
+          numbers, and dashes, and be from 1-63 characters in length.
+        </span>
+        <span class="mount-point-name-rules tool-relaxed">
+          A valid mount point for this tool must begin with a letter or number, contain only
+          letters, numbers, dashes, underscores, periods, and plus signs, and be
+          from 1-63 characters in length.
+        </span>
+        <span class="mount-point-name-rules subproject">
+          A valid subproject mount point must begin with a letter, contain only letters,
+          numbers, and dashes, and be from 3-63 characters in length.
+        </span>
+      </small>
+    </div>
     <hr>
     <div class="grid-13">&nbsp;</div>
     <div class="grid-13">

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index ea2b4d2..b118efe 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -53,8 +53,9 @@ from allura.lib import AsciiDammit
 from .security import has_access
 
 re_path_portion_fragment = re.compile(r'[a-z][-a-z0-9]*')
-re_path_portion = re.compile(r'^[a-z][-a-z0-9]{2,}$')
+re_path_portion = re.compile(r'^[a-z][-a-z0-9]{2,62}$')
 re_tool_mount_point = re.compile(r'^[a-z][-a-z0-9]{0,62}$')
+re_relaxed_tool_mount_point = re.compile(r'^[a-z0-9][-a-z0-9_\.\+]{0,62}$')
 re_clean_vardec_key = re.compile(r'''\A
 ( # first part
 \w+# name...

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/lib/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index 69736b6..3a432ec 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -53,6 +53,7 @@ class RepositoryApp(Application):
     tool_label='Repository'
     default_mount_label='Code'
     default_mount_point='code'
+    relaxed_mount_points=True
     ordinal=2
     forkable=False
     default_branch_name=None # master or default or some such

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index d207aab..b3f1131 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -547,7 +547,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             for x in range(10):
                 if self.app_instance(mount_point) is None: break
                 mount_point = base_mount_point + '-%d' % x
-        if not h.re_tool_mount_point.match(mount_point):
+        if not App.validate_mount_point(mount_point):
             raise exceptions.ToolError, 'Mount point "%s" is invalid' % mount_point
         # HACK: reserved url components
         if mount_point in ('feed', 'index', 'icon', '_nav.json'):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/public/nf/js/project_tools.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/project_tools.js b/Allura/allura/public/nf/js/project_tools.js
index 3a5b5d7..b148ba4 100644
--- a/Allura/allura/public/nf/js/project_tools.js
+++ b/Allura/allura/public/nf/js/project_tools.js
@@ -28,20 +28,30 @@
     var new_mount_point = install_form.find('input.new_mount_point');
     var new_mount_label = install_form.find('input.new_mount_label');
     var install_tool_label = $('#install_tool_label');
+    var mount_point_rule_names = $('#install_form .mount-point-rule-names');
     install_popup.append(install_form.show());
     $('a.install_trig').click(function () {
-        var datatool = $(this).attr('data-tool');
+        var datatool = $(this).data('tool');
+        var relaxed_mount_points = $(this).data('relaxed-mount-points');
+        install_form.find('.mount-point-name-rules').hide();
         if (datatool) {
             var tool = defaults[datatool];
             install_tool_label.html(tool.default_label);
             new_ep_name.val(datatool);
             new_mount_point.val(tool.default_mount);
             new_mount_label.val(tool.default_label);
+            if (relaxed_mount_points) {
+              install_form.find('.mount-point-name-rules.tool-relaxed').show();
+            }
+            else {
+              install_form.find('.mount-point-name-rules.tool').show();
+            }
         } else {
             install_tool_label.html("Subproject");
             new_ep_name.val('');
             new_mount_point.val('');
             new_mount_label.val('');
+            install_form.find('.mount-point-name-rules.subproject').show();
         }
     });
     // Edit popup

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba32ac79/Allura/allura/tests/unit/test_app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_app.py b/Allura/allura/tests/unit/test_app.py
index 668ac65..8f0c0db 100644
--- a/Allura/allura/tests/unit/test_app.py
+++ b/Allura/allura/tests/unit/test_app.py
@@ -15,6 +15,9 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import re
+from unittest import TestCase
+
 from allura.app import Application
 from allura import model
 from allura.tests.unit import WithDatabase
@@ -22,6 +25,16 @@ from allura.tests.unit.patches import fake_app_patch
 from allura.tests.unit.factories import create_project, create_app_config
 
 
+class TestApplication(TestCase):
+
+    def test_validate_mount_point(self):
+        app = Application
+        mount_point = '1.2+foo_bar'
+        self.assertIsNone(app.validate_mount_point(mount_point))
+        app.relaxed_mount_points = True
+        self.assertIsNotNone(app.validate_mount_point(mount_point))
+
+
 class TestInstall(WithDatabase):
     patches = [fake_app_patch]
 


[15/50] git commit: [#5607] make max markdown render length more easily configurable; and lower the default cutoff

Posted by br...@apache.org.
[#5607] make max markdown render length more easily configurable; and lower the default cutoff


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/5fb297e6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/5fb297e6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/5fb297e6

Branch: refs/heads/db/6007
Commit: 5fb297e6dc05ea9a38b43532febbb79d7b4edf0a
Parents: 4510805
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Apr 29 21:59:29 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 21:59:43 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py    |    4 +---
 Allura/allura/tests/test_globals.py |    3 +--
 2 files changed, 2 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5fb297e6/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index a8d2006..0621b8d 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -60,12 +60,10 @@ from allura.lib.zarkov_helpers import ZarkovClient, zmq
 
 log = logging.getLogger(__name__)
 
-BIG_TEXT_THRESHOLD = 90000
-
 
 class ForgeMarkdown(markdown.Markdown):
     def convert(self, source):
-        if len(source) > BIG_TEXT_THRESHOLD:
+        if len(source) > asint(config.get('markdown_render_max_length', 40000)):
             # if text is too big, markdown can take a long time to process it, so we return it as a plain text
             log.info('Text is too big. Skipping markdown processing')
             escaped = cgi.escape(h.really_unicode(source))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5fb297e6/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index ccf90cc..2adc64c 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -285,8 +285,7 @@ def test_markdown_within_html():
 
 def test_markdown_big_text():
     '''If text is too big g.markdown.convert should return plain text'''
-    from allura.lib.app_globals import BIG_TEXT_THRESHOLD
-    text = 'a' * (BIG_TEXT_THRESHOLD + 1)
+    text = 'a' * 40001
     assert_equal(g.markdown.convert(text), '<pre>%s</pre>' % text)
     assert_equal(g.markdown_wiki.convert(text), '<pre>%s</pre>' % text)
 


[35/50] git commit: [#6138] Force all tool_names to be lower-case

Posted by br...@apache.org.
[#6138] Force all tool_names to be lower-case

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7cc8df70
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7cc8df70
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7cc8df70

Branch: refs/heads/db/6007
Commit: 7cc8df70ee7a28b8f111434ddc8aafced682a3c5
Parents: dbee43f
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed May 1 21:35:07 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 19:06:08 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py            |    2 +-
 Allura/allura/tests/model/test_project.py |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7cc8df70/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index f95aae0..982dad8 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -577,7 +577,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         options.update(override_options)
         cfg = AppConfig(
             project_id=self._id,
-            tool_name=ep_name,
+            tool_name=ep_name.lower(),
             options=options)
         app = App(self, cfg)
         with h.push_config(c, project=self, app=app):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7cc8df70/Allura/allura/tests/model/test_project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index bbff251..232dec5 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -20,7 +20,7 @@
 """
 Model tests for project
 """
-from nose.tools import with_setup
+from nose.tools import with_setup, assert_equal
 from pylons import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 
@@ -62,6 +62,7 @@ def test_project():
 
     c.project.install_app('Wiki', 'hello-test-mount-point')
     c.project.support_page = 'hello-test-mount-point'
+    assert_equal(c.project.app_config('wiki').tool_name, 'wiki')
     ThreadLocalORMSession.flush_all()
     with td.raises(ToolError):
         # already installed


[16/50] git commit: [#5607] ticket:319 Render text as plain text if it's too big

Posted by br...@apache.org.
[#5607] ticket:319 Render text as plain text if it's too big


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/4510805a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/4510805a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/4510805a

Branch: refs/heads/db/6007
Commit: 4510805ac0c6fe8594cb220850dd0efe2cc50e4c
Parents: ed4a5a0
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Apr 25 10:49:20 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 21:59:43 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py    |    7 +++++++
 Allura/allura/tests/test_globals.py |    8 ++++++++
 2 files changed, 15 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/4510805a/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index e5b00c7..a8d2006 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -60,9 +60,16 @@ from allura.lib.zarkov_helpers import ZarkovClient, zmq
 
 log = logging.getLogger(__name__)
 
+BIG_TEXT_THRESHOLD = 90000
+
 
 class ForgeMarkdown(markdown.Markdown):
     def convert(self, source):
+        if len(source) > BIG_TEXT_THRESHOLD:
+            # if text is too big, markdown can take a long time to process it, so we return it as a plain text
+            log.info('Text is too big. Skipping markdown processing')
+            escaped = cgi.escape(h.really_unicode(source))
+            return h.html.literal(u'<pre>%s</pre>' % escaped)
         try:
             return markdown.Markdown.convert(self, source)
         except Exception:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/4510805a/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index ea7fc1d..ccf90cc 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -283,6 +283,14 @@ def test_markdown_within_html():
 </div>''' in r, r
 
 
+def test_markdown_big_text():
+    '''If text is too big g.markdown.convert should return plain text'''
+    from allura.lib.app_globals import BIG_TEXT_THRESHOLD
+    text = 'a' * (BIG_TEXT_THRESHOLD + 1)
+    assert_equal(g.markdown.convert(text), '<pre>%s</pre>' % text)
+    assert_equal(g.markdown_wiki.convert(text), '<pre>%s</pre>' % text)
+
+
 @td.with_wiki
 def test_markdown_basics():
     with h.push_context('test', 'wiki', neighborhood='Projects'):


[09/50] git commit: [#2835] fix test setup

Posted by br...@apache.org.
[#2835] fix test setup


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f2c34752
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f2c34752
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f2c34752

Branch: refs/heads/db/6007
Commit: f2c34752741fdfe19c53ce774bcd9f89c167415c
Parents: 69d7575
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Apr 29 14:16:31 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 14:16:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/unit/test_solr.py |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f2c34752/Allura/allura/tests/unit/test_solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_solr.py b/Allura/allura/tests/unit/test_solr.py
index f431ea3..b3dee43 100644
--- a/Allura/allura/tests/unit/test_solr.py
+++ b/Allura/allura/tests/unit/test_solr.py
@@ -23,6 +23,7 @@ from markupsafe import Markup
 
 from allura.lib import helpers as h
 from allura.tests import decorators as td
+from alluratest.controller import setup_basic_test
 from allura.lib.solr import Solr
 from allura.lib.search import solarize, search_app
 
@@ -83,6 +84,10 @@ class TestSolarize(unittest.TestCase):
 
 class TestSearch_app(unittest.TestCase):
 
+    def setUp(self):
+        # need to create the "test" project so @td.with_wiki works
+        setup_basic_test()
+
     @td.with_wiki
     @mock.patch('allura.lib.search.url')
     @mock.patch('allura.lib.search.request')


[24/50] git commit: [#6172] Refactor feed functionality into mixin controller

Posted by br...@apache.org.
[#6172] Refactor feed functionality into mixin controller

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/391aa922
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/391aa922
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/391aa922

Branch: refs/heads/db/6007
Commit: 391aa92294b69a228cee4b857c65e0d780ee0a36
Parents: 7244932
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Apr 30 17:44:37 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Apr 30 19:45:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/basetest_project_root.py |    2 -
 Allura/allura/controllers/discuss.py               |   75 ++++-------
 Allura/allura/controllers/feed.py                  |  108 +++++++++++++++
 Allura/allura/controllers/project.py               |   39 ++----
 Allura/allura/controllers/repository.py            |   31 +----
 Allura/allura/ext/user_profile/user_main.py        |   55 ++------
 ForgeBlog/forgeblog/main.py                        |   62 ++-------
 .../forgediscussion/controllers/root.py            |   44 ++----
 ForgeSVN/forgesvn/controllers.py                   |    3 +-
 ForgeSVN/forgesvn/svn_main.py                      |    3 -
 ForgeTracker/forgetracker/tracker_main.py          |   64 ++-------
 ForgeWiki/forgewiki/wiki_main.py                   |   67 ++-------
 12 files changed, 219 insertions(+), 334 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/Allura/allura/controllers/basetest_project_root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/basetest_project_root.py b/Allura/allura/controllers/basetest_project_root.py
index f9ec3d5..8c48ed6 100644
--- a/Allura/allura/controllers/basetest_project_root.py
+++ b/Allura/allura/controllers/basetest_project_root.py
@@ -66,8 +66,6 @@ class BasetestProjectRootController(WsgiDispatchController, ProjectController):
     '''
 
     def __init__(self):
-        setattr(self, 'feed.rss', self.feed)
-        setattr(self, 'feed.atom', self.feed)
         for n in M.Neighborhood.query.find():
             if n.url_prefix.startswith('//'): continue
             n.bind_controller(self)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 5abb3a2..b37d880 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -38,6 +38,7 @@ from allura.lib.helpers import DateTimeConverter
 
 from allura.lib.widgets import discuss as DW
 from .attachments import AttachmentsController, AttachmentController
+from .feed import Feed, FeedController
 
 log = logging.getLogger(__name__)
 
@@ -68,13 +69,11 @@ class WidgetConfig(object):
     thread_header = DW.ThreadHeader()
 
 # Controllers
-class DiscussionController(BaseController):
+class DiscussionController(BaseController, FeedController):
     M=ModelConfig
     W=WidgetConfig
 
     def __init__(self):
-        setattr(self, 'feed.rss', self.feed)
-        setattr(self, 'feed.atom', self.feed)
         if not hasattr(self, 'ThreadController'):
             self.ThreadController = ThreadController
         if not hasattr(self, 'PostController'):
@@ -106,29 +105,18 @@ class DiscussionController(BaseController):
             M.session.artifact_orm_session._get().skip_mod_date = True
         redirect(request.referer)
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=DateTimeConverter(if_empty=None),
-            until=DateTimeConverter(if_empty=None),
-            page=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, page=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent posts to %s' % self.discussion.name
-        feed = M.Feed.feed(
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
+        return Feed(
             dict(ref_id={'$in': [t.index_id() for t in self.discussion.threads]}),
-            feed_type,
-            title,
-            self.discussion.url(),
-            title,
-            since, until, page, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+            'Recent posts to %s' % self.discussion.name,
+            self.discussion.url())
+
 
 class AppDiscussionController(DiscussionController):
 
@@ -156,7 +144,7 @@ class ThreadsController(BaseController):
         else:
             raise exc.HTTPNotFound()
 
-class ThreadController(BaseController):
+class ThreadController(BaseController, FeedController):
     __metaclass__=h.ProxiedAttrMeta
     M=h.attrproxy('_discussion_controller', 'M')
     W=h.attrproxy('_discussion_controller', 'W')
@@ -170,8 +158,6 @@ class ThreadController(BaseController):
             require_access(self.thread.ref.artifact, 'read')
 
     def __init__(self, discussion_controller, thread_id):
-        setattr(self, 'feed.rss', self.feed)
-        setattr(self, 'feed.atom', self.feed)
         self._discussion_controller = discussion_controller
         self.discussion = discussion_controller.discussion
         self.thread = self.M.Thread.query.get(_id=thread_id)
@@ -237,29 +223,18 @@ class ThreadController(BaseController):
         flash('Thread flagged as spam.')
         redirect(self.discussion.url())
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=DateTimeConverter(if_empty=None),
-            until=DateTimeConverter(if_empty=None),
-            page=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, page=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent posts to %s' % (self.thread.subject or '(no subject)')
-        feed = M.Feed.feed(
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
+        return Feed(
             dict(ref_id=self.thread.index_id()),
-            feed_type,
-            title,
-            self.thread.url(),
-            title,
-            since, until, page, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+            'Recent posts to %s' % (self.thread.subject or '(no subject)'),
+            self.thread.url())
+
 
 class PostController(BaseController):
     __metaclass__=h.ProxiedAttrMeta

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/Allura/allura/controllers/feed.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/feed.py b/Allura/allura/controllers/feed.py
new file mode 100644
index 0000000..f014b21
--- /dev/null
+++ b/Allura/allura/controllers/feed.py
@@ -0,0 +1,108 @@
+#       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.
+
+from tg import expose, validate, request, response
+from tg.decorators import without_trailing_slash
+from formencode import validators as V
+from pylons import tmpl_context as c
+from webob import exc
+
+from allura import model as M
+from allura.lib import helpers as h
+
+
+class Feed(object):
+    """A facade for the arguments required by
+    :meth:`allura.model.artifact.Feed.feed`.
+
+    Used by :meth:`FeedController.feed` to create a real feed.
+
+    """
+    def __init__(self, query, title, url, description=None):
+        self.query = query
+        self.title = title
+        self.url = url
+        self.description = description or title
+
+
+class FeedController(object):
+    """Mixin class which adds RSS and Atom feed endpoints to an existing
+    controller.
+
+    Feeds will be accessible at the following URLs:
+
+        http://host/path/to/controller/feed -> RSS
+        http://host/path/to/controller/feed.rss -> RSS
+        http://host/path/to/controller/feed.atom -> Atom
+
+    A default feed is provided by :meth:`get_feed`. Subclasses that need
+    a customized feed should override :meth:`get_feed`.
+
+    """
+    FEED_TYPES = ['.atom', '.rss']
+    FEED_NAMES = ['feed{0}'.format(typ) for typ in FEED_TYPES]
+
+    def __getattr__(self, name):
+        if name in self.FEED_NAMES:
+            return self.feed
+        raise AttributeError(name)
+
+    def _get_feed_type(self, request):
+        for typ in self.FEED_TYPES:
+            if request.environ['PATH_INFO'].endswith(typ):
+                return typ.lstrip('.')
+        return 'rss'
+
+    @without_trailing_slash
+    @expose()
+    @validate(dict(
+            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
+            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
+            page=V.Int(if_empty=None),
+            limit=V.Int(if_empty=None)))
+    def feed(self, since=None, until=None, page=None, limit=None, **kw):
+        """Return a utf8-encoded XML feed (RSS or Atom) to the browser.
+        """
+        feed_def = self.get_feed(c.project, c.app, c.user)
+        if not feed_def:
+            raise exc.HTTPNotFound
+        feed = M.Feed.feed(
+            feed_def.query,
+            self._get_feed_type(request),
+            feed_def.title,
+            feed_def.url,
+            feed_def.description,
+            since, until, page, limit)
+        response.headers['Content-Type'] = ''
+        response.content_type = 'application/xml'
+        return feed.writeString('utf-8')
+
+    def get_feed(self, project, app, user):
+        """Return a default :class:`Feed` for this controller.
+
+        Subclasses should override to customize the feed.
+
+        :param project: :class:`allura.model.project.Project`
+        :param app: :class:`allura.app.Application`
+        :param user: :class:`allura.model.auth.User`
+        :rtype: :class:`Feed`
+
+        """
+        return Feed(
+            dict(project_id=project._id, app_config_id=app.config._id),
+            'Recent changes to %s' % app.config.options.mount_point,
+            app.url)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 4f02632..3bfe0ca 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -40,6 +40,7 @@ from allura.lib import helpers as h
 from allura.lib import utils
 from allura.lib.decorators import require_post
 from allura.controllers.error import ErrorController
+from allura.controllers.feed import Feed, FeedController
 from allura.lib.security import require_access, has_access
 from allura.lib.security import RoleCache
 from allura.lib.widgets import forms as ff
@@ -299,11 +300,9 @@ class ToolListController(object):
                 if e.tool_name and e.tool_name.lower() == tool_name]
         return dict(entries=entries, type=entries[0].tool_name.capitalize() if entries else None)
 
-class ProjectController(object):
+class ProjectController(FeedController):
 
     def __init__(self):
-        setattr(self, 'feed.rss', self.feed)
-        setattr(self, 'feed.atom', self.feed)
         setattr(self, '_nav.json', self._nav)
         self.screenshot = ScreenshotsController()
         self._list = ToolListController()
@@ -367,29 +366,17 @@ class ProjectController(object):
         else:
             redirect(c.project.app_configs[0].options.mount_point + '/')
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            page=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, page=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent changes to Project %s' % c.project.name
-        feed = M.Feed.feed(
-            dict(project_id=c.project._id),
-            feed_type,
-            title,
-            c.project.url(),
-            title,
-            since, until, page, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
+        return Feed(
+            dict(project_id=project._id),
+            'Recent changes to Project %s' % project.name,
+            project.url())
 
     @expose()
     def icon(self, **kw):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 5e006ba..59b154e 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -49,6 +49,7 @@ from allura.lib.widgets.subscriptions import SubscribeForm
 from allura import model as M
 from allura.lib.widgets import form_fields as ffw
 from allura.controllers.base import DispatchIndex
+from allura.controllers.feed import FeedController
 from allura.lib.diff import HtmlSideBySideDiff
 from paste.deploy.converters import asbool
 from allura.app import SitemapEntry
@@ -61,14 +62,10 @@ def on_import():
     CommitBrowser.TreeBrowserClass = TreeBrowser
     TreeBrowser.FileBrowserClass = FileBrowser
 
-class RepoRootController(BaseController):
+class RepoRootController(BaseController, FeedController):
     _discuss = AppDiscussionController()
     commit_browser_widget=SCMCommitBrowserWidget()
 
-    def __init__(self):
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
-
     def _check_security(self):
         security.require(security.has_access(c.app, 'read'))
 
@@ -187,30 +184,6 @@ class RepoRootController(BaseController):
             redirect(mr.url())
 
     @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent changes to %s' % c.app.config.options.mount_point
-        feed = M.Feed.feed(
-            dict(project_id=c.project._id,app_config_id=c.app.config._id),
-            feed_type,
-            title,
-            c.app.url,
-            title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
-
-    @without_trailing_slash
     @expose('jinja:allura:templates/repo/commit_browser.html')
     def commit_browser(self):
         if not c.app.repo or c.app.repo.status != 'ready':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/Allura/allura/ext/user_profile/user_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index 0491199..c6e2402 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -32,6 +32,7 @@ from allura.lib.helpers import DateTimeConverter
 from allura.lib.security import require_access
 from allura.model import User, Feed, ACE
 from allura.controllers import BaseController
+from allura.controllers.feed import Feed, FeedController
 from allura.lib.decorators import require_post
 
 log = logging.getLogger(__name__)
@@ -79,11 +80,7 @@ class UserProfileApp(Application):
         pass
 
 
-class UserProfileController(BaseController):
-
-    def __init__(self):
-        setattr(self, 'feed.rss', self.feed)
-        setattr(self, 'feed.atom', self.feed)
+class UserProfileController(BaseController, FeedController):
 
     def _check_security(self):
         require_access(c.project, 'read')
@@ -94,38 +91,16 @@ class UserProfileController(BaseController):
         if not user:
             raise exc.HTTPNotFound()
         return dict(user=user)
-    # This will be fully implemented in a future iteration
-    # @expose('jinja:allura.ext.user_profile:templates/user_subscriptions.html')
-    # def subscriptions(self):
-    #     username = c.project.shortname.split('/')[1]
-    #     user = User.by_username(username)
-    #     subs = Subscriptions.query.find({'user_id':user._id}).all()
-    #     for sub in subs:
-    #         for s in sub.subscriptions:
-    #             r = g.solr_short_timeout.search(s.artifact_index_id)
-    #             print r.docs
-    #     return dict(user=user)
-
-    @expose()
-    @validate(dict(
-            since=DateTimeConverter(if_empty=None),
-            until=DateTimeConverter(if_empty=None),
-            page=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, page=None, limit=None, **kw):
-        user = c.project.user_project_of
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent posts by %s' % user.display_name
-        feed = Feed.feed(
-            {'author_link':user.url()},
-            feed_type,
-            title,
-            c.project.url(),
-            title,
-            since, until, page, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
+        user = project.user_project_of
+        return Feed(
+            {'author_link': user.url()},
+            'Recent posts by %s' % user.display_name,
+            project.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index f745af9..0c7af13 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -46,6 +46,7 @@ from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.search import SearchResults, SearchHelp
 from allura import model as M
 from allura.controllers import BaseController, AppDiscussionController
+from allura.controllers.feed import Feed, FeedController
 
 # Local imports
 from forgeblog import model as BM
@@ -180,11 +181,9 @@ class ForgeBlogApp(Application):
         BM.BlogPostSnapshot.query.remove(dict(app_config_id=c.app.config._id))
         super(ForgeBlogApp, self).uninstall(project)
 
-class RootController(BaseController):
+class RootController(BaseController, FeedController):
 
     def __init__(self):
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
         self._discuss = AppDiscussionController()
 
     def _check_security(self):
@@ -255,30 +254,6 @@ class RootController(BaseController):
         redirect(h.really_unicode(post.url()).encode('utf-8'))
 
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = '%s - %s' % (c.project.name, c.app.config.options.mount_label)
-        feed = M.Feed.feed(
-            dict(project_id=c.project._id, app_config_id=c.app.config._id),
-            feed_type,
-            title,
-            c.app.url,
-            title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
-
     @with_trailing_slash
     @expose('jinja:allura:templates/markdown_syntax_dialog.html')
     def markdown_syntax_dialog(self, **kw):
@@ -293,12 +268,10 @@ class RootController(BaseController):
             raise exc.HTTPNotFound()
         return PostController(post), rest
 
-class PostController(BaseController):
+class PostController(BaseController, FeedController):
 
     def __init__(self, post):
         self.post = post
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
 
     def _check_security(self):
         require_access(self.post, 'read')
@@ -380,28 +353,17 @@ class PostController(BaseController):
             self.post.unsubscribe()
         redirect(h.really_unicode(request.referer).encode('utf-8'))
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        feed = M.Feed.feed(
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
+        return Feed(
             dict(ref_id=self.post.index_id()),
-            feed_type,
-            'Recent changes to %s' % self.post.title,
-            self.post.url(),
             'Recent changes to %s' % self.post.title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+            self.post.url())
 
     def _get_version(self, version):
         if not version: return self.post

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index 02c3cde..f731da3 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -27,14 +27,13 @@ from pylons import request
 from formencode import validators
 from webob import exc
 
-
 from allura.lib.security import require_access, has_access, require_authenticated
-from allura.model import Feed
 from allura.lib.search import search_app
 from allura.lib import helpers as h
 from allura.lib.utils import AntiSpam
 from allura.lib.decorators import require_post
 from allura.controllers import BaseController, DispatchIndex
+from allura.controllers.feed import Feed, FeedController
 
 from .forum import ForumController
 from forgediscussion import import_support
@@ -48,7 +47,7 @@ from forgediscussion.widgets.admin import AddForumShort
 
 log = logging.getLogger(__name__)
 
-class RootController(BaseController, DispatchIndex):
+class RootController(BaseController, DispatchIndex, FeedController):
 
     class W(object):
         forum_subscription_form=FW.ForumSubscriptionForm()
@@ -58,10 +57,6 @@ class RootController(BaseController, DispatchIndex):
         search_results = SearchResults()
         search_help = SearchHelp(comments=False, history=False)
 
-    def __init__(self):
-        setattr(self, 'feed.rss', self.feed)
-        setattr(self, 'feed.atom', self.feed)
-
     def _check_security(self):
         require_access(c.app, 'read')
 
@@ -191,29 +186,18 @@ class RootController(BaseController, DispatchIndex):
                 obj['obj'].subscriptions.pop(str(c.user._id), None)
         redirect(request.referer)
 
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None),
-            until=h.DateTimeConverter(if_empty=None),
-            page=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, page=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent posts to %s' % c.app.config.options.mount_label
-
-        feed = Feed.feed(
-            dict(project_id=c.project._id, app_config_id=c.app.config._id),
-            feed_type,
-            title,
-            c.app.url,
-            title,
-            since, until, page, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
+        return Feed(
+            dict(project_id=project._id, app_config_id=app.config._id),
+             'Recent posts to %s' % app.config.options.mount_label,
+            app.url)
+
 
 class RootRestController(BaseController):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/ForgeSVN/forgesvn/controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/controllers.py b/ForgeSVN/forgesvn/controllers.py
index 2e39fc7..66709f0 100644
--- a/ForgeSVN/forgesvn/controllers.py
+++ b/ForgeSVN/forgesvn/controllers.py
@@ -20,9 +20,10 @@ from tg.decorators import with_trailing_slash
 from pylons import tmpl_context as c
 
 from allura.controllers import repository
+from allura.controllers.feed import FeedController
 
 
-class BranchBrowser(repository.BranchBrowser):
+class BranchBrowser(repository.BranchBrowser, FeedController):
 
     def __init__(self):
         super(BranchBrowser, self).__init__(None)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/ForgeSVN/forgesvn/svn_main.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/svn_main.py b/ForgeSVN/forgesvn/svn_main.py
index ef7d008..dcb4fd6 100644
--- a/ForgeSVN/forgesvn/svn_main.py
+++ b/ForgeSVN/forgesvn/svn_main.py
@@ -64,9 +64,6 @@ class ForgeSVNApp(RepositoryApp):
         self.root = BranchBrowser()
         default_root = RepoRootController()
         self.root.refresh = default_root.refresh
-        self.root.feed = default_root.feed
-        setattr(self.root, 'feed.rss', self.root.feed)
-        setattr(self.root, 'feed.atom', self.root.feed)
         self.root.commit_browser = default_root.commit_browser
         self.root.commit_browser_data = default_root.commit_browser_data
         self.root.status = default_root.status

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 349ef1e..6270e96 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -61,6 +61,7 @@ from allura.lib.zarkov_helpers import zero_fill_zarkov_result
 from allura.controllers import AppDiscussionController, AppDiscussionRestController
 from allura.controllers import attachments as ac
 from allura.controllers import BaseController
+from allura.controllers.feed import Feed, FeedController
 from allura.tasks import mail_tasks
 
 # Local imports
@@ -467,11 +468,9 @@ def solr_columns():
         columns.append(dict(name='votes', sort_name='votes_total_i', label='Votes', active=True))
     return columns
 
-class RootController(BaseController):
+class RootController(BaseController, FeedController):
 
     def __init__(self):
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
         setattr(self, 'search_feed.atom', self.search_feed)
         setattr(self, 'search_feed.rss', self.search_feed)
         self._discuss = AppDiscussionController()
@@ -711,30 +710,6 @@ class RootController(BaseController):
         'Static page explaining markdown.'
         return dict()
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent changes to %s' % c.app.config.options.mount_point
-        feed = M.Feed.feed(
-            dict(project_id=c.project._id,app_config_id=c.app.config._id),
-            feed_type,
-            title,
-            c.app.url,
-            title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
-
     @expose()
     @h.vardec
     @require_post()
@@ -1233,7 +1208,7 @@ def filtered_by_subscription(tickets, project_id=None, app_config_id=None):
     return filtered
 
 
-class TicketController(BaseController):
+class TicketController(BaseController, FeedController):
 
     def __init__(self, ticket_num=None):
         if ticket_num is not None:
@@ -1248,8 +1223,6 @@ class TicketController(BaseController):
                     utils.permanent_redirect(self.ticket.url())
             self.attachment = AttachmentsController(self.ticket)
             # self.comments = CommentController(self.ticket)
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
 
     def _check_security(self):
         if self.ticket is not None:
@@ -1285,30 +1258,19 @@ class TicketController(BaseController):
         else:
             raise exc.HTTPNotFound, 'Ticket #%s does not exist.' % self.ticket_num
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
         title = 'Recent changes to %d: %s' % (
             self.ticket.ticket_num, self.ticket.summary)
-        feed = M.Feed.feed(
-            {'ref_id':self.ticket.index_id()},
-            feed_type,
-            title,
-            self.ticket.url(),
+        return Feed(
+            {'ref_id': self.ticket.index_id()},
             title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+            self.ticket.url())
 
     @expose()
     @require_post()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/391aa922/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index b923350..dfb982b 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -41,6 +41,7 @@ from allura.lib.security import require_access, has_access
 from allura.controllers import AppDiscussionController, BaseController
 from allura.controllers import DispatchIndex
 from allura.controllers import attachments as ac
+from allura.controllers.feed import Feed, FeedController
 from allura.lib import widgets as w
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.subscriptions import SubscribeForm
@@ -277,11 +278,9 @@ The wiki uses [Markdown](%s) syntax.
         WM.Globals.query.remove(dict(app_config_id=self.config._id))
         super(ForgeWikiApp, self).uninstall(project)
 
-class RootController(BaseController, DispatchIndex):
+class RootController(BaseController, DispatchIndex, FeedController):
 
     def __init__(self):
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
         c.create_page_lightbox = W.create_page_lightbox
         self._discuss = AppDiscussionController()
 
@@ -409,31 +408,8 @@ class RootController(BaseController, DispatchIndex):
         'Display a page about how to use markdown.'
         return dict(example=MARKDOWN_EXAMPLE)
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        title = 'Recent changes to %s' % c.app.config.options.mount_point
-        feed = M.Feed.feed(
-            dict(project_id=c.project._id,app_config_id=c.app.config._id),
-            feed_type,
-            title,
-            c.app.url,
-            title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
-
-class PageController(BaseController):
+
+class PageController(BaseController, FeedController):
 
     def __init__(self, title):
         self.title = h.really_unicode(unquote(title))
@@ -442,8 +418,6 @@ class PageController(BaseController):
         if self.page is not None:
             self.attachment = WikiAttachmentsController(self.page)
         c.create_page_lightbox = W.create_page_lightbox
-        setattr(self, 'feed.atom', self.feed)
-        setattr(self, 'feed.rss', self.feed)
 
     def _check_security(self):
         if self.page:
@@ -583,30 +557,19 @@ class PageController(BaseController):
             raise exc.HTTPNotFound
         return pformat(self.page)
 
-    @without_trailing_slash
-    @expose()
-    @validate(dict(
-            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            until=h.DateTimeConverter(if_empty=None, if_invalid=None),
-            offset=validators.Int(if_empty=None),
-            limit=validators.Int(if_empty=None)))
-    def feed(self, since=None, until=None, offset=None, limit=None, **kw):
+    def get_feed(self, project, app, user):
+        """Return a :class:`allura.controllers.feed.Feed` object describing
+        the xml feed for this controller.
+
+        Overrides :meth:`allura.controllers.feed.FeedController.get_feed`.
+
+        """
         if not self.page:
-            raise exc.HTTPNotFound
-        if request.environ['PATH_INFO'].endswith('.atom'):
-            feed_type = 'atom'
-        else:
-            feed_type = 'rss'
-        feed = M.Feed.feed(
-            {'ref_id':self.page.index_id()},
-            feed_type,
-            'Recent changes to %s' % self.page.title,
-            self.page.url(),
+            return None
+        return Feed(
+            {'ref_id': self.page.index_id()},
             'Recent changes to %s' % self.page.title,
-            since, until, offset, limit)
-        response.headers['Content-Type'] = ''
-        response.content_type = 'application/xml'
-        return feed.writeString('utf-8')
+            self.page.url())
 
     @without_trailing_slash
     @expose('json')


[44/50] git commit: [#6161] ticket:329 Push changes to multiple solr instances

Posted by br...@apache.org.
[#6161] ticket:329 Push changes to multiple solr instances


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7a332c6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7a332c6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7a332c6e

Branch: refs/heads/db/6007
Commit: 7a332c6ecdc6c2cffd5f262d0293d7afdf195d85
Parents: ba100cc
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Apr 29 12:46:33 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 22:18:14 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py      |   19 +++++---
 Allura/allura/lib/solr.py             |   47 +++++++++++++++-----
 Allura/allura/tests/unit/test_solr.py |   67 +++++++++++++++++++++------
 Allura/development.ini                |    3 +
 4 files changed, 104 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7a332c6e/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 0621b8d..b030d6f 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -38,7 +38,7 @@ import pygments.util
 from tg import config, session
 from pylons import request
 from pylons import tmpl_context as c
-from paste.deploy.converters import asbool, asint
+from paste.deploy.converters import asbool, asint, aslist
 from pypeline.markup import markup as pypeline_markup
 
 import ew as ew_core
@@ -93,14 +93,21 @@ class Globals(object):
         self.allura_templates = pkg_resources.resource_filename('allura', 'templates')
 
         # Setup SOLR
-        self.solr_server = config.get('solr.server')
+        self.solr_server = aslist(config.get('solr.server'), ',')
+        # skip empty strings in case of extra commas
+        self.solr_server = [s for s in self.solr_server if s]
+        self.solr_query_server = config.get('solr.query_server')
         if asbool(config.get('solr.mock')):
             self.solr = self.solr_short_timeout = MockSOLR()
         elif self.solr_server:
-            self.solr = Solr(self.solr_server, commit=asbool(config.get('solr.commit', True)),
-                    commitWithin=config.get('solr.commitWithin'), timeout=int(config.get('solr.long_timeout', 60)))
-            self.solr_short_timeout = Solr(self.solr_server, commit=asbool(config.get('solr.commit', True)),
-                    commitWithin=config.get('solr.commitWithin'), timeout=int(config.get('solr.short_timeout', 10)))
+            self.solr = Solr(self.solr_server, self.solr_query_server,
+                             commit=asbool(config.get('solr.commit', True)),
+                             commitWithin=config.get('solr.commitWithin'),
+                             timeout=int(config.get('solr.long_timeout', 60)))
+            self.solr_short_timeout = Solr(self.solr_server, self.solr_query_server,
+                                           commit=asbool(config.get('solr.commit', True)),
+                                           commitWithin=config.get('solr.commitWithin'),
+                                           timeout=int(config.get('solr.short_timeout', 10)))
         else: # pragma no cover
             self.solr = None
             self.solr_short_timeout = None

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7a332c6e/Allura/allura/lib/solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/solr.py b/Allura/allura/lib/solr.py
index e91b183..e1e9567 100644
--- a/Allura/allura/lib/solr.py
+++ b/Allura/allura/lib/solr.py
@@ -20,28 +20,53 @@ import pysolr
 from pysolr import SolrError
 
 
-class Solr(pysolr.Solr):
-    """Solr server that accepts default values for `commit` and
-    `commitWithin` and passes those values through to each `add` and
-    `delete` call, unless explicitly overridden.
+class Solr(object):
+    """Solr interface that pushes updates to multiple solr instances.
+
+    `push_servers`: list of servers to push to.
+    `query_server`: server to read from. Uses `push_servers[0]` if not specified.
+
+    Also, accepts default values for `commit` and `commitWithin`
+    and passes those values through to each `add` and `delete` call,
+    unless explicitly overridden.
     """
 
-    def __init__(self, server, commit=True, commitWithin=None, **kw):
-        pysolr.Solr.__init__(self, server, **kw)
-        self.commit = commit
+    def __init__(self, push_servers, query_server=None,
+                 commit=True, commitWithin=None, **kw):
+        self.push_pool = [pysolr.Solr(s, **kw) for s in push_servers]
+        if query_server:
+            self.query_server = pysolr.Solr(query_server, **kw)
+        else:
+            self.query_server = self.push_pool[0]
+        self._commit = commit
         self.commitWithin = commitWithin
 
     def add(self, *args, **kw):
         if 'commit' not in kw:
-            kw['commit'] = self.commit
+            kw['commit'] = self._commit
         if self.commitWithin and 'commitWithin' not in kw:
             kw['commitWithin'] = self.commitWithin
-        return pysolr.Solr.add(self, *args, **kw)
+        responses = []
+        for solr in self.push_pool:
+            responses.append(solr.add(*args, **kw))
+        return responses
 
     def delete(self, *args, **kw):
         if 'commit' not in kw:
-            kw['commit'] = self.commit
-        return pysolr.Solr.delete(self, *args, **kw)
+            kw['commit'] = self._commit
+        responses = []
+        for solr in self.push_pool:
+            responses.append(solr.delete(*args, **kw))
+        return responses
+
+    def commit(self, *args, **kw):
+        responses = []
+        for solr in self.push_pool:
+            responses.append(solr.commit(*args, **kw))
+        return responses
+
+    def search(self, *args, **kw):
+        return self.query_server.search(*args, **kw)
 
 
 class MockSOLR(object):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7a332c6e/Allura/allura/tests/unit/test_solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_solr.py b/Allura/allura/tests/unit/test_solr.py
index b3dee43..2bc5cdb 100644
--- a/Allura/allura/tests/unit/test_solr.py
+++ b/Allura/allura/tests/unit/test_solr.py
@@ -28,30 +28,67 @@ from allura.lib.solr import Solr
 from allura.lib.search import solarize, search_app
 
 class TestSolr(unittest.TestCase):
+
     @mock.patch('allura.lib.solr.pysolr')
-    def setUp(self, pysolr):
-        self.solr = Solr('server', commit=False, commitWithin='10000')
+    def test_init(self, pysolr):
+        servers = ['server1', 'server2']
+        solr = Solr(servers, commit=False, commitWithin='10000')
+        calls = [mock.call('server1'), mock.call('server2')]
+        pysolr.Solr.assert_has_calls(calls)
+        assert_equal(len(solr.push_pool), 2)
+
+        pysolr.reset_mock()
+        solr = Solr(servers, 'server3', commit=False, commitWithin='10000')
+        calls = [mock.call('server1'), mock.call('server2'), mock.call('server3')]
+        pysolr.Solr.assert_has_calls(calls)
+        assert_equal(len(solr.push_pool), 2)
 
     @mock.patch('allura.lib.solr.pysolr')
     def test_add(self, pysolr):
-        s = self.solr
-        s.add('foo', commit=True, commitWithin=None)
-        pysolr.Solr.add.assert_called_once_with(s, 'foo', commit=True,
-                commitWithin=None)
+        servers = ['server1', 'server2']
+        solr = Solr(servers, commit=False, commitWithin='10000')
+        solr.add('foo', commit=True, commitWithin=None)
+        calls = [mock.call('foo', commit=True, commitWithin=None)] * 2
+        pysolr.Solr().add.assert_has_calls(calls)
         pysolr.reset_mock()
-        s.add('bar', somekw='value')
-        pysolr.Solr.add.assert_called_once_with(s, 'bar', commit=False,
-                commitWithin='10000', somekw='value')
+        solr.add('bar', somekw='value')
+        calls = [mock.call('bar', commit=False,
+            commitWithin='10000', somekw='value')] * 2
+        pysolr.Solr().add.assert_has_calls(calls)
 
     @mock.patch('allura.lib.solr.pysolr')
     def test_delete(self, pysolr):
-        s = self.solr
-        s.delete('foo', commit=True)
-        pysolr.Solr.delete.assert_called_once_with(s, 'foo', commit=True)
+        servers = ['server1', 'server2']
+        solr = Solr(servers, commit=False, commitWithin='10000')
+        solr.delete('foo', commit=True)
+        calls = [mock.call('foo', commit=True)] * 2
+        pysolr.Solr().delete.assert_has_calls(calls)
+        pysolr.reset_mock()
+        solr.delete('bar', somekw='value')
+        calls = [mock.call('bar', commit=False, somekw='value')] * 2
+        pysolr.Solr().delete.assert_has_calls(calls)
+
+    @mock.patch('allura.lib.solr.pysolr')
+    def test_commit(self, pysolr):
+        servers = ['server1', 'server2']
+        solr = Solr(servers, commit=False, commitWithin='10000')
+        solr.commit('arg')
+        pysolr.Solr().commit.assert_has_calls([mock.call('arg')] * 2)
         pysolr.reset_mock()
-        s.delete('bar', somekw='value')
-        pysolr.Solr.delete.assert_called_once_with(s, 'bar', commit=False,
-                somekw='value')
+        solr.commit('arg', kw='kw')
+        calls = [mock.call('arg', kw='kw')] * 2
+        pysolr.Solr().commit.assert_has_calls(calls)
+
+    @mock.patch('allura.lib.solr.pysolr')
+    def test_search(self, pysolr):
+        servers = ['server1', 'server2']
+        solr = Solr(servers, commit=False, commitWithin='10000')
+        solr.search('foo')
+        solr.query_server.search.assert_called_once_with('foo')
+        pysolr.reset_mock()
+        solr.search('bar', kw='kw')
+        solr.query_server.search.assert_called_once_with('bar', kw='kw')
+
 
 class TestSolarize(unittest.TestCase):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7a332c6e/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 761876b..b2ac7bf 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -177,7 +177,10 @@ amqp.enabled = false
 openid.realm = http://localhost:8080/
 
 # SOLR setup
+# comma-separated list of servers to push changes to
 solr.server = http://localhost:8983/solr/core0
+# server to read from. Uses solr.server[0] if not specified.
+# solr.query_server =
 # commit on every add/delete?
 solr.commit = false
 # commit add operations within N ms


[08/50] git commit: [#2835] avoid double-escaping solr text by escaping it only on the way out. tests

Posted by br...@apache.org.
[#2835] avoid double-escaping solr text by escaping it only on the way out.  tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/69d75753
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/69d75753
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/69d75753

Branch: refs/heads/db/6007
Commit: 69d757538ad8d5c30cffe491b56c8b701f7c4dd8
Parents: c8311bb
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Apr 25 20:20:12 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 13:38:36 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/search.py           |    4 +-
 Allura/allura/tests/unit/test_solr.py |   86 +++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/69d75753/Allura/allura/lib/search.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/search.py b/Allura/allura/lib/search.py
index 203e37a..d43af9c 100644
--- a/Allura/allura/lib/search.py
+++ b/Allura/allura/lib/search.py
@@ -46,8 +46,6 @@ def solarize(obj):
     text = doc['text']
     text = g.markdown.convert(text)
     doc['text'] = jinja2.Markup.escape(text).striptags()
-    # striptags decodes html entities, so we should escape them again
-    doc['text'] = jinja2.Markup.escape(doc['text'])
     return doc
 
 class SearchError(SolrError):
@@ -201,7 +199,7 @@ def search_app(q='', fq=None, app=True, **kw):
     score_url = url(request.path, params=params)
     params.update({'sort': date_url})
     date_url = url(request.path, params=params)
-    return dict(q=q, history=history, results=results or [],
+    return dict(q=q, history=history, results=list(results) or [],
                 count=count, limit=limit, page=page, search_error=search_error,
                 sort_score_url=score_url, sort_date_url=date_url,
                 sort_field=field)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/69d75753/Allura/allura/tests/unit/test_solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_solr.py b/Allura/allura/tests/unit/test_solr.py
index 5226f07..f431ea3 100644
--- a/Allura/allura/tests/unit/test_solr.py
+++ b/Allura/allura/tests/unit/test_solr.py
@@ -16,11 +16,15 @@
 #       under the License.
 
 import unittest
+
 import mock
 from nose.tools import assert_equal
+from markupsafe import Markup
 
+from allura.lib import helpers as h
+from allura.tests import decorators as td
 from allura.lib.solr import Solr
-from allura.lib.search import solarize
+from allura.lib.search import solarize, search_app
 
 class TestSolr(unittest.TestCase):
     @mock.patch('allura.lib.solr.pysolr')
@@ -72,5 +76,83 @@ class TestSolarize(unittest.TestCase):
         obj = mock.MagicMock()
         obj.index.return_value = {'text': '<script>alert(1)</script>'}
         assert_equal(solarize(obj), {'text': ''})
+
         obj.index.return_value = {'text': '&lt;script&gt;alert(1)&lt;/script&gt;'}
-        assert_equal(solarize(obj), {'text': '&lt;script&gt;alert(1)&lt;/script&gt;'})
+        assert_equal(solarize(obj), {'text': '<script>alert(1)</script>'})
+
+
+class TestSearch_app(unittest.TestCase):
+
+    @td.with_wiki
+    @mock.patch('allura.lib.search.url')
+    @mock.patch('allura.lib.search.request')
+    def test_basic(self, req, url_fn):
+        req.GET = dict()
+        req.path = '/test/search'
+        url_fn.side_effect = ['the-score-url', 'the-date-url']
+        with h.push_context('test', 'wiki', neighborhood='Projects'):
+            resp = search_app(q='foo bar')
+        assert_equal(resp, dict(
+            q='foo bar',
+            history=None,
+            results=[],
+            count=0,
+            limit=25,
+            page=0,
+            search_error=None,
+            sort_score_url='the-score-url',
+            sort_date_url='the-date-url',
+            sort_field='score',
+        ))
+
+    @td.with_wiki
+    @mock.patch('allura.lib.search.g.solr.search')
+    @mock.patch('allura.lib.search.url')
+    @mock.patch('allura.lib.search.request')
+    def test_escape_solr_text(self, req, url_fn, solr_search):
+        req.GET = dict()
+        req.path = '/test/wiki/search'
+        url_fn.side_effect = ['the-score-url', 'the-date-url']
+        results = mock.Mock(hits=2, docs=[
+                {'id': 123, 'type_s':'WikiPage Snapshot', 'url_s':'/test/wiki/Foo', 'version_i':2},
+                {'id': 321, 'type_s':'Post'},
+            ], highlighting={
+                123: dict(title='some #ALLURA-HIGHLIGHT-START#Foo#ALLURA-HIGHLIGHT-END# stuff',
+                         text='scary <script>alert(1)</script> bar'),
+                321: dict(title='blah blah',
+                         text='less scary but still dangerous &lt;script&gt;alert(1)&lt;/script&gt; '
+                              'blah #ALLURA-HIGHLIGHT-START#bar#ALLURA-HIGHLIGHT-END# foo foo'),
+            },
+        )
+        results.__iter__ = lambda self: iter(results.docs)
+        solr_search.return_value = results
+        with h.push_context('test', 'wiki', neighborhood='Projects'):
+            resp = search_app(q='foo bar')
+
+        assert_equal(resp, dict(
+            q='foo bar',
+            history=None,
+            count=2,
+            limit=25,
+            page=0,
+            search_error=None,
+            sort_score_url='the-score-url',
+            sort_date_url='the-date-url',
+            sort_field='score',
+            results=[{
+                'id': 123,
+                'type_s': 'WikiPage Snapshot',
+                'version_i': 2,
+                'url_s': '/test/wiki/Foo?version=2',
+                # highlighting works
+                'title_match': Markup('some <strong>Foo</strong> stuff'),
+                # HTML in the solr plaintext results get escaped
+                'text_match': Markup('scary &lt;script&gt;alert(1)&lt;/script&gt; bar'),
+                }, {
+                'id': 321,
+                'type_s': 'Post',
+                'title_match': Markup('blah blah'),
+                # highlighting in text
+                'text_match': Markup('less scary but still dangerous &amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt; blah <strong>bar</strong> foo foo'),
+                }]
+        ))


[17/50] git commit: [#5891] ticket:327 refactoring for comments attachments

Posted by br...@apache.org.
[#5891]  ticket:327  refactoring for comments attachments


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c40773b7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c40773b7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c40773b7

Branch: refs/heads/db/6007
Commit: c40773b77f71335adfe7a300955e5fc99d0266c1
Parents: 57d4e6f
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Apr 30 11:15:35 2013 +0400
Committer: Yuriy Arhipov <yu...@yandex.ru>
Committed: Tue Apr 30 11:16:44 2013 +0400

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py         |   35 ++------------------
 Allura/allura/lib/helpers.py                 |   13 ++++++++
 Allura/allura/tests/model/test_discussion.py |   14 ++++++++
 3 files changed, 31 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c40773b7/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index b0bb426..eb34981 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -211,12 +211,7 @@ class ThreadController(BaseController):
         file_info = kw.get('file_info', None)
         p = self.thread.add_post(**kw)
         is_spam = g.spam_checker.check(kw['text'], artifact=p, user=c.user)
-        if hasattr(file_info, 'file'):
-            p.attach(
-                file_info.filename, file_info.file, content_type=file_info.type,
-                post_id=p._id,
-                thread_id=p.thread_id,
-                discussion_id=p.discussion_id)
+        h.attach_to_post(p, file_info)
         if self.thread.artifact:
             self.thread.artifact.mod_date = datetime.utcnow()
         flash('Message posted')
@@ -299,12 +294,7 @@ class PostController(BaseController):
             require_access(self.post, 'moderate')
             post_fields = self.W.edit_post.to_python(kw, None)
             file_info = post_fields.pop('file_info', None)
-            if hasattr(file_info, 'file'):
-                self.post.attach(
-                    file_info.filename, file_info.file, content_type=file_info.type,
-                    post_id=self.post._id,
-                    thread_id=self.post.thread_id,
-                    discussion_id=self.post.discussion_id)
+            h.attach_to_post(self.post, file_info)
             for k,v in post_fields.iteritems():
                 try:
                     setattr(self.post, k, v)
@@ -349,15 +339,7 @@ class PostController(BaseController):
         kw = self.W.edit_post.to_python(kw, None)
         p = self.thread.add_post(parent_id=self.post._id, **kw)
         is_spam = g.spam_checker.check(kw['text'], artifact=p, user=c.user)
-        if hasattr(file_info, 'file'):
-            mime_type = file_info.type
-            if not mime_type or '/' not in mime_type:
-                mime_type = utils.guess_mime_type(file_info.filename)
-            p.attach(
-                file_info.filename, file_info.file, content_type=mime_type,
-                post_id=p._id,
-                thread_id=p.thread_id,
-                discussion_id=p.discussion_id)
+        h.attach_to_post(p, file_info)
         redirect(request.referer)
 
     @h.vardec
@@ -391,16 +373,7 @@ class PostController(BaseController):
     @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
-        if hasattr(file_info, 'file'):
-            mime_type = file_info.type
-            # If mime type was not passed or bogus, guess it
-            if not mime_type or '/' not in mime_type:
-                mime_type = utils.guess_mime_type(file_info.filename)
-            self.post.attach(
-                file_info.filename, file_info.file, content_type=mime_type,
-                post_id=self.post._id,
-                thread_id=self.post.thread_id,
-                discussion_id=self.post.discussion_id)
+        h.attach_to_post(self.post, file_info)
         redirect(request.referer)
 
     @expose()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c40773b7/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 9ddad18..deed268 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -51,6 +51,7 @@ from allura.lib import exceptions as exc
 from allura.lib.decorators import exceptionless
 from allura.lib import AsciiDammit
 from .security import has_access
+from allura.lib import utils
 
 
 # validates project, subproject, and user names
@@ -702,3 +703,15 @@ def get_first(d, key):
     if isinstance(v, list):
         return v[0] if len(v) > 0 else None
     return v
+
+
+def attach_to_post(post, file_info):
+    if hasattr(file_info, 'file'):
+        mime_type = file_info.type
+        if not mime_type or '/' not in mime_type:
+            mime_type = utils.guess_mime_type(file_info.filename)
+        post.attach(
+            file_info.filename, file_info.file, content_type=mime_type,
+            post_id=post._id,
+            thread_id=post.thread_id,
+            discussion_id=post.discussion_id)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c40773b7/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 7e9df32..2ab4b2a 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -206,6 +206,20 @@ def test_attachment_methods():
     assert '\nAttachment: fake.txt (37 Bytes; text/plain)' in n.text
 
 @with_setup(setUp, tearDown)
+def test_attach_to_post():
+    test_file = FieldStorage()
+    test_file.name = 'file_info'
+    test_file.filename = 'test.txt'
+    test_file.type = 'text/plain'
+    test_file.file=StringIO('test file\n')
+    d = M.Discussion(shortname='test', name='test')
+    t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
+    test_post = t.post('test post')
+    h.attach_to_post(test_post, test_file)
+    ThreadLocalORMSession.flush_all()
+    assert test_post.attachments.count() == 1, test_post.attachments.count()
+
+@with_setup(setUp, tearDown)
 def test_discussion_delete():
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread.new(discussion_id=d._id, subject='Test Thread')


[14/50] git commit: [#5998] remove newrelic config flag, since it is not config driven any more

Posted by br...@apache.org.
[#5998] remove newrelic config flag, since it is not config driven any more


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ed4a5a0e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ed4a5a0e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ed4a5a0e

Branch: refs/heads/db/6007
Commit: ed4a5a0e804c60eebf9bed8c359b5f6acf91558a
Parents: 2c50ad0
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Apr 29 13:09:59 2013 -0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Apr 29 13:09:59 2013 -0400

----------------------------------------------------------------------
 Allura/development.ini |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ed4a5a0e/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 9cb99c3..761876b 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -49,8 +49,6 @@ use_queue = true
 
 base_url = http://localhost:8080
 
-# newrelic = true
-
 #lang = ru
 cache_dir = %(here)s/data
 beaker.session.key = allura


[46/50] git commit: [#6110] Log output on all tasks to prevent Broken pipe errors

Posted by br...@apache.org.
[#6110] Log output on all tasks to prevent Broken pipe errors

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/94cd1ede
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/94cd1ede
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/94cd1ede

Branch: refs/heads/db/6007
Commit: 94cd1ede798aa2cb4ec4b3a515cb1a3f627a2eaa
Parents: b4fa50d
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri May 3 17:09:19 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri May 3 18:59:22 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py        |   23 ++++++++++++++++++++++-
 Allura/allura/model/monq_model.py   |    4 +++-
 Allura/allura/scripts/scripttask.py |   23 ++++-------------------
 3 files changed, 29 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94cd1ede/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 9d97c02..d55b511 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -17,6 +17,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import sys
 import os
 import os.path
 import difflib
@@ -705,4 +706,24 @@ def get_first(d, key):
 
 
 def datetimeformat(value, format='%Y-%m-%d %H:%M:%S'):
-    return value.strftime(format)
\ No newline at end of file
+    return value.strftime(format)
+
+
+@contextmanager
+def log_output(log):
+    class Writer(object):
+        def __init__(self, func):
+            self.func = func
+
+        def write(self, buf):
+            self.func(buf)
+
+    _stdout = sys.stdout
+    _stderr = sys.stderr
+    sys.stdout = Writer(log.info)
+    sys.stderr = Writer(log.error)
+    try:
+        yield log
+    finally:
+        sys.stdout = _stdout
+        sys.stderr = _stderr

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94cd1ede/Allura/allura/model/monq_model.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/monq_model.py b/Allura/allura/model/monq_model.py
index 49cb6e9..d298c1b 100644
--- a/Allura/allura/model/monq_model.py
+++ b/Allura/allura/model/monq_model.py
@@ -30,6 +30,7 @@ from ming import schema as S
 from ming.orm import session, FieldProperty
 from ming.orm.declarative import MappedClass
 
+from allura.lib.helpers import log_output
 from .session import task_orm_session
 
 log = logging.getLogger(__name__)
@@ -251,7 +252,8 @@ class MonQTask(MappedClass):
                 if app_config:
                     c.app = c.project.app_instance(app_config)
             c.user = M.User.query.get(_id=self.context.user_id)
-            self.result = func(*self.args, **self.kwargs)
+            with log_output(log):
+                self.result = func(*self.args, **self.kwargs)
             self.state = 'complete'
             return self.result
         except Exception, exc:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/94cd1ede/Allura/allura/scripts/scripttask.py
----------------------------------------------------------------------
diff --git a/Allura/allura/scripts/scripttask.py b/Allura/allura/scripts/scripttask.py
index 8fa0984..b686838 100644
--- a/Allura/allura/scripts/scripttask.py
+++ b/Allura/allura/scripts/scripttask.py
@@ -55,13 +55,6 @@ from allura.lib.decorators import task
 log = logging.getLogger(__name__)
 
 
-class Writer(object):
-    def __init__(self, func):
-        self.func = func
-
-    def write(self, buf):
-        self.func(buf)
-
 
 class ScriptTask(object):
     """Base class for a command-line script that is also executable as a task."""
@@ -79,18 +72,10 @@ class ScriptTask(object):
     @classmethod
     def _execute_task(cls, arg_string):
         try:
-            _stdout = sys.stdout
-            _stderr = sys.stderr
-            sys.stdout = Writer(log.info)
-            sys.stderr = Writer(log.error)
-            try:
-                options = cls.parser().parse_args(shlex.split(arg_string or ''))
-            except SystemExit:
-                raise Exception("Error parsing args: '%s'" % arg_string)
-            cls.execute(options)
-        finally:
-            sys.stdout = _stdout
-            sys.stderr = _stderr
+            options = cls.parser().parse_args(shlex.split(arg_string or ''))
+        except SystemExit:
+            raise Exception("Error parsing args: '%s'" % arg_string)
+        cls.execute(options)
 
     @classmethod
     def execute(cls, options):


[03/50] git commit: [#5655] Added root REST view with hook for providing site stats

Posted by br...@apache.org.
[#5655] Added root REST view with hook for providing site stats

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/68a35476
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/68a35476
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/68a35476

Branch: refs/heads/db/6007
Commit: 68a354766986384384d5ab5ee30ceb10f44ab04b
Parents: c086502
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Apr 22 23:29:12 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Fri Apr 26 15:33:52 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py |    9 ++++++++-
 Allura/allura/lib/app_globals.py  |    1 +
 2 files changed, 9 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/68a35476/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index e7d11f9..0d519cc 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -23,7 +23,7 @@ import logging
 import oauth2 as oauth
 from webob import exc
 from tg import expose, flash, redirect
-from pylons import tmpl_context as c
+from pylons import tmpl_context as c, app_globals as g
 from pylons import request
 
 from ming.orm import session
@@ -60,6 +60,13 @@ class RestController(object):
         else:
             return None
 
+    @expose('json:')
+    def index(self, **kw):
+        provider = g.entry_points['site_stats'].get('provider')
+        if provider:
+            return provider()
+        return dict()
+
     @expose()
     def _lookup(self, name, *remainder):
         api_token = self._authenticate_request()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/68a35476/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 3eb816b..e5b00c7 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -185,6 +185,7 @@ class Globals(object):
             user_prefs=_cache_eps('allura.user_prefs'),
             spam=_cache_eps('allura.spam'),
             stats=_cache_eps('allura.stats'),
+            site_stats=_cache_eps('allura.site_stats'),
             )
 
         # Zarkov logger


[33/50] git commit: [#5599] ticket:296 fixed css

Posted by br...@apache.org.
[#5599] ticket:296 fixed css


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/be11653c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/be11653c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/be11653c

Branch: refs/heads/db/6007
Commit: be11653c5f804cfcdc31ddbacd5b35b9b469defa
Parents: a028f97
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Thu Apr 18 16:56:03 2013 +0400
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:38 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py                    |    2 +-
 Allura/allura/nf/allura/css/site_style.css        |    9 ++++++---
 Allura/allura/templates/jinja_master/top_nav.html |   14 +++++++++-----
 Allura/allura/tests/functional/test_admin.py      |    2 +-
 Allura/allura/tests/functional/test_home.py       |    2 +-
 5 files changed, 18 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/be11653c/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 73894e3..8a06566 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -511,7 +511,7 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                         grouped_nav[tool_name].children.append(e)
                     elif len(grouped_nav[tool_name].children) == 10:
                         e.url = self.url() + '_list/' + tool_name
-                        e.label = '...more...'
+                        e.label = 'More...'
                         grouped_nav[tool_name].children.append(e)
         return grouped_nav.values()
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/be11653c/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 98938e8..06b93ca 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -994,7 +994,6 @@ a.btn:active {
   text-align: center;
   position: relative;
   margin: 0 0 20px;
-  height: 50px;
 }
 .btn-bar.pop, .pop#top_nav {
   height: 150px;
@@ -2123,8 +2122,8 @@ nav .ico {
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4) inset,0 1px 0 rgba(255, 255, 255, 0.9);
   border: medium none;
   margin: 0 0 20px 0;
-  display: block;
   overflow: visible;
+  width: 940px;
 }
 #top_nav a {
   float: left;
@@ -2923,6 +2922,9 @@ ul.dropdown ul {
     background-color: #ffffff;
     -moz-border-radius: 5px;
     -webkit-border-radius: 5px;
+    -o-border-radius: 5px;
+    -ms-border-radius: 5px;
+    -khtml-border-radius: 5px;
     border-radius: 5px;
     border-width: 1px;
     border-style: solid;
@@ -2942,6 +2944,7 @@ ul.dropdown ul li a {
     height: 20px !important;
     font-weight:normal;
 }
-li.selected {
+li.selected,
+ul.dropdown ul li.selected a{
     font-weight:bold;
 }

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/be11653c/Allura/allura/templates/jinja_master/top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index aeec126..47ef332 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -36,11 +36,15 @@
         </a>
         {% set grouped_tool_count = s.matching_urls|length %}
         {% if grouped_tool_count %}
-          <ul>
-              {%for tool in s.children%}
-                <li><span><a href="{{tool.url}}">{{tool.label}}</a></span></li>
-              {%endfor%}
-          </ul>
+            <ul>
+                {%for tool in s.children%}
+                    {% set selected = False %}
+                    {% if tool.matches_url(request) or c.project.neighborhood.url()+'_admin' in request.upath_info%}
+                        {% set selected = True %}
+                    {% endif %}
+                    <li class="{% if selected %}selected{% endif %}"><a href="{{tool.url}}">{{tool.label}}</a></li>
+                {%endfor%}
+            </ul>
         {% endif %}
     </li>
 	{% endfor %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/be11653c/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 1752707..3197386 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -119,7 +119,7 @@ class TestProjectAdmin(TestController):
         # check the nav - tools of same type are grouped
         r = self.app.get('/p/test/test-tool/Home/')
         active_link = r.html.findAll('li',{'class':'selected'})
-        assert len(active_link) == 1
+        assert len(active_link) == 2
         assert active_link[0].contents[1]['href'] == '/p/test/_list/wiki'
         assert r.html.findAll('a', {'href':'/p/test/test-tool2/'})
         assert r.html.findAll('a', {'href':'/p/test/test-tool/'})

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/be11653c/Allura/allura/tests/functional/test_home.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_home.py b/Allura/allura/tests/functional/test_home.py
index 4904394..3e11437 100644
--- a/Allura/allura/tests/functional/test_home.py
+++ b/Allura/allura/tests/functional/test_home.py
@@ -65,7 +65,7 @@ class TestProjectHome(TestController):
         response = self.app.get('/p/test/_nav.json')
         menu = response.json['menu']
         assert_equal(len(menu[1]['children']), 11)
-        assert {u'url': u'/p/test/_list/wiki', u'name': u'...more...', u'icon': u'tool-wiki'} in menu[1]['children']
+        assert {u'url': u'/p/test/_list/wiki', u'name': u'More...', u'icon': u'tool-wiki'} in menu[1]['children']
 
     @td.with_wiki
     def test_neighborhood_home(self):


[27/50] git commit: [#5913] Updated to use new nav style

Posted by br...@apache.org.
[#5913] Updated to use new nav style


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/833aa4a9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/833aa4a9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/833aa4a9

Branch: refs/heads/db/6007
Commit: 833aa4a9823103697228eca014c5d7213ef0571a
Parents: 404b152
Author: Jenny Steele <js...@geek.net>
Authored: Tue Mar 19 19:01:48 2013 -0700
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed May 1 20:38:36 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/master.html  |    2 +-
 Allura/allura/templates/jinja_master/top_nav.html |   36 +++++++++-------
 2 files changed, 21 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/833aa4a9/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index 11482a7..00052c1 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -82,7 +82,7 @@
             {% include g.theme.nav_menu %}
             {% endblock %}
       </div>
-      <div id="top_nav" class="">
+      <div id="main_nav" class="">
         {% block top_nav %}
         {% include g.theme.top_nav %}
         {% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/833aa4a9/Allura/allura/templates/jinja_master/top_nav.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index 1e4f54a..7304f4c 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -17,24 +17,28 @@
        under the License.
 -#}
 {% if c.project %}
+  <div><ul>
   {% for s in c.project.grouped_navbar_entries() %}
-    <a href="{{s.url}}" class="ui-icon-{{s.ui_icon or 'admin'}}">
-      {{s.label}}
-      {% if s.label == 'Home' %}
-        {% set url_length = s.url|length %}
-        {% if request.url.rfind(s.url, -url_length) != -1 %}
-          <span class="diamond"></span>
-        {% endif %}
-      {% else %}
-        {% if s.matches_url(request) or c.project.neighborhood.url()+'_admin' in request.upath_info %}
-          <span class="diamond"></span>
-        {% endif %}
+    {% set selected = False %}
+    {% if s.label == 'Home' %}
+      {% set url_length = s.url|length %}
+      {% if request.url.rfind(s.url, -url_length) != -1 %}
+        {% set selected = True %}
       {% endif %}
-      {% set grouped_tool_count = s.matching_urls|length %}
-      {% if grouped_tool_count %}
-        <span class="tool-count">{{grouped_tool_count}}</span>
+    {% else %}
+      {% if s.matches_url(request) or c.project.neighborhood.url()+'_admin' in request.upath_info %}
+        {% set selected = True %}
       {% endif %}
-    </a>
+    {% endif %}
+    <li{% if selected %} class="selected"{% endif %}>
+      <a href="{{s.url}}">
+        {{s.label}}
+        {% set grouped_tool_count = s.matching_urls|length %}
+        {% if grouped_tool_count %}
+          <span class="tool-count">{{grouped_tool_count}}</span>
+        {% endif %}
+      </a>
+    </li>
 	{% endfor %}
-	<div style="clear:both"></div>
+	</div></ul>
 {% endif %}


[04/50] git commit: [#5655] Added documentation for site_stats

Posted by br...@apache.org.
[#5655] Added documentation for site_stats

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/57fadd1f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/57fadd1f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/57fadd1f

Branch: refs/heads/db/6007
Commit: 57fadd1fdf94b7dc25cd2eb029160a71459bd956
Parents: c40ddaf
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Apr 26 16:31:04 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Fri Apr 26 16:31:04 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py |   21 +++++++++++++++++++++
 Allura/docs/api/controllers.rst   |   12 ++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/57fadd1f/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 70e3ac7..c90a1ef 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -62,6 +62,27 @@ class RestController(object):
 
     @expose('json:')
     def index(self, **kw):
+        """Return site summary information as JSON.
+
+        Currently, the only summary information returned are any site_stats
+        whose providers are defined as entry points under the
+        'allura.site_stats' group in a package or tool's setup.py, e.g.::
+
+            [allura.site_stats]
+            new_users_24hr = allura.site_stats:new_users_24hr
+
+        The stat provider will be called with no arguments to generate the
+        stat, which will be included under a key equal to the name of the
+        entry point.
+
+        Example output::
+
+            {
+                'site_stats': {
+                    'new_users_24hr': 10
+                }
+            }
+        """
         summary = dict()
         stats = dict()
         for stat, provider in g.entry_points['site_stats'].iteritems():

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/57fadd1f/Allura/docs/api/controllers.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/controllers.rst b/Allura/docs/api/controllers.rst
new file mode 100644
index 0000000..5e56976
--- /dev/null
+++ b/Allura/docs/api/controllers.rst
@@ -0,0 +1,12 @@
+.. _controllers_module:
+
+:mod:`allura.controllers`
+--------------------------------
+
+.. automodule:: allura.controllers
+
+  .. automodule:: allura.controllers.rest
+
+    .. autoclass:: RestController
+        :members:
+


[43/50] git commit: [#5773] ticket:328 fixed authored.name and committed name

Posted by br...@apache.org.
[#5773]  ticket:328  fixed authored.name and committed name


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ba100cc3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ba100cc3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ba100cc3

Branch: refs/heads/db/6007
Commit: ba100cc3fa89641552ec2618d97bbe6d1cf25acd
Parents: 5a51840
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Thu May 2 09:53:31 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu May 2 20:37:06 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/widgets/repo/log.html |   16 ++++++----------
 1 files changed, 6 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ba100cc3/Allura/allura/templates/widgets/repo/log.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/repo/log.html b/Allura/allura/templates/widgets/repo/log.html
index c46b425..1d2c24d 100644
--- a/Allura/allura/templates/widgets/repo/log.html
+++ b/Allura/allura/templates/widgets/repo/log.html
@@ -43,23 +43,19 @@
                         <a href="{{c.app.repo.url_for_commit(tag)}}">{{tag}}</a>{% if not loop.last %}&nbsp;{% endif %}
                     {%- endfor %})
                 {% endif %}
-                {% if commit.committed.email != commit.authored.email %}
-                {% if commit.committer_url %}
+                {%if is_file%}
+                    ({{commit.tree.get_obj_by_path(request.params.get('path')).size|filesizeformat}})
+                {%endif%}
                 by
+                {{email_gravatar(commit.authored.email, title=commit.authored.name, size=16)}} {{commit.authored.name}}{%if commit.committed.email != commit.authored.email %}, pushed by
+                {% if commit.committer_url %}
                 <a href="{{commit.committer_url}}">{{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}}
                     {{commit.committed.name}}</a>,
                 pushed
                 {% else %}
-                by
-                {{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}} {{commit.committed.name}},
-                pushed
+                {{email_gravatar(commit.committed.email, title=commit.committed.name, size=16)}} {{commit.committed.name}}
                 {% endif %}
                 {% endif %}
-                by
-                {{email_gravatar(commit.authored.email, title=commit.authored.name, size=16)}} {{commit.authored.name}}
-                {%if is_file%}
-                    ({{commit.tree.get_obj_by_path(request.params.get('path')).size|filesizeformat}})
-                {%endif%}
                 {{g.markdown.convert(commit.message)}}
             </div>
           </td>