You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by tv...@apache.org on 2013/05/08 00:27:48 UTC
[10/50] [abbrv] git commit: [#6172] Refactor feed functionality into
mixin controller
[#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/tv/3854
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')