Switched most stuff over from Routes

Removed the Routes routing functionality and replaced it with
werkzeug.routes. Most views are functional.

Known issues:

 - Translation integration with the request object is not yet figured
   out. This breaks 404 pages.
This commit is contained in:
Joar Wandborg 2012-10-14 13:46:31 +02:00
parent a817fb76b1
commit 7742dcc1fb
11 changed files with 189 additions and 176 deletions

View File

@ -18,11 +18,12 @@ import os
import urllib import urllib
import logging import logging
import routes from mediagoblin.routing import url_map, view_functions, add_route
from webob import exc
from werkzeug.wrappers import Request
from mediagoblin import routing, meddleware, __version__ from werkzeug.wrappers import Request
from werkzeug.exceptions import HTTPException, NotFound
from mediagoblin import meddleware, __version__
from mediagoblin.tools import common, translate, template from mediagoblin.tools import common, translate, template
from mediagoblin.tools.response import render_404 from mediagoblin.tools.response import render_404
from mediagoblin.tools.theme import register_themes from mediagoblin.tools.theme import register_themes
@ -90,7 +91,10 @@ class MediaGoblinApp(object):
self.public_store, self.queue_store = setup_storage() self.public_store, self.queue_store = setup_storage()
# set up routing # set up routing
self.routing = routing.get_mapper(PluginManager().get_routes()) self.url_map = url_map
for route in PluginManager().get_routes():
add_route(*route)
# set up staticdirector tool # set up staticdirector tool
self.staticdirector = get_staticdirector(app_config) self.staticdirector = get_staticdirector(app_config)
@ -135,7 +139,7 @@ class MediaGoblinApp(object):
## Routing / controller loading stuff ## Routing / controller loading stuff
path_info = request.path path_info = request.path
route_match = self.routing.match(path_info) map_adapter = self.url_map.bind_to_environ(request.environ)
# By using fcgi, mediagoblin can run under a base path # By using fcgi, mediagoblin can run under a base path
# like /mediagoblin/. request.path_info contains the # like /mediagoblin/. request.path_info contains the
@ -154,47 +158,52 @@ class MediaGoblinApp(object):
environ.pop('HTTPS') environ.pop('HTTPS')
## Attach utilities to the request object ## Attach utilities to the request object
request.matchdict = route_match
request.urlgen = routes.URLGenerator(self.routing, environ)
# Do we really want to load this via middleware? Maybe? # Do we really want to load this via middleware? Maybe?
request.session = request.environ['beaker.session'] request.session = request.environ['beaker.session']
# Attach self as request.app # Attach self as request.app
# Also attach a few utilities from request.app for convenience? # Also attach a few utilities from request.app for convenience?
request.app = self request.app = self
request.locale = translate.get_locale_from_request(request)
request.template_env = template.get_jinja_env(
self.template_loader, request.locale)
request.db = self.db request.db = self.db
request.staticdirect = self.staticdirector request.staticdirect = self.staticdirector
mg_request.setup_user_in_request(request) mg_request.setup_user_in_request(request)
# No matching page? try:
if route_match is None: endpoint, url_values = map_adapter.match()
# Try to do see if we have a match with a trailing slash request.matchdict = url_values
# added and if so, redirect
if not path_info.endswith('/') \
and request.method == 'GET' \
and self.routing.match(path_info + '/'):
new_path_info = path_info + '/'
if request.GET:
new_path_info = '%s?%s' % (
new_path_info, urllib.urlencode(request.GET))
redirect = exc.HTTPFound(location=new_path_info)
return request.get_response(redirect)(environ, start_response)
# Okay, no matches. 404 time! request.locale = translate.get_locale_from_request(request)
request.matchdict = {} # in case our template expects it request.template_env = template.get_jinja_env(
self.template_loader, request.locale)
except NotFound as exc:
return NotImplemented
return render_404(request)(environ, start_response) return render_404(request)(environ, start_response)
except HTTPException as exc:
# Support legacy webob.exc responses
return exc(environ, start_response)
# import the controller, or if it's already a callable, call that def build_proxy(endpoint, **kw):
route_controller = route_match['controller'] try:
if isinstance(route_controller, unicode) \ qualified = kw.pop('qualified')
or isinstance(route_controller, str): except KeyError:
controller = common.import_component(route_match['controller']) qualified = False
return map_adapter.build(
endpoint,
values=dict(**kw),
force_external=qualified)
request.urlgen = build_proxy
view_func = view_functions[endpoint]
# import the endpoint, or if it's already a callable, call that
if isinstance(view_func, unicode) \
or isinstance(view_func, str):
controller = common.import_component(view_func)
else: else:
controller = route_match['controller'] controller = view_func
# pass the request through our meddleware classes # pass the request through our meddleware classes
for m in self.meddleware: for m in self.meddleware:

