import urllib
import logging
-import routes
-from webob import exc
+from mediagoblin.routing import url_map, view_functions, add_route
+
from werkzeug.wrappers import Request
+from werkzeug.exceptions import HTTPException, NotFound
-from mediagoblin import routing, meddleware, __version__
+from mediagoblin import meddleware, __version__
from mediagoblin.tools import common, translate, template
from mediagoblin.tools.response import render_404
from mediagoblin.tools.theme import register_themes
self.public_store, self.queue_store = setup_storage()
# 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
self.staticdirector = get_staticdirector(app_config)
## Routing / controller loading stuff
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
# like /mediagoblin/. request.path_info contains the
environ.pop('HTTPS')
## 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?
request.session = request.environ['beaker.session']
# Attach self as request.app
# Also attach a few utilities from request.app for convenience?
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.staticdirect = self.staticdirector
mg_request.setup_user_in_request(request)
- # No matching page?
- if route_match is None:
- # Try to do see if we have a match with a trailing slash
- # 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.matchdict = {} # in case our template expects it
+ try:
+ endpoint, url_values = map_adapter.match()
+ request.matchdict = url_values
+
+ request.locale = translate.get_locale_from_request(request)
+ 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)
+ except HTTPException as exc:
+ # Support legacy webob.exc responses
+ return exc(environ, start_response)
+
+ def build_proxy(endpoint, **kw):
+ try:
+ qualified = kw.pop('qualified')
+ except KeyError:
+ qualified = False
+
+ return map_adapter.build(
+ endpoint,
+ values=dict(**kw),
+ force_external=qualified)
+
+ request.urlgen = build_proxy
+
+ view_func = view_functions[endpoint]
- # import the controller, or if it's already a callable, call that
- route_controller = route_match['controller']
- if isinstance(route_controller, unicode) \
- or isinstance(route_controller, str):
- controller = common.import_component(route_match['controller'])
+ # 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:
- controller = route_match['controller']
+ controller = view_func
# pass the request through our meddleware classes
for m in self.meddleware:
# 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/>.
-from routes.route import Route
-
-auth_routes = [
- Route('mediagoblin.auth.register', '/register/',
- controller='mediagoblin.auth.views:register'),
- Route('mediagoblin.auth.login', '/login/',
- controller='mediagoblin.auth.views:login'),
- Route('mediagoblin.auth.logout', '/logout/',
- controller='mediagoblin.auth.views:logout'),
- Route('mediagoblin.auth.verify_email', '/verify_email/',
- controller='mediagoblin.auth.views:verify_email'),
- Route('mediagoblin.auth.resend_verification', '/resend_verification/',
- controller='mediagoblin.auth.views:resend_activation'),
- Route('mediagoblin.auth.resend_verification_success',
- '/resend_verification_success/',
- template='mediagoblin/auth/resent_verification_email.html',
- controller='mediagoblin.views:simple_template_render'),
- Route('mediagoblin.auth.forgot_password', '/forgot_password/',
- controller='mediagoblin.auth.views:forgot_password'),
- Route('mediagoblin.auth.verify_forgot_password',
- '/forgot_password/verify/',
- controller='mediagoblin.auth.views:verify_forgot_password')]
+from routes.route import add_route
+from mediagoblin.routing import add_route
+
+add_route('mediagoblin.auth.logout',
+ '/auth/logout/', 'mediagoblin.auth.views:logout')
+
+
+add_route('mediagoblin.auth.register', '/register/',
+ 'mediagoblin.auth.views:register')
+
+add_route('mediagoblin.auth.login', '/login/',
+ 'mediagoblin.auth.views:login')
+
+add_route('mediagoblin.auth.logout', '/logout/',
+ 'mediagoblin.auth.views:logout')
+
+add_route('mediagoblin.auth.verify_email', '/verify_email/',
+ 'mediagoblin.auth.views:verify_email')
+
+add_route('mediagoblin.auth.resend_verification', '/resend_verification/',
+ 'mediagoblin.auth.views:resend_activation')
+
+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')
# 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/>.
+from mediagoblin.routing import add_route
-from routes.route import Route
-
-edit_routes = [
- # Media editing view handled in user_pages/routing.py
- Route('mediagoblin.edit.profile', '/profile/',
- controller="mediagoblin.edit.views:edit_profile"),
- Route('mediagoblin.edit.account', '/account/',
- controller="mediagoblin.edit.views:edit_account"),
- ]
+add_route('mediagoblin.edit.profile', '/edit/profile/',
+ 'mediagoblin.edit.views:edit_profile')
+add_route('mediagoblin.edit.account', '/edit/account/',
+ 'mediagoblin.edit.views:edit_account')
# 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/>.
+from mediagoblin.routing import add_route
-from routes.route import Route
-
-tag_routes = [
- # Route('mediagoblin.listings.tags_home', "/",
- # controller="mediagoblin.listings.views:tags_home"),
- 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"),
- ]
+add_route('mediagoblin.listings.tags_listing',
+ "/tag/<string:tag>/",
+ "mediagoblin.listings.views:tag_listing")
+add_route('mediagoblin.listings.tag_atom_feed', "/tag/<string:tag>/atom/",
+ "mediagoblin.listings.views:tag_atom_feed")
_log.debug('API config: {0}'.format(config))
routes = [
- Route('mediagoblin.plugins.api.test', '/api/test',
- controller='mediagoblin.plugins.api.views:api_test'),
- Route('mediagoblin.plugins.api.entries', '/api/entries',
- controller='mediagoblin.plugins.api.views:get_entries'),
- Route('mediagoblin.plugins.api.post_entry', '/api/submit',
- controller='mediagoblin.plugins.api.views:post_entry')]
+ ('mediagoblin.plugins.api.test', '/api/test',
+ 'mediagoblin.plugins.api.views:api_test'),
+ ('mediagoblin.plugins.api.entries', '/api/entries',
+ 'mediagoblin.plugins.api.views:get_entries'),
+ ('mediagoblin.plugins.api.post_entry', '/api/submit',
+ 'mediagoblin.plugins.api.views:post_entry')]
pluginapi.register_routes(routes)
_log.debug('OAuth config: {0}'.format(config))
routes = [
- Route('mediagoblin.plugins.oauth.authorize', '/oauth/authorize',
- controller='mediagoblin.plugins.oauth.views:authorize'),
- Route('mediagoblin.plugins.oauth.authorize_client', '/oauth/client/authorize',
- controller='mediagoblin.plugins.oauth.views:authorize_client'),
- Route('mediagoblin.plugins.oauth.access_token', '/oauth/access_token',
- controller='mediagoblin.plugins.oauth.views:access_token'),
- Route('mediagoblin.plugins.oauth.access_token',
+ ('mediagoblin.plugins.oauth.authorize', '/oauth/authorize',
+ 'mediagoblin.plugins.oauth.views:authorize'),
+ ('mediagoblin.plugins.oauth.authorize_client', '/oauth/client/authorize',
+ 'mediagoblin.plugins.oauth.views:authorize_client'),
+ ('mediagoblin.plugins.oauth.access_token', '/oauth/access_token',
+ 'mediagoblin.plugins.oauth.views:access_token'),
+ ('mediagoblin.plugins.oauth.access_token',
'/oauth/client/connections',
- controller='mediagoblin.plugins.oauth.views:list_connections'),
- Route('mediagoblin.plugins.oauth.register_client',
+ 'mediagoblin.plugins.oauth.views:list_connections'),
+ ('mediagoblin.plugins.oauth.register_client',
'/oauth/client/register',
- controller='mediagoblin.plugins.oauth.views:register_client'),
- Route('mediagoblin.plugins.oauth.list_clients',
+ 'mediagoblin.plugins.oauth.views:register_client'),
+ ('mediagoblin.plugins.oauth.list_clients',
'/oauth/client/list',
- controller='mediagoblin.plugins.oauth.views:list_clients')]
+ 'mediagoblin.plugins.oauth.views:list_clients')]
pluginapi.register_routes(routes)
pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates'))
# 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/>.
-from routes import Mapper
+from werkzeug.routing import Map, Rule
-from mediagoblin.auth.routing import auth_routes
-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
+url_map = Map()
+view_functions = {'index': 'mediagoblin.views:index'}
-def get_mapper(plugin_routes):
- mapping = Mapper()
- mapping.minimization = False
+def add_route(endpoint, url, controller):
+ view_functions.update({endpoint: controller})
- # Plugin routes go first so they can override default routes.
- mapping.extend(plugin_routes)
+ url_map.add(Rule(url, endpoint=endpoint))
- mapping.connect(
- "index", "/",
- controller="mediagoblin.views:root_view")
+add_route('index', '/', 'mediagoblin.views:root_view')
- mapping.extend(auth_routes, '/auth')
- mapping.extend(submit_routes, '/submit')
- mapping.extend(user_routes, '/u')
- mapping.extend(edit_routes, '/edit')
- mapping.extend(tag_routes, '/tag')
- mapping.extend(webfinger_well_known_routes, '/.well-known')
- mapping.extend(webfinger_routes, '/api/webfinger')
- mapping.extend(admin_routes, '/a')
-
- return mapping
+import mediagoblin.submit.routing
+import mediagoblin.user_pages.routing
+import mediagoblin.auth.routing
+import mediagoblin.edit.routing
+import mediagoblin.webfinger.routing
+import mediagoblin.listings.routing
# 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/>.
-from routes.route import Route
+from mediagoblin.routing import add_route
-submit_routes = [
- Route('mediagoblin.submit.start', '/',
- controller='mediagoblin.submit.views:submit_start'),
- Route('mediagoblin.submit.collection', '/collection',
- controller='mediagoblin.submit.views:add_collection'),
- ]
+add_route('mediagoblin.submit.start',
+ '/submit/', 'mediagoblin.submit.views:submit_start')
+add_route('collection_home', '/submit/collection', 'mediagoblin.submit.views:add_collection')
Be careful when designing your route urls. If they clash with
core urls, then it could result in DISASTER!
"""
- if isinstance(routes, (tuple, list)):
+ if isinstance(routes, list):
for route in routes:
PluginManager().register_route(route)
else:
# 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/>.
-from routes.route import Route
-
-user_routes = [
- Route('mediagoblin.user_pages.user_home', "/{user}/",
- controller="mediagoblin.user_pages.views:user_home"),
- Route('mediagoblin.user_pages.user_gallery', "/{user}/gallery/",
- controller="mediagoblin.user_pages.views:user_gallery"),
- Route('mediagoblin.user_pages.media_home', '/{user}/m/{media}/',
- requirements=dict(m_id="[0-9a-fA-F]{24}"),
- controller="mediagoblin.user_pages.views:media_home"),
- Route('mediagoblin.user_pages.media_home.view_comment',
- '/{user}/m/{media}/c/{comment}/',
- controller="mediagoblin.user_pages.views:media_home"),
- Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/",
- controller="mediagoblin.edit.views:edit_media"),
- Route('mediagoblin.edit.attachments',
- '/{user}/m/{media}/attachments/',
- controller="mediagoblin.edit.views:edit_attachments"),
- Route('mediagoblin.user_pages.media_confirm_delete',
- "/{user}/m/{media}/confirm-delete/",
- controller="mediagoblin.user_pages.views:media_confirm_delete"),
- Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/',
- controller="mediagoblin.user_pages.views:atom_feed"),
- Route('mediagoblin.user_pages.media_post_comment',
- '/{user}/m/{media}/comment/add/',
- controller="mediagoblin.user_pages.views:media_post_comment"),
- Route('mediagoblin.user_pages.media_collect',
- "/{user}/m/{media}/collect/",
- controller="mediagoblin.user_pages.views:media_collect"),
- Route('mediagoblin.user_pages.user_collection', "/{user}/collection/{collection}/",
- controller="mediagoblin.user_pages.views:user_collection"),
- Route('mediagoblin.edit.edit_collection', "/{user}/c/{collection}/edit/",
- controller="mediagoblin.edit.views:edit_collection"),
- Route('mediagoblin.user_pages.collection_confirm_delete',
- "/{user}/c/{collection}/confirm-delete/",
- controller="mediagoblin.user_pages.views:collection_confirm_delete"),
- Route('mediagoblin.user_pages.collection_item_confirm_remove',
- "/{user}/collection/{collection}/{collection_item}/confirm_remove/",
- controller="mediagoblin.user_pages.views:collection_item_confirm_remove"),
- Route('mediagoblin.user_pages.collection_atom_feed', '/{user}/collection/{collection}/atom/',
- controller="mediagoblin.user_pages.views:collection_atom_feed"),
- Route('mediagoblin.user_pages.processing_panel',
- '/{user}/panel/',
- controller="mediagoblin.user_pages.views:processing_panel"),
- ]
+from mediagoblin.routing import add_route
+
+add_route('mediagoblin.user_pages.user_home',
+ '/u/<string:user>/', 'mediagoblin.user_pages.views:user_home')
+
+add_route('mediagoblin.user_pages.media_home',
+ '/u/<string:user>/m/<string:media>/',
+ 'mediagoblin.user_pages.views:media_home')
+
+add_route('mediagoblin.user_pages.media_confirm_delete',
+ '/u/<string:user>/m/<string:media>/confirm-delete/',
+ 'mediagoblin.user_pages.views:media_confirm_delete')
+
+add_route('mediagoblin.user_pages.media_post_comment',
+ '/u/<string:user>/m/<string:media>/comment/add/',
+ 'mediagoblin.user_pages.views:media_post_comment')
+
+add_route('mediagoblin.user_pages.user_gallery',
+ '/u/<string:user>/gallery/',
+ 'mediagoblin.user_pages.views:user_gallery')
+
+add_route('mediagoblin.user_pages.media_home.view_comment',
+ '/u/<string:user>/m/<string:media>/c/<string:comment>/',
+ 'mediagoblin.user_pages.views:media_home')
+
+add_route('mediagoblin.user_pages.atom_feed',
+ '/u/<string:user>/atom/',
+ 'mediagoblin.user_pages.views:atom_feed')
+
+add_route('mediagoblin.user_pages.media_collect',
+ '/u/<string:user>/m/<string:media>/collect/',
+ 'mediagoblin.user_pages.views:media_collect')
+
+add_route('mediagoblin.user_pages.user_collection',
+ '/u/<string:user>/collection/<string:collection>/',
+ 'mediagoblin.user_pages.views:user_collection')
+
+add_route('mediagoblin.edit.edit_collection',
+ '/u/<string:user>/c/<string:collection>/edit/',
+ 'mediagoblin.edit.views:edit_collection')
+
+add_route('mediagoblin.user_pages.collection_confirm_delete',
+ '/u/<string:user>/c/<string:collection>/confirm-delete/',
+ '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')
# 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/>.
-from routes.route import Route
+from mediagoblin.routing import add_route
-webfinger_well_known_routes = [
- Route('mediagoblin.webfinger.host_meta', '/host-meta',
- controller='mediagoblin.webfinger.views:host_meta')]
+add_route('mediagoblin.webfinger.host_meta', '/.well-known/host-meta',
+ 'mediagoblin.webfinger.views:host_meta')
-webfinger_routes = [
- Route('mediagoblin.webfinger.xrd', '/xrd',
- controller='mediagoblin.webfinger.views:xrd')]
+add_route('mediagoblin.webfinger.xrd', '/webfinger/xrd',
+ 'mediagoblin.webfinger.views:xrd')