Create the RoutedMixin class
It will be used both in the app, and later blueprint classes.
This commit is contained in:
parent
89dc258a5b
commit
8d45611e35
@ -25,6 +25,8 @@ from flask_babelex import Babel, get_locale as babel_get_locale
|
|||||||
from flask_security import SQLAlchemyUserDatastore, current_user, login_required
|
from flask_security import SQLAlchemyUserDatastore, current_user, login_required
|
||||||
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
|
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
|
||||||
|
|
||||||
|
from calsocial.utils import RoutedMixin
|
||||||
|
|
||||||
|
|
||||||
def get_locale():
|
def get_locale():
|
||||||
"""Locale selector
|
"""Locale selector
|
||||||
@ -53,22 +55,7 @@ def template_vars():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def route(*args, **kwargs):
|
class CalendarSocialApp(Flask, RoutedMixin):
|
||||||
"""Mark a function as a future route
|
|
||||||
|
|
||||||
Such functions will be iterated over when the application is initialised. ``*args`` and
|
|
||||||
``**kwargs`` will be passed verbatim to `Flask.route()`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def decorator(func): # pylint: disable=missing-docstring
|
|
||||||
setattr(func, 'routing', (args, kwargs))
|
|
||||||
|
|
||||||
return func
|
|
||||||
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
class CalendarSocialApp(Flask):
|
|
||||||
"""The Calendar.social app
|
"""The Calendar.social app
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -101,18 +88,7 @@ class CalendarSocialApp(Flask):
|
|||||||
|
|
||||||
self.context_processor(template_vars)
|
self.context_processor(template_vars)
|
||||||
|
|
||||||
for attr_name in self.__dir__():
|
RoutedMixin.register_routes(self)
|
||||||
attr = getattr(self, attr_name)
|
|
||||||
|
|
||||||
if not callable(attr):
|
|
||||||
continue
|
|
||||||
|
|
||||||
args, kwargs = getattr(attr, 'routing', (None, None))
|
|
||||||
|
|
||||||
if args is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.route(*args, **kwargs)(attr)
|
|
||||||
|
|
||||||
self.before_request(self.goto_first_steps)
|
self.before_request(self.goto_first_steps)
|
||||||
|
|
||||||
@ -165,7 +141,7 @@ class CalendarSocialApp(Flask):
|
|||||||
|
|
||||||
return GregorianCalendar(timestamp.timestamp())
|
return GregorianCalendar(timestamp.timestamp())
|
||||||
|
|
||||||
@route('/about')
|
@RoutedMixin.route('/about')
|
||||||
def about(self):
|
def about(self):
|
||||||
"""View for the about page
|
"""View for the about page
|
||||||
"""
|
"""
|
||||||
@ -190,7 +166,7 @@ class CalendarSocialApp(Flask):
|
|||||||
user_count=user_count,
|
user_count=user_count,
|
||||||
event_count=event_count)
|
event_count=event_count)
|
||||||
|
|
||||||
@route('/')
|
@RoutedMixin.route('/')
|
||||||
def hello(self):
|
def hello(self):
|
||||||
"""View for the main page
|
"""View for the main page
|
||||||
|
|
||||||
@ -206,7 +182,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('index.html', calendar=calendar, user_only=True)
|
return render_template('index.html', calendar=calendar, user_only=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/register', methods=['POST', 'GET'])
|
@RoutedMixin.route('/register', methods=['POST', 'GET'])
|
||||||
def register():
|
def register():
|
||||||
"""View for user registration
|
"""View for user registration
|
||||||
|
|
||||||
@ -236,7 +212,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('registration.html', form=form)
|
return render_template('registration.html', form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/new-event', methods=['GET', 'POST'])
|
@RoutedMixin.route('/new-event', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def new_event():
|
def new_event():
|
||||||
"""View for creating a new event
|
"""View for creating a new event
|
||||||
@ -261,7 +237,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('event-edit.html', form=form)
|
return render_template('event-edit.html', form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/settings', methods=['GET', 'POST'])
|
@RoutedMixin.route('/settings', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def settings():
|
def settings():
|
||||||
"""View for user settings
|
"""View for user settings
|
||||||
@ -282,7 +258,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('user-settings.html', form=form)
|
return render_template('user-settings.html', form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/event/<string:event_uuid>', methods=['GET', 'POST'])
|
@RoutedMixin.route('/event/<string:event_uuid>', methods=['GET', 'POST'])
|
||||||
def event_details(event_uuid):
|
def event_details(event_uuid):
|
||||||
"""View to display event details
|
"""View to display event details
|
||||||
"""
|
"""
|
||||||
@ -309,7 +285,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('event-details.html', event=event, form=form)
|
return render_template('event-details.html', event=event, form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/profile/@<string:username>')
|
@RoutedMixin.route('/profile/@<string:username>')
|
||||||
def display_profile(username):
|
def display_profile(username):
|
||||||
"""View to display profile details
|
"""View to display profile details
|
||||||
"""
|
"""
|
||||||
@ -324,7 +300,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('profile-details.html', profile=profile)
|
return render_template('profile-details.html', profile=profile)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/profile/@<string:username>/follow')
|
@RoutedMixin.route('/profile/@<string:username>/follow')
|
||||||
@login_required
|
@login_required
|
||||||
def follow_user(username):
|
def follow_user(username):
|
||||||
"""View for following a user
|
"""View for following a user
|
||||||
@ -345,7 +321,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return redirect(url_for('display_profile', username=username))
|
return redirect(url_for('display_profile', username=username))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/notifications')
|
@RoutedMixin.route('/notifications')
|
||||||
def notifications():
|
def notifications():
|
||||||
"""View to list the notifications for the current user
|
"""View to list the notifications for the current user
|
||||||
"""
|
"""
|
||||||
@ -360,7 +336,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('notifications.html', notifs=notifs)
|
return render_template('notifications.html', notifs=notifs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/accept/<int:invite_id>')
|
@RoutedMixin.route('/accept/<int:invite_id>')
|
||||||
def accept_invite(invite_id):
|
def accept_invite(invite_id):
|
||||||
"""View to accept an invitation
|
"""View to accept an invitation
|
||||||
"""
|
"""
|
||||||
@ -390,7 +366,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return redirect(url_for('event_details', event_uuid=invitation.event.event_uuid))
|
return redirect(url_for('event_details', event_uuid=invitation.event.event_uuid))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/first-steps', methods=['GET', 'POST'])
|
@RoutedMixin.route('/first-steps', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def first_steps():
|
def first_steps():
|
||||||
"""View to set up a new registrant’s profile
|
"""View to set up a new registrant’s profile
|
||||||
@ -417,7 +393,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('first-steps.html', form=form)
|
return render_template('first-steps.html', form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/edit-profile', methods=['GET', 'POST'])
|
@RoutedMixin.route('/edit-profile', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def edit_profile():
|
def edit_profile():
|
||||||
"""View for editing one’s profile
|
"""View for editing one’s profile
|
||||||
@ -438,7 +414,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('profile-edit.html', form=form)
|
return render_template('profile-edit.html', form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/all-events')
|
@RoutedMixin.route('/all-events')
|
||||||
def all_events():
|
def all_events():
|
||||||
"""View for listing all available events
|
"""View for listing all available events
|
||||||
"""
|
"""
|
||||||
@ -455,7 +431,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('index.html', calendar=calendar, user_only=False)
|
return render_template('index.html', calendar=calendar, user_only=False)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/follow-requests')
|
@RoutedMixin.route('/follow-requests')
|
||||||
@login_required
|
@login_required
|
||||||
def follow_requests():
|
def follow_requests():
|
||||||
"""View for listing follow requests
|
"""View for listing follow requests
|
||||||
@ -470,7 +446,7 @@ class CalendarSocialApp(Flask):
|
|||||||
return render_template('follow-requests.html', requests=requests)
|
return render_template('follow-requests.html', requests=requests)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/follow-request/<int:follower_id>/accept')
|
@RoutedMixin.route('/follow-request/<int:follower_id>/accept')
|
||||||
@login_required
|
@login_required
|
||||||
def accept_follow(follower_id):
|
def accept_follow(follower_id):
|
||||||
"""View for accepting a follow request
|
"""View for accepting a follow request
|
||||||
|
@ -68,3 +68,51 @@ def force_locale(locale):
|
|||||||
babel.locale_selector_func = orig_locale_selector_func
|
babel.locale_selector_func = orig_locale_selector_func
|
||||||
for key, value in orig_attrs.items():
|
for key, value in orig_attrs.items():
|
||||||
setattr(ctx, key, value)
|
setattr(ctx, key, value)
|
||||||
|
|
||||||
|
|
||||||
|
class RoutedMixin:
|
||||||
|
"""Mixin to lazily register class methods as routes
|
||||||
|
|
||||||
|
Works both for `Flask` and `Blueprint` objects.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
class MyBlueprint(Blueprint, RoutedMixin):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
do_whatever_you_like()
|
||||||
|
|
||||||
|
RoutedMixin.register_routes(self)
|
||||||
|
|
||||||
|
@RoutedMixin.route('/')
|
||||||
|
def index(self):
|
||||||
|
return 'Hello, World!'
|
||||||
|
"""
|
||||||
|
|
||||||
|
def register_routes(self):
|
||||||
|
for attr_name in self.__dir__():
|
||||||
|
attr = getattr(self, attr_name)
|
||||||
|
|
||||||
|
if not callable(attr):
|
||||||
|
continue
|
||||||
|
|
||||||
|
args, kwargs = getattr(attr, 'routing', (None, None))
|
||||||
|
|
||||||
|
if args is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.route(*args, **kwargs)(attr)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def route(*args, **kwargs):
|
||||||
|
"""Mark a function as a future route
|
||||||
|
|
||||||
|
Such functions will be iterated over when the application is initialised. ``*args`` and
|
||||||
|
``**kwargs`` will be passed verbatim to `Flask.route()`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func): # pylint: disable=missing-docstring
|
||||||
|
setattr(func, 'routing', (args, kwargs))
|
||||||
|
|
||||||
|
return func
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
Loading…
Reference in New Issue
Block a user