View File

@ -14,25 +14,36 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from routes.route import Route from routes.route import add_route
from mediagoblin.routing import add_route
auth_routes = [ add_route('mediagoblin.auth.logout',
Route('mediagoblin.auth.register', '/register/', '/auth/logout/', 'mediagoblin.auth.views:logout')
controller='mediagoblin.auth.views:register'),
Route('mediagoblin.auth.login', '/login/',
controller='mediagoblin.auth.views:login'), add_route('mediagoblin.auth.register', '/register/',
Route('mediagoblin.auth.logout', '/logout/', 'mediagoblin.auth.views:register')
controller='mediagoblin.auth.views:logout'),
Route('mediagoblin.auth.verify_email', '/verify_email/', add_route('mediagoblin.auth.login', '/login/',
controller='mediagoblin.auth.views:verify_email'), 'mediagoblin.auth.views:login')
Route('mediagoblin.auth.resend_verification', '/resend_verification/',
controller='mediagoblin.auth.views:resend_activation'), add_route('mediagoblin.auth.logout', '/logout/',
Route('mediagoblin.auth.resend_verification_success', 'mediagoblin.auth.views:logout')
'/resend_verification_success/',
template='mediagoblin/auth/resent_verification_email.html', add_route('mediagoblin.auth.verify_email', '/verify_email/',
controller='mediagoblin.views:simple_template_render'), 'mediagoblin.auth.views:verify_email')
Route('mediagoblin.auth.forgot_password', '/forgot_password/',
controller='mediagoblin.auth.views:forgot_password'), add_route('mediagoblin.auth.resend_verification', '/resend_verification/',
Route('mediagoblin.auth.verify_forgot_password', 'mediagoblin.auth.views:resend_activation')
'/forgot_password/verify/',
controller='mediagoblin.auth.views:verify_forgot_password')] add_route('mediagoblin.auth.resend_verification_success',
'/resend_verification_success/',
template='mediagoblin/auth/resent_verification_email.html',
'mediagoblin.views:simple_template_render')
add_route('mediagoblin.auth.forgot_password', '/forgot_password/',
'mediagoblin.auth.views:forgot_password')
add_route('mediagoblin.auth.verify_forgot_password',
'/forgot_password/verify/',
'mediagoblin.auth.views:verify_forgot_password')

View File

