forked from gergely/calendar-social
Allow users to invite other users to events
This commit is contained in:
parent
6274543206
commit
17cca9380f
@ -235,12 +235,13 @@ 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>')
|
@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
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .models import Event
|
from .forms import InviteForm
|
||||||
|
from .models import db, Event, Invitation, Notification, NotificationAction
|
||||||
|
|
||||||
try:
|
try:
|
||||||
event = Event.query.filter(Event.event_uuid == event_uuid).one()
|
event = Event.query.filter(Event.event_uuid == event_uuid).one()
|
||||||
@ -249,7 +250,24 @@ class CalendarSocialApp(Flask):
|
|||||||
except MultipleResultsFound:
|
except MultipleResultsFound:
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
return render_template('event-details.html', event=event)
|
form = InviteForm(event)
|
||||||
|
|
||||||
|
if form.validate_on_submit():
|
||||||
|
invite = Invitation(event=event, sender=current_user.profile)
|
||||||
|
form.populate_obj(invite)
|
||||||
|
db.session.add(invite)
|
||||||
|
|
||||||
|
notification = Notification(profile=form.invitee.data,
|
||||||
|
actor=current_user.profile,
|
||||||
|
item=event,
|
||||||
|
action=NotificationAction.invite)
|
||||||
|
db.session.add(notification)
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for('event_details', event_uuid=event.event_uuid))
|
||||||
|
|
||||||
|
return render_template('event-details.html', event=event, form=form)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@route('/profile/@<string:username>')
|
@route('/profile/@<string:username>')
|
||||||
|
@ -194,3 +194,68 @@ class LoginForm(BaseLoginForm):
|
|||||||
AuditLog.log(self.user, AuditLog.TYPE_LOGIN_FAIL)
|
AuditLog.log(self.user, AuditLog.TYPE_LOGIN_FAIL)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileField(StringField):
|
||||||
|
"""Input field for profiles
|
||||||
|
"""
|
||||||
|
|
||||||
|
def process_formdata(self, valuelist):
|
||||||
|
from sqlalchemy.orm.exc import NoResultFound
|
||||||
|
|
||||||
|
from .models import User, Profile
|
||||||
|
|
||||||
|
if not valuelist:
|
||||||
|
self.data = None
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
value = valuelist[0]
|
||||||
|
|
||||||
|
if value.startswith('@'):
|
||||||
|
value = value[1:]
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.data = Profile.query.join(User).filter(User.username == value).one()
|
||||||
|
except NoResultFound:
|
||||||
|
self.data = None
|
||||||
|
|
||||||
|
raise ValueError('Unknown user')
|
||||||
|
|
||||||
|
def _value(self):
|
||||||
|
if self.data:
|
||||||
|
return self.data.fqn
|
||||||
|
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
class InviteForm(FlaskForm):
|
||||||
|
"""Form for event invitations
|
||||||
|
"""
|
||||||
|
|
||||||
|
invitee = ProfileField(validators=[DataRequired()])
|
||||||
|
|
||||||
|
def __init__(self, event, *args, **kwargs):
|
||||||
|
FlaskForm.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
self.event = event
|
||||||
|
|
||||||
|
def validate_invitee(self, field):
|
||||||
|
"""Validate the value of the invitee field
|
||||||
|
|
||||||
|
:raises ValidationError: If the given user is already invited
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy.orm.exc import NoResultFound
|
||||||
|
|
||||||
|
from .models import Invitation
|
||||||
|
|
||||||
|
try:
|
||||||
|
Invitation.query \
|
||||||
|
.filter(Invitation.event == self.event) \
|
||||||
|
.filter(Invitation.invitee == field.data) \
|
||||||
|
.one()
|
||||||
|
|
||||||
|
raise ValidationError(_('User is already invited'))
|
||||||
|
except NoResultFound:
|
||||||
|
pass
|
||||||
|
@ -64,9 +64,13 @@ class NotificationAction(Enum):
|
|||||||
#: A user followed another
|
#: A user followed another
|
||||||
follow = 1
|
follow = 1
|
||||||
|
|
||||||
|
#: A user has been invited to an event
|
||||||
|
invite = 2
|
||||||
|
|
||||||
|
|
||||||
NOTIFICATION_ACTION_MESSAGES = {
|
NOTIFICATION_ACTION_MESSAGES = {
|
||||||
NotificationAction.follow: (_('%(actor)s followed you'), _('%(actor)s followed %(item)s'))
|
NotificationAction.follow: (_('%(actor)s followed you'), _('%(actor)s followed %(item)s')),
|
||||||
|
NotificationAction.invite: (None, _('%(actor)s invited you to %(item)s')),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,4 +11,22 @@
|
|||||||
</small>
|
</small>
|
||||||
</h1>
|
</h1>
|
||||||
{{ event.description }}
|
{{ event.description }}
|
||||||
|
<hr>
|
||||||
|
<h2>{% trans %}Invited users{% endtrans %}</h2>
|
||||||
|
<ul>
|
||||||
|
{% for invitation in event.invitations %}
|
||||||
|
<li>{{ invitation.invitee }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<hr>
|
||||||
|
<h2>{% trans %}Invite{% endtrans %}</h2>
|
||||||
|
<form method="post">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
|
{{ form.invitee.errors }}
|
||||||
|
{{ form.invitee.label }}
|
||||||
|
{{ form.invitee}}
|
||||||
|
|
||||||
|
<button type="submit">{% trans %}Invite{% endtrans %}</button>
|
||||||
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user