@ -14,13 +14,9 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from mediagoblin.routing import add_route
from routes.route import Route add_route('mediagoblin.edit.profile', '/edit/profile/',
'mediagoblin.edit.views:edit_profile')
edit_routes = [ add_route('mediagoblin.edit.account', '/edit/account/',
# Media editing view handled in user_pages/routing.py 'mediagoblin.edit.views:edit_account')
Route('mediagoblin.edit.profile', '/profile/',
controller="mediagoblin.edit.views:edit_profile"),
Route('mediagoblin.edit.account', '/account/',
controller="mediagoblin.edit.views:edit_account"),
]

View File

@ -14,14 +14,10 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from mediagoblin.routing import add_route
from routes.route import Route add_route('mediagoblin.listings.tags_listing',
"/tag/<string:tag>/",
tag_routes = [ "mediagoblin.listings.views:tag_listing")
# Route('mediagoblin.listings.tags_home', "/", add_route('mediagoblin.listings.tag_atom_feed', "/tag/<string:tag>/atom/",
# controller="mediagoblin.listings.views:tags_home"), "mediagoblin.listings.views:tag_atom_feed")
Route('mediagoblin.listings.tags_listing', "/{tag}/",
controller="mediagoblin.listings.views:tag_listing"),
Route('mediagoblin.listings.tag_atom_feed', "/{tag}/atom/",
controller="mediagoblin.listings.views:tag_atom_feed"),
]

View File

@ -33,12 +33,12 @@ def setup_plugin():
_log.debug('API config: {0}'.format(config)) _log.debug('API config: {0}'.format(config))
routes = [ routes = [
Route('mediagoblin.plugins.api.test', '/api/test', ('mediagoblin.plugins.api.test', '/api/test',
controller='mediagoblin.plugins.api.views:api_test'), 'mediagoblin.plugins.api.views:api_test'),
Route('mediagoblin.plugins.api.entries', '/api/entries', ('mediagoblin.plugins.api.entries', '/api/entries',
controller='mediagoblin.plugins.api.views:get_entries'), 'mediagoblin.plugins.api.views:get_entries'),
Route('mediagoblin.plugins.api.post_entry', '/api/submit', ('mediagoblin.plugins.api.post_entry', '/api/submit',
controller='mediagoblin.plugins.api.views:post_entry')] 'mediagoblin.plugins.api.views:post_entry')]
pluginapi.register_routes(routes) pluginapi.register_routes(routes)

View File

@ -36,21 +36,21 @@ def setup_plugin():
_log.debug('OAuth config: {0}'.format(config)) _log.debug('OAuth config: {0}'.format(config))
routes = [ routes = [
Route('mediagoblin.plugins.oauth.authorize', '/oauth/authorize', ('mediagoblin.plugins.oauth.authorize', '/oauth/authorize',
controller='mediagoblin.plugins.oauth.views:authorize'), 'mediagoblin.plugins.oauth.views:authorize'),
Route('mediagoblin.plugins.oauth.authorize_client', '/oauth/client/authorize', ('mediagoblin.plugins.oauth.authorize_client', '/oauth/client/authorize',
controller='mediagoblin.plugins.oauth.views:authorize_client'), 'mediagoblin.plugins.oauth.views:authorize_client'),
Route('mediagoblin.plugins.oauth.access_token', '/oauth/access_token', ('mediagoblin.plugins.oauth.access_token', '/oauth/access_token',
controller='mediagoblin.plugins.oauth.views:access_token'), 'mediagoblin.plugins.oauth.views:access_token'),
Route('mediagoblin.plugins.oauth.access_token', ('mediagoblin.plugins.oauth.access_token',
'/oauth/client/connections', '/oauth/client/connections',
controller='mediagoblin.plugins.oauth.views:list_connections'), 'mediagoblin.plugins.oauth.views:list_connections'),
Route('mediagoblin.plugins.oauth.register_client', ('mediagoblin.plugins.oauth.register_client',
'/oauth/client/register', '/oauth/client/register',
controller='mediagoblin.plugins.oauth.views:register_client'), 'mediagoblin.plugins.oauth.views:register_client'),
Route('mediagoblin.plugins.oauth.list_clients', ('mediagoblin.plugins.oauth.list_clients',
'/oauth/client/list', '/oauth/client/list',
controller='mediagoblin.plugins.oauth.views:list_clients')] 'mediagoblin.plugins.oauth.views:list_clients')]
pluginapi.register_routes(routes) pluginapi.register_routes(routes)
pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates')) pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates'))

View File

@ -14,36 +14,22 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from routes import Mapper from werkzeug.routing import Map, Rule
from mediagoblin.auth.routing import auth_routes url_map = Map()
from mediagoblin.submit.routing import submit_routes
from mediagoblin.user_pages.routing import user_routes
from mediagoblin.edit.routing import edit_routes
from mediagoblin.listings.routing import tag_routes
from mediagoblin.webfinger.routing import webfinger_well_known_routes, \
webfinger_routes
from mediagoblin.admin.routing import admin_routes
view_functions = {'index': 'mediagoblin.views:index'}
def get_mapper(plugin_routes): def add_route(endpoint, url, controller):
mapping = Mapper() view_functions.update({endpoint: controller})
mapping.minimization = False
# Plugin routes go first so they can override default routes. url_map.add(Rule(url, endpoint=endpoint))
mapping.extend(plugin_routes)
mapping.connect( add_route('index', '/', 'mediagoblin.views:root_view')
"index", "/",
controller="mediagoblin.views:root_view")
mapping.extend(auth_routes, '/auth') import mediagoblin.submit.routing
mapping.extend(submit_routes, '/submit') import mediagoblin.user_pages.routing
mapping.extend(user_routes, '/u') import mediagoblin.auth.routing
mapping.extend(edit_routes, '/edit') import mediagoblin.edit.routing
mapping.extend(tag_routes, '/tag') import mediagoblin.webfinger.routing
mapping.extend(webfinger_well_known_routes, '/.well-known') import mediagoblin.listings.routing
mapping.extend(webfinger_routes, '/api/webfinger')
mapping.extend(admin_routes, '/a')
return mapping

View File

@ -14,11 +14,8 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from routes.route import Route from mediagoblin.routing import add_route
submit_routes = [ add_route('mediagoblin.submit.start',
Route('mediagoblin.submit.start', '/', '/submit/', 'mediagoblin.submit.views:submit_start')
controller='mediagoblin.submit.views:submit_start'), add_route('collection_home', '/submit/collection', 'mediagoblin.submit.views:add_collection')
Route('mediagoblin.submit.collection', '/collection',
controller='mediagoblin.submit.views:add_collection'),
]

View File

@ -162,7 +162,7 @@ def register_routes(routes):
Be careful when designing your route urls. If they clash with Be careful when designing your route urls. If they clash with
core urls, then it could result in DISASTER! core urls, then it could result in DISASTER!
""" """
if isinstance(routes, (tuple, list)): if isinstance(routes, list):
for route in routes: for route in routes:
PluginManager().register_route(route) PluginManager().register_route(route)
else: else:

View File

@ -14,48 +14,68 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from routes.route import Route from mediagoblin.routing import add_route
user_routes = [ add_route('mediagoblin.user_pages.user_home',
Route('mediagoblin.user_pages.user_home', "/{user}/", '/u/<string:user>/', 'mediagoblin.user_pages.views:user_home')
controller="mediagoblin.user_pages.views:user_home"),
Route('mediagoblin.user_pages.user_gallery', "/{user}/gallery/", add_route('mediagoblin.user_pages.media_home',
controller="mediagoblin.user_pages.views:user_gallery"), '/u/<string:user>/m/<string:media>/',
Route('mediagoblin.user_pages.media_home', '/{user}/m/{media}/', 'mediagoblin.user_pages.views:media_home')
requirements=dict(m_id="[0-9a-fA-F]{24}"),
controller="mediagoblin.user_pages.views:media_home"), add_route('mediagoblin.user_pages.media_confirm_delete',
Route('mediagoblin.user_pages.media_home.view_comment', '/u/<string:user>/m/<string:media>/confirm-delete/',
'/{user}/m/{media}/c/{comment}/', 'mediagoblin.user_pages.views:media_confirm_delete')
controller="mediagoblin.user_pages.views:media_home"),
Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/", add_route('mediagoblin.user_pages.media_post_comment',
controller="mediagoblin.edit.views:edit_media"), '/u/<string:user>/m/<string:media>/comment/add/',
Route('mediagoblin.edit.attachments', 'mediagoblin.user_pages.views:media_post_comment')
'/{user}/m/{media}/attachments/',
controller="mediagoblin.edit.views:edit_attachments"), add_route('mediagoblin.user_pages.user_gallery',
Route('mediagoblin.user_pages.media_confirm_delete', '/u/<string:user>/gallery/',
"/{user}/m/{media}/confirm-delete/", 'mediagoblin.user_pages.views:user_gallery')
controller="mediagoblin.user_pages.views:media_confirm_delete"),
Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/', add_route('mediagoblin.user_pages.media_home.view_comment',
controller="mediagoblin.user_pages.views:atom_feed"), '/u/<string:user>/m/<string:media>/c/<string:comment>/',
Route('mediagoblin.user_pages.media_post_comment', 'mediagoblin.user_pages.views:media_home')
'/{user}/m/{media}/comment/add/',
controller="mediagoblin.user_pages.views:media_post_comment"), add_route('mediagoblin.user_pages.atom_feed',
Route('mediagoblin.user_pages.media_collect', '/u/<string:user>/atom/',
"/{user}/m/{media}/collect/", 'mediagoblin.user_pages.views:atom_feed')
controller="mediagoblin.user_pages.views:media_collect"),
Route('mediagoblin.user_pages.user_collection', "/{user}/collection/{collection}/", add_route('mediagoblin.user_pages.media_collect',
controller="mediagoblin.user_pages.views:user_collection"), '/u/<string:user>/m/<string:media>/collect/',
Route('mediagoblin.edit.edit_collection', "/{user}/c/{collection}/edit/", 'mediagoblin.user_pages.views:media_collect')
controller="mediagoblin.edit.views:edit_collection"),
Route('mediagoblin.user_pages.collection_confirm_delete', add_route('mediagoblin.user_pages.user_collection',
"/{user}/c/{collection}/confirm-delete/", '/u/<string:user>/collection/<string:collection>/',
controller="mediagoblin.user_pages.views:collection_confirm_delete"), 'mediagoblin.user_pages.views:user_collection')
Route('mediagoblin.user_pages.collection_item_confirm_remove',
"/{user}/collection/{collection}/{collection_item}/confirm_remove/", add_route('mediagoblin.edit.edit_collection',
controller="mediagoblin.user_pages.views:collection_item_confirm_remove"), '/u/<string:user>/c/<string:collection>/edit/',
Route('mediagoblin.user_pages.collection_atom_feed', '/{user}/collection/{collection}/atom/', 'mediagoblin.edit.views:edit_collection')
controller="mediagoblin.user_pages.views:collection_atom_feed"),
Route('mediagoblin.user_pages.processing_panel', add_route('mediagoblin.user_pages.collection_confirm_delete',
'/{user}/panel/', '/u/<string:user>/c/<string:collection>/confirm-delete/',
controller="mediagoblin.user_pages.views:processing_panel"), 'mediagoblin.user_pages.views:collection_confirm_delete')
]
add_route('mediagoblin.user_pages.collection_item_confirm_remove',
'/u/<string:user>/collection/<string:collection>/<string:collection_item>/confirm_remove/',
'mediagoblin.user_pages.views:collection_item_confirm_remove')
add_route('mediagoblin.user_pages.collection_atom_feed',
'/u/<string:user>/collection/<string:collection>/atom/',
'mediagoblin.user_pages.views:collection_atom_feed')
add_route('mediagoblin.user_pages.processing_panel',
'/u/<string:user>/panel/',
'mediagoblin.user_pages.views:processing_panel')
# Stray edit routes
add_route('mediagoblin.edit.edit_media',
'/u/<string:user>/m/<string:media>/edit/',
'mediagoblin.user_pages.views:edit_media')
add_route('mediagoblin.edit.attachments',
'/u/<string:user>/m/<string:media>/attachments/',
'mediagoblin.user_pages.views:edit_attachments')

View File

@ -14,12 +14,10 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from routes.route import Route from mediagoblin.routing import add_route
webfinger_well_known_routes = [ add_route('mediagoblin.webfinger.host_meta', '/.well-known/host-meta',
Route('mediagoblin.webfinger.host_meta', '/host-meta', 'mediagoblin.webfinger.views:host_meta')
controller='mediagoblin.webfinger.views:host_meta')]
webfinger_routes = [ add_route('mediagoblin.webfinger.xrd', '/webfinger/xrd',
Route('mediagoblin.webfinger.xrd', '/xrd', 'mediagoblin.webfinger.views:xrd')
controller='mediagoblin.webfinger.views:xrd